aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorFelix Domke <tmbinc@elitedvb.net>2009-02-11 12:52:48 +0100
committerFelix Domke <tmbinc@elitedvb.net>2009-02-11 12:52:48 +0100
commitbbfcb7ea1f040d030277e2b6f2efa9ea0967bf2b (patch)
treec5945c791698c14723e989449e6b4bfcc275c05d /lib
parent4f7990ff2a55874b9eb65e3c9cd47dacb9f76deb (diff)
parent5e6f814d005a01caa437a532e61f4b338617ff67 (diff)
downloadenigma2-bbfcb7ea1f040d030277e2b6f2efa9ea0967bf2b.tar.gz
enigma2-bbfcb7ea1f040d030277e2b6f2efa9ea0967bf2b.zip
Merge branch 'master' of /home/tmbinc/enigma2-git into tmbinc/FixTimingBugs
Conflicts: lib/dvb/decoder.cpp
Diffstat (limited to 'lib')
-rw-r--r--lib/actions/parseactions.py4
-rw-r--r--lib/base/ebase.cpp22
-rw-r--r--lib/base/ebase.h3
-rw-r--r--lib/base/eerror.cpp12
-rw-r--r--lib/base/nconfig.cpp1
-rw-r--r--lib/driver/avswitch.cpp30
-rw-r--r--lib/driver/avswitch.h2
-rw-r--r--lib/dvb/db.cpp125
-rw-r--r--lib/dvb/decoder.cpp177
-rw-r--r--lib/dvb/decoder.h15
-rw-r--r--lib/dvb/demux.cpp19
-rw-r--r--lib/dvb/demux.h4
-rw-r--r--lib/dvb/dvb.cpp166
-rw-r--r--lib/dvb/dvb.h11
-rw-r--r--lib/dvb/dvbtime.cpp16
-rw-r--r--lib/dvb/dvbtime.h2
-rw-r--r--lib/dvb/epgcache.cpp114
-rw-r--r--lib/dvb/frontend.cpp668
-rw-r--r--lib/dvb/frontend.h20
-rw-r--r--lib/dvb/frontendparms.h125
-rw-r--r--lib/dvb/idemux.h2
-rw-r--r--lib/dvb/idvb.h26
-rw-r--r--lib/dvb/metaparser.cpp23
-rw-r--r--lib/dvb/metaparser.h3
-rw-r--r--lib/dvb/pmt.cpp94
-rw-r--r--lib/dvb/pmt.h4
-rw-r--r--lib/dvb/pvrparse.cpp17
-rw-r--r--lib/dvb/pvrparse.h3
-rw-r--r--lib/dvb/scan.cpp2
-rw-r--r--lib/dvb/sec.cpp504
-rw-r--r--lib/dvb/sec.h31
-rw-r--r--lib/gdi/picexif.cpp14
-rw-r--r--lib/gdi/picexif.h11
-rw-r--r--lib/gdi/picload.cpp1111
-rw-r--r--lib/gdi/picload.h104
-rw-r--r--lib/gui/elistbox.cpp2
-rw-r--r--lib/gui/elistboxcontent.cpp102
-rw-r--r--lib/gui/eslider.cpp15
-rw-r--r--lib/gui/eslider.h4
-rw-r--r--lib/gui/esubtitle.cpp1
-rw-r--r--lib/nav/core.cpp47
-rw-r--r--lib/nav/core.h7
-rw-r--r--lib/nav/pcore.cpp8
-rw-r--r--lib/nav/pcore.h4
-rw-r--r--lib/python/Components/AVSwitch.py71
-rw-r--r--lib/python/Components/Console.py9
-rw-r--r--lib/python/Components/Converter/EventTime.py4
-rw-r--r--lib/python/Components/Converter/MovieInfo.py4
-rw-r--r--lib/python/Components/Converter/RemainingToText.py34
-rw-r--r--lib/python/Components/Converter/ServicePosition.py15
-rw-r--r--lib/python/Components/Converter/ServiceTime.py4
-rw-r--r--lib/python/Components/Converter/TemplatedMultiContent.py32
-rw-r--r--lib/python/Components/Element.py7
-rw-r--r--lib/python/Components/EpgList.py62
-rw-r--r--lib/python/Components/FileList.py7
-rw-r--r--lib/python/Components/Harddisk.py190
-rw-r--r--lib/python/Components/Language.py1
-rw-r--r--lib/python/Components/Makefile.am2
-rw-r--r--lib/python/Components/MovieList.py5
-rw-r--r--lib/python/Components/MultiContent.py2
-rw-r--r--lib/python/Components/NimManager.py387
-rw-r--r--lib/python/Components/Renderer/Canvas.py2
-rw-r--r--lib/python/Components/ResourceManager.py23
-rw-r--r--lib/python/Components/Scanner.py2
-rw-r--r--lib/python/Components/ServiceScan.py98
-rw-r--r--lib/python/Components/Sources/List.py23
-rw-r--r--lib/python/Components/Sources/Progress.py7
-rw-r--r--lib/python/Components/Task.py18
-rw-r--r--lib/python/Components/TimerSanityCheck.py5
-rw-r--r--lib/python/Components/TuneTest.py235
-rw-r--r--lib/python/Components/TunerInfo.py40
-rw-r--r--lib/python/Components/UsageConfig.py22
-rwxr-xr-xlib/python/Components/config.py402
-rw-r--r--lib/python/Components/language_cache.py140
-rw-r--r--lib/python/Plugins/DemoPlugins/TestPlugin/plugin.py2
-rw-r--r--lib/python/Plugins/Extensions/CutListEditor/plugin.py103
-rw-r--r--lib/python/Plugins/Extensions/DVDBurn/DVDProject.py100
-rw-r--r--lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py10
-rw-r--r--lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py8
-rw-r--r--lib/python/Plugins/Extensions/DVDBurn/DreamboxDVD.ddvdp.xml14
-rw-r--r--lib/python/Plugins/Extensions/DVDBurn/DreamboxDVDtemplate.ddvdp.xml23
-rw-r--r--lib/python/Plugins/Extensions/DVDBurn/Process.py258
-rw-r--r--lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py36
-rw-r--r--lib/python/Plugins/Extensions/DVDBurn/Text menu boat.ddvdm.xml35
-rw-r--r--lib/python/Plugins/Extensions/DVDBurn/Thumbs menu clouds.ddvdm.xml35
-rw-r--r--lib/python/Plugins/Extensions/DVDBurn/TitleCutter.py7
-rw-r--r--lib/python/Plugins/Extensions/DVDBurn/TitleList.py28
-rw-r--r--lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py45
-rw-r--r--lib/python/Plugins/Extensions/DVDBurn/dreamdvd_clouds.jpgbin0 -> 62697 bytes
-rw-r--r--[-rwxr-xr-x]lib/python/Plugins/Extensions/DVDBurn/dvdburn.pngbin3869 -> 3869 bytes
-rw-r--r--lib/python/Plugins/Extensions/DVDPlayer/keymap.xml3
-rw-r--r--lib/python/Plugins/Extensions/DVDPlayer/plugin.py58
-rw-r--r--lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp87
-rw-r--r--lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py216
-rw-r--r--lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py4
-rw-r--r--lib/python/Plugins/Extensions/Makefile.am1
-rw-r--r--lib/python/Plugins/Extensions/MediaPlayer/plugin.py146
-rw-r--r--lib/python/Plugins/Extensions/MediaPlayer/settings.py22
-rw-r--r--lib/python/Plugins/Extensions/MediaScanner/plugin.py1
-rw-r--r--lib/python/Plugins/Extensions/PicturePlayer/plugin.py913
-rw-r--r--lib/python/Plugins/SystemPlugins/DiseqcTester/Makefile.am5
-rw-r--r--lib/python/Plugins/SystemPlugins/DiseqcTester/__init__.py0
-rw-r--r--lib/python/Plugins/SystemPlugins/DiseqcTester/plugin.py642
-rw-r--r--lib/python/Plugins/SystemPlugins/Hotplug/plugin.py15
-rw-r--r--lib/python/Plugins/SystemPlugins/Makefile.am2
-rw-r--r--lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py115
-rw-r--r--lib/python/Plugins/SystemPlugins/NFIFlash/flasher.py10
-rw-r--r--lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py200
-rw-r--r--lib/python/Plugins/SystemPlugins/Satfinder/plugin.py181
-rw-r--r--lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py81
-rw-r--r--lib/python/Plugins/SystemPlugins/Videomode/plugin.py1
-rw-r--r--lib/python/Plugins/newplugin.py146
-rw-r--r--lib/python/Screens/ChannelSelection.py2
-rw-r--r--lib/python/Screens/Console.py3
-rw-r--r--lib/python/Screens/EpgSelection.py99
-rw-r--r--lib/python/Screens/EventView.py56
-rw-r--r--lib/python/Screens/InfoBarGenerics.py74
-rwxr-xr-xlib/python/Screens/Makefile.am3
-rw-r--r--lib/python/Screens/Menu.py71
-rw-r--r--lib/python/Screens/Satconfig.py163
-rw-r--r--lib/python/Screens/ScanSetup.py361
-rw-r--r--lib/python/Screens/ServiceInfo.py37
-rw-r--r--lib/python/Screens/Setup.py52
-rw-r--r--lib/python/Screens/Standby.py6
-rw-r--r--lib/python/Screens/TextBox.py26
-rw-r--r--lib/python/Screens/TimerEdit.py59
-rw-r--r--lib/python/Screens/TimerEntry.py49
-rwxr-xr-x[-rw-r--r--]lib/python/Screens/Wizard.py10
-rw-r--r--lib/python/Tools/Directories.py3
-rw-r--r--lib/python/Tools/LoadPixmap.py2
-rw-r--r--lib/python/Tools/Makefile.am2
-rw-r--r--lib/python/Tools/NumericalTextInput.py59
-rw-r--r--lib/python/Tools/Transponder.py117
-rw-r--r--lib/python/enigma_python.i3
-rw-r--r--lib/python/python.cpp16
-rw-r--r--lib/python/python.h11
-rw-r--r--lib/service/listboxservice.cpp2
-rw-r--r--lib/service/servicedvb.cpp336
-rw-r--r--lib/service/servicedvb.h1
-rw-r--r--lib/service/servicedvbrecord.cpp115
-rw-r--r--lib/service/servicedvbrecord.h9
-rw-r--r--lib/service/servicemp3.cpp502
-rw-r--r--lib/service/servicemp3.h1
143 files changed, 7431 insertions, 3900 deletions
diff --git a/lib/actions/parseactions.py b/lib/actions/parseactions.py
index 4ab71af7..2462a751 100644
--- a/lib/actions/parseactions.py
+++ b/lib/actions/parseactions.py
@@ -65,7 +65,7 @@ def do_file(f, mode):
except:
pass
- raise "action enum must be simple."
+ raise Exception("action enum must be simple.")
counter = 0
@@ -82,7 +82,7 @@ def do_file(f, mode):
if counter:
if t != ",":
- raise "no comma"
+ raise Exception("no comma")
t = tokens.next()
if firsthit:
diff --git a/lib/base/ebase.cpp b/lib/base/ebase.cpp
index bd2ec589..313732ab 100644
--- a/lib/base/ebase.cpp
+++ b/lib/base/ebase.cpp
@@ -126,6 +126,17 @@ eMainloop::~eMainloop()
void eMainloop::addSocketNotifier(eSocketNotifier *sn)
{
int fd = sn->getFD();
+ if (m_inActivate && m_inActivate->ref.count == 1)
+ {
+ /* when the current active SocketNotifier's refcount is one,
+ then no more external references are existing.
+ So it gets destroyed when the activate callback is finished (->AddRef() / ->Release() calls in processOneEvent).
+ But then the sn->stop() is called to late for the next Asserion.
+ Thus we call sn->stop() here (this implicitly calls eMainloop::removeSocketNotifier) and we don't get trouble
+ with the next Assertion.
+ */
+ m_inActivate->stop();
+ }
ASSERT(notifiers.find(fd) == notifiers.end());
notifiers[fd]=sn;
}
@@ -243,14 +254,15 @@ int eMainloop::processOneEvent(unsigned int twisted_timeout, PyObject **res, ePy
if (it != notifiers.end()
&& it->second->state == 1) // added and in poll
{
- eSocketNotifier *sn = it->second;
- int req = sn->getRequested();
+ m_inActivate = it->second;
+ int req = m_inActivate->getRequested();
if (pfd[i].revents & req) {
- sn->AddRef();
- sn->activate(pfd[i].revents & req);
- sn->Release();
+ m_inActivate->AddRef();
+ m_inActivate->activate(pfd[i].revents & req);
+ m_inActivate->Release();
}
pfd[i].revents &= ~req;
+ m_inActivate = 0;
}
if (pfd[i].revents & (POLLERR|POLLHUP|POLLNVAL))
eDebug("poll: unhandled POLLERR/HUP/NVAL for fd %d(%d)", pfd[i].fd, pfd[i].revents);
diff --git a/lib/base/ebase.h b/lib/base/ebase.h
index 84845a95..524052bd 100644
--- a/lib/base/ebase.h
+++ b/lib/base/ebase.h
@@ -195,6 +195,7 @@ class eMainloop
int processOneEvent(unsigned int user_timeout, PyObject **res=0, ePyObject additional=ePyObject());
int retval;
int m_is_idle;
+ eSocketNotifier *m_inActivate;
int m_interrupt_requested;
timespec m_twisted_timer; // twisted timer
@@ -209,7 +210,7 @@ public:
#endif
eMainloop()
- :app_quit_now(0),loop_level(0),retval(0), m_is_idle(0), m_interrupt_requested(0)
+ :app_quit_now(0),loop_level(0),retval(0), m_is_idle(0), m_inActivate(0), m_interrupt_requested(0)
{
existing_loops.push_back(this);
}
diff --git a/lib/base/eerror.cpp b/lib/base/eerror.cpp
index 1e4d348f..4c4d6551 100644
--- a/lib/base/eerror.cpp
+++ b/lib/base/eerror.cpp
@@ -77,7 +77,7 @@ int logOutputConsole=1;
static pthread_mutex_t DebugLock =
PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP;
-extern void bsodFatal();
+extern void bsodFatal(const char *component);
void eFatal(const char* fmt, ...)
{
@@ -86,10 +86,12 @@ void eFatal(const char* fmt, ...)
va_start(ap, fmt);
vsnprintf(buf, 1024, fmt, ap);
va_end(ap);
- singleLock s(DebugLock);
- logOutput(lvlFatal, "FATAL: " + std::string(buf) + "\n");
- fprintf(stderr, "FATAL: %s\n",buf );
- bsodFatal();
+ {
+ singleLock s(DebugLock);
+ logOutput(lvlFatal, "FATAL: " + std::string(buf) + "\n");
+ fprintf(stderr, "FATAL: %s\n",buf );
+ }
+ bsodFatal("enigma2");
}
#ifdef DEBUG
diff --git a/lib/base/nconfig.cpp b/lib/base/nconfig.cpp
index 31b0a36f..106558ac 100644
--- a/lib/base/nconfig.cpp
+++ b/lib/base/nconfig.cpp
@@ -25,6 +25,7 @@ RESULT ePythonConfigQuery::getConfigValue(const char *key, std::string &value)
if (PyString_Check(pRet))
{
value.assign(PyString_AS_STRING(pRet));
+ Py_DECREF(pRet);
return 0;
}
Py_DECREF(pRet);
diff --git a/lib/driver/avswitch.cpp b/lib/driver/avswitch.cpp
index dbfebf5f..f05bdd95 100644
--- a/lib/driver/avswitch.cpp
+++ b/lib/driver/avswitch.cpp
@@ -132,23 +132,6 @@ void eAVSwitch::setInput(int val)
write(fd, input[val], strlen(input[val]));
close(fd);
-
- if (val == 1)
- setFastBlank(2);
-}
-
-void eAVSwitch::setFastBlank(int val)
-{
- int fd;
- const char *fb[] = {"low", "high", "vcr"};
-
- if((fd = open("/proc/stb/avs/0/fb", O_WRONLY)) < 0) {
- eDebug("cannot open /proc/stb/avs/0/fb");
- return;
- }
-
- write(fd, fb[val], strlen(fb[0]));
- close(fd);
}
void eAVSwitch::setColorFormat(int format)
@@ -284,18 +267,5 @@ void eAVSwitch::setWSS(int val) // 0 = auto, 1 = auto(4:3_off)
close(fd);
}
-void eAVSwitch::setSlowblank(int val)
-{
- int fd;
- if((fd = open("/proc/stb/avs/0/sb", O_WRONLY)) < 0) {
- eDebug("cannot open /proc/stb/avs/0/sb");
- return;
- }
- const char *sb[] = {"0", "6", "12", "vcr", "auto"};
- write(fd, sb[val], strlen(sb[val]));
-// eDebug("set slow blanking to %s", sb[val]);
- close(fd);
-}
-
//FIXME: correct "run/startlevel"
eAutoInitP0<eAVSwitch> init_avswitch(eAutoInitNumbers::rc, "AVSwitch Driver");
diff --git a/lib/driver/avswitch.h b/lib/driver/avswitch.h
index 8fdafdd1..bcb29c40 100644
--- a/lib/driver/avswitch.h
+++ b/lib/driver/avswitch.h
@@ -26,12 +26,10 @@ public:
static eAVSwitch *getInstance();
bool haveScartSwitch();
int getVCRSlowBlanking();
- void setFastBlank(int val);
void setColorFormat(int format);
void setAspectRatio(int ratio);
void setVideomode(int mode);
void setInput(int val);
- void setSlowblank(int val);
void setWSS(int val);
PSignal1<void, int> vcr_sb_notifier;
};
diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp
index 1c332033..e6108ab5 100644
--- a/lib/dvb/db.cpp
+++ b/lib/dvb/db.cpp
@@ -327,10 +327,10 @@ void eDVBDB::loadServicelist(const char *file)
eDVBFrontendParametersSatellite sat;
int frequency, symbol_rate, polarisation, fec, orbital_position, inversion,
flags=0,
- system=eDVBFrontendParametersSatellite::System::DVB_S,
- modulation=eDVBFrontendParametersSatellite::Modulation::QPSK,
- rolloff=eDVBFrontendParametersSatellite::RollOff::alpha_0_35,
- pilot=eDVBFrontendParametersSatellite::Pilot::Unknown;
+ system=eDVBFrontendParametersSatellite::System_DVB_S,
+ modulation=eDVBFrontendParametersSatellite::Modulation_QPSK,
+ rolloff=eDVBFrontendParametersSatellite::RollOff_alpha_0_35,
+ pilot=eDVBFrontendParametersSatellite::Pilot_Unknown;
if (version == 3)
sscanf(line+3, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &polarisation, &fec, &orbital_position, &inversion, &system, &modulation, &rolloff, &pilot);
else
@@ -368,9 +368,9 @@ void eDVBDB::loadServicelist(const char *file)
{
eDVBFrontendParametersCable cab;
int frequency, symbol_rate,
- inversion=eDVBFrontendParametersCable::Inversion::Unknown,
- modulation=eDVBFrontendParametersCable::Modulation::Auto,
- fec_inner=eDVBFrontendParametersCable::FEC::fAuto,
+ inversion=eDVBFrontendParametersCable::Inversion_Unknown,
+ modulation=eDVBFrontendParametersCable::Modulation_Auto,
+ fec_inner=eDVBFrontendParametersCable::FEC_Auto,
flags=0;
sscanf(line+3, "%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &inversion, &modulation, &fec_inner, &flags);
cab.frequency = frequency;
@@ -495,9 +495,9 @@ void eDVBDB::saveServicelist(const char *file)
ch.m_frontendParameters->getFlags(flags);
if (!ch.m_frontendParameters->getDVBS(sat))
{
- if (sat.system == eDVBFrontendParametersSatellite::System::DVB_S2)
+ if (sat.system == eDVBFrontendParametersSatellite::System_DVB_S2)
{
- fprintf(f, "\ts %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
+ fprintf(f, "\ts %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d\n",
sat.frequency, sat.symbol_rate,
sat.polarisation, sat.fec,
sat.orbital_position > 1800 ? sat.orbital_position - 3600 : sat.orbital_position,
@@ -786,7 +786,7 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
return Py_False;
}
int tmp, *dest = NULL,
- modulation, system, freq, sr, pol, fec, inv, pilot, rolloff;
+ modulation, system, freq, sr, pol, fec, inv, pilot, rolloff, tsid, onid;
char *end_ptr;
const Attribute *at;
std::string name;
@@ -842,18 +842,21 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
// eDebug("\telement: %s", (*it)->name().c_str());
const AttributeList &tp_attributes = (*it)->getAttributeList();
AttributeConstIterator end = tp_attributes.end();
- modulation = 1; // QPSK default
- system = 0; // DVB-S default
+ modulation = eDVBFrontendParametersSatellite::Modulation_QPSK;
+ system = eDVBFrontendParametersSatellite::System_DVB_S;
freq = 0;
sr = 0;
pol = -1;
- fec = 0; // AUTO default
- inv = 2; // AUTO default
- pilot = 2; // AUTO default
- rolloff = 0; // alpha 0.35
+ fec = eDVBFrontendParametersSatellite::FEC_Auto;
+ inv = eDVBFrontendParametersSatellite::Inversion_Unknown;
+ pilot = eDVBFrontendParametersSatellite::Pilot_Unknown;
+ rolloff = eDVBFrontendParametersSatellite::RollOff_alpha_0_35;
+ tsid = -1;
+ onid = -1;
+
for (AttributeConstIterator it(tp_attributes.begin()); it != end; ++it)
{
-// eDebug("\t\tattr: %s", at->name().c_str());
+ //eDebug("\t\tattr: %s", at->name().c_str());
at = *it;
name = at->name();
if (name == "modulation") dest = &modulation;
@@ -865,6 +868,8 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
else if (name == "inversion") dest = &inv;
else if (name == "rolloff") dest = &rolloff;
else if (name == "pilot") dest = &pilot;
+ else if (name == "tsid") dest = &tsid;
+ else if (name == "onid") dest = &onid;
if (dest)
{
tmp = strtol(at->value().c_str(), &end_ptr, 10);
@@ -874,7 +879,7 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
}
if (freq && sr && pol != -1)
{
- tuple = PyTuple_New(10);
+ tuple = PyTuple_New(12);
PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0));
PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(freq));
PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(sr));
@@ -885,6 +890,8 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
PyTuple_SET_ITEM(tuple, 7, PyInt_FromLong(inv));
PyTuple_SET_ITEM(tuple, 8, PyInt_FromLong(rolloff));
PyTuple_SET_ITEM(tuple, 9, PyInt_FromLong(pilot));
+ PyTuple_SET_ITEM(tuple, 10, PyInt_FromLong(tsid));
+ PyTuple_SET_ITEM(tuple, 11, PyInt_FromLong(onid));
PyList_Append(tplist, tuple);
Py_DECREF(tuple);
}
@@ -974,8 +981,8 @@ PyObject *eDVBDB::readCables(ePyObject cab_list, ePyObject tp_dict)
// eDebug("\telement: %s", (*it)->name().c_str());
const AttributeList &tp_attributes = (*it)->getAttributeList();
AttributeConstIterator end = tp_attributes.end();
- modulation = 3; // QAM64 default
- fec = 0; // AUTO default
+ modulation = eDVBFrontendParametersCable::Modulation_QAM64;
+ fec = eDVBFrontendParametersCable::FEC_Auto;
freq = 0;
sr = 0;
for (AttributeConstIterator it(tp_attributes.begin()); it != end; ++it)
@@ -1088,14 +1095,14 @@ PyObject *eDVBDB::readTerrestrials(ePyObject ter_list, ePyObject tp_dict)
const AttributeList &tp_attributes = (*it)->getAttributeList();
AttributeConstIterator end = tp_attributes.end();
freq = 0;
- bw = 3; // AUTO
- constellation = 1; // AUTO
- crh = 5; // AUTO
- crl = 5; // AUTO
- guard = 4; // AUTO
- transm = 2; // AUTO
- hierarchy = 4; // AUTO
- inv = 2; // AUTO
+ bw = eDVBFrontendParametersTerrestrial::Bandwidth_Auto;
+ constellation = eDVBFrontendParametersTerrestrial::Modulation_Auto;
+ crh = eDVBFrontendParametersTerrestrial::FEC_Auto;
+ crl = eDVBFrontendParametersTerrestrial::FEC_Auto;
+ guard = eDVBFrontendParametersTerrestrial::GuardInterval_Auto;
+ transm = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto;
+ hierarchy = eDVBFrontendParametersTerrestrial::Hierarchy_Auto;
+ inv = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
for (AttributeConstIterator it(tp_attributes.begin()); it != end; ++it)
{
// eDebug("\t\tattr: %s", at->name().c_str());
@@ -1497,7 +1504,7 @@ int eDVBDBQueryBase::compareLessEqual(const eServiceReferenceDVB &a, const eServ
{
ePtr<eDVBService> a_service, b_service;
int sortmode = m_query ? m_query->m_sort : eDVBChannelQuery::tName;
-
+
if ((sortmode == eDVBChannelQuery::tName) || (sortmode == eDVBChannelQuery::tProvider))
{
if (a.name.empty() && m_db->getService(a, a_service))
@@ -1505,7 +1512,7 @@ int eDVBDBQueryBase::compareLessEqual(const eServiceReferenceDVB &a, const eServ
if (b.name.empty() && m_db->getService(b, b_service))
return 1;
}
-
+
switch (sortmode)
{
case eDVBChannelQuery::tName:
@@ -1747,10 +1754,10 @@ static int decodeType(const std::string &type)
RESULT parseExpression(ePtr<eDVBChannelQuery> &res, std::list<std::string>::const_iterator begin, std::list<std::string>::const_iterator end)
{
std::list<std::string>::const_iterator end_of_exp;
-
+
if (begin == end)
return 0;
-
+
if (*begin == "(")
{
end_of_exp = begin;
@@ -1759,36 +1766,36 @@ RESULT parseExpression(ePtr<eDVBChannelQuery> &res, std::list<std::string>::cons
break;
else
++end_of_exp;
-
+
if (end_of_exp == end)
{
eDebug("expression parse: end of expression while searching for closing brace");
return -1;
}
-
+
++begin;
// begin..end_of_exp
int r = parseExpression(res, begin, end_of_exp);
if (r)
return r;
++end_of_exp;
-
+
/* we had only one sub expression */
if (end_of_exp == end)
{
// eDebug("only one sub expression");
return 0;
}
-
+
/* otherwise we have an operator here.. */
-
+
ePtr<eDVBChannelQuery> r2 = res;
res = new eDVBChannelQuery();
res->m_sort = 0;
res->m_p1 = r2;
res->m_inverse = 0;
r2 = 0;
-
+
if (*end_of_exp == "||")
res->m_type = eDVBChannelQuery::tOR;
else if (*end_of_exp == "&&")
@@ -1799,18 +1806,18 @@ RESULT parseExpression(ePtr<eDVBChannelQuery> &res, std::list<std::string>::cons
res = 0;
return 1;
}
-
+
++end_of_exp;
-
+
return parseExpression(res->m_p2, end_of_exp, end);
}
-
+
// "begin" <op> "end"
std::string type, op, val;
-
+
res = new eDVBChannelQuery();
res->m_sort = 0;
-
+
int cnt = 0;
while (begin != end)
{
@@ -1832,23 +1839,23 @@ RESULT parseExpression(ePtr<eDVBChannelQuery> &res, std::list<std::string>::cons
++begin;
++cnt;
}
-
+
if (cnt != 3)
{
eDebug("malformed query: missing stuff");
res = 0;
return 1;
}
-
+
res->m_type = decodeType(type);
-
+
if (res->m_type == -1)
{
eDebug("malformed query: invalid type %s", type.c_str());
res = 0;
return 1;
}
-
+
if (op == "==")
res->m_inverse = 0;
else if (op == "!=")
@@ -1859,7 +1866,7 @@ RESULT parseExpression(ePtr<eDVBChannelQuery> &res, std::list<std::string>::cons
res = 0;
return 1;
}
-
+
res->m_string = val;
if (res->m_type == eDVBChannelQuery::tChannelID)
@@ -1879,7 +1886,7 @@ RESULT parseExpression(ePtr<eDVBChannelQuery> &res, std::list<std::string>::cons
RESULT eDVBChannelQuery::compile(ePtr<eDVBChannelQuery> &res, std::string query)
{
std::list<std::string> tokens;
-
+
std::string current_token;
std::string bouquet_name;
@@ -1891,34 +1898,34 @@ RESULT eDVBChannelQuery::compile(ePtr<eDVBChannelQuery> &res, std::string query)
{
int c = (i < query.size()) ? query[i] : ' ';
++i;
-
+
int issplit = !!strchr(splitchars, c);
int isaln = isalnum(c);
int iswhite = c == ' ';
int isquot = c == '\"';
-
+
if (quotemode)
{
iswhite = issplit = 0;
isaln = lastalnum;
}
-
+
if (issplit || iswhite || isquot || lastsplit || (lastalnum != isaln))
{
if (current_token.size())
tokens.push_back(current_token);
current_token.clear();
}
-
+
if (!(iswhite || isquot))
current_token += c;
-
+
if (isquot)
quotemode = !quotemode;
lastsplit = issplit;
lastalnum = isaln;
}
-
+
// for (std::list<std::string>::const_iterator a(tokens.begin()); a != tokens.end(); ++a)
// {
// printf("%s\n", a->c_str());
@@ -1970,12 +1977,12 @@ RESULT eDVBChannelQuery::compile(ePtr<eDVBChannelQuery> &res, std::string query)
res = 0;
return -1;
}
-
+
// eDebug("sort by %d", sort);
-
+
/* now we recursivly parse that. */
int r = parseExpression(res, tokens.begin(), tokens.end());
-
+
/* we have an empty (but valid!) expression */
if (!r && !res)
{
@@ -1983,7 +1990,7 @@ RESULT eDVBChannelQuery::compile(ePtr<eDVBChannelQuery> &res, std::string query)
res->m_inverse = 0;
res->m_type = eDVBChannelQuery::tAny;
}
-
+
if (res)
{
res->m_sort = sort;
diff --git a/lib/dvb/decoder.cpp b/lib/dvb/decoder.cpp
index 66b923a6..f73dbdd9 100644
--- a/lib/dvb/decoder.cpp
+++ b/lib/dvb/decoder.cpp
@@ -187,11 +187,15 @@ int eDVBAudio::startPid(int pid, int type)
case aAC3:
bypass = 0;
break;
- /*
case aDTS:
bypass = 2;
break;
- */
+ case aAAC:
+ bypass = 8;
+ break;
+ case aAACHE:
+ bypass = 9;
+ break;
}
eDebugNoNewLine("AUDIO_SET_BYPASS(%d) - ", bypass);
@@ -291,7 +295,9 @@ eDVBAudio::~eDVBAudio()
DEFINE_REF(eDVBVideo);
eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev)
- :m_demux(demux), m_dev(dev)
+<<<<<<< HEAD:lib/dvb/decoder.cpp
+ : m_demux(demux), m_dev(dev),
+ m_width(-1), m_height(-1), m_framerate(-1), m_aspect(-1), m_progressive(-1)
{
char filename[128];
#if HAVE_DVB_API_VERSION < 3
@@ -325,6 +331,10 @@ eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev)
// not finally values i think.. !!
#define VIDEO_STREAMTYPE_MPEG2 0
#define VIDEO_STREAMTYPE_MPEG4_H264 1
+#define VIDEO_STREAMTYPE_VC1 3
+#define VIDEO_STREAMTYPE_MPEG4_Part2 4
+#define VIDEO_STREAMTYPE_VC1_SM 5
+#define VIDEO_STREAMTYPE_MPEG1 6
#if HAVE_DVB_API_VERSION < 3
int eDVBVideo::setPid(int pid)
@@ -386,13 +396,36 @@ int eDVBVideo::stopPid()
#else
int eDVBVideo::startPid(int pid, int type)
{
+ int streamtype = VIDEO_STREAMTYPE_MPEG2;
+
if ((m_fd < 0) || (m_fd_demux < 0))
return -1;
dmx_pes_filter_params pes;
- eDebugNoNewLine("VIDEO_SET_STREAMTYPE %d - ",type == MPEG4_H264 ? VIDEO_STREAMTYPE_MPEG4_H264 : VIDEO_STREAMTYPE_MPEG2);
- if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE,
- type == MPEG4_H264 ? VIDEO_STREAMTYPE_MPEG4_H264 : VIDEO_STREAMTYPE_MPEG2) < 0)
+ switch(type)
+ {
+ default:
+ case MPEG2:
+ break;
+ case MPEG4_H264:
+ streamtype = VIDEO_STREAMTYPE_MPEG4_H264;
+ break;
+ case MPEG1:
+ streamtype = VIDEO_STREAMTYPE_MPEG1;
+ break;
+ case MPEG4_Part2:
+ streamtype = VIDEO_STREAMTYPE_MPEG4_Part2;
+ break;
+ case VC1:
+ streamtype = VIDEO_STREAMTYPE_VC1;
+ break;
+ case VC1_SM:
+ streamtype = VIDEO_STREAMTYPE_VC1_SM;
+ break;
+ }
+
+ eDebugNoNewLine("VIDEO_SET_STREAMTYPE %d - ", streamtype);
+ if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE, streamtype) < 0)
eDebug("failed (%m)");
else
eDebug("ok");
@@ -533,23 +566,23 @@ void eDVBVideo::video_event(int)
{
struct iTSMPEGDecoder::videoEvent event;
event.type = iTSMPEGDecoder::videoEvent::eventSizeChanged;
- event.aspect = evt.u.size.aspect_ratio;
- event.height = evt.u.size.h;
- event.width = evt.u.size.w;
+ m_aspect = event.aspect = evt.u.size.aspect_ratio == 0 ? 2 : 3; // convert dvb api to etsi
+ m_height = event.height = evt.u.size.h;
+ m_width = event.width = evt.u.size.w;
/* emit */ m_event(event);
}
else if (evt.type == VIDEO_EVENT_FRAME_RATE_CHANGED)
{
struct iTSMPEGDecoder::videoEvent event;
event.type = iTSMPEGDecoder::videoEvent::eventFrameRateChanged;
- event.framerate = evt.u.frame_rate;
+ m_framerate = event.framerate = evt.u.frame_rate;
/* emit */ m_event(event);
}
else if (evt.type == 16 /*VIDEO_EVENT_PROGRESSIVE_CHANGED*/)
{
struct iTSMPEGDecoder::videoEvent event;
event.type = iTSMPEGDecoder::videoEvent::eventProgressiveChanged;
- event.progressive = evt.u.frame_rate;
+ m_progressive = event.progressive = evt.u.frame_rate;
/* emit */ m_event(event);
}
else
@@ -566,6 +599,93 @@ RESULT eDVBVideo::connectEvent(const Slot1<void, struct iTSMPEGDecoder::videoEve
return 0;
}
+static int readMpegProc(char *str, int decoder)
+{
+ int val = -1;
+ char tmp[64];
+ sprintf(tmp, "/proc/stb/vmpeg/%d/%s", decoder, str);
+ FILE *f = fopen(tmp, "r");
+ if (f)
+ {
+ fscanf(f, "%x", &val);
+ fclose(f);
+ }
+ return val;
+}
+
+static int readApiSize(int fd, int &xres, int &yres, int &aspect)
+{
+#if HAVE_DVB_API_VERSION >= 3
+ video_size_t size;
+ if (!::ioctl(fd, VIDEO_GET_SIZE, &size))
+ {
+ xres = size.w;
+ yres = size.h;
+ aspect = size.aspect_ratio == 0 ? 2 : 3; // convert dvb api to etsi
+ return 0;
+ }
+// eDebug("VIDEO_GET_SIZE failed (%m)");
+#endif
+ return -1;
+}
+
+static int readApiFrameRate(int fd, int &framerate)
+{
+#if HAVE_DVB_API_VERSION >= 3
+ unsigned int frate;
+ if (!::ioctl(fd, VIDEO_GET_FRAME_RATE, &frate))
+ {
+ framerate = frate;
+ return 0;
+ }
+// eDebug("VIDEO_GET_FRAME_RATE failed (%m)");
+#endif
+ return -1;
+}
+
+int eDVBVideo::getWidth()
+{
+ if (m_width == -1)
+ readApiSize(m_fd, m_width, m_height, m_aspect);
+ if (m_width == -1)
+ m_width = readMpegProc("xres", m_dev);
+ return m_width;
+}
+
+int eDVBVideo::getHeight()
+{
+ if (m_height == -1)
+ readApiSize(m_fd, m_width, m_height, m_aspect);
+ if (m_height == -1)
+ m_height = readMpegProc("yres", m_dev);
+ return m_height;
+}
+
+int eDVBVideo::getAspect()
+{
+ if (m_aspect == -1)
+ readApiSize(m_fd, m_width, m_height, m_aspect);
+ if (m_aspect == -1)
+ m_aspect = readMpegProc("aspect", m_dev);
+ return m_aspect;
+}
+
+int eDVBVideo::getProgressive()
+{
+ if (m_progressive == -1)
+ m_progressive = readMpegProc("progressive", m_dev);
+ return m_progressive;
+}
+
+int eDVBVideo::getFrameRate()
+{
+ if (m_framerate == -1)
+ readApiFrameRate(m_fd, m_framerate);
+ if (m_framerate == -1)
+ m_framerate = readMpegProc("framerate", m_dev);
+ return m_framerate;
+}
+
DEFINE_REF(eDVBPCR);
eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux)
@@ -1227,3 +1347,38 @@ void eTSMPEGDecoder::video_event(struct videoEvent event)
{
/* emit */ m_video_event(event);
}
+
+int eTSMPEGDecoder::getVideoWidth()
+{
+ if (m_video)
+ return m_video->getWidth();
+ return -1;
+}
+
+int eTSMPEGDecoder::getVideoHeight()
+{
+ if (m_video)
+ return m_video->getHeight();
+ return -1;
+}
+
+int eTSMPEGDecoder::getVideoProgressive()
+{
+ if (m_video)
+ return m_video->getProgressive();
+ return -1;
+}
+
+int eTSMPEGDecoder::getVideoFrameRate()
+{
+ if (m_video)
+ return m_video->getFrameRate();
+ return -1;
+}
+
+int eTSMPEGDecoder::getVideoAspect()
+{
+ if (m_video)
+ return m_video->getAspect();
+ return -1;
+}
diff --git a/lib/dvb/decoder.h b/lib/dvb/decoder.h
index 04501fe6..51be5141 100644
--- a/lib/dvb/decoder.h
+++ b/lib/dvb/decoder.h
@@ -13,7 +13,7 @@ private:
ePtr<eDVBDemux> m_demux;
int m_fd, m_fd_demux, m_dev, m_is_freezed;
public:
- enum { aMPEG, aAC3, aDTS, aAAC };
+ enum { aMPEG, aAC3, aDTS, aAAC, aAACHE };
eDVBAudio(eDVBDemux *demux, int dev);
enum { aMonoLeft, aStereo, aMonoRight };
void setChannel(int channel);
@@ -47,8 +47,9 @@ private:
ePtr<eSocketNotifier> m_sn;
void video_event(int what);
Signal1<void, struct iTSMPEGDecoder::videoEvent> m_event;
+ int m_width, m_height, m_framerate, m_aspect, m_progressive;
public:
- enum { MPEG2, MPEG4_H264 };
+ enum { MPEG2, MPEG4_H264, MPEG1, MPEG4_Part2, VC1, VC1_SM };
eDVBVideo(eDVBDemux *demux, int dev);
void stop();
#if HAVE_DVB_API_VERSION < 3
@@ -67,6 +68,11 @@ public:
int getPTS(pts_t &now);
virtual ~eDVBVideo();
RESULT connectEvent(const Slot1<void, struct iTSMPEGDecoder::videoEvent> &event, ePtr<eConnection> &conn);
+ int getWidth();
+ int getHeight();
+ int getProgressive();
+ int getFrameRate();
+ int getAspect();
};
class eDVBPCR: public iObject
@@ -182,6 +188,11 @@ public:
/* what 0=auto, 1=video, 2=audio. */
RESULT getPTS(int what, pts_t &pts);
RESULT connectVideoEvent(const Slot1<void, struct videoEvent> &event, ePtr<eConnection> &connection);
+ int getVideoWidth();
+ int getVideoHeight();
+ int getVideoProgressive();
+ int getVideoFrameRate();
+ int getVideoAspect();
};
#endif
diff --git a/lib/dvb/demux.cpp b/lib/dvb/demux.cpp
index a0f1c326..810b10a5 100644
--- a/lib/dvb/demux.cpp
+++ b/lib/dvb/demux.cpp
@@ -405,12 +405,14 @@ public:
void setTimingPID(int pid);
void saveTimingInformation(const std::string &filename);
+ int getLastPTS(pts_t &pts);
protected:
int filterRecordData(const unsigned char *data, int len, size_t &current_span_remaining);
private:
eMPEGStreamParserTS m_ts_parser;
eMPEGStreamInformation m_stream_info;
off_t m_current_offset;
+ pts_t m_last_pcr; /* very approximate.. */
int m_pid;
};
@@ -430,6 +432,11 @@ void eDVBRecordFileThread::saveTimingInformation(const std::string &filename)
m_stream_info.save(filename.c_str());
}
+int eDVBRecordFileThread::getLastPTS(pts_t &pts)
+{
+ return m_ts_parser.getLastPTS(pts);
+}
+
int eDVBRecordFileThread::filterRecordData(const unsigned char *data, int len, size_t &current_span_remaining)
{
m_ts_parser.parseData(m_current_offset, data, len);
@@ -589,6 +596,18 @@ RESULT eDVBTSRecorder::stop()
return 0;
}
+RESULT eDVBTSRecorder::getCurrentPCR(pts_t &pcr)
+{
+ if (!m_running)
+ return 0;
+ if (!m_thread)
+ return 0;
+ /* XXX: we need a lock here */
+
+ /* we don't filter PCR data, so just use the last received PTS, which is not accurate, but better than nothing */
+ return m_thread->getLastPTS(pcr);
+}
+
RESULT eDVBTSRecorder::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &conn)
{
conn = new eConnection(this, m_event.connect(event));
diff --git a/lib/dvb/demux.h b/lib/dvb/demux.h
index 1a7db979..14501b98 100644
--- a/lib/dvb/demux.h
+++ b/lib/dvb/demux.h
@@ -101,7 +101,9 @@ public:
RESULT setBoundary(off_t max);
RESULT stop();
-
+
+ RESULT getCurrentPCR(pts_t &pcr);
+
RESULT connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &conn);
private:
RESULT startPID(int pid);
diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp
index 28012e7a..c320fc78 100644
--- a/lib/dvb/dvb.cpp
+++ b/lib/dvb/dvb.cpp
@@ -4,6 +4,7 @@
#include <lib/dvb/dvb.h>
#include <lib/dvb/pmt.h>
#include <lib/dvb/sec.h>
+#include <lib/dvb/specs.h>
#include <errno.h>
#include <sys/types.h>
@@ -69,19 +70,19 @@ eDVBResourceManager::eDVBResourceManager()
if (!instance)
instance = this;
-
+
/* search available adapters... */
// add linux devices
-
+
int num_adapter = 0;
while (eDVBAdapterLinux::exist(num_adapter))
{
addAdapter(new eDVBAdapterLinux(num_adapter));
num_adapter++;
}
-
- eDebug("found %d adapter, %d frontends(%d sim) and %d demux",
+
+ eDebug("found %d adapter, %d frontends(%d sim) and %d demux",
m_adapter.size(), m_frontend.size(), m_simulate_frontend.size(), m_demux.size());
eDVBCAService::registerChannelCallback(this);
@@ -103,7 +104,7 @@ eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
{
// scan frontends
int num_fe = 0;
-
+
eDebug("scanning for frontends..");
while (1)
{
@@ -132,7 +133,7 @@ eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
}
++num_fe;
}
-
+
// scan demux
int num_demux = 0;
while (1)
@@ -147,10 +148,10 @@ eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
if (stat(filename, &s))
break;
ePtr<eDVBDemux> demux;
-
+
demux = new eDVBDemux(m_nr, num_demux);
m_demux.push_back(demux);
-
+
++num_demux;
}
}
@@ -168,12 +169,12 @@ RESULT eDVBAdapterLinux::getDemux(ePtr<eDVBDemux> &demux, int nr)
--nr;
++i;
}
-
+
if (i != m_demux.end())
demux = *i;
else
return -1;
-
+
return 0;
}
@@ -190,12 +191,12 @@ RESULT eDVBAdapterLinux::getFrontend(ePtr<eDVBFrontend> &fe, int nr, bool simula
--nr;
++i;
}
-
+
if (i != m_frontend.end())
fe = *i;
else
return -1;
-
+
return 0;
}
@@ -223,9 +224,9 @@ void eDVBResourceManager::addAdapter(iDVBAdapter *adapter)
{
int num_fe = adapter->getNumFrontends();
int num_demux = adapter->getNumDemux();
-
+
m_adapter.push_back(adapter);
-
+
int i;
for (i=0; i<num_demux; ++i)
{
@@ -425,9 +426,9 @@ RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBA
if (i == m_demux.end())
return -1;
-
+
ePtr<eDVBRegisteredDemux> unused;
-
+
if (m_demux.size() < 5)
{
/* FIXME: hardware demux policy */
@@ -443,14 +444,14 @@ RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBA
for (; i != m_demux.end(); ++i, ++n)
{
int is_decode = n < 2;
-
+
int in_use = is_decode ? (i->m_demux->getRefCount() != 2) : i->m_inuse;
-
+
if ((!in_use) && ((!fe) || (i->m_adapter == fe->m_adapter)))
{
if ((cap & iDVBChannel::capDecode) && !is_decode)
continue;
- unused = i;
+ unused = i;
break;
}
}
@@ -466,7 +467,7 @@ RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBA
if (!unused)
unused = i;
}
- else if (i->m_adapter == fe->m_adapter &&
+ else if (i->m_adapter == fe->m_adapter &&
i->m_demux->getSource() == fe->m_frontend->getDVBID())
{
demux = new eDVBAllocatedDemux(i);
@@ -572,7 +573,7 @@ RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUse
}
/* allocate a frontend. */
-
+
ePtr<eDVBAllocatedFrontend> fe;
int err = allocateFrontend(fe, feparm, simulate);
@@ -998,7 +999,7 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s
if (m_iframe_state == 1)
{
- /* we are allowing data, and stop allowing data on the next frame.
+ /* we are allowing data, and stop allowing data on the next frame.
we now found a frame. so stop here. */
memset(data + offset, 0, 188 - (offset%188)); /* zero out rest of TS packet */
current_span_remaining = 0;
@@ -1072,9 +1073,9 @@ eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *fronte
m_frontend = frontend;
m_pvr_thread = 0;
-
+
m_skipmode_n = m_skipmode_m = 0;
-
+
if (m_frontend)
m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
}
@@ -1090,14 +1091,14 @@ eDVBChannel::~eDVBChannel()
void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
{
int state, ourstate = 0;
-
+
/* if we are already in shutdown, don't change state. */
if (m_state == state_release)
return;
-
+
if (fe->getState(state))
return;
-
+
if (state == iDVBFrontend::stateLock)
{
eDebug("OURSTATE: ok");
@@ -1126,7 +1127,7 @@ void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
ourstate = state_failed;
} else
eFatal("state unknown");
-
+
if (ourstate != m_state)
{
m_state = ourstate;
@@ -1243,7 +1244,7 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
const int blocksize = 188;
unsigned int max = align(10*1024*1024, blocksize);
current_offset = align(current_offset, blocksize);
-
+
if (!m_cue)
{
eDebug("no cue sheet. forcing normal play");
@@ -1314,7 +1315,7 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
continue;
}
}
-
+
if (relative == 1) /* pts relative */
{
pts += now;
@@ -1325,7 +1326,7 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
if (relative != 2)
if (pts < 0)
pts = 0;
-
+
if (relative == 2) /* AP relative */
{
eDebug("AP relative seeking: %lld, at %lld", pts, now);
@@ -1340,7 +1341,7 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
eDebug("next ap is %llx\n", pts);
}
}
-
+
off_t offset = 0;
if (m_tstools.getOffset(offset, pts, -1))
{
@@ -1358,7 +1359,7 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
{
long long aligned_start = align(i->first, blocksize);
long long aligned_end = align(i->second, blocksize);
-
+
if ((current_offset >= aligned_start) && (current_offset < aligned_end))
{
start = current_offset;
@@ -1470,7 +1471,7 @@ RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontend
{
if (m_channel_id)
m_mgr->removeChannel(this);
-
+
if (!channelid)
return 0;
@@ -1479,7 +1480,7 @@ RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontend
eDebug("no frontend to tune!");
return -ENODEV;
}
-
+
m_channel_id = channelid;
m_mgr->addChannel(channelid, this);
m_state = state_tuning;
@@ -1487,14 +1488,14 @@ RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontend
int res;
res = m_frontend->get().tune(*feparm);
m_current_frontend_parameters = feparm;
-
+
if (res)
{
m_state = state_release;
m_stateChanged(this);
return res;
}
-
+
return 0;
}
@@ -1521,24 +1522,79 @@ RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
return -1;
}
+void eDVBChannel::SDTready(int result)
+{
+ ePyObject args = PyTuple_New(2), ret;
+ bool ok=false;
+ if (!result)
+ {
+ for (std::vector<ServiceDescriptionSection*>::const_iterator i = m_SDT->getSections().begin(); i != m_SDT->getSections().end(); ++i)
+ {
+ ok = true;
+ PyTuple_SET_ITEM(args, 0, PyInt_FromLong((*i)->getTransportStreamId()));
+ PyTuple_SET_ITEM(args, 1, PyInt_FromLong((*i)->getOriginalNetworkId()));
+ break;
+ }
+ }
+ if (!ok)
+ {
+ PyTuple_SET_ITEM(args, 0, Py_None);
+ PyTuple_SET_ITEM(args, 1, Py_None);
+ Py_INCREF(Py_None);
+ Py_INCREF(Py_None);
+ }
+ ret = PyObject_CallObject(m_tsid_onid_callback, args);
+ if (ret)
+ Py_DECREF(ret);
+ Py_DECREF(args);
+ Py_DECREF(m_tsid_onid_callback);
+ m_tsid_onid_callback = ePyObject();
+ m_tsid_onid_demux = 0;
+ m_SDT = 0;
+}
+
+RESULT eDVBChannel::requestTsidOnid(ePyObject callback)
+{
+ if (PyCallable_Check(callback))
+ {
+ if (!getDemux(m_tsid_onid_demux, 0))
+ {
+ m_SDT = new eTable<ServiceDescriptionSection>;
+ CONNECT(m_SDT->tableReady, eDVBChannel::SDTready);
+ if (m_SDT->start(m_tsid_onid_demux, eDVBSDTSpec()))
+ {
+ m_tsid_onid_demux = 0;
+ m_SDT = 0;
+ }
+ else
+ {
+ Py_INCREF(callback);
+ m_tsid_onid_callback = callback;
+ return 0;
+ }
+ }
+ }
+ return -1;
+}
+
RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
{
ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
-
+
if (!our_demux)
{
demux = 0;
-
+
if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
return -1;
}
-
+
demux = *our_demux;
/* don't hold a reference to the decoding demux, we don't need it. */
-
+
/* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
- the refcount is lost. thus, decoding demuxes are never allocated.
-
+ the refcount is lost. thus, decoding demuxes are never allocated.
+
this poses a big problem for PiP. */
if (cap & capDecode)
our_demux = 0;
@@ -1571,12 +1627,12 @@ RESULT eDVBChannel::playFile(const char *file)
delete m_pvr_thread;
m_pvr_thread = 0;
}
-
+
m_tstools.openFile(file);
-
+
/* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
THEN DO A REAL FIX HERE! */
-
+
/* (this codepath needs to be improved anyway.) */
#if HAVE_DVB_API_VERSION < 3
m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
@@ -1637,11 +1693,11 @@ RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, in
{
if (!decoding_demux)
return -1;
-
+
pts_t now;
-
+
int r;
-
+
if (mode == 0) /* demux */
{
r = decoding_demux->getSTC(now, 0);
@@ -1652,7 +1708,7 @@ RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, in
}
} else
now = pos; /* fixup supplied */
-
+
off_t off = 0; /* TODO: fixme */
r = m_tstools.fixupPTS(off, now);
if (r)
@@ -1660,9 +1716,9 @@ RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, in
eDebug("fixup PTS failed");
return -1;
}
-
+
pos = now;
-
+
return 0;
}
@@ -1673,7 +1729,7 @@ void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
a.) the filepush's internal buffer
b.) the PVR buffer (before demux)
c.) the ratebuffer (after demux)
-
+
it's important to clear them in the correct order, otherwise
the ratebuffer (for example) would immediately refill from
the not-yet-flushed PVR buffer.
@@ -1684,7 +1740,7 @@ void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
m_pvr_thread->flush();
/* HACK: flush PVR buffer */
::ioctl(m_pvr_fd_dst, 0);
-
+
/* flush ratebuffers (video, audio) */
if (decoding_demux)
decoding_demux->flush();
@@ -1708,7 +1764,7 @@ void eCueSheet::seekTo(int relative, const pts_t &pts)
m_lock.Unlock();
m_event(evtSeek);
}
-
+
void eCueSheet::clear()
{
m_lock.WrLock();
diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h
index 13556c26..fa1801db 100644
--- a/lib/dvb/dvb.h
+++ b/lib/dvb/dvb.h
@@ -10,8 +10,11 @@
#include <lib/dvb/demux.h>
#include <lib/dvb/frontend.h>
#include <lib/dvb/tstools.h>
+#include <lib/dvb/esection.h>
#include <connection.h>
+#include <dvbsi++/service_description_section.h>
+
class eDVBChannel;
/* we do NOT handle resource conflicts here. instead, the allocateChannel
@@ -259,6 +262,8 @@ public:
RESULT getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode);
int getUseCount() { return m_use_count; }
+
+ RESULT requestTsidOnid(ePyObject callback);
private:
ePtr<eDVBAllocatedFrontend> m_frontend;
ePtr<eDVBAllocatedDemux> m_demux, m_decoder_demux;
@@ -299,6 +304,12 @@ private:
oRefCount m_use_count;
void AddUse();
void ReleaseUse();
+
+ /* for tsid/onid read */
+ ePyObject m_tsid_onid_callback;
+ ePtr<iDVBDemux> m_tsid_onid_demux;
+ ePtr<eTable<ServiceDescriptionSection> > m_SDT;
+ void SDTready(int err);
};
#endif // SWIG
diff --git a/lib/dvb/dvbtime.cpp b/lib/dvb/dvbtime.cpp
index c4335795..d879cfac 100644
--- a/lib/dvb/dvbtime.cpp
+++ b/lib/dvb/dvbtime.cpp
@@ -11,6 +11,8 @@
#define FP_IOCTL_SET_RTC 0x101
#define FP_IOCTL_GET_RTC 0x102
+#define TIME_UPDATE_INTERVAL (30*60*1000)
+
static time_t prev_time;
void setRTC(time_t time)
@@ -143,7 +145,7 @@ eDVBLocalTimeHandler *eDVBLocalTimeHandler::instance;
DEFINE_REF(eDVBLocalTimeHandler);
eDVBLocalTimeHandler::eDVBLocalTimeHandler()
- :m_time_ready(false)
+ :m_time_ready(false), m_updateNonTunedTimer(eTimer::create(eApp))
{
if ( !instance )
instance=this;
@@ -164,6 +166,7 @@ eDVBLocalTimeHandler::eDVBLocalTimeHandler()
/*emit*/ m_timeUpdated();
}
}
+ CONNECT(m_updateNonTunedTimer->timeout, eDVBLocalTimeHandler::updateNonTuned);
}
eDVBLocalTimeHandler::~eDVBLocalTimeHandler()
@@ -211,6 +214,12 @@ void eDVBLocalTimeHandler::writeTimeOffsetData( const char* filename )
}
}
+void eDVBLocalTimeHandler::updateNonTuned()
+{
+ updateTime(-1, 0, 0);
+ m_updateNonTunedTimer->start(TIME_UPDATE_INTERVAL, true);
+}
+
void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan, int update_count )
{
int time_difference;
@@ -397,7 +406,7 @@ void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan, int up
int updateCount = it->second.tdt->getUpdateCount();
it->second.tdt = 0;
it->second.tdt = new TDT(chan, updateCount);
- it->second.tdt->startTimer(60*60*1000); // restart TDT for this transponder in 60min
+ it->second.tdt->startTimer(TIME_UPDATE_INTERVAL); // restart TDT for this transponder in 30min
}
}
}
@@ -430,12 +439,15 @@ void eDVBLocalTimeHandler::DVBChannelStateChanged(iDVBChannel *chan)
{
case iDVBChannel::state_ok:
eDebug("[eDVBLocalTimerHandler] channel %p running", chan);
+ m_updateNonTunedTimer->stop();
it->second.tdt = new TDT(it->second.channel);
it->second.tdt->start();
break;
case iDVBChannel::state_release:
eDebug("[eDVBLocalTimerHandler] remove channel %p", chan);
m_knownChannels.erase(it);
+ if (m_knownChannels.empty())
+ m_updateNonTunedTimer->start(TIME_UPDATE_INTERVAL, true);
break;
default: // ignore all other events
return;
diff --git a/lib/dvb/dvbtime.h b/lib/dvb/dvbtime.h
index f403ffd4..3f8d9b7d 100644
--- a/lib/dvb/dvbtime.h
+++ b/lib/dvb/dvbtime.h
@@ -54,6 +54,7 @@ class eDVBLocalTimeHandler: public Object
ePtr<eConnection> m_stateChangedConn;
int m_prevChannelState;
};
+ ePtr<eTimer> m_updateNonTunedTimer;
friend class TDT;
std::map<iDVBChannel*, channel_data> m_knownChannels;
std::map<eDVBChannelID,int> m_timeOffsetMap;
@@ -66,6 +67,7 @@ class eDVBLocalTimeHandler: public Object
void readTimeOffsetData(const char*);
void writeTimeOffsetData(const char*);
void updateTime(time_t tp_time, eDVBChannel*, int updateCount);
+ void updateNonTuned();
static eDVBLocalTimeHandler *instance;
#ifdef SWIG
eDVBLocalTimeHandler();
diff --git a/lib/dvb/epgcache.cpp b/lib/dvb/epgcache.cpp
index 0bb6e25b..fdcbe0e9 100644
--- a/lib/dvb/epgcache.cpp
+++ b/lib/dvb/epgcache.cpp
@@ -1672,7 +1672,7 @@ int handleEvent(eServiceEvent *ptr, ePyObject dest_list, const char* argstring,
{
fillTuple(convertFuncArgs, argstring, argcount, service, ptr, nowTime, service_name);
ePyObject result = PyObject_CallObject(convertFunc, convertFuncArgs);
- if (result)
+ if (!result)
{
if (service_name)
Py_DECREF(service_name);
@@ -2047,6 +2047,8 @@ PyObject *eEPGCache::search(ePyObject arg)
int querytype=-1;
bool needServiceEvent=false;
int maxmatches=0;
+ int must_get_service_name = 0;
+ bool must_get_service_reference = false;
if (PyTuple_Check(arg))
{
@@ -2056,7 +2058,11 @@ PyObject *eEPGCache::search(ePyObject arg)
ePyObject obj = PyTuple_GET_ITEM(arg,0);
if (PyString_Check(obj))
{
+#if PY_VERSION_HEX < 0x02060000
argcount = PyString_GET_SIZE(obj);
+#else
+ argcount = PyString_Size(obj);
+#endif
argstring = PyString_AS_STRING(obj);
for (int i=0; i < argcount; ++i)
switch(argstring[i])
@@ -2065,6 +2071,16 @@ PyObject *eEPGCache::search(ePyObject arg)
case 'E':
case 'T':
needServiceEvent=true;
+ break;
+ case 'N':
+ must_get_service_name = 1;
+ break;
+ case 'n':
+ must_get_service_name = 2;
+ break;
+ case 'R':
+ must_get_service_reference = true;
+ break;
default:
break;
}
@@ -2144,7 +2160,11 @@ PyObject *eEPGCache::search(ePyObject arg)
{
int casetype = PyLong_AsLong(PyTuple_GET_ITEM(arg, 4));
const char *str = PyString_AS_STRING(obj);
+#if PY_VERSION_HEX < 0x02060000
int textlen = PyString_GET_SIZE(obj);
+#else
+ int textlen = PyString_Size(obj);
+#endif
if (querytype == 1)
eDebug("lookup for events with '%s' as title(%s)", str, casetype?"ignore case":"case sensitive");
else
@@ -2159,22 +2179,32 @@ PyObject *eEPGCache::search(ePyObject arg)
int title_len = data[5];
if ( querytype == 1 )
{
- if (title_len > textlen)
- continue;
- else if (title_len < textlen)
+ int offs = 6;
+ // skip DVB-Text Encoding!
+ if (data[6] == 0x10)
+ {
+ offs+=3;
+ title_len-=3;
+ }
+ else if(data[6] > 0 && data[6] < 0x20)
+ {
+ offs+=1;
+ title_len-=1;
+ }
+ if (title_len != textlen)
continue;
if ( casetype )
{
- if ( !strncasecmp((const char*)data+6, str, title_len) )
+ if ( !strncasecmp((const char*)data+offs, str, title_len) )
{
-// std::string s((const char*)data+6, title_len);
+// std::string s((const char*)data+offs, title_len);
// eDebug("match1 %s %s", str, s.c_str() );
descr[++descridx] = it->first;
}
}
- else if ( !strncmp((const char*)data+6, str, title_len) )
+ else if ( !strncmp((const char*)data+offs, str, title_len) )
{
-// std::string s((const char*)data+6, title_len);
+// std::string s((const char*)data+offs, title_len);
// eDebug("match2 %s %s", str, s.c_str() );
descr[++descridx] = it->first;
}
@@ -2193,13 +2223,13 @@ PyObject *eEPGCache::search(ePyObject arg)
// eDebug("match 3 %s %s", str, s.c_str() );
break;
}
- else if (!strncmp((const char*)data+6+idx, str, textlen) )
- {
- descr[++descridx] = it->first;
-// std::string s((const char*)data+6, title_len);
-// eDebug("match 4 %s %s", str, s.c_str() );
- break;
- }
+ }
+ else if (!strncmp((const char*)data+6+idx, str, textlen) )
+ {
+ descr[++descridx] = it->first;
+// std::string s((const char*)data+6, title_len);
+// eDebug("match 4 %s %s", str, s.c_str() );
+ break;
}
++idx;
}
@@ -2303,44 +2333,40 @@ PyObject *eEPGCache::search(ePyObject arg)
}
}
// create service name
- if (!service_name)
+ if (must_get_service_name && !service_name)
{
- int must_get_service_name = strchr(argstring, 'N') ? 1 : strchr(argstring, 'n') ? 2 : 0;
- if (must_get_service_name)
+ ePtr<iStaticServiceInformation> sptr;
+ eServiceCenterPtr service_center;
+ eServiceCenter::getPrivInstance(service_center);
+ if (service_center)
{
- ePtr<iStaticServiceInformation> sptr;
- eServiceCenterPtr service_center;
- eServiceCenter::getPrivInstance(service_center);
- if (service_center)
+ service_center->info(ref, sptr);
+ if (sptr)
{
- service_center->info(ref, sptr);
- if (sptr)
- {
- std::string name;
- sptr->getName(ref, name);
+ std::string name;
+ sptr->getName(ref, name);
- if (must_get_service_name == 1)
- {
- size_t pos;
- // filter short name brakets
- while((pos = name.find("\xc2\x86")) != std::string::npos)
- name.erase(pos,2);
- while((pos = name.find("\xc2\x87")) != std::string::npos)
- name.erase(pos,2);
- }
- else
- name = buildShortName(name);
-
- if (name.length())
- service_name = PyString_FromString(name.c_str());
+ if (must_get_service_name == 1)
+ {
+ size_t pos;
+ // filter short name brakets
+ while((pos = name.find("\xc2\x86")) != std::string::npos)
+ name.erase(pos,2);
+ while((pos = name.find("\xc2\x87")) != std::string::npos)
+ name.erase(pos,2);
}
+ else
+ name = buildShortName(name);
+
+ if (name.length())
+ service_name = PyString_FromString(name.c_str());
}
- if (!service_name)
- service_name = PyString_FromString("<n/a>");
}
+ if (!service_name)
+ service_name = PyString_FromString("<n/a>");
}
// create servicereference string
- if (!service_reference && strchr(argstring,'R'))
+ if (must_get_service_reference && !service_reference)
service_reference = PyString_FromString(ref.toString().c_str());
// create list
if (!ret)
diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp
index b0e92d39..e0291ec1 100644
--- a/lib/dvb/frontend.cpp
+++ b/lib/dvb/frontend.cpp
@@ -1,4 +1,5 @@
#include <lib/dvb/dvb.h>
+#include <lib/dvb/frontendparms.h>
#include <lib/base/eerror.h>
#include <lib/base/nconfig.h> // access to python config
#include <errno.h>
@@ -148,10 +149,10 @@ void eDVBFrontendParametersSatellite::set(const SatelliteDeliverySystemDescripto
symbol_rate = descriptor.getSymbolRate() * 100;
polarisation = descriptor.getPolarization();
fec = descriptor.getFecInner();
- if ( fec != FEC::fNone && fec > FEC::f9_10 )
- fec = FEC::fAuto;
- inversion = Inversion::Unknown;
- pilot = Pilot::Unknown;
+ if ( fec != eDVBFrontendParametersSatellite::FEC_None && fec > eDVBFrontendParametersSatellite::FEC_9_10 )
+ fec = eDVBFrontendParametersSatellite::FEC_Auto;
+ inversion = eDVBFrontendParametersSatellite::Inversion_Unknown;
+ pilot = eDVBFrontendParametersSatellite::Pilot_Unknown;
orbital_position = ((descriptor.getOrbitalPosition() >> 12) & 0xF) * 1000;
orbital_position += ((descriptor.getOrbitalPosition() >> 8) & 0xF) * 100;
orbital_position += ((descriptor.getOrbitalPosition() >> 4) & 0xF) * 10;
@@ -160,13 +161,13 @@ void eDVBFrontendParametersSatellite::set(const SatelliteDeliverySystemDescripto
orbital_position = 3600 - orbital_position;
system = descriptor.getModulationSystem();
modulation = descriptor.getModulation();
- if (system == System::DVB_S && modulation == Modulation::M8PSK)
+ if (system == eDVBFrontendParametersSatellite::System_DVB_S && modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
{
eDebug("satellite_delivery_descriptor non valid modulation type.. force QPSK");
- modulation=QPSK;
+ modulation=eDVBFrontendParametersSatellite::Modulation_QPSK;
}
rolloff = descriptor.getRollOff();
- if (system == System::DVB_S2)
+ if (system == eDVBFrontendParametersSatellite::System_DVB_S2)
{
eDebug("SAT DVB-S2 freq %d, %s, pos %d, sr %d, fec %d, modulation %d, rolloff %d",
frequency,
@@ -191,12 +192,12 @@ void eDVBFrontendParametersCable::set(const CableDeliverySystemDescriptor &descr
frequency = descriptor.getFrequency() / 10;
symbol_rate = descriptor.getSymbolRate() * 100;
fec_inner = descriptor.getFecInner();
- if ( fec_inner == 0xF )
- fec_inner = FEC::fNone;
+ if ( fec_inner != eDVBFrontendParametersCable::FEC_None && fec_inner > eDVBFrontendParametersCable::FEC_8_9 )
+ fec_inner = eDVBFrontendParametersCable::FEC_Auto;
modulation = descriptor.getModulation();
if ( modulation > 0x5 )
- modulation = Modulation::Auto;
- inversion = Inversion::Unknown;
+ modulation = eDVBFrontendParametersCable::Modulation_Auto;
+ inversion = eDVBFrontendParametersCable::Inversion_Unknown;
eDebug("Cable freq %d, mod %d, sr %d, fec %d",
frequency,
modulation, symbol_rate, fec_inner);
@@ -207,24 +208,24 @@ void eDVBFrontendParametersTerrestrial::set(const TerrestrialDeliverySystemDescr
frequency = descriptor.getCentreFrequency() * 10;
bandwidth = descriptor.getBandwidth();
if ( bandwidth > 2 ) // 5Mhz forced to auto
- bandwidth = Bandwidth::BwAuto;
+ bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto;
code_rate_HP = descriptor.getCodeRateHpStream();
if (code_rate_HP > 4)
- code_rate_HP = FEC::fAuto;
+ code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_Auto;
code_rate_LP = descriptor.getCodeRateLpStream();
if (code_rate_LP > 4)
- code_rate_LP = FEC::fAuto;
+ code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_Auto;
transmission_mode = descriptor.getTransmissionMode();
if (transmission_mode > 1) // TM4k forced to auto
- transmission_mode = TransmissionMode::TMAuto;
+ transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto;
guard_interval = descriptor.getGuardInterval();
if (guard_interval > 3)
- guard_interval = GuardInterval::GI_Auto;
+ guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_Auto;
hierarchy = descriptor.getHierarchyInformation()&3;
modulation = descriptor.getConstellation();
if (modulation > 2)
- modulation = Modulation::Auto;
- inversion = Inversion::Unknown;
+ modulation = eDVBFrontendParametersTerrestrial::Modulation_Auto;
+ inversion = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
eDebug("Terr freq %d, bw %d, cr_hp %d, cr_lp %d, tm_mode %d, guard %d, hierarchy %d, const %d",
frequency, bandwidth, code_rate_HP, code_rate_LP, transmission_mode,
guard_interval, hierarchy, modulation);
@@ -316,9 +317,9 @@ RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters
diff = 1<<29;
else if (sat.polarisation != osat.polarisation)
diff = 1<<28;
- else if (exact && sat.fec != osat.fec && sat.fec != eDVBFrontendParametersSatellite::FEC::fAuto && osat.fec != eDVBFrontendParametersSatellite::FEC::fAuto)
+ else if (exact && sat.fec != osat.fec && sat.fec != eDVBFrontendParametersSatellite::FEC_Auto && osat.fec != eDVBFrontendParametersSatellite::FEC_Auto)
diff = 1<<27;
- else if (exact && sat.modulation != osat.modulation && sat.modulation != eDVBFrontendParametersSatellite::Modulation::Auto && osat.modulation != eDVBFrontendParametersSatellite::Modulation::Auto)
+ else if (exact && sat.modulation != osat.modulation && sat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto && osat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto)
diff = 1<<27;
else
{
@@ -333,10 +334,10 @@ RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters
return -2;
if (exact && cable.modulation != ocable.modulation
- && cable.modulation != eDVBFrontendParametersCable::Modulation::Auto
- && ocable.modulation != eDVBFrontendParametersCable::Modulation::Auto)
+ && cable.modulation != eDVBFrontendParametersCable::Modulation_Auto
+ && ocable.modulation != eDVBFrontendParametersCable::Modulation_Auto)
diff = 1 << 29;
- else if (exact && cable.fec_inner != ocable.fec_inner && cable.fec_inner != eDVBFrontendParametersCable::FEC::fAuto && ocable.fec_inner != eDVBFrontendParametersCable::FEC::fAuto)
+ else if (exact && cable.fec_inner != ocable.fec_inner && cable.fec_inner != eDVBFrontendParametersCable::FEC_Auto && ocable.fec_inner != eDVBFrontendParametersCable::FEC_Auto)
diff = 1 << 27;
else
{
@@ -350,32 +351,32 @@ RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters
return -2;
if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
- oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth::BwAuto &&
- terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth::BwAuto)
+ oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto &&
+ terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto)
diff = 1 << 30;
else if (exact && oterrestrial.modulation != terrestrial.modulation &&
- oterrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation::Auto &&
- terrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation::Auto)
+ oterrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto &&
+ terrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto)
diff = 1 << 30;
else if (exact && oterrestrial.transmission_mode != terrestrial.transmission_mode &&
- oterrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode::TMAuto &&
- terrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode::TMAuto)
+ oterrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto &&
+ terrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto)
diff = 1 << 30;
else if (exact && oterrestrial.guard_interval != terrestrial.guard_interval &&
- oterrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval::GI_Auto &&
- terrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval::GI_Auto)
+ oterrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto &&
+ terrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto)
diff = 1 << 30;
else if (exact && oterrestrial.hierarchy != terrestrial.hierarchy &&
- oterrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy::HAuto &&
- terrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy::HAuto)
+ oterrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto &&
+ terrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto)
diff = 1 << 30;
else if (exact && oterrestrial.code_rate_LP != terrestrial.code_rate_LP &&
- oterrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC::fAuto &&
- terrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC::fAuto)
+ oterrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
+ terrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto)
diff = 1 << 30;
else if (exact && oterrestrial.code_rate_HP != terrestrial.code_rate_HP &&
- oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC::fAuto &&
- terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC::fAuto)
+ oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
+ terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto)
diff = 1 << 30;
else
diff = abs(terrestrial.frequency - oterrestrial.frequency);
@@ -587,6 +588,10 @@ int eDVBFrontend::closeFrontend(bool force)
if (m_fd >= 0)
{
eDebugNoSimulate("close frontend %d", m_dvbid);
+ if (m_data[SATCR] != -1)
+ {
+ turnOffSatCR(m_data[SATCR]);
+ }
setTone(iDVBFrontend::toneOff);
setVoltage(iDVBFrontend::voltageOff);
m_tuneTimer->stop();
@@ -695,6 +700,12 @@ void eDVBFrontend::timeout()
#define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
+/* unsigned 32 bit division */
+static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
+{
+ return (a + b / 2) / b;
+}
+
int eDVBFrontend::readFrontendData(int type)
{
switch(type)
@@ -710,25 +721,18 @@ int eDVBFrontend::readFrontendData(int type)
return ber;
}
case signalQuality:
- {
- uint16_t snr=0;
- if (!m_simulate)
- {
- if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
- eDebug("FE_READ_SNR failed (%m)");
- }
- return snr;
- }
case signalQualitydB: /* this will move into the driver */
{
+ int sat_max = 1600; // for stv0288 / bsbe2
+ int ret = 0x12345678;
uint16_t snr=0;
if (m_simulate)
return 0;
if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
eDebug("FE_READ_SNR failed (%m)");
- if (!strcmp(m_description, "BCM4501 (internal)"))
+ else if (!strcmp(m_description, "BCM4501 (internal)"))
{
- unsigned int SDS_SNRE = snr << 16;
+ float SDS_SNRE = snr << 16;
float snr_in_db;
if (parm_u_qpsk_fec_inner <= FEC_AUTO) // DVB-S1 / QPSK
@@ -748,7 +752,7 @@ int eDVBFrontend::readFrontendData(int type)
if (fval1 < 10.0)
{
fval2 = SNR_COEFF[0];
- for (int i=0; i<6; ++i)
+ for (int i=1; i<6; ++i)
{
fval2 *= fval1;
fval2 += SNR_COEFF[i];
@@ -781,15 +785,16 @@ int eDVBFrontend::readFrontendData(int type)
snr_in_db = fval1;
}
#endif
- return (int)(snr_in_db * 100.0);
+ sat_max = 1750;
+ ret = (int)(snr_in_db * 100);
}
else if (strstr(m_description, "Alps BSBE1 C01A") ||
!strcmp(m_description, "Alps -S(STV0288)"))
{
if (snr == 0)
- return 0;
+ ret = 0;
else if (snr == 0xFFFF) // i think this should not happen
- return 100*100;
+ ret = 100*100;
else
{
enum { REALVAL, REGVAL };
@@ -817,28 +822,60 @@ int eDVBFrontend::readFrontendData(int type)
else
Imin = i;
}
- return (((regval - CN_lookup[Imin][REGVAL])
+ ret = (((regval - CN_lookup[Imin][REGVAL])
* (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
/ (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
+ CN_lookup[Imin][REALVAL]) * 10;
}
- return 100;
+ else
+ ret = 100;
}
- return 0;
}
else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
!strcmp(m_description, "Alps -S") ||
!strcmp(m_description, "Philips -S") ||
!strcmp(m_description, "LG -S") )
{
- float snr_in_db=(snr-39075)/1764.7;
- return (int)(snr_in_db * 100.0);
+ sat_max = 1500;
+ ret = (int)((snr-39075)/17.647);
} else if (!strcmp(m_description, "Alps BSBE2"))
{
- return (int)((snr >> 7) * 10.0);
- } /* else
+ ret = (int)((snr >> 7) * 10);
+ } else if (!strcmp(m_description, "Philips CU1216Mk3"))
+ {
+ int mse = (~snr) & 0xFF;
+ switch (parm_u_qam_modulation) {
+ case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
+ case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
+ case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
+ case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
+ case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
+ default: break;
+ }
+ } else if (!strcmp(m_description, "Philips TU1216"))
+ {
+ snr = 0xFF - (snr & 0xFF);
+ if (snr != 0)
+ ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
+ }
+
+ if (type == signalQuality)
+ {
+ if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
+ return snr;
+ switch(m_type)
+ {
+ case feSatellite:
+ return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
+ case feCable: // we assume a max of 42db here
+ return ret >= 4200 ? 65536 : ret * 65536 / 4200;
+ case feTerrestrial: // we assume a max of 24db here
+ return ret >= 2400 ? 65536 : ret * 65536 / 2400;
+ }
+ }
+/* else
eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
- return 0x12345678;
+ return ret;
}
case signalPower:
{
@@ -927,120 +964,79 @@ void PutToDict(ePyObject &dict, const char*key, const char *value)
void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, eDVBFrontend *fe)
{
long freq_offset=0;
- const char *tmp=0;
+ long tmp=0;
fe->getData(eDVBFrontend::FREQ_OFFSET, freq_offset);
int frequency = parm_frequency + freq_offset;
PutToDict(dict, "frequency", frequency);
PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
switch(parm_u_qpsk_fec_inner)
{
- case FEC_1_2:
- tmp = "FEC_1_2";
- break;
- case FEC_2_3:
- tmp = "FEC_2_3";
- break;
- case FEC_3_4:
- tmp = "FEC_3_4";
- break;
- case FEC_5_6:
- tmp = "FEC_5_6";
- break;
- case FEC_7_8:
- tmp = "FEC_7_8";
- break;
- case FEC_NONE:
- tmp = "FEC_NONE";
+ case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
+ case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
+ case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
+ case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
+ case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
+ case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
default:
- case FEC_AUTO:
- tmp = "FEC_AUTO";
- break;
+ case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
#if HAVE_DVB_API_VERSION >=3
- case FEC_S2_8PSK_1_2:
- case FEC_S2_QPSK_1_2:
- tmp = "FEC_1_2";
- break;
+ case FEC_S2_8PSK_1_2:
+ case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
case FEC_S2_8PSK_2_3:
- case FEC_S2_QPSK_2_3:
- tmp = "FEC_2_3";
- break;
+ case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
case FEC_S2_8PSK_3_4:
- case FEC_S2_QPSK_3_4:
- tmp = "FEC_3_4";
- break;
+ case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
case FEC_S2_8PSK_5_6:
- case FEC_S2_QPSK_5_6:
- tmp = "FEC_5_6";
- break;
+ case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
case FEC_S2_8PSK_7_8:
- case FEC_S2_QPSK_7_8:
- tmp = "FEC_7_8";
- break;
+ case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
case FEC_S2_8PSK_8_9:
- case FEC_S2_QPSK_8_9:
- tmp = "FEC_8_9";
- break;
+ case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
case FEC_S2_8PSK_3_5:
- case FEC_S2_QPSK_3_5:
- tmp = "FEC_3_5";
- break;
+ case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
case FEC_S2_8PSK_4_5:
- case FEC_S2_QPSK_4_5:
- tmp = "FEC_4_5";
- break;
+ case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
case FEC_S2_8PSK_9_10:
- case FEC_S2_QPSK_9_10:
- tmp = "FEC_9_10";
- break;
+ case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
#endif
}
PutToDict(dict, "fec_inner", tmp);
#if HAVE_DVB_API_VERSION >=3
PutToDict(dict, "modulation",
- parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ? "8PSK": "QPSK" );
+ parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ?
+ eDVBFrontendParametersSatellite::Modulation_8PSK :
+ eDVBFrontendParametersSatellite::Modulation_QPSK );
if (parm_u_qpsk_fec_inner > FEC_AUTO)
{
switch(parm_inversion & 0xc)
{
default: // unknown rolloff
- case 0: // 0.35
- tmp = "ROLLOFF_0_35";
- break;
- case 4: // 0.25
- tmp = "ROLLOFF_0_25";
- break;
- case 8: // 0.20
- tmp = "ROLLOFF_0_20";
- break;
+ case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
+ case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
+ case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
}
PutToDict(dict, "rolloff", tmp);
switch(parm_inversion & 0x30)
{
- case 0: // pilot off
- tmp = "PILOT_OFF";
- break;
- case 0x10: // pilot on
- tmp = "PILOT_ON";
- break;
- case 0x20: // pilot auto
- tmp = "PILOT_AUTO";
- break;
+ case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
+ case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
+ case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
}
PutToDict(dict, "pilot", tmp);
- tmp = "DVB-S2";
+ tmp = eDVBFrontendParametersSatellite::System_DVB_S2;
}
else
- tmp = "DVB-S";
+ tmp = eDVBFrontendParametersSatellite::System_DVB_S;
#else
- PutToDict(dict, "modulation", "QPSK" );
- tmp = "DVB-S";
+ PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK );
+ tmp = eDVBFrontendParametersSatellite::System_DVB_S;
#endif
PutToDict(dict, "system", tmp);
}
void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
{
- const char *tmp=0;
+ long tmp=0;
#if HAVE_DVB_API_VERSION < 3
PutToDict(dict, "frequency", parm_frequency);
#else
@@ -1049,196 +1045,102 @@ void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
switch(parm_u_qam_fec_inner)
{
- case FEC_NONE:
- tmp = "FEC_NONE";
- break;
- case FEC_1_2:
- tmp = "FEC_1_2";
- break;
- case FEC_2_3:
- tmp = "FEC_2_3";
- break;
- case FEC_3_4:
- tmp = "FEC_3_4";
- break;
- case FEC_5_6:
- tmp = "FEC_5_6";
- break;
- case FEC_7_8:
- tmp = "FEC_7_8";
- break;
+ case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
+ case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
+ case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
+ case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
+ case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
+ case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
#if HAVE_DVB_API_VERSION >= 3
- case FEC_8_9:
- tmp = "FEC_8_9";
- break;
+ case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
#endif
default:
- case FEC_AUTO:
- tmp = "FEC_AUTO";
- break;
+ case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
}
PutToDict(dict, "fec_inner", tmp);
switch(parm_u_qam_modulation)
{
- case QAM_16:
- tmp = "QAM_16";
- break;
- case QAM_32:
- tmp = "QAM_32";
- break;
- case QAM_64:
- tmp = "QAM_64";
- break;
- case QAM_128:
- tmp = "QAM_128";
- break;
- case QAM_256:
- tmp = "QAM_256";
- break;
+ case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
+ case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
+ case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
+ case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
+ case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
default:
- case QAM_AUTO:
- tmp = "QAM_AUTO";
- break;
+ case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
}
PutToDict(dict, "modulation", tmp);
}
void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
{
- const char *tmp=0;
+ long tmp=0;
PutToDict(dict, "frequency", parm_frequency);
switch (parm_u_ofdm_bandwidth)
{
- case BANDWIDTH_8_MHZ:
- tmp = "BANDWIDTH_8_MHZ";
- break;
- case BANDWIDTH_7_MHZ:
- tmp = "BANDWIDTH_7_MHZ";
- break;
- case BANDWIDTH_6_MHZ:
- tmp = "BANDWIDTH_6_MHZ";
- break;
+ case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
+ case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
+ case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
default:
- case BANDWIDTH_AUTO:
- tmp = "BANDWIDTH_AUTO";
- break;
+ case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
}
PutToDict(dict, "bandwidth", tmp);
switch (parm_u_ofdm_code_rate_LP)
{
- case FEC_1_2:
- tmp = "FEC_1_2";
- break;
- case FEC_2_3:
- tmp = "FEC_2_3";
- break;
- case FEC_3_4:
- tmp = "FEC_3_4";
- break;
- case FEC_5_6:
- tmp = "FEC_5_6";
- break;
- case FEC_7_8:
- tmp = "FEC_7_8";
- break;
+ case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
+ case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
+ case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
+ case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
+ case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
default:
- case FEC_AUTO:
- tmp = "FEC_AUTO";
- break;
+ case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
}
PutToDict(dict, "code_rate_lp", tmp);
switch (parm_u_ofdm_code_rate_HP)
{
- case FEC_1_2:
- tmp = "FEC_1_2";
- break;
- case FEC_2_3:
- tmp = "FEC_2_3";
- break;
- case FEC_3_4:
- tmp = "FEC_3_4";
- break;
- case FEC_5_6:
- tmp = "FEC_5_6";
- break;
- case FEC_7_8:
- tmp = "FEC_7_8";
- break;
+ case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
+ case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
+ case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
+ case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
+ case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
default:
- case FEC_AUTO:
- tmp = "FEC_AUTO";
- break;
+ case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
}
PutToDict(dict, "code_rate_hp", tmp);
switch (parm_u_ofdm_constellation)
{
- case QPSK:
- tmp = "QPSK";
- break;
- case QAM_16:
- tmp = "QAM_16";
- break;
- case QAM_64:
- tmp = "QAM_64";
- break;
+ case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
+ case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
+ case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
default:
- case QAM_AUTO:
- tmp = "QAM_AUTO";
- break;
+ case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
}
PutToDict(dict, "constellation", tmp);
switch (parm_u_ofdm_transmission_mode)
{
- case TRANSMISSION_MODE_2K:
- tmp = "TRANSMISSION_MODE_2K";
- break;
- case TRANSMISSION_MODE_8K:
- tmp = "TRANSMISSION_MODE_8K";
- break;
+ case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
+ case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
default:
- case TRANSMISSION_MODE_AUTO:
- tmp = "TRANSMISSION_MODE_AUTO";
- break;
+ case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
}
PutToDict(dict, "transmission_mode", tmp);
switch (parm_u_ofdm_guard_interval)
{
- case GUARD_INTERVAL_1_32:
- tmp = "GUARD_INTERVAL_1_32";
- break;
- case GUARD_INTERVAL_1_16:
- tmp = "GUARD_INTERVAL_1_16";
- break;
- case GUARD_INTERVAL_1_8:
- tmp = "GUARD_INTERVAL_1_8";
- break;
- case GUARD_INTERVAL_1_4:
- tmp = "GUARD_INTERVAL_1_4";
- break;
+ case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
+ case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
+ case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
+ case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
default:
- case GUARD_INTERVAL_AUTO:
- tmp = "GUARD_INTERVAL_AUTO";
- break;
+ case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
}
PutToDict(dict, "guard_interval", tmp);
switch (parm_u_ofdm_hierarchy_information)
{
- case HIERARCHY_NONE:
- tmp = "HIERARCHY_NONE";
- break;
- case HIERARCHY_1:
- tmp = "HIERARCHY_1";
- break;
- case HIERARCHY_2:
- tmp = "HIERARCHY_2";
- break;
- case HIERARCHY_4:
- tmp = "HIERARCHY_4";
- break;
+ case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
+ case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
+ case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
+ case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
default:
- case HIERARCHY_AUTO:
- tmp = "HIERARCHY_AUTO";
- break;
+ case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
}
PutToDict(dict, "hierarchy_information", tmp);
}
@@ -1306,20 +1208,18 @@ void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
}
{
const FRONTENDPARAMETERS &parm = original || m_simulate ? this->parm : front;
- const char *tmp = "INVERSION_AUTO";
+ long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
switch(parm_inversion & 3)
{
case INVERSION_ON:
- tmp = "INVERSION_ON";
+ tmp = eDVBFrontendParametersSatellite::Inversion_On;
break;
case INVERSION_OFF:
- tmp = "INVERSION_OFF";
- break;
+ tmp = eDVBFrontendParametersSatellite::Inversion_Off;
default:
break;
}
- if (tmp)
- PutToDict(dest, "inversion", tmp);
+ PutToDict(dest, "inversion", tmp);
switch(m_type)
{
@@ -1827,6 +1727,20 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm,
res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
if (!res)
{
+#if HAVE_DVB_API_VERSION >= 3
+ eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d system %d modulation %d pilot %d, rolloff %d",
+ feparm.system,
+ feparm.frequency,
+ feparm.polarisation,
+ feparm.symbol_rate,
+ feparm.inversion,
+ feparm.fec,
+ feparm.orbital_position,
+ feparm.system,
+ feparm.modulation,
+ feparm.pilot,
+ feparm.rolloff);
+#else
eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
feparm.system,
feparm.frequency,
@@ -1835,44 +1749,45 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm,
feparm.inversion,
feparm.fec,
feparm.orbital_position);
+#endif
parm_u_qpsk_symbol_rate = feparm.symbol_rate;
switch (feparm.inversion)
{
- case eDVBFrontendParametersSatellite::Inversion::On:
+ case eDVBFrontendParametersSatellite::Inversion_On:
parm_inversion = INVERSION_ON;
break;
- case eDVBFrontendParametersSatellite::Inversion::Off:
+ case eDVBFrontendParametersSatellite::Inversion_Off:
parm_inversion = INVERSION_OFF;
break;
default:
- case eDVBFrontendParametersSatellite::Inversion::Unknown:
+ case eDVBFrontendParametersSatellite::Inversion_Unknown:
parm_inversion = INVERSION_AUTO;
break;
}
- if (feparm.system == eDVBFrontendParametersSatellite::System::DVB_S)
+ if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
switch (feparm.fec)
{
- case eDVBFrontendParametersSatellite::FEC::fNone:
+ case eDVBFrontendParametersSatellite::FEC_None:
parm_u_qpsk_fec_inner = FEC_NONE;
break;
- case eDVBFrontendParametersSatellite::FEC::f1_2:
+ case eDVBFrontendParametersSatellite::FEC_1_2:
parm_u_qpsk_fec_inner = FEC_1_2;
break;
- case eDVBFrontendParametersSatellite::FEC::f2_3:
+ case eDVBFrontendParametersSatellite::FEC_2_3:
parm_u_qpsk_fec_inner = FEC_2_3;
break;
- case eDVBFrontendParametersSatellite::FEC::f3_4:
+ case eDVBFrontendParametersSatellite::FEC_3_4:
parm_u_qpsk_fec_inner = FEC_3_4;
break;
- case eDVBFrontendParametersSatellite::FEC::f5_6:
+ case eDVBFrontendParametersSatellite::FEC_5_6:
parm_u_qpsk_fec_inner = FEC_5_6;
break;
- case eDVBFrontendParametersSatellite::FEC::f7_8:
+ case eDVBFrontendParametersSatellite::FEC_7_8:
parm_u_qpsk_fec_inner = FEC_7_8;
break;
default:
eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
- case eDVBFrontendParametersSatellite::FEC::fAuto:
+ case eDVBFrontendParametersSatellite::FEC_Auto:
parm_u_qpsk_fec_inner = FEC_AUTO;
break;
}
@@ -1881,31 +1796,31 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm,
{
switch (feparm.fec)
{
- case eDVBFrontendParametersSatellite::FEC::f1_2:
+ case eDVBFrontendParametersSatellite::FEC_1_2:
parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
break;
- case eDVBFrontendParametersSatellite::FEC::f2_3:
+ case eDVBFrontendParametersSatellite::FEC_2_3:
parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
break;
- case eDVBFrontendParametersSatellite::FEC::f3_4:
+ case eDVBFrontendParametersSatellite::FEC_3_4:
parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
break;
- case eDVBFrontendParametersSatellite::FEC::f3_5:
+ case eDVBFrontendParametersSatellite::FEC_3_5:
parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
break;
- case eDVBFrontendParametersSatellite::FEC::f4_5:
+ case eDVBFrontendParametersSatellite::FEC_4_5:
parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
break;
- case eDVBFrontendParametersSatellite::FEC::f5_6:
+ case eDVBFrontendParametersSatellite::FEC_5_6:
parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
break;
- case eDVBFrontendParametersSatellite::FEC::f7_8:
+ case eDVBFrontendParametersSatellite::FEC_7_8:
parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
break;
- case eDVBFrontendParametersSatellite::FEC::f8_9:
+ case eDVBFrontendParametersSatellite::FEC_8_9:
parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
break;
- case eDVBFrontendParametersSatellite::FEC::f9_10:
+ case eDVBFrontendParametersSatellite::FEC_9_10:
parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
break;
default:
@@ -1914,7 +1829,7 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm,
}
parm_inversion |= (feparm.rolloff << 2); // Hack.. we use bit 2..3 of inversion param for rolloff
parm_inversion |= (feparm.pilot << 4); // Hack.. we use bit 4..5 of inversion param for pilot
- if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation::M8PSK) {
+ if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK) {
parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
// 8PSK fec driver values are decimal 9 bigger
}
@@ -1941,66 +1856,66 @@ RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
parm_u_qam_symbol_rate = feparm.symbol_rate;
switch (feparm.modulation)
{
- case eDVBFrontendParametersCable::Modulation::QAM16:
+ case eDVBFrontendParametersCable::Modulation_QAM16:
parm_u_qam_modulation = QAM_16;
break;
- case eDVBFrontendParametersCable::Modulation::QAM32:
+ case eDVBFrontendParametersCable::Modulation_QAM32:
parm_u_qam_modulation = QAM_32;
break;
- case eDVBFrontendParametersCable::Modulation::QAM64:
+ case eDVBFrontendParametersCable::Modulation_QAM64:
parm_u_qam_modulation = QAM_64;
break;
- case eDVBFrontendParametersCable::Modulation::QAM128:
+ case eDVBFrontendParametersCable::Modulation_QAM128:
parm_u_qam_modulation = QAM_128;
break;
- case eDVBFrontendParametersCable::Modulation::QAM256:
+ case eDVBFrontendParametersCable::Modulation_QAM256:
parm_u_qam_modulation = QAM_256;
break;
default:
- case eDVBFrontendParametersCable::Modulation::Auto:
+ case eDVBFrontendParametersCable::Modulation_Auto:
parm_u_qam_modulation = QAM_AUTO;
break;
}
switch (feparm.inversion)
{
- case eDVBFrontendParametersCable::Inversion::On:
+ case eDVBFrontendParametersCable::Inversion_On:
parm_inversion = INVERSION_ON;
break;
- case eDVBFrontendParametersCable::Inversion::Off:
+ case eDVBFrontendParametersCable::Inversion_Off:
parm_inversion = INVERSION_OFF;
break;
default:
- case eDVBFrontendParametersCable::Inversion::Unknown:
+ case eDVBFrontendParametersCable::Inversion_Unknown:
parm_inversion = INVERSION_AUTO;
break;
}
switch (feparm.fec_inner)
{
- case eDVBFrontendParametersCable::FEC::fNone:
+ case eDVBFrontendParametersCable::FEC_None:
parm_u_qam_fec_inner = FEC_NONE;
break;
- case eDVBFrontendParametersCable::FEC::f1_2:
+ case eDVBFrontendParametersCable::FEC_1_2:
parm_u_qam_fec_inner = FEC_1_2;
break;
- case eDVBFrontendParametersCable::FEC::f2_3:
+ case eDVBFrontendParametersCable::FEC_2_3:
parm_u_qam_fec_inner = FEC_2_3;
break;
- case eDVBFrontendParametersCable::FEC::f3_4:
+ case eDVBFrontendParametersCable::FEC_3_4:
parm_u_qam_fec_inner = FEC_3_4;
break;
- case eDVBFrontendParametersCable::FEC::f5_6:
+ case eDVBFrontendParametersCable::FEC_5_6:
parm_u_qam_fec_inner = FEC_5_6;
break;
- case eDVBFrontendParametersCable::FEC::f7_8:
+ case eDVBFrontendParametersCable::FEC_7_8:
parm_u_qam_fec_inner = FEC_7_8;
break;
#if HAVE_DVB_API_VERSION >= 3
- case eDVBFrontendParametersCable::FEC::f8_9:
+ case eDVBFrontendParametersCable::FEC_8_9:
parm_u_qam_fec_inner = FEC_8_9;
break;
#endif
default:
- case eDVBFrontendParametersCable::FEC::fAuto:
+ case eDVBFrontendParametersCable::FEC_Auto:
parm_u_qam_fec_inner = FEC_AUTO;
break;
}
@@ -2019,141 +1934,141 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial
switch (feparm.bandwidth)
{
- case eDVBFrontendParametersTerrestrial::Bandwidth::Bw8MHz:
+ case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
break;
- case eDVBFrontendParametersTerrestrial::Bandwidth::Bw7MHz:
+ case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
break;
- case eDVBFrontendParametersTerrestrial::Bandwidth::Bw6MHz:
+ case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
break;
default:
- case eDVBFrontendParametersTerrestrial::Bandwidth::BwAuto:
+ case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
break;
}
switch (feparm.code_rate_LP)
{
- case eDVBFrontendParametersTerrestrial::FEC::f1_2:
+ case eDVBFrontendParametersTerrestrial::FEC_1_2:
parm_u_ofdm_code_rate_LP = FEC_1_2;
break;
- case eDVBFrontendParametersTerrestrial::FEC::f2_3:
+ case eDVBFrontendParametersTerrestrial::FEC_2_3:
parm_u_ofdm_code_rate_LP = FEC_2_3;
break;
- case eDVBFrontendParametersTerrestrial::FEC::f3_4:
+ case eDVBFrontendParametersTerrestrial::FEC_3_4:
parm_u_ofdm_code_rate_LP = FEC_3_4;
break;
- case eDVBFrontendParametersTerrestrial::FEC::f5_6:
+ case eDVBFrontendParametersTerrestrial::FEC_5_6:
parm_u_ofdm_code_rate_LP = FEC_5_6;
break;
- case eDVBFrontendParametersTerrestrial::FEC::f7_8:
+ case eDVBFrontendParametersTerrestrial::FEC_7_8:
parm_u_ofdm_code_rate_LP = FEC_7_8;
break;
default:
- case eDVBFrontendParametersTerrestrial::FEC::fAuto:
+ case eDVBFrontendParametersTerrestrial::FEC_Auto:
parm_u_ofdm_code_rate_LP = FEC_AUTO;
break;
}
switch (feparm.code_rate_HP)
{
- case eDVBFrontendParametersTerrestrial::FEC::f1_2:
+ case eDVBFrontendParametersTerrestrial::FEC_1_2:
parm_u_ofdm_code_rate_HP = FEC_1_2;
break;
- case eDVBFrontendParametersTerrestrial::FEC::f2_3:
+ case eDVBFrontendParametersTerrestrial::FEC_2_3:
parm_u_ofdm_code_rate_HP = FEC_2_3;
break;
- case eDVBFrontendParametersTerrestrial::FEC::f3_4:
+ case eDVBFrontendParametersTerrestrial::FEC_3_4:
parm_u_ofdm_code_rate_HP = FEC_3_4;
break;
- case eDVBFrontendParametersTerrestrial::FEC::f5_6:
+ case eDVBFrontendParametersTerrestrial::FEC_5_6:
parm_u_ofdm_code_rate_HP = FEC_5_6;
break;
- case eDVBFrontendParametersTerrestrial::FEC::f7_8:
+ case eDVBFrontendParametersTerrestrial::FEC_7_8:
parm_u_ofdm_code_rate_HP = FEC_7_8;
break;
default:
- case eDVBFrontendParametersTerrestrial::FEC::fAuto:
+ case eDVBFrontendParametersTerrestrial::FEC_Auto:
parm_u_ofdm_code_rate_HP = FEC_AUTO;
break;
}
switch (feparm.modulation)
{
- case eDVBFrontendParametersTerrestrial::Modulation::QPSK:
+ case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
parm_u_ofdm_constellation = QPSK;
break;
- case eDVBFrontendParametersTerrestrial::Modulation::QAM16:
+ case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
parm_u_ofdm_constellation = QAM_16;
break;
- case eDVBFrontendParametersTerrestrial::Modulation::QAM64:
+ case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
parm_u_ofdm_constellation = QAM_64;
break;
default:
- case eDVBFrontendParametersTerrestrial::Modulation::Auto:
+ case eDVBFrontendParametersTerrestrial::Modulation_Auto:
parm_u_ofdm_constellation = QAM_AUTO;
break;
}
switch (feparm.transmission_mode)
{
- case eDVBFrontendParametersTerrestrial::TransmissionMode::TM2k:
+ case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
break;
- case eDVBFrontendParametersTerrestrial::TransmissionMode::TM8k:
+ case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
break;
default:
- case eDVBFrontendParametersTerrestrial::TransmissionMode::TMAuto:
+ case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
break;
}
switch (feparm.guard_interval)
{
- case eDVBFrontendParametersTerrestrial::GuardInterval::GI_1_32:
+ case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
break;
- case eDVBFrontendParametersTerrestrial::GuardInterval::GI_1_16:
+ case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
break;
- case eDVBFrontendParametersTerrestrial::GuardInterval::GI_1_8:
+ case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
break;
- case eDVBFrontendParametersTerrestrial::GuardInterval::GI_1_4:
+ case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
break;
default:
- case eDVBFrontendParametersTerrestrial::GuardInterval::GI_Auto:
+ case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
break;
}
switch (feparm.hierarchy)
{
- case eDVBFrontendParametersTerrestrial::Hierarchy::HNone:
+ case eDVBFrontendParametersTerrestrial::Hierarchy_None:
parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
break;
- case eDVBFrontendParametersTerrestrial::Hierarchy::H1:
+ case eDVBFrontendParametersTerrestrial::Hierarchy_1:
parm_u_ofdm_hierarchy_information = HIERARCHY_1;
break;
- case eDVBFrontendParametersTerrestrial::Hierarchy::H2:
+ case eDVBFrontendParametersTerrestrial::Hierarchy_2:
parm_u_ofdm_hierarchy_information = HIERARCHY_2;
break;
- case eDVBFrontendParametersTerrestrial::Hierarchy::H4:
+ case eDVBFrontendParametersTerrestrial::Hierarchy_4:
parm_u_ofdm_hierarchy_information = HIERARCHY_4;
break;
default:
- case eDVBFrontendParametersTerrestrial::Hierarchy::HAuto:
+ case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
break;
}
switch (feparm.inversion)
{
- case eDVBFrontendParametersTerrestrial::Inversion::On:
+ case eDVBFrontendParametersTerrestrial::Inversion_On:
parm_inversion = INVERSION_ON;
break;
- case eDVBFrontendParametersTerrestrial::Inversion::Off:
+ case eDVBFrontendParametersTerrestrial::Inversion_Off:
parm_inversion = INVERSION_OFF;
break;
default:
- case eDVBFrontendParametersTerrestrial::Inversion::Unknown:
+ case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
parm_inversion = INVERSION_AUTO;
break;
}
@@ -2463,10 +2378,10 @@ int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
eDVBFrontendParametersSatellite sat_parm;
int ret = feparm->getDVBS(sat_parm);
ASSERT(!ret);
- if (sat_parm.system == eDVBFrontendParametersSatellite::System::DVB_S2 && !m_can_handle_dvbs2)
+ if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !m_can_handle_dvbs2)
return 0;
ret = m_sec->canTune(sat_parm, this, 1 << m_slotid);
- if (ret > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System::DVB_S && m_can_handle_dvbs2)
+ if (ret > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2)
ret -= 1;
return ret;
}
@@ -2505,3 +2420,42 @@ arg_error:
"eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");
return false;
}
+
+RESULT eDVBFrontend::turnOffSatCR(int satcr)
+{
+ eSecCommandList sec_sequence;
+ // check if voltage is disabled
+ eSecCommand::pair compare;
+ compare.steps = +9; //nothing to do
+ compare.voltage = iDVBFrontend::voltageOff;
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_NOT_VOLTAGE_GOTO, compare) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50 ) );
+
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage18_5) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 250) );
+
+ eDVBDiseqcCommand diseqc;
+ memset(diseqc.data, 0, MAX_DISEQC_LENGTH);
+ diseqc.len = 5;
+ diseqc.data[0] = 0xE0;
+ diseqc.data[1] = 0x10;
+ diseqc.data[2] = 0x5A;
+ diseqc.data[3] = satcr << 5;
+ diseqc.data[4] = 0x00;
+
+ sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50+20+14*diseqc.len) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
+ setSecSequence(sec_sequence);
+ return 0;
+}
+
+RESULT eDVBFrontend::ScanSatCR()
+{
+ setFrontend();
+ usleep(20000);
+ setTone(iDVBFrontend::toneOff);
+ return 0;
+}
diff --git a/lib/dvb/frontend.h b/lib/dvb/frontend.h
index 06ed12cc..81334886 100644
--- a/lib/dvb/frontend.h
+++ b/lib/dvb/frontend.h
@@ -20,22 +20,22 @@ public:
{
}
- RESULT getSystem(int &type) const;
- RESULT getDVBS(eDVBFrontendParametersSatellite &) const;
- RESULT getDVBC(eDVBFrontendParametersCable &) const;
- RESULT getDVBT(eDVBFrontendParametersTerrestrial &) const;
+ SWIG_VOID(RESULT) getSystem(int &SWIG_OUTPUT) const;
+ SWIG_VOID(RESULT) getDVBS(eDVBFrontendParametersSatellite &SWIG_OUTPUT) const;
+ SWIG_VOID(RESULT) getDVBC(eDVBFrontendParametersCable &SWIG_OUTPUT) const;
+ SWIG_VOID(RESULT) getDVBT(eDVBFrontendParametersTerrestrial &SWIG_OUTPUT) const;
RESULT setDVBS(const eDVBFrontendParametersSatellite &p, bool no_rotor_command_on_tune=false);
RESULT setDVBC(const eDVBFrontendParametersCable &p);
RESULT setDVBT(const eDVBFrontendParametersTerrestrial &p);
-
+ SWIG_VOID(RESULT) getFlags(unsigned int &SWIG_NAMED_OUTPUT(flags)) const { flags = m_flags; return 0; }
+ RESULT setFlags(unsigned int flags) { m_flags = flags; return 0; }
+#ifndef SWIG
RESULT calculateDifference(const iDVBFrontendParameters *parm, int &, bool exact) const;
RESULT getHash(unsigned long &) const;
RESULT calcLockTimeout(unsigned int &) const;
-
- RESULT getFlags(unsigned int &flags) const { flags = m_flags; return 0; }
- RESULT setFlags(unsigned int flags) { m_flags = flags; return 0; }
+#endif
};
#ifndef SWIG
@@ -63,6 +63,7 @@ public:
FREQ_OFFSET, // current frequency offset
CUR_VOLTAGE, // current voltage
CUR_TONE, // current continuous tone
+ SATCR, // current SatCR
NUM_DATA_ENTRIES
};
Signal1<void,iDVBFrontend*> m_stateChanged;
@@ -142,6 +143,9 @@ public:
int closeFrontend(bool force=false);
const char *getDescription() const { return m_description; }
bool is_simulate() const { return m_simulate; }
+
+ RESULT turnOffSatCR(int satcr);
+ RESULT ScanSatCR();
};
#endif // SWIG
diff --git a/lib/dvb/frontendparms.h b/lib/dvb/frontendparms.h
index c963a251..b537963f 100644
--- a/lib/dvb/frontendparms.h
+++ b/lib/dvb/frontendparms.h
@@ -12,43 +12,35 @@ struct eDVBFrontendParametersSatellite
#ifndef SWIG
void set(const SatelliteDeliverySystemDescriptor &);
#endif
- struct Polarisation {
- enum {
- Horizontal, Vertical, CircularLeft, CircularRight
- };
+ enum {
+ Polarisation_Horizontal, Polarisation_Vertical, Polarisation_CircularLeft, Polarisation_CircularRight
};
- struct Inversion {
- enum {
- Off, On, Unknown
- };
+
+ enum {
+ Inversion_Off, Inversion_On, Inversion_Unknown
};
- struct FEC {
- enum {
- fAuto, f1_2, f2_3, f3_4, f5_6, f7_8, f8_9, f3_5, f4_5, f9_10, fNone=15
- };
+
+ enum {
+ FEC_Auto, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_8_9, FEC_3_5, FEC_4_5, FEC_9_10, FEC_None=15
};
- struct System {
- enum {
- DVB_S, DVB_S2
- };
+
+ enum {
+ System_DVB_S, System_DVB_S2
};
- struct Modulation {
- enum {
- Auto, QPSK, M8PSK, QAM_16
- };
+
+ enum {
+ Modulation_Auto, Modulation_QPSK, Modulation_8PSK, Modulation_QAM16
};
+
// dvb-s2
- struct RollOff {
- enum {
- alpha_0_35, alpha_0_25, alpha_0_20
- };
+ enum {
+ RollOff_alpha_0_35, RollOff_alpha_0_25, RollOff_alpha_0_20
};
- // only 8psk
- struct Pilot {
- enum {
- Off, On, Unknown
- };
+
+ enum {
+ Pilot_Off, Pilot_On, Pilot_Unknown
};
+
bool no_rotor_command_on_tune;
unsigned int frequency, symbol_rate;
int polarisation, fec, inversion, orbital_position, system, modulation, rolloff, pilot;
@@ -60,21 +52,18 @@ struct eDVBFrontendParametersCable
#ifndef SWIG
void set(const CableDeliverySystemDescriptor &);
#endif
- struct Inversion {
- enum {
- Off, On, Unknown
- };
+ enum {
+ Inversion_Off, Inversion_On, Inversion_Unknown
};
- struct FEC {
- enum {
- fAuto, f1_2, f2_3, f3_4, f5_6, f7_8, f8_9, fNone=15
- };
+
+ enum {
+ FEC_Auto, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_8_9, FEC_None=15
};
- struct Modulation {
- enum {
- Auto, QAM16, QAM32, QAM64, QAM128, QAM256
- };
+
+ enum {
+ Modulation_Auto, Modulation_QAM16, Modulation_QAM32, Modulation_QAM64, Modulation_QAM128, Modulation_QAM256
};
+
unsigned int frequency, symbol_rate;
int modulation, inversion, fec_inner;
};
@@ -85,42 +74,34 @@ struct eDVBFrontendParametersTerrestrial
#ifndef SWIG
void set(const TerrestrialDeliverySystemDescriptor &);
#endif
- struct Bandwidth {
- enum {
- Bw8MHz, Bw7MHz, Bw6MHz, /*Bw5MHz,*/ BwAuto
- }; // Bw5Mhz nyi (compatibilty with enigma1)
- };
- struct FEC {
- enum {
- f1_2, f2_3, f3_4, f5_6, f7_8, fAuto
- };
- };
- struct TransmissionMode {
- enum {
- TM2k, TM8k, /*TM4k,*/ TMAuto
- }; // TM4k nyi (compatibility with enigma1)
+ enum {
+ Bandwidth_8MHz, Bandwidth_7MHz, Bandwidth_6MHz, /*Bandwidth_5MHz,*/ Bandwidth_Auto
+ }; // Bw5Mhz nyi (compatibilty with enigma1)
+
+ enum {
+ FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_Auto
};
- struct GuardInterval {
- enum {
- GI_1_32, GI_1_16, GI_1_8, GI_1_4, GI_Auto
- };
+
+ enum {
+ TransmissionMode_2k, TransmissionMode_8k, /*TransmissionMode_4k,*/ TransmissionMode_Auto
+ }; // TM4k nyi (compatibility with enigma1)
+
+ enum {
+ GuardInterval_1_32, GuardInterval_1_16, GuardInterval_1_8, GuardInterval_1_4, GuardInterval_Auto
};
- struct Hierarchy {
- enum {
- HNone, H1, H2, H4, HAuto
- };
+
+ enum {
+ Hierarchy_None, Hierarchy_1, Hierarchy_2, Hierarchy_4, Hierarchy_Auto
};
- struct Modulation {
- enum {
- QPSK, QAM16, QAM64, Auto
- };
+
+ enum {
+ Modulation_QPSK, Modulation_QAM16, Modulation_QAM64, Modulation_Auto
};
- struct Inversion
- {
- enum {
- Off, On, Unknown
- };
+
+ enum {
+ Inversion_Off, Inversion_On, Inversion_Unknown
};
+
unsigned int frequency;
int bandwidth;
int code_rate_HP, code_rate_LP;
diff --git a/lib/dvb/idemux.h b/lib/dvb/idemux.h
index 2b750882..9432afb6 100644
--- a/lib/dvb/idemux.h
+++ b/lib/dvb/idemux.h
@@ -38,6 +38,8 @@ public:
virtual RESULT setBoundary(off_t max) = 0;
virtual RESULT stop() = 0;
+
+ virtual RESULT getCurrentPCR(pts_t &pcr) = 0;
enum {
eventWriteError,
diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h
index bd1c7035..cfa98ecf 100644
--- a/lib/dvb/idvb.h
+++ b/lib/dvb/idvb.h
@@ -404,15 +404,16 @@ class iDVBFrontendParameters: public iObject
#endif
public:
enum { flagOnlyFree = 1 };
- virtual RESULT getSystem(int &SWIG_OUTPUT) const = 0;
- virtual RESULT getDVBS(eDVBFrontendParametersSatellite &SWIG_OUTPUT) const = 0;
- virtual RESULT getDVBC(eDVBFrontendParametersCable &SWIG_OUTPUT) const = 0;
- virtual RESULT getDVBT(eDVBFrontendParametersTerrestrial &SWIG_OUTPUT) const = 0;
-
- virtual RESULT calculateDifference(const iDVBFrontendParameters *parm, int &SWIG_OUTPUT, bool exact) const = 0;
- virtual RESULT getHash(unsigned long &SWIG_OUTPUT) const = 0;
- virtual RESULT calcLockTimeout(unsigned int &) const = 0;
- virtual RESULT getFlags(unsigned int &) const = 0;
+ virtual SWIG_VOID(RESULT) getSystem(int &SWIG_OUTPUT) const = 0;
+ virtual SWIG_VOID(RESULT) getDVBS(eDVBFrontendParametersSatellite &SWIG_OUTPUT) const = 0;
+ virtual SWIG_VOID(RESULT) getDVBC(eDVBFrontendParametersCable &SWIG_OUTPUT) const = 0;
+ virtual SWIG_VOID(RESULT) getDVBT(eDVBFrontendParametersTerrestrial &SWIG_OUTPUT) const = 0;
+ virtual SWIG_VOID(RESULT) getFlags(unsigned int &SWIG_OUTPUT) const = 0;
+#ifndef SWIG
+ virtual SWIG_VOID(RESULT) calculateDifference(const iDVBFrontendParameters *parm, int &, bool exact) const = 0;
+ virtual SWIG_VOID(RESULT) getHash(unsigned long &) const = 0;
+ virtual SWIG_VOID(RESULT) calcLockTimeout(unsigned int &) const = 0;
+#endif
};
SWIG_TEMPLATE_TYPEDEF(ePtr<iDVBFrontendParameters>, iDVBFrontendParametersPtr);
@@ -504,6 +505,7 @@ class iDVBChannel: public iObject
public:
/* direct frontend access for raw channels and/or status inquiries. */
virtual SWIG_VOID(RESULT) getFrontend(ePtr<iDVBFrontend> &SWIG_OUTPUT)=0;
+ virtual RESULT requestTsidOnid(SWIG_PYOBJECT(ePyObject) callback) { return -1; }
#ifndef SWIG
enum
{
@@ -701,6 +703,12 @@ public:
};
virtual RESULT connectVideoEvent(const Slot1<void, struct videoEvent> &event, ePtr<eConnection> &connection) = 0;
+
+ virtual int getVideoWidth() = 0;
+ virtual int getVideoHeight() = 0;
+ virtual int getVideoProgressive() = 0;
+ virtual int getVideoFrameRate() = 0;
+ virtual int getVideoAspect() = 0;
};
#endif //SWIG
diff --git a/lib/dvb/metaparser.cpp b/lib/dvb/metaparser.cpp
index 3e3f9a79..175c7cdb 100644
--- a/lib/dvb/metaparser.cpp
+++ b/lib/dvb/metaparser.cpp
@@ -6,6 +6,8 @@ eDVBMetaParser::eDVBMetaParser()
{
m_time_create = 0;
m_data_ok = 0;
+ m_length = 0;
+ m_filesize = 0;
}
int eDVBMetaParser::parseFile(const std::string &basename)
@@ -59,6 +61,12 @@ int eDVBMetaParser::parseMeta(const std::string &tsname)
case 4:
m_tags = line;
break;
+ case 5:
+ m_length = atoi(line); //movielength in pts
+ break;
+ case 6:
+ m_filesize = atoll(line);
+ break;
default:
break;
}
@@ -105,17 +113,19 @@ int eDVBMetaParser::parseRecordings(const std::string &filename)
ref = eServiceReferenceDVB(line + 10);
if (!strncmp(line, "#DESCRIPTION: ", 14))
description = line + 14;
-
- if ((line[0] == '/') && (ref.path == filename))
+ if ((line[0] == '/') && (ref.path.substr(ref.path.find_last_of('/')) == filename.substr(filename.find_last_of('/'))))
{
// eDebug("hit! ref %s descr %s", m_ref.toString().c_str(), m_name.c_str());
m_ref = ref;
m_name = description;
m_description = "";
m_time_create = 0;
-
+ m_length = 0;
+ m_filesize = 0;
+
m_data_ok = 1;
fclose(f);
+ updateMeta(filename.c_str());
return 0;
}
}
@@ -125,14 +135,17 @@ int eDVBMetaParser::parseRecordings(const std::string &filename)
int eDVBMetaParser::updateMeta(const std::string &tsname)
{
- if (!m_data_ok)
+ /* write meta file only if we have valid data. Note that we might convert recordings.epl data to .meta, which is fine. */
+ if (!m_data_ok)
return -1;
std::string filename = tsname + ".meta";
+ eServiceReference ref = m_ref;
+ ref.path = "";
FILE *f = fopen(filename.c_str(), "w");
if (!f)
return -ENOENT;
- fprintf(f, "%s\n%s\n%s\n%d\n%s\n", m_ref.toString().c_str(), m_name.c_str(), m_description.c_str(), m_time_create, m_tags.c_str());
+ fprintf(f, "%s\n%s\n%s\n%d\n%s\n%d\n%lld\n", ref.toString().c_str(), m_name.c_str(), m_description.c_str(), m_time_create, m_tags.c_str(), m_length, m_filesize );
fclose(f);
return 0;
}
diff --git a/lib/dvb/metaparser.h b/lib/dvb/metaparser.h
index 01fabde8..2ca94d6d 100644
--- a/lib/dvb/metaparser.h
+++ b/lib/dvb/metaparser.h
@@ -18,7 +18,8 @@ public:
eServiceReferenceDVB m_ref;
std::string m_name, m_description;
- int m_time_create;
+ int m_time_create, m_length;
+ long long m_filesize;
std::string m_tags;
};
diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp
index 842d6979..279ec74f 100644
--- a/lib/dvb/pmt.cpp
+++ b/lib/dvb/pmt.cpp
@@ -16,6 +16,7 @@
#include <dvbsi++/stream_identifier_descriptor.h>
#include <dvbsi++/subtitling_descriptor.h>
#include <dvbsi++/teletext_descriptor.h>
+#include <dvbsi++/video_stream_descriptor.h>
eDVBServicePMTHandler::eDVBServicePMTHandler()
:m_ca_servicePtr(0), m_dvb_scan(0), m_decode_demux_num(0xFF)
@@ -50,10 +51,13 @@ void eDVBServicePMTHandler::channelStateChanged(iDVBChannel *channel)
{
eDebug("ok ... now we start!!");
- if (m_pmt_pid == -1)
- m_PAT.begin(eApp, eDVBPATSpec(), m_demux);
- else
- m_PMT.begin(eApp, eDVBPMTSpec(m_pmt_pid, m_reference.getServiceID().get()), m_demux);
+ if (!m_service || m_service->usePMT())
+ {
+ if (m_pmt_pid == -1)
+ m_PAT.begin(eApp, eDVBPATSpec(), m_demux);
+ else
+ m_PMT.begin(eApp, eDVBPMTSpec(m_pmt_pid, m_reference.getServiceID().get()), m_demux);
+ }
if ( m_service && !m_service->cacheEmpty() )
serviceEvent(eventNewProgramInfo);
@@ -214,25 +218,49 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
audioStream audio;
audio.component_tag=video.component_tag=-1;
video.type = videoStream::vtMPEG2;
+ audio.type = audioStream::atMPEG;
switch ((*es)->getType())
{
case 0x1b: // AVC Video Stream (MPEG4 H264)
video.type = videoStream::vtMPEG4_H264;
+ isvideo = 1;
+ //break; fall through !!!
+ case 0x10: // MPEG 4 Part 2
+ if (!isvideo)
+ {
+ video.type = videoStream::vtMPEG4_Part2;
+ isvideo = 1;
+ }
+ //break; fall through !!!
case 0x01: // MPEG 1 video
+ if (!isvideo)
+ video.type = videoStream::vtMPEG1;
+ //break; fall through !!!
case 0x02: // MPEG 2 video
isvideo = 1;
//break; fall through !!!
case 0x03: // MPEG 1 audio
case 0x04: // MPEG 2 audio:
if (!isvideo)
+ isaudio = 1;
+ //break; fall through !!!
+ case 0x0f: // MPEG 2 AAC
+ if (!isvideo && !isaudio)
{
isaudio = 1;
- audio.type = audioStream::atMPEG;
+ audio.type = audioStream::atAAC;
}
//break; fall through !!!
+ case 0x11: // MPEG 4 AAC
+ if (!isvideo && !isaudio)
+ {
+ isaudio = 1;
+ audio.type = audioStream::atAACHE;
+ }
case 0x06: // PES Private
case 0x81: // user private
+ case 0xEA: // TS_PSI_ST_SMPTE_VC1
for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
desc != (*es)->getDescriptors()->end(); ++desc)
{
@@ -243,6 +271,17 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
check descriptors to get the exakt type. */
switch (tag)
{
+ case AUDIO_STREAM_DESCRIPTOR:
+ isaudio = 1;
+ break;
+ case VIDEO_STREAM_DESCRIPTOR:
+ {
+ isvideo = 1;
+ VideoStreamDescriptor *d = (VideoStreamDescriptor*)(*desc);
+ if (d->getMpeg1OnlyFlag())
+ video.type = videoStream::vtMPEG1;
+ break;
+ }
case SUBTITLING_DESCRIPTOR:
{
SubtitlingDescriptor *d = (SubtitlingDescriptor*)(*desc);
@@ -301,9 +340,14 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
isaudio = 1;
audio.type = audioStream::atDTS;
break;
+ case 0x2B: // TS_PSI_DT_MPEG2_AAC
+ isaudio = 1;
+ audio.type = audioStream::atAAC; // MPEG2-AAC
+ break;
+ case 0x1C: // TS_PSI_DT_MPEG4_Audio
case AAC_DESCRIPTOR:
isaudio = 1;
- audio.type = audioStream::atAAC;
+ audio.type = audioStream::atAACHE; // MPEG4-AAC
break;
case AC3_DESCRIPTOR:
isaudio = 1;
@@ -312,7 +356,7 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
case REGISTRATION_DESCRIPTOR: /* some services don't have a separate AC3 descriptor */
{
/* libdvbsi++ doesn't yet support this descriptor type, so work around. */
- if ((*desc)->getLength() != 4)
+ if ((*desc)->getLength() < 4)
break;
unsigned char descr[6];
(*desc)->writeToBuffer(descr);
@@ -323,11 +367,29 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
isaudio = 1;
audio.type = audioStream::atAC3;
break;
+ case 0x56432d31:
+ if (descr[6] == 0x01) // subdescriptor tag
+ {
+ if (descr[7] >= 0x90) // profile_level
+ video.type = videoStream::vtVC1; // advanced profile
+ else
+ video.type = videoStream::vtVC1_SM; // simple main
+ isvideo = 1;
+ }
+ break;
default:
break;
}
break;
}
+ case 0x28: // TS_PSI_DT_AVC
+ isvideo = 1;
+ video.type = videoStream::vtMPEG4_H264;
+ break;
+ case 0x1B: // TS_PSI_DT_MPEG4_Video
+ isvideo = 1;
+ video.type = videoStream::vtMPEG4_Part2;
+ break;
default:
break;
}
@@ -1143,8 +1205,8 @@ void eDVBCAService::sendCAPMT()
static PyObject *createTuple(int pid, const char *type)
{
PyObject *r = PyTuple_New(2);
- PyTuple_SetItem(r, 0, PyInt_FromLong(pid));
- PyTuple_SetItem(r, 1, PyString_FromString(type));
+ PyTuple_SET_ITEM(r, 0, PyInt_FromLong(pid));
+ PyTuple_SET_ITEM(r, 1, PyString_FromString(type));
return r;
}
@@ -1154,17 +1216,18 @@ static inline void PyList_AppendSteal(PyObject *list, PyObject *item)
Py_DECREF(item);
}
+extern void PutToDict(ePyObject &dict, const char*key, ePyObject item); // defined in dvb/frontend.cpp
+
PyObject *eDVBServicePMTHandler::program::createPythonObject()
{
- PyObject *r = PyDict_New();
+ ePyObject r = PyDict_New();
+ ePyObject l = PyList_New(0);
- PyObject *l = PyList_New(0);
-
PyList_AppendSteal(l, createTuple(0, "pat"));
if (pmtPid != -1)
PyList_AppendSteal(l, createTuple(pmtPid, "pmt"));
-
+
for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
i(videoStreams.begin());
i != videoStreams.end(); ++i)
@@ -1184,7 +1247,8 @@ PyObject *eDVBServicePMTHandler::program::createPythonObject()
if (textPid != -1)
PyList_AppendSteal(l, createTuple(textPid, "text"));
-
- PyDict_SetItemString(r, "pids", l);
+
+ PutToDict(r, "pids", l);
+
return r;
}
diff --git a/lib/dvb/pmt.h b/lib/dvb/pmt.h
index ff0ef046..3e22174b 100644
--- a/lib/dvb/pmt.h
+++ b/lib/dvb/pmt.h
@@ -135,14 +135,14 @@ public:
{
int pid;
int component_tag;
- enum { vtMPEG2, vtMPEG4_H264 };
+ enum { vtMPEG2, vtMPEG4_H264, vtMPEG1, vtMPEG4_Part2, vtVC1, vtVC1_SM };
int type;
};
struct audioStream
{
int pid;
- enum { atMPEG, atAC3, atDTS, atAAC };
+ enum { atMPEG, atAC3, atDTS, atAAC, atAACHE };
int type; // mpeg2, ac3, dts, ...
int component_tag;
diff --git a/lib/dvb/pvrparse.cpp b/lib/dvb/pvrparse.cpp
index c7a37460..71cbd602 100644
--- a/lib/dvb/pvrparse.cpp
+++ b/lib/dvb/pvrparse.cpp
@@ -284,7 +284,7 @@ int eMPEGStreamInformation::getNextAccessPoint(pts_t &ts, const pts_t &start, in
return 0;
}
-eMPEGStreamParserTS::eMPEGStreamParserTS(eMPEGStreamInformation &streaminfo): m_streaminfo(streaminfo), m_pktptr(0), m_pid(-1), m_need_next_packet(0), m_skip(0)
+eMPEGStreamParserTS::eMPEGStreamParserTS(eMPEGStreamInformation &streaminfo): m_streaminfo(streaminfo), m_pktptr(0), m_pid(-1), m_need_next_packet(0), m_skip(0), m_last_pts_valid(0)
{
}
@@ -331,6 +331,9 @@ int eMPEGStreamParserTS::processPacket(const unsigned char *pkt, off_t offset)
pts |= ((unsigned long long)(pkt[12]&0xFF)) << 7;
pts |= ((unsigned long long)(pkt[13]&0xFE)) >> 1;
ptsvalid = 1;
+
+ m_last_pts = pts;
+ m_last_pts_valid = 1;
#if 0
int sec = pts / 90000;
@@ -522,3 +525,15 @@ void eMPEGStreamParserTS::setPid(int _pid)
m_pktptr = 0;
m_pid = _pid;
}
+
+int eMPEGStreamParserTS::getLastPTS(pts_t &last_pts)
+{
+ if (!m_last_pts_valid)
+ {
+ last_pts = 0;
+ return -1;
+ }
+ last_pts = m_last_pts;
+ return 0;
+}
+
diff --git a/lib/dvb/pvrparse.h b/lib/dvb/pvrparse.h
index b2ddd23d..20d33470 100644
--- a/lib/dvb/pvrparse.h
+++ b/lib/dvb/pvrparse.h
@@ -55,6 +55,7 @@ public:
eMPEGStreamParserTS(eMPEGStreamInformation &streaminfo);
void parseData(off_t offset, const void *data, unsigned int len);
void setPid(int pid);
+ int getLastPTS(pts_t &last_pts);
private:
eMPEGStreamInformation &m_streaminfo;
unsigned char m_pkt[188];
@@ -64,6 +65,8 @@ private:
int m_pid;
int m_need_next_packet;
int m_skip;
+ int m_last_pts_valid;
+ pts_t m_last_pts;
};
#endif
diff --git a/lib/dvb/scan.cpp b/lib/dvb/scan.cpp
index 71893f95..76c71011 100644
--- a/lib/dvb/scan.cpp
+++ b/lib/dvb/scan.cpp
@@ -40,6 +40,8 @@ int eDVBScan::isValidONIDTSID(int orbital_position, eOriginalNetworkID onid, eTr
case 0:
case 0x1111:
return 0;
+ case 0x13E: // workaround for 11258H and 11470V on hotbird with same ONID/TSID (0x13E/0x578)
+ return orbital_position != 130 || tsid != 0x578;
case 1:
return orbital_position == 192;
case 0x00B1:
diff --git a/lib/dvb/sec.cpp b/lib/dvb/sec.cpp
index 2b7f717b..ac1a2028 100644
--- a/lib/dvb/sec.cpp
+++ b/lib/dvb/sec.cpp
@@ -37,81 +37,11 @@ void eDVBSatelliteEquipmentControl::setParam(int param, int value)
}
eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl(eSmartPtrList<eDVBRegisteredFrontend> &avail_frontends, eSmartPtrList<eDVBRegisteredFrontend> &avail_simulate_frontends)
- :m_lnbidx(-1), m_curSat(m_lnbs[0].m_satellites.end()), m_avail_frontends(avail_frontends), m_avail_simulate_frontends(avail_simulate_frontends), m_rotorMoving(false)
+ :m_lnbidx((sizeof(m_lnbs) / sizeof(eDVBSatelliteLNBParameters))-1), m_curSat(m_lnbs[0].m_satellites.end()), m_avail_frontends(avail_frontends), m_avail_simulate_frontends(avail_simulate_frontends), m_rotorMoving(false)
{
if (!instance)
instance = this;
-
clear();
-
-// ASTRA
- addLNB();
- setLNBSlotMask(3);
- setLNBLOFL(9750000);
- setLNBThreshold(11700000);
- setLNBLOFH(10607000);
- setDiSEqCMode(eDVBSatelliteDiseqcParameters::V1_0);
- setToneburst(eDVBSatelliteDiseqcParameters::NO);
- setRepeats(0);
- setCommittedCommand(eDVBSatelliteDiseqcParameters::BB);
- setCommandOrder(0); // committed, toneburst
- setFastDiSEqC(true);
- setSeqRepeat(false);
- addSatellite(192);
- setVoltageMode(eDVBSatelliteSwitchParameters::HV);
- setToneMode(eDVBSatelliteSwitchParameters::HILO);
-
-// Hotbird
- addLNB();
- setLNBSlotMask(3);
- setLNBLOFL(9750000);
- setLNBThreshold(11700000);
- setLNBLOFH(10600000);
- setDiSEqCMode(eDVBSatelliteDiseqcParameters::V1_0);
- setToneburst(eDVBSatelliteDiseqcParameters::NO);
- setRepeats(0);
- setCommittedCommand(eDVBSatelliteDiseqcParameters::AB);
- setCommandOrder(0); // committed, toneburst
- setFastDiSEqC(true);
- setSeqRepeat(false);
- addSatellite(130);
- setVoltageMode(eDVBSatelliteSwitchParameters::HV);
- setToneMode(eDVBSatelliteSwitchParameters::HILO);
-
-// Rotor
- addLNB();
- setLNBSlotMask(3);
- setLNBLOFL(9750000);
- setLNBThreshold(11700000);
- setLNBLOFH(10600000);
- setDiSEqCMode(eDVBSatelliteDiseqcParameters::V1_2);
- setToneburst(eDVBSatelliteDiseqcParameters::NO);
- setRepeats(0);
- setCommittedCommand(eDVBSatelliteDiseqcParameters::AA);
- setCommandOrder(0); // committed, toneburst
- setFastDiSEqC(true);
- setSeqRepeat(false);
- setLaDirection(eDVBSatelliteRotorParameters::NORTH);
- setLoDirection(eDVBSatelliteRotorParameters::EAST);
- setLatitude(51.017);
- setLongitude(8.683);
- setUseInputpower(true);
- setInputpowerDelta(50);
-
- addSatellite(235);
- setVoltageMode(eDVBSatelliteSwitchParameters::HV);
- setToneMode(eDVBSatelliteSwitchParameters::HILO);
- setRotorPosNum(0);
-
- addSatellite(284);
- setVoltageMode(eDVBSatelliteSwitchParameters::HV);
- setToneMode(eDVBSatelliteSwitchParameters::HILO);
- setRotorPosNum(0);
-
- addSatellite(420);
- setVoltageMode(eDVBSatelliteSwitchParameters::HV);
- setToneMode(eDVBSatelliteSwitchParameters::HILO);
- setRotorPosNum(1); // stored pos 1
}
#define eSecDebugNoSimulate(x...) \
@@ -140,7 +70,7 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
{
bool rotor=false;
eDVBSatelliteLNBParameters &lnb_param = m_lnbs[idx];
- if ( lnb_param.slot_mask & slot_id ) // lnb for correct tuner?
+ if ( lnb_param.m_slot_mask & slot_id ) // lnb for correct tuner?
{
int ret = 0;
eDVBSatelliteDiseqcParameters &di_param = lnb_param.m_diseqc_parameters;
@@ -169,7 +99,7 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
if ( sat.frequency > lnb_param.m_lof_threshold )
band |= 1;
- if (!(sat.polarisation & eDVBFrontendParametersSatellite::Polarisation::Vertical))
+ if (!(sat.polarisation & eDVBFrontendParametersSatellite::Polarisation_Vertical))
band |= 2;
if (di_param.m_diseqc_mode >= eDVBSatelliteDiseqcParameters::V1_0)
@@ -283,7 +213,7 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
eSecDebugNoSimulate("ret5 %d", ret);
}
- if (ret && rotor && curRotorPos != -1 && (direct_connected || satpos_depends_ptr == -1) ) // direct conntected or loopthrough!
+ if (ret && rotor && curRotorPos != -1)
ret -= abs(curRotorPos-sat.orbital_position);
eSecDebugNoSimulate("ret6 %d", ret);
@@ -297,6 +227,9 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
ret=0;
}
+ if (ret && lnb_param.m_prio != -1)
+ ret = lnb_param.m_prio;
+
eSecDebugNoSimulate("ret %d, score old %d", ret, score);
if (ret > score)
{
@@ -309,7 +242,12 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
}
}
if (score && satcount)
- score -= (satcount-1);
+ {
+ if (score > (satcount-1))
+ score -= (satcount-1);
+ else
+ score = 1; // min score
+ }
if (score && direct_connected)
score += 5; // increase score for tuners with direct sat connection
eSecDebugNoSimulate("final score %d", score);
@@ -367,10 +305,16 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
lnb_param.m_satellites.find(sat.orbital_position);
if ( sit != lnb_param.m_satellites.end())
{
+ eSecCommandList sec_sequence;
+
+ lnb_param.guard_offset = 0; //HACK
+
+ frontend.setData(eDVBFrontend::SATCR, lnb_param.SatCR_idx);
+
eDVBSatelliteSwitchParameters &sw_param = sit->second;
bool doSetFrontend = true;
bool doSetVoltageToneFrontend = true;
- bool sendDiSEqC = false;
+ bool forceStaticMode = true;
bool forceChanged = false;
bool needDiSEqCReset = false;
long band=0,
@@ -388,6 +332,11 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
iDVBFrontend *sec_fe=&frontend;
eDVBRegisteredFrontend *linked_fe = 0;
eDVBSatelliteDiseqcParameters::t_diseqc_mode diseqc_mode = di_param.m_diseqc_mode;
+ eDVBSatelliteSwitchParameters::t_voltage_mode voltage_mode = sw_param.m_voltage_mode;
+ bool diseqc13V = voltage_mode == eDVBSatelliteSwitchParameters::HV_13;
+
+ if (diseqc13V)
+ voltage_mode = eDVBSatelliteSwitchParameters::HV;
frontend.getData(eDVBFrontend::SATPOS_DEPENDS_PTR, satposDependPtr);
@@ -424,35 +373,54 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
if ( sat.frequency > lnb_param.m_lof_threshold )
band |= 1;
+ if (!(sat.polarisation & eDVBFrontendParametersSatellite::Polarisation_Vertical))
+ band |= 2;
- if (band&1)
- parm.FREQUENCY = sat.frequency - lnb_param.m_lof_hi;
- else
- parm.FREQUENCY = sat.frequency - lnb_param.m_lof_lo;
-
- parm.FREQUENCY = abs(parm.FREQUENCY);
-
- frontend.setData(eDVBFrontend::FREQ_OFFSET, sat.frequency - parm.FREQUENCY);
+ int lof = (band&1)?lnb_param.m_lof_hi:lnb_param.m_lof_lo;
- if (!(sat.polarisation & eDVBFrontendParametersSatellite::Polarisation::Vertical))
- band |= 2;
+ int local=0;
- if ( sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::_14V
- || ( sat.polarisation & eDVBFrontendParametersSatellite::Polarisation::Vertical
- && sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::HV ) )
- voltage = VOLTAGE(13);
- else if ( sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::_18V
- || ( !(sat.polarisation & eDVBFrontendParametersSatellite::Polarisation::Vertical)
- && sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::HV ) )
- voltage = VOLTAGE(18);
- if ( (sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::ON)
- || ( sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::HILO && (band&1) ) )
- tone = iDVBFrontend::toneOn;
- else if ( (sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::OFF)
- || ( sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::HILO && !(band&1) ) )
- tone = iDVBFrontend::toneOff;
- eSecCommandList sec_sequence;
+ if(lnb_param.SatCR_idx == -1)
+ {
+ // calc Frequency
+ local = abs(sat.frequency
+ - ((lof - (lof % 1000)) + ((lof % 1000)>500 ? 1000 : 0)) ); //TODO für den Mist mal ein Macro schreiben
+ parm.FREQUENCY = (local - (local % 125)) + ((local % 125)>62 ? 125 : 0);
+ frontend.setData(eDVBFrontend::FREQ_OFFSET, sat.frequency - parm.FREQUENCY);
+
+ if ( voltage_mode == eDVBSatelliteSwitchParameters::_14V
+ || ( sat.polarisation & eDVBFrontendParametersSatellite::Polarisation_Vertical
+ && voltage_mode == eDVBSatelliteSwitchParameters::HV ) )
+ voltage = VOLTAGE(13);
+ else if ( voltage_mode == eDVBSatelliteSwitchParameters::_18V
+ || ( !(sat.polarisation & eDVBFrontendParametersSatellite::Polarisation_Vertical)
+ && voltage_mode == eDVBSatelliteSwitchParameters::HV ) )
+ voltage = VOLTAGE(18);
+ if ( (sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::ON)
+ || ( sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::HILO && (band&1) ) )
+ tone = iDVBFrontend::toneOn;
+ else if ( (sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::OFF)
+ || ( sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::HILO && !(band&1) ) )
+ tone = iDVBFrontend::toneOff;
+ }
+ else
+ {
+ unsigned int tmp = abs(sat.frequency
+ - ((lof - (lof % 1000)) + ((lof % 1000)>500 ? 1000 : 0)) )
+ + lnb_param.SatCRvco
+ - 1400000
+ + lnb_param.guard_offset;
+ parm.FREQUENCY = (lnb_param.SatCRvco - (tmp % 4000))+((tmp%4000)>2000?4000:0)+lnb_param.guard_offset;
+ lnb_param.UnicableTuningWord = (((tmp / 4000)+((tmp%4000)>2000?1:0))
+ | ((band & 1) ? 0x400 : 0) //HighLow
+ | ((band & 2) ? 0x800 : 0) //VertHor
+ | ((lnb_param.LNBNum & 1) ? 0 : 0x1000) //Umschaltung LNB1 LNB2
+ | (lnb_param.SatCR_idx << 13)); //Adresse des SatCR
+ eDebug("[prepare] UnicableTuningWord %#04x",lnb_param.UnicableTuningWord);
+ eDebug("[prepare] guard_offset %d",lnb_param.guard_offset);
+ frontend.setData(eDVBFrontend::FREQ_OFFSET, sat.frequency - ((lnb_param.UnicableTuningWord & 0x3FF) *4000 + 1400000 - lnb_param.SatCRvco + lof));
+ }
if (diseqc_mode >= eDVBSatelliteDiseqcParameters::V1_0)
{
@@ -597,7 +565,9 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE]) );
- if ( RotorCmd != -1 && RotorCmd != lastRotorCmd )
+ if (diseqc13V)
+ vlt = iDVBFrontend::voltage13;
+ else if ( RotorCmd != -1 && RotorCmd != lastRotorCmd )
{
if (rotor_param.m_inputpower_parameters.m_use)
vlt = VOLTAGE(18); // in input power mode set 18V for measure input power
@@ -723,14 +693,13 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
if (di_param.m_seq_repeat && seq_repeat == 0)
sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_BEFORE_SEQUENCE_REPEAT]) );
}
- sendDiSEqC = true;
}
eDebugNoSimulate("RotorCmd %02x, lastRotorCmd %02lx", RotorCmd, lastRotorCmd);
if ( RotorCmd != -1 && RotorCmd != lastRotorCmd )
{
eSecCommand::pair compare;
- if (!send_mask)
+ if (!send_mask && lnb_param.SatCR_idx == -1)
{
compare.steps = +3;
compare.tone = iDVBFrontend::toneOff;
@@ -784,107 +753,113 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
diseqc.data[3] = RotorCmd;
diseqc.data[4] = 0x00;
}
-
- if ( rotor_param.m_inputpower_parameters.m_use )
- { // use measure rotor input power to detect rotor state
- bool turn_fast = need_turn_fast(rotor_param.m_inputpower_parameters.m_turning_speed);
- eSecCommand::rotor cmd;
- eSecCommand::pair compare;
- compare.voltage = VOLTAGE(18);
- compare.steps = +3;
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, compare.voltage) );
-// measure idle power values
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MEASURE_IDLE_INPUTPOWER]) ); // wait 150msec after voltage change
- sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_IDLE_INPUTPOWER, 1) );
- compare.val = 1;
- compare.steps = -2;
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO, compare) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(13)) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MEASURE_IDLE_INPUTPOWER]) ); // wait 150msec before measure
- sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_IDLE_INPUTPOWER, 0) );
- compare.val = 0;
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO, compare) );
-////////////////////////////
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_DISEQC_RETRYS, m_params[MOTOR_COMMAND_RETRIES]) ); // 2 retries
- sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_ROTORPARMS) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, 40) ); // 2 seconds rotor start timout
-// rotor start loop
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); // 50msec delay
- sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_RUNNING_INPUTPOWER) );
- cmd.direction=1; // check for running rotor
- cmd.deltaA=rotor_param.m_inputpower_parameters.m_delta;
- cmd.steps=+5;
- cmd.okcount=0;
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_INPUTPOWER_DELTA_GOTO, cmd ) ); // check if rotor has started
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +2 ) ); // timeout .. we assume now the rotor is already at the correct position
- sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) ); // goto loop start
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO, turn_fast ? 10 : 9 ) ); // timeout .. we assume now the rotor is already at the correct position
- sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -8) ); // goto loop start
-////////////////////
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_MOVING) );
- if (turn_fast)
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(18)) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, m_params[MOTOR_RUNNING_TIMEOUT]*20) ); // 2 minutes running timeout
-// rotor running loop
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); // wait 50msec
- sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_RUNNING_INPUTPOWER) );
- cmd.direction=0; // check for stopped rotor
- cmd.steps=+3;
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_INPUTPOWER_DELTA_GOTO, cmd ) );
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +2 ) ); // timeout ? this should never happen
- sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) ); // running loop start
-/////////////////////
- sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_ROTORPARAMS) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_STOPPED) );
- }
- else
- { // use normal turning mode
- doSetVoltageToneFrontend=false;
- doSetFrontend=false;
- eSecCommand::rotor cmd;
- eSecCommand::pair compare;
- compare.voltage = VOLTAGE(13);
- compare.steps = +3;
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, compare.voltage) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MOTOR_CMD]) ); // wait 150msec after voltage change
-
- sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_ROTORPARMS) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_MOVING) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
-
- compare.voltage = voltage;
- compare.steps = +3;
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); // correct final voltage?
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 2000) ); // wait 2 second before set high voltage
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) );
-
- compare.tone = tone;
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE]) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
-
- cmd.direction=1; // check for running rotor
- cmd.deltaA=0;
- cmd.steps=+3;
- cmd.okcount=0;
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, m_params[MOTOR_RUNNING_TIMEOUT]*4) ); // 2 minutes running timeout
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 250) ); // 250msec delay
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_TUNER_LOCKED_GOTO, cmd ) );
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +3 ) );
- sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -3) ); // goto loop start
- sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_ROTORPARAMS) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_STOPPED) );
- sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +3) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
- sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) );
+ if(lnb_param.SatCR_idx == -1)
+ {
+ if ( rotor_param.m_inputpower_parameters.m_use )
+ { // use measure rotor input power to detect rotor state
+ bool turn_fast = need_turn_fast(rotor_param.m_inputpower_parameters.m_turning_speed);
+ eSecCommand::rotor cmd;
+ eSecCommand::pair compare;
+ if (turn_fast)
+ compare.voltage = VOLTAGE(18);
+ else
+ compare.voltage = VOLTAGE(13);
+ compare.steps = +3;
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, compare.voltage) );
+ // measure idle power values
+ compare.steps = -2;
+ if (turn_fast) {
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MEASURE_IDLE_INPUTPOWER]) ); // wait 150msec after voltage change
+ sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_IDLE_INPUTPOWER, 1) );
+ compare.val = 1;
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO, compare) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(13)) );
+ }
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MEASURE_IDLE_INPUTPOWER]) ); // wait 150msec before measure
+ sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_IDLE_INPUTPOWER, 0) );
+ compare.val = 0;
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO, compare) );
+ ////////////////////////////
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_DISEQC_RETRYS, m_params[MOTOR_COMMAND_RETRIES]) ); // 2 retries
+ sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_ROTORPARMS) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, 40) ); // 2 seconds rotor start timout
+ // rotor start loop
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); // 50msec delay
+ sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_RUNNING_INPUTPOWER) );
+ cmd.direction=1; // check for running rotor
+ cmd.deltaA=rotor_param.m_inputpower_parameters.m_delta;
+ cmd.steps=+5;
+ cmd.okcount=0;
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_INPUTPOWER_DELTA_GOTO, cmd ) ); // check if rotor has started
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +2 ) ); // timeout .. we assume now the rotor is already at the correct position
+ sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) ); // goto loop start
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO, turn_fast ? 10 : 9 ) ); // timeout .. we assume now the rotor is already at the correct position
+ sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -8) ); // goto loop start
+ ////////////////////
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_MOVING) );
+ if (turn_fast)
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(18)) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, m_params[MOTOR_RUNNING_TIMEOUT]*20) ); // 2 minutes running timeout
+ // rotor running loop
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); // wait 50msec
+ sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_RUNNING_INPUTPOWER) );
+ cmd.direction=0; // check for stopped rotor
+ cmd.steps=+3;
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_INPUTPOWER_DELTA_GOTO, cmd ) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +2 ) ); // timeout ? this should never happen
+ sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) ); // running loop start
+ /////////////////////
+ sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_ROTORPARAMS) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_STOPPED) );
+ }
+ else
+ { // use normal turning mode
+ doSetVoltageToneFrontend=false;
+ doSetFrontend=false;
+ eSecCommand::rotor cmd;
+ eSecCommand::pair compare;
+ compare.voltage = VOLTAGE(13);
+ compare.steps = +3;
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, compare.voltage) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MOTOR_CMD]) ); // wait 150msec after voltage change
+
+ sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_ROTORPARMS) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_MOVING) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
+
+ compare.voltage = voltage;
+ compare.steps = +3;
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); // correct final voltage?
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 2000) ); // wait 2 second before set high voltage
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) );
+
+ compare.tone = tone;
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE]) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
+
+ cmd.direction=1; // check for running rotor
+ cmd.deltaA=0;
+ cmd.steps=+3;
+ cmd.okcount=0;
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, m_params[MOTOR_RUNNING_TIMEOUT]*4) ); // 2 minutes running timeout
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 250) ); // 250msec delay
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_TUNER_LOCKED_GOTO, cmd ) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +3 ) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -3) ); // goto loop start
+ sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_ROTORPARAMS) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_STOPPED) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +3) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) );
+ }
}
sec_fe->setData(eDVBFrontend::NEW_ROTOR_CMD, RotorCmd);
sec_fe->setData(eDVBFrontend::NEW_ROTOR_POS, sat.orbital_position);
- sendDiSEqC = true;
}
}
}
@@ -894,14 +869,11 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
csw = band;
}
-// if (sendDiSEqC)
- sec_sequence.push_front( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeStatic) );
-
sec_fe->setData(eDVBFrontend::NEW_CSW, csw);
sec_fe->setData(eDVBFrontend::NEW_UCSW, ucsw);
sec_fe->setData(eDVBFrontend::NEW_TONEBURST, di_param.m_toneburst_param);
- if (doSetVoltageToneFrontend)
+ if ((doSetVoltageToneFrontend) && (lnb_param.SatCR_idx == -1))
{
eSecCommand::pair compare;
compare.voltage = voltage;
@@ -917,16 +889,45 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_SWITCHPARMS) );
+ if(lnb_param.SatCR_idx != -1)
+ {
+ // check if voltage is disabled
+ eSecCommand::pair compare;
+ compare.steps = +3;
+ compare.voltage = iDVBFrontend::voltageOff;
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_NOT_VOLTAGE_GOTO, compare) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50 ) );
+
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage18_5) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MOTOR_CMD]) ); // wait 150msec after voltage change
+
+ eDVBDiseqcCommand diseqc;
+ memset(diseqc.data, 0, MAX_DISEQC_LENGTH);
+ diseqc.len = 5;
+ diseqc.data[0] = 0xE0;
+ diseqc.data[1] = 0x10;
+ diseqc.data[2] = 0x5A;
+ diseqc.data[3] = lnb_param.UnicableTuningWord >> 8;
+ diseqc.data[4] = lnb_param.UnicableTuningWord;
+
+ sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_LAST_DISEQC_CMD]) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
+ }
+
if (doSetFrontend)
{
sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, tunetimeout) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
}
-
-// if (sendDiSEqC)
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeDynamic) );
-
+
+ if (forceStaticMode)
+ {
+ sec_sequence.push_front( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeStatic) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeDynamic) );
+ }
frontend.setSecSequence(sec_sequence);
return 0;
@@ -935,12 +936,12 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
eDebugNoSimulate("found no useable satellite configuration for %s freq %d%s %s on orbital position (%d)",
sat.system ? "DVB-S2" : "DVB-S",
sat.frequency,
- sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Horizontal ? "H" :
- eDVBFrontendParametersSatellite::Polarisation::Vertical ? "V" :
- eDVBFrontendParametersSatellite::Polarisation::CircularLeft ? "CL" : "CR",
- sat.modulation == eDVBFrontendParametersSatellite::Modulation::Auto ? "AUTO" :
- eDVBFrontendParametersSatellite::Modulation::QPSK ? "QPSK" :
- eDVBFrontendParametersSatellite::Modulation::M8PSK ? "8PSK" : "QAM16",
+ sat.polarisation == eDVBFrontendParametersSatellite::Polarisation_Horizontal ? "H" :
+ eDVBFrontendParametersSatellite::Polarisation_Vertical ? "V" :
+ eDVBFrontendParametersSatellite::Polarisation_CircularLeft ? "CL" : "CR",
+ sat.modulation == eDVBFrontendParametersSatellite::Modulation_Auto ? "AUTO" :
+ eDVBFrontendParametersSatellite::Modulation_QPSK ? "QPSK" :
+ eDVBFrontendParametersSatellite::Modulation_8PSK ? "8PSK" : "QAM16",
sat.orbital_position );
return -1;
}
@@ -951,7 +952,8 @@ RESULT eDVBSatelliteEquipmentControl::clear()
for (int i=0; i <= m_lnbidx; ++i)
{
m_lnbs[i].m_satellites.clear();
- m_lnbs[i].slot_mask = 0;
+ m_lnbs[i].m_slot_mask = 0;
+ m_lnbs[i].m_prio = -1; // auto
}
m_lnbidx=-1;
@@ -977,6 +979,7 @@ RESULT eDVBSatelliteEquipmentControl::clear()
it->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, -1);
it->m_frontend->setData(eDVBFrontend::ROTOR_POS, -1);
it->m_frontend->setData(eDVBFrontend::ROTOR_CMD, -1);
+ it->m_frontend->setData(eDVBFrontend::SATCR, -1);
}
for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(m_avail_simulate_frontends.begin()); it != m_avail_simulate_frontends.end(); ++it)
@@ -986,6 +989,7 @@ RESULT eDVBSatelliteEquipmentControl::clear()
it->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, -1);
it->m_frontend->setData(eDVBFrontend::ROTOR_POS, -1);
it->m_frontend->setData(eDVBFrontend::ROTOR_CMD, -1);
+ it->m_frontend->setData(eDVBFrontend::SATCR, -1);
}
return 0;
@@ -1009,7 +1013,7 @@ RESULT eDVBSatelliteEquipmentControl::setLNBSlotMask(int slotmask)
{
eSecDebug("eDVBSatelliteEquipmentControl::setLNBSlotMask(%d)", slotmask);
if ( currentLNBValid() )
- m_lnbs[m_lnbidx].slot_mask = slotmask;
+ m_lnbs[m_lnbidx].m_slot_mask = slotmask;
else
return -ENOENT;
return 0;
@@ -1055,6 +1059,28 @@ RESULT eDVBSatelliteEquipmentControl::setLNBIncreasedVoltage(bool onoff)
return 0;
}
+RESULT eDVBSatelliteEquipmentControl::setLNBPrio(int prio)
+{
+ eSecDebug("eDVBSatelliteEquipmentControl::setLNBPrio(%d)", prio);
+ if ( currentLNBValid() )
+ m_lnbs[m_lnbidx].m_prio = prio;
+ else
+ return -ENOENT;
+ return 0;
+}
+
+RESULT eDVBSatelliteEquipmentControl::setLNBNum(int LNBNum)
+{
+ eSecDebug("eDVBSatelliteEquipmentControl::setLNBNum(%d)", LNBNum);
+ if(!((LNBNum >= 1) && (LNBNum <= MAX_LNBNUM)))
+ return -EPERM;
+ if ( currentLNBValid() )
+ m_lnbs[m_lnbidx].LNBNum = LNBNum;
+ else
+ return -ENOENT;
+ return 0;
+}
+
/* DiSEqC Specific Parameters */
RESULT eDVBSatelliteEquipmentControl::setDiSEqCMode(int diseqcmode)
{
@@ -1197,6 +1223,46 @@ RESULT eDVBSatelliteEquipmentControl::setInputpowerDelta(int delta)
return 0;
}
+/* Unicable Specific Parameters */
+RESULT eDVBSatelliteEquipmentControl::setLNBSatCR(int SatCR_idx)
+{
+ eSecDebug("eDVBSatelliteEquipmentControl::setLNBSatCR(%d)", SatCR_idx);
+ if(!((SatCR_idx >=-1) && (SatCR_idx < MAX_SATCR)))
+ return -EPERM;
+ if ( currentLNBValid() )
+ m_lnbs[m_lnbidx].SatCR_idx = SatCR_idx;
+ else
+ return -ENOENT;
+ return 0;
+}
+
+RESULT eDVBSatelliteEquipmentControl::setLNBSatCRvco(int SatCRvco)
+{
+ eSecDebug("eDVBSatelliteEquipmentControl::setLNBSatCRvco(%d)", SatCRvco);
+ if(!((SatCRvco >= 950*1000) && (SatCRvco <= 2150*1000)))
+ return -EPERM;
+ if(!((m_lnbs[m_lnbidx].SatCR_idx >= 0) && (m_lnbs[m_lnbidx].SatCR_idx < MAX_SATCR)))
+ return -ENOENT;
+ if ( currentLNBValid() )
+ m_lnbs[m_lnbidx].SatCRvco = SatCRvco;
+ else
+ return -ENOENT;
+ return 0;
+}
+RESULT eDVBSatelliteEquipmentControl::getLNBSatCR()
+{
+ if ( currentLNBValid() )
+ return m_lnbs[m_lnbidx].SatCR_idx;
+ return -ENOENT;
+}
+
+RESULT eDVBSatelliteEquipmentControl::getLNBSatCRvco()
+{
+ if ( currentLNBValid() )
+ return m_lnbs[m_lnbidx].SatCRvco;
+ return -ENOENT;
+}
+
/* Satellite Specific Parameters */
RESULT eDVBSatelliteEquipmentControl::addSatellite(int orbital_position)
{
diff --git a/lib/dvb/sec.h b/lib/dvb/sec.h
index e68ed167..5bff6bf7 100644
--- a/lib/dvb/sec.h
+++ b/lib/dvb/sec.h
@@ -170,7 +170,7 @@ class eDVBSatelliteSwitchParameters
#endif
public:
enum t_22khz_signal { HILO=0, ON=1, OFF=2 }; // 22 Khz
- enum t_voltage_mode { HV=0, _14V=1, _18V=2, _0V=3 }; // 14/18 V
+ enum t_voltage_mode { HV=0, _14V=1, _18V=2, _0V=3, HV_13=4 }; // 14/18 V
#ifndef SWIG
t_voltage_mode m_voltage_mode;
t_22khz_signal m_22khz_signal;
@@ -231,7 +231,7 @@ public:
#ifndef SWIG
t_12V_relais_state m_12V_relais_state; // 12V relais output on/off
- __u8 slot_mask; // useable by slot ( 1 | 2 | 4...)
+ int m_slot_mask; // useable by slot ( 1 | 2 | 4...)
unsigned int m_lof_hi, // for 2 band universal lnb 10600 Mhz (high band offset frequency)
m_lof_lo, // for 2 band universal lnb 9750 Mhz (low band offset frequency)
@@ -242,7 +242,26 @@ public:
std::map<int, eDVBSatelliteSwitchParameters> m_satellites;
eDVBSatelliteDiseqcParameters m_diseqc_parameters;
eDVBSatelliteRotorParameters m_rotor_parameters;
+
+ int m_prio; // to override automatic tuner management ... -1 is Auto
#endif
+public:
+#define guard_offset_min -8000
+#define guard_offset_max 8000
+#define guard_offset_step 8000
+#define MAX_SATCR 8
+#define MAX_LNBNUM 32
+
+ int SatCR_idx;
+ unsigned int SatCRvco;
+ unsigned int UnicableTuningWord;
+ unsigned int UnicableConfigWord;
+ int old_frequency;
+ int old_polarisation;
+ int old_orbital_position;
+ int guard_offset_old;
+ int guard_offset;
+ int LNBNum;
};
class eDVBRegisteredFrontend;
@@ -304,6 +323,8 @@ public:
RESULT setLNBLOFH(int lofh);
RESULT setLNBThreshold(int threshold);
RESULT setLNBIncreasedVoltage(bool onoff);
+ RESULT setLNBPrio(int prio);
+ RESULT setLNBNum(int LNBNum);
/* DiSEqC Specific Parameters */
RESULT setDiSEqCMode(int diseqcmode);
RESULT setToneburst(int toneburst);
@@ -321,6 +342,12 @@ public:
RESULT setUseInputpower(bool onoff);
RESULT setInputpowerDelta(int delta); // delta between running and stopped rotor
RESULT setRotorTurningSpeed(int speed); // set turning speed..
+/* Unicable Specific Parameters */
+ RESULT setLNBSatCR(int SatCR_idx);
+ RESULT setLNBSatCRvco(int SatCRvco);
+// RESULT checkGuardOffset(const eDVBFrontendParametersSatellite &sat);
+ RESULT getLNBSatCR();
+ RESULT getLNBSatCRvco();
/* Satellite Specific Parameters */
RESULT addSatellite(int orbital_position);
RESULT setVoltageMode(int mode);
diff --git a/lib/gdi/picexif.cpp b/lib/gdi/picexif.cpp
index 844673ce..f9e8055f 100644
--- a/lib/gdi/picexif.cpp
+++ b/lib/gdi/picexif.cpp
@@ -75,7 +75,6 @@ Cexif::Cexif()
Cexif::~Cexif()
{
- //ClearExif();
}
void Cexif::ClearExif()
@@ -89,7 +88,7 @@ void Cexif::ClearExif()
}
}
-bool Cexif::DecodeExif(const char *filename)
+bool Cexif::DecodeExif(const char *filename, int Thumb)
{
FILE * hFile = fopen(filename, "r");
if(!hFile) return false;
@@ -98,6 +97,7 @@ bool Cexif::DecodeExif(const char *filename)
m_exifinfo = new EXIFINFO;
memset(m_exifinfo,0,sizeof(EXIFINFO));
freeinfo = true;
+ m_exifinfo->Thumnailstate = Thumb;
m_szLastError[0]='\0';
ExifImageWidth = MotorolaOrder = SectionsRead=0;
@@ -555,12 +555,16 @@ bool Cexif::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase,
ProcessExifDir(SubdirStart, OffsetBase, ExifLength, m_exifinfo, LastExifRefdP);
}
- if (ThumbnailSize && ThumbnailOffset)
+ if (ThumbnailSize && ThumbnailOffset && m_exifinfo->Thumnailstate)
{
if (ThumbnailSize + ThumbnailOffset <= ExifLength)
{
- m_exifinfo->ThumbnailPointer = OffsetBase + ThumbnailOffset;
- m_exifinfo->ThumbnailSize = ThumbnailSize;
+ if(FILE *tf = fopen(THUMBNAILTMPFILE, "w"))
+ {
+ fwrite( OffsetBase + ThumbnailOffset, ThumbnailSize, 1, tf);
+ fclose(tf);
+ m_exifinfo->Thumnailstate = 2;
+ }
}
}
diff --git a/lib/gdi/picexif.h b/lib/gdi/picexif.h
index cd321d7b..bdd64b2a 100644
--- a/lib/gdi/picexif.h
+++ b/lib/gdi/picexif.h
@@ -8,7 +8,7 @@
#define MAX_COMMENT 1000
#define MAX_SECTIONS 20
-
+#define THUMBNAILTMPFILE "/tmp/.thumbcache"
typedef struct tag_ExifInfo {
char Version [5];
@@ -29,7 +29,7 @@ typedef struct tag_ExifInfo {
float ExposureTime;
float ExposureBias;
float Distance;
- float CCDWidth; //in milimeters
+ float CCDWidth;
float FocalplaneXRes;
float FocalplaneYRes;
float FocalplaneUnits;
@@ -40,9 +40,10 @@ typedef struct tag_ExifInfo {
int ISOequivalent;
int Process;
int Orient;
- unsigned char * ThumbnailPointer;
- unsigned ThumbnailSize;
+ //unsigned char *ThumbnailPointer;
+ //unsigned ThumbnailSize;
bool IsExif;
+ int Thumnailstate;
} EXIFINFO;
static const int BytesPerFormat[] = {0,1,1,2,4,8,1,1,2,4,8,4,8};
@@ -59,7 +60,7 @@ public:
char m_szLastError[256];
Cexif();
~Cexif();
- bool DecodeExif(const char *filename);
+ bool DecodeExif(const char *filename, int Thumb=0);
void ClearExif();
protected:
bool process_EXIF(unsigned char * CharBuf, unsigned int length);
diff --git a/lib/gdi/picload.cpp b/lib/gdi/picload.cpp
index 1f9bed48..c162f89d 100644
--- a/lib/gdi/picload.cpp
+++ b/lib/gdi/picload.cpp
@@ -1,38 +1,38 @@
#include <png.h> // must be included before Python.h because of setjmp
-#include <lib/gdi/picload.h>
-#include "picexif.h"
-#include <lib/python/python.h>
-
#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <epng.h> // savePNG need it
-
-#define JDCT_DEFAULT JDCT_IFAST
+#include <lib/gdi/picload.h>
+#include <lib/gdi/picexif.h>
extern "C" {
#include <jpeglib.h>
#include <gif_lib.h>
-//#include "transupp.h"
}
-unsigned char *pic_buffer=NULL;
+extern const uint32_t crc32_table[256];
+
+DEFINE_REF(ePicLoad);
+
+static std::string getSize(const char* file)
+{
+ struct stat64 s;
+ if (stat64(file, &s) < 0)
+ return "";
+ char tmp[20];
+ snprintf(tmp, 20, "%ld kB",(long)s.st_size / 1024);
+ return tmp;
+}
-static unsigned char *conv24to32(unsigned char * orgin, int size, int background = 0)
+static unsigned char *conv24to32(unsigned char *orgin, int size, unsigned char alpha = 0xFF)
{
int s, d;
unsigned char *cr = new unsigned char[size * 4];
if (cr == NULL)
{
- printf("[CONV32] Error: malloc\n");
+ eDebug("[Picload] Error malloc");
return(orgin);
}
- unsigned char alpha = 0x00;
- if(background) alpha = 0xFF;
-
for (s = 0, d = 0 ; s < (size * 3); s += 3, d += 4 )
{
cr[d] = orgin[s];
@@ -44,28 +44,27 @@ static unsigned char *conv24to32(unsigned char * orgin, int size, int background
return(cr);
}
-static unsigned char *simple_resize(unsigned char * orgin, int ox, int oy, int dx, int dy)
+static unsigned char *simple_resize(unsigned char *orgin, int ox, int oy, int dx, int dy)
{
unsigned char *cr, *p, *l;
int i, j, k, ip;
- cr = new unsigned char[dx * dy * 4];
+ cr = new unsigned char[dx * dy * 3];
if (cr == NULL)
{
- printf("[RESIZE] Error: malloc\n");
+ eDebug("[Picload] Error malloc");
return(orgin);
}
l = cr;
- for (j = 0; j < dy; j++,l += dx * 4)
+ for (j = 0; j < dy; j++,l += dx * 3)
{
- p = orgin + (j * oy / dy * ox * 4);
- for (i = 0, k = 0; i < dx; i++, k += 4)
+ p = orgin + (j * oy / dy * ox * 3);
+ for (i = 0, k = 0; i < dx; i++, k += 3)
{
- ip = i * ox / dx * 4;
+ ip = i * ox / dx * 3;
l[k] = p[ip];
l[k+1] = p[ip + 1];
l[k+2] = p[ip + 2];
- l[k+3] = p[ip + 3];
}
}
delete [] orgin;
@@ -76,18 +75,18 @@ static unsigned char *color_resize(unsigned char * orgin, int ox, int oy, int dx
{
unsigned char *cr, *p, *q;
int i, j, k, l, xa, xb, ya, yb;
- int sq, r, g, b, a;
- cr = new unsigned char[dx * dy * 4];
+ int sq, r, g, b;
+ cr = new unsigned char[dx * dy * 3];
if (cr == NULL)
{
- printf("[RESIZE] Error: malloc\n");
+ eDebug("[Picload] Error malloc");
return(orgin);
}
p = cr;
for (j = 0; j < dy; j++)
{
- for (i = 0; i < dx; i++, p += 4)
+ for (i = 0; i < dx; i++, p += 3)
{
xa = i * ox / dx;
ya = j * oy / dy;
@@ -97,269 +96,21 @@ static unsigned char *color_resize(unsigned char * orgin, int ox, int oy, int dx
yb = (j + 1) * oy / dy;
if (yb >= oy)
yb = oy - 1;
- for (l = ya, r = 0, g = 0, b = 0, a = 0, sq = 0; l <= yb; l++)
+ for (l = ya, r = 0, g = 0, b = 0, sq = 0; l <= yb; l++)
{
- q = orgin + ((l * ox + xa) * 4);
- for (k = xa; k <= xb; k++, q += 4, sq++)
+ q = orgin + ((l * ox + xa) * 3);
+ for (k = xa; k <= xb; k++, q += 3, sq++)
{
- r += q[0]; g += q[1]; b += q[2]; a += q[3];
+ r += q[0]; g += q[1]; b += q[2];
}
}
- p[0] = r / sq; p[1] = g / sq; p[2] = b / sq; p[3] = a / sq;
+ p[0] = r / sq; p[1] = g / sq; p[2] = b / sq;
}
}
delete [] orgin;
return(cr);
}
-//-------------------------------------------------------------------
-
-struct r_jpeg_error_mgr
-{
- struct jpeg_error_mgr pub;
- jmp_buf envbuffer;
-};
-
-void jpeg_cb_error_exit(j_common_ptr cinfo)
-{
- struct r_jpeg_error_mgr *mptr;
- mptr = (struct r_jpeg_error_mgr *) cinfo->err;
- (*cinfo->err->output_message) (cinfo);
- longjmp(mptr->envbuffer, 1);
-}
-
-static int jpeg_save(unsigned char *image_buffer, const char * filename, int quality, int image_height, int image_width)
-{
- struct jpeg_compress_struct cinfo;
- struct jpeg_error_mgr jerr;
- FILE * outfile; /* target file */
- JSAMPROW row_pointer[1];/* pointer to JSAMPLE row[s] */
- int row_stride; /* physical row width in image buffer */
-
- cinfo.err = jpeg_std_error(&jerr);
- jpeg_create_compress(&cinfo);
-
- if ((outfile = fopen(filename, "wb")) == NULL)
- {
- eDebug("[JPEG] can't open %s", filename);
- return -1;
- }
- jpeg_stdio_dest(&cinfo, outfile);
-
- cinfo.image_width = image_width;
- cinfo.image_height = image_height;
- cinfo.input_components = 3;
- cinfo.in_color_space = JCS_RGB;
- jpeg_set_defaults(&cinfo);
- jpeg_set_quality(&cinfo, quality, TRUE );
- jpeg_start_compress(&cinfo, TRUE);
- row_stride = image_width * 3;
- while (cinfo.next_scanline < cinfo.image_height)
- {
- row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
- (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
- }
- jpeg_finish_compress(&cinfo);
- fclose(outfile);
- jpeg_destroy_compress(&cinfo);
- return 0;
-}
-
-/* Expanded data source object for memory buffer input */
-typedef struct
-{
- struct jpeg_source_mgr pub; /* public fields */
- FILE *infile; /* source stream */
- JOCTET *buffer; /* start of buffer */
- boolean start_of_file; /* have we gotten any data yet? */
-} mem_source_mgr;
-
-typedef mem_source_mgr *mem_src_ptr;
-
-static void init_source (j_decompress_ptr cinfo)
-{
- mem_src_ptr src = (mem_src_ptr) cinfo->src;
- src->start_of_file = TRUE;
-}
-
-static boolean fill_input_buffer (j_decompress_ptr cinfo)
-{
- /* no-op */ (void)cinfo;
- return TRUE;
- }
-
-static void skip_input_data (j_decompress_ptr cinfo, long num_bytes)
-{
- mem_src_ptr src = (mem_src_ptr) cinfo->src;
-
- if (num_bytes > 0)
- {
- src->pub.next_input_byte += (size_t) num_bytes;
- src->pub.bytes_in_buffer -= (size_t) num_bytes;
- }
-}
-
-static void term_source (j_decompress_ptr cinfo)
-{
- /* no-op */ (void)cinfo;
-}
-
-static void jpeg_memory_src (j_decompress_ptr cinfo, unsigned char *inbfr, int len)
-{
- mem_src_ptr src;
- if (cinfo->src == NULL)
- {
- cinfo->src = (struct jpeg_source_mgr *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, (size_t)sizeof(mem_source_mgr));
- src = (mem_src_ptr) cinfo->src;
- src->buffer = (JOCTET *) inbfr;
- }
- src = (mem_src_ptr) cinfo->src;
- src->pub.init_source = init_source;
- src->pub.fill_input_buffer = fill_input_buffer;
- src->pub.skip_input_data = skip_input_data;
- src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
- src->pub.term_source = term_source;
- src->infile = 0L;
- src->pub.bytes_in_buffer = len; /* sets to entire file len */
- src->pub.next_input_byte = (JOCTET *)inbfr; /* at start of buffer */
-}
-
-static int jpeg_load_thumb(const char *filename, int *x, int *y)
-{
- struct jpeg_decompress_struct cinfo;
- struct jpeg_decompress_struct *ciptr = &cinfo;
- struct r_jpeg_error_mgr emgr;
- FILE *fh;
-
- if (!(fh = fopen(filename, "rb")))
- return 0;
-
- ciptr->err = jpeg_std_error(&emgr.pub);
- emgr.pub.error_exit = jpeg_cb_error_exit;
- if (setjmp(emgr.envbuffer) == 1)
- {
- jpeg_destroy_decompress(ciptr);
- fclose(fh);
- return 0;
- }
-
- jpeg_create_decompress(ciptr);
- jpeg_stdio_src(ciptr, fh);
-
- jpeg_save_markers (ciptr, JPEG_APP0 + 1, 0xffff);
-
- jpeg_read_header(ciptr, TRUE);
-
- struct jpeg_marker_struct *m = cinfo.marker_list;
-
- unsigned char *thumb_buf = NULL;
- size_t bufsize;
-
- if ( m )
- {
- unsigned char *p_data = m->data;
- while ( p_data < m->data+m->data_length )
- {
- if ( p_data[0] == 0xFF && p_data[1] == 0xD8 )
- {
- bufsize = (size_t) m->data_length - (size_t) (p_data-m->data);
- thumb_buf = new unsigned char[bufsize];
- bufsize = 0;
- do {
- thumb_buf[bufsize++] = *p_data;
- } while ( !(*p_data++ == 0xFF && *p_data == 0xD9) && p_data < m->data+m->data_length );
- thumb_buf[bufsize++] = *p_data;
- }
- p_data++;
- }
- }
-
- if ( thumb_buf != NULL )
- {
- jpeg_create_decompress(ciptr);
- jpeg_memory_src(ciptr, thumb_buf, bufsize-2);
- jpeg_read_header(ciptr, TRUE);
- }
- else
- eDebug("no exif thumbnail found! loading actual image instead");
-
- ciptr->out_color_space = JCS_RGB;
- ciptr->scale_denom = 1;
-
- jpeg_start_decompress(ciptr);
-
- *x=ciptr->output_width;
- *y=ciptr->output_height;
-
- if(ciptr->output_components == 3)
- {
- JSAMPLE *lb = (JSAMPLE *)(*ciptr->mem->alloc_small)((j_common_ptr) ciptr, JPOOL_PERMANENT, ciptr->output_width * ciptr->output_components);
- pic_buffer = new unsigned char[ciptr->output_height * ciptr->output_width * ciptr->output_components];
- unsigned char *bp = pic_buffer;
-
- while (ciptr->output_scanline < ciptr->output_height)
- {
- jpeg_read_scanlines(ciptr, &lb, 1);
- memcpy(bp, lb, ciptr->output_width * ciptr->output_components);
- bp += ciptr->output_width * ciptr->output_components;
- }
- }
- jpeg_finish_decompress(ciptr);
- jpeg_destroy_decompress(ciptr);
- fclose(fh);
- return 1;
-}
-
-static int jpeg_load(const char *filename, int *x, int *y)
-{
- struct jpeg_decompress_struct cinfo;
- struct jpeg_decompress_struct *ciptr = &cinfo;
- struct r_jpeg_error_mgr emgr;
- FILE *fh;
-
- if (!(fh = fopen(filename, "rb")))
- return 0;
-
- ciptr->err = jpeg_std_error(&emgr.pub);
- emgr.pub.error_exit = jpeg_cb_error_exit;
- if (setjmp(emgr.envbuffer) == 1)
- {
- jpeg_destroy_decompress(ciptr);
- fclose(fh);
- return 0;
- }
-
- jpeg_create_decompress(ciptr);
- jpeg_stdio_src(ciptr, fh);
- jpeg_read_header(ciptr, TRUE);
- ciptr->out_color_space = JCS_RGB;
- ciptr->scale_denom = 1;
-
- jpeg_start_decompress(ciptr);
-
- *x=ciptr->output_width;
- *y=ciptr->output_height;
-
- if(ciptr->output_components == 3)
- {
- JSAMPLE *lb = (JSAMPLE *)(*ciptr->mem->alloc_small)((j_common_ptr) ciptr, JPOOL_PERMANENT, ciptr->output_width * ciptr->output_components);
- pic_buffer = new unsigned char[ciptr->output_height * ciptr->output_width * ciptr->output_components];
- unsigned char *bp = pic_buffer;
-
- while (ciptr->output_scanline < ciptr->output_height)
- {
- jpeg_read_scanlines(ciptr, &lb, 1);
- memcpy(bp, lb, ciptr->output_width * ciptr->output_components);
- bp += ciptr->output_width * ciptr->output_components;
- }
- }
- jpeg_finish_decompress(ciptr);
- jpeg_destroy_decompress(ciptr);
- fclose(fh);
- return 1;
-}
-
//---------------------------------------------------------------------------------------------
#define BMP_TORASTER_OFFSET 10
@@ -389,26 +140,26 @@ static void fetch_pallete(int fd, struct color pallete[], int count)
}
}
-static int bmp_load(const char *filename, int *x, int *y)
+static unsigned char *bmp_load(const char *file, int *x, int *y)
{
unsigned char buff[4];
struct color pallete[256];
- int fd = open(filename, O_RDONLY);
- if (fd == -1) return 0;
- if (lseek(fd, BMP_SIZE_OFFSET, SEEK_SET) == -1) return 0;
+ int fd = open(file, O_RDONLY);
+ if (fd == -1) return NULL;
+ if (lseek(fd, BMP_SIZE_OFFSET, SEEK_SET) == -1) return NULL;
read(fd, buff, 4);
*x = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
read(fd, buff, 4);
*y = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
- if (lseek(fd, BMP_TORASTER_OFFSET, SEEK_SET) == -1) return 0;
+ if (lseek(fd, BMP_TORASTER_OFFSET, SEEK_SET) == -1) return NULL;
read(fd, buff, 4);
int raster = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
- if (lseek(fd, BMP_BPP_OFFSET, SEEK_SET) == -1) return 0;
+ if (lseek(fd, BMP_BPP_OFFSET, SEEK_SET) == -1) return NULL;
read(fd, buff, 2);
int bpp = buff[0] + (buff[1] << 8);
- pic_buffer = new unsigned char[(*x) * (*y) * 3];
+ unsigned char *pic_buffer = new unsigned char[(*x) * (*y) * 3];
unsigned char *wr_buffer = pic_buffer + (*x) * ((*y) - 1) * 3;
switch (bpp)
@@ -420,7 +171,7 @@ static int bmp_load(const char *filename, int *x, int *y)
lseek(fd, raster, SEEK_SET);
unsigned char * tbuffer = new unsigned char[*x / 2 + 1];
if (tbuffer == NULL)
- return 0;
+ return NULL;
for (int i = 0; i < *y; i++)
{
read(fd, tbuffer, (*x) / 2 + *x % 2);
@@ -456,7 +207,7 @@ static int bmp_load(const char *filename, int *x, int *y)
lseek(fd, raster, SEEK_SET);
unsigned char * tbuffer = new unsigned char[*x];
if (tbuffer == NULL)
- return 0;
+ return NULL;
for (int i = 0; i < *y; i++)
{
read(fd, tbuffer, *x);
@@ -492,45 +243,44 @@ static int bmp_load(const char *filename, int *x, int *y)
break;
}
default:
- return 0;
+ return NULL;
}
close(fd);
- return 1;
+ return(pic_buffer);
}
-//---------------------------------------------------------------------------------------------
-static int png_load(const char *filename, int *x, int *y)
+//---------------------------------------------------------------------
+
+static unsigned char *png_load(const char *file, int *ox, int *oy)
{
static const png_color_16 my_background = {0, 0, 0, 0, 0};
- png_structp png_ptr;
- png_infop info_ptr;
png_uint_32 width, height;
unsigned int i;
int bit_depth, color_type, interlace_type;
- int number_passes, pass;
- png_byte * fbptr;
- FILE * fh;
+ png_byte *fbptr;
+ FILE *fh;
- if (!(fh = fopen(filename, "rb"))) return 0;
+ if (!(fh = fopen(file, "rb")))
+ return NULL;
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL)
- return 0;
- info_ptr = png_create_info_struct(png_ptr);
+ return NULL;
+ png_infop info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
- fclose(fh);
- return 0;
+ fclose(fh);
+ return NULL;
}
if (setjmp(png_ptr->jmpbuf))
{
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
- fclose(fh);
- return 0;
+ fclose(fh);
+ return NULL;
}
png_init_io(png_ptr, fh);
@@ -545,41 +295,137 @@ static int png_load(const char *filename, int *x, int *y)
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png_ptr);
- number_passes = png_set_interlace_handling(png_ptr);
+ int number_passes = png_set_interlace_handling(png_ptr);
png_read_update_info(png_ptr, info_ptr);
- int bpp = png_get_rowbytes(png_ptr, info_ptr)/width;
- if ((bpp !=4) && (bpp !=3))
- {
- eDebug("[PNG] Error processing");
- return 0;
- }
-
- if (width * height > 1000000) // 1000x1000 or equiv.
+ if (width * 3 != png_get_rowbytes(png_ptr, info_ptr))
{
- eDebug("[png_load] image size is %d x %d, which is \"too large\".", (int)width, (int)height);
- png_read_end(png_ptr, info_ptr);
+ eDebug("[Picload] Error processing");
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
fclose(fh);
- return 0;
+ return NULL;
}
- pic_buffer = new unsigned char[width * height * bpp];
- *x=width;
- *y=height;
+ unsigned char *pic_buffer = new unsigned char[height * width * 3];
+ *ox=width;
+ *oy=height;
- for(pass = 0; pass < number_passes; pass++)
+ for(int pass = 0; pass < number_passes; pass++)
{
fbptr = (png_byte *)pic_buffer;
- for (i = 0; i < height; i++, fbptr += width * bpp)
+ for (i = 0; i < height; i++, fbptr += width * 3)
png_read_row(png_ptr, fbptr, NULL);
}
png_read_end(png_ptr, info_ptr);
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
fclose(fh);
- if (bpp == 3)
- pic_buffer = conv24to32(pic_buffer, width * height, 1);
- return 1;
+ return(pic_buffer);
+}
+
+//-------------------------------------------------------------------
+
+struct r_jpeg_error_mgr
+{
+ struct jpeg_error_mgr pub;
+ jmp_buf envbuffer;
+};
+
+void jpeg_cb_error_exit(j_common_ptr cinfo)
+{
+ struct r_jpeg_error_mgr *mptr;
+ mptr = (struct r_jpeg_error_mgr *) cinfo->err;
+ (*cinfo->err->output_message) (cinfo);
+ longjmp(mptr->envbuffer, 1);
+}
+
+static unsigned char *jpeg_load(const char *file, int *ox, int *oy)
+{
+ struct jpeg_decompress_struct cinfo;
+ struct jpeg_decompress_struct *ciptr = &cinfo;
+ struct r_jpeg_error_mgr emgr;
+ FILE *fh;
+ unsigned char *pic_buffer=NULL;
+
+ if (!(fh = fopen(file, "rb")))
+ return NULL;
+
+ ciptr->err = jpeg_std_error(&emgr.pub);
+ emgr.pub.error_exit = jpeg_cb_error_exit;
+ if (setjmp(emgr.envbuffer) == 1)
+ {
+ jpeg_destroy_decompress(ciptr);
+ fclose(fh);
+ return NULL;
+ }
+
+ jpeg_create_decompress(ciptr);
+ jpeg_stdio_src(ciptr, fh);
+ jpeg_read_header(ciptr, TRUE);
+ ciptr->out_color_space = JCS_RGB;
+ ciptr->scale_denom = 1;
+
+ jpeg_start_decompress(ciptr);
+
+ *ox=ciptr->output_width;
+ *oy=ciptr->output_height;
+
+ if(ciptr->output_components == 3)
+ {
+ JSAMPLE *lb = (JSAMPLE *)(*ciptr->mem->alloc_small)((j_common_ptr) ciptr, JPOOL_PERMANENT, ciptr->output_width * ciptr->output_components);
+ pic_buffer = new unsigned char[ciptr->output_height * ciptr->output_width * ciptr->output_components];
+ unsigned char *bp = pic_buffer;
+
+ while (ciptr->output_scanline < ciptr->output_height)
+ {
+ jpeg_read_scanlines(ciptr, &lb, 1);
+ memcpy(bp, lb, ciptr->output_width * ciptr->output_components);
+ bp += ciptr->output_width * ciptr->output_components;
+ }
+ }
+ jpeg_finish_decompress(ciptr);
+ jpeg_destroy_decompress(ciptr);
+ fclose(fh);
+ return(pic_buffer);
+}
+
+
+static int jpeg_save(const char * filename, int ox, int oy, unsigned char *pic_buffer)
+{
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ FILE * outfile;
+ JSAMPROW row_pointer[1];
+ int row_stride;
+
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+
+ if ((outfile = fopen(filename, "wb")) == NULL)
+ {
+ eDebug("[Picload] jpeg can't open %s", filename);
+ return 1;
+ }
+ eDebug("[Picload] save Thumbnail... %s",filename);
+
+ jpeg_stdio_dest(&cinfo, outfile);
+
+ cinfo.image_width = ox;
+ cinfo.image_height = oy;
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality(&cinfo, 70, TRUE );
+ jpeg_start_compress(&cinfo, TRUE);
+ row_stride = ox * 3;
+ while (cinfo.next_scanline < cinfo.image_height)
+ {
+ row_pointer[0] = & pic_buffer[cinfo.next_scanline * row_stride];
+ (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
+ }
+ jpeg_finish_compress(&cinfo);
+ fclose(outfile);
+ jpeg_destroy_compress(&cinfo);
+ return 0;
}
//-------------------------------------------------------------------
@@ -597,8 +443,9 @@ inline void m_rend_gif_decodecolormap(unsigned char *cmb, unsigned char *rgbb, C
}
}
-static int gif_load(const char *filename, int *x, int *y)
+static unsigned char *gif_load(const char *file, int *ox, int *oy)
{
+ unsigned char *pic_buffer = NULL;
int px, py, i, j, ibxs;
unsigned char *fbptr;
unsigned char *lb=NULL;
@@ -610,9 +457,9 @@ static int gif_load(const char *filename, int *x, int *y)
int cmaps;
int extcode;
- gft = DGifOpenFileName(filename);
+ gft = DGifOpenFileName(file);
if (gft == NULL)
- return 0;
+ return NULL;
do
{
if (DGifGetRecordType(gft, &rt) == GIF_ERROR)
@@ -622,8 +469,8 @@ static int gif_load(const char *filename, int *x, int *y)
case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(gft) == GIF_ERROR)
goto ERROR_R;
- *x = px = gft->Image.Width;
- *y = py = gft->Image.Height;
+ *ox = px = gft->Image.Width;
+ *oy = py = gft->Image.Height;
pic_buffer = new unsigned char[px * py * 3];
lb = (unsigned char *)malloc(px * 3);
slb = (unsigned char *) malloc(px);
@@ -685,239 +532,531 @@ static int gif_load(const char *filename, int *x, int *y)
while (rt != TERMINATE_RECORD_TYPE);
DGifCloseFile(gft);
- return 1;
+ return(pic_buffer);
ERROR_R:
- eDebug("[GIF] Error");
+ eDebug("[Picload] <Error gif>");
if (lb) free(lb);
if (slb) free(slb);
DGifCloseFile(gft);
- return 0;
+ return NULL;
}
//---------------------------------------------------------------------------------------------
-PyObject *getExif(const char *filename)
+ePicLoad::ePicLoad()
+ :msg_thread(this,1), msg_main(eApp,1)
{
- ePyObject list;
- Cexif exif;
- if(exif.DecodeExif(filename))
+ CONNECT(msg_thread.recv_msg, ePicLoad::gotMessage);
+ CONNECT(msg_main.recv_msg, ePicLoad::gotMessage);
+
+ threadrunning = false;
+ m_filepara = NULL;
+ m_conf.max_x = 0;
+ m_conf.max_y = 0;
+ m_conf.aspect_ratio = 1.066400; //4:3
+ m_conf.usecache = false;
+ m_conf.resizetype = 1;
+ memset(m_conf.background,0x00,sizeof(m_conf.background));
+ m_conf.thumbnailsize = 180;
+}
+
+void ePicLoad::waitFinished()
+{
+ msg_thread.send(Message(Message::quit));
+ kill();
+}
+
+ePicLoad::~ePicLoad()
+{
+ if (threadrunning)
+ waitFinished();
+ if(m_filepara != NULL)
+ delete m_filepara;
+}
+
+void ePicLoad::thread_finished()
+{
+ threadrunning=false;
+}
+
+void ePicLoad::thread()
+{
+ hasStarted();
+ threadrunning=true;
+ nice(4);
+ runLoop();
+}
+
+void ePicLoad::decodePic()
+{
+ eDebug("[Picload] decode picture... %s",m_filepara->file);
+
+ switch(m_filepara->id)
{
- if(exif.m_exifinfo->IsExif)
+ case F_PNG: m_filepara->pic_buffer = png_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
+ case F_JPEG: m_filepara->pic_buffer = jpeg_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
+ case F_BMP: m_filepara->pic_buffer = bmp_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
+ case F_GIF: m_filepara->pic_buffer = gif_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
+ }
+
+ if(m_filepara->pic_buffer != NULL)
+ {
+ resizePic();
+ }
+}
+
+void ePicLoad::decodeThumb()
+{
+ eDebug("[Picload] get Thumbnail... %s",m_filepara->file);
+
+ bool exif_thumbnail = false;
+ bool cachefile_found = false;
+ std::string cachefile = "";
+ std::string cachedir = "/.Thumbnails";
+
+ if(m_filepara->id == F_JPEG)
+ {
+ Cexif *exif = new Cexif;
+ if(exif->DecodeExif(m_filepara->file, 1))
{
- int pos=0;
- char tmp[256];
- list = PyList_New(22);
- PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->Version));
- PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->CameraMake));
- PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->CameraModel));
- PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->DateTime));
- PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->Comments));
- PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d x %d", exif.m_exifinfo->Width, exif.m_exifinfo->Height));
- PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->Orientation));
- PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->MeteringMode));
- PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->ExposureProgram));
- PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->LightSource));
- PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->FlashUsed));
- PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", exif.m_exifinfo->CompressionLevel));
- PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", exif.m_exifinfo->ISOequivalent));
- sprintf(tmp, "%.2f", exif.m_exifinfo->Xresolution);
- PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
- sprintf(tmp, "%.2f", exif.m_exifinfo->Yresolution);
- PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
- PyList_SET_ITEM(list, pos++, PyString_FromString(exif.m_exifinfo->ResolutionUnit));
- sprintf(tmp, "%.2f", exif.m_exifinfo->Brightness);
- PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
- sprintf(tmp, "%.5f sec.", exif.m_exifinfo->ExposureTime);
- PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
- sprintf(tmp, "%.5f", exif.m_exifinfo->ExposureBias);
- PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
- sprintf(tmp, "%.5f", exif.m_exifinfo->Distance);
- PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
- sprintf(tmp, "%.5f", exif.m_exifinfo->CCDWidth);
- PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
- sprintf(tmp, "%.2f", exif.m_exifinfo->ApertureFNumber);
- PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
+ if(exif->m_exifinfo->IsExif)
+ {
+ if(exif->m_exifinfo->Thumnailstate==2)
+ {
+ m_filepara->file = strdup(THUMBNAILTMPFILE);
+ exif_thumbnail = true;
+ eDebug("[Picload] Exif Thumbnail found");
+ }
+ m_filepara->addExifInfo(exif->m_exifinfo->CameraMake);
+ m_filepara->addExifInfo(exif->m_exifinfo->CameraModel);
+ m_filepara->addExifInfo(exif->m_exifinfo->DateTime);
+ char buf[20];
+ snprintf(buf, 20, "%d x %d", exif->m_exifinfo->Width, exif->m_exifinfo->Height);
+ m_filepara->addExifInfo(buf);
+ }
+ exif->ClearExif();
}
- else
+ delete exif;
+ }
+
+ if((! exif_thumbnail) && m_conf.usecache)
+ {
+ if(FILE *f=fopen(m_filepara->file, "rb"))
{
- list = PyList_New(1);
- PyList_SET_ITEM(list, 0, PyString_FromString(exif.m_szLastError));
+ int c;
+ int count = 1024*100;
+ unsigned long crc32 = 0;
+ char crcstr[9];*crcstr=0;
+
+ while ((c=getc(f))!=EOF)
+ {
+ crc32 = crc32_table[((crc32) ^ (c)) & 0xFF] ^ ((crc32) >> 8);
+ if(--count < 0) break;
+ }
+
+ fclose(f);
+ crc32 = ~crc32;
+ sprintf(crcstr, "%08lX", crc32);
+
+ cachedir = m_filepara->file;
+ unsigned int pos = cachedir.find_last_of("/");
+ if (pos != std::string::npos)
+ cachedir = cachedir.substr(0, pos) + "/.Thumbnails";
+
+ cachefile = cachedir + std::string("/pc_") + crcstr;
+ if(!access(cachefile.c_str(), R_OK))
+ {
+ cachefile_found = true;
+ m_filepara->file = strdup(cachefile.c_str());
+ m_filepara->id = F_JPEG;
+ eDebug("[Picload] Cache File found");
+ }
}
- exif.ClearExif();
}
- else
+
+ switch(m_filepara->id)
{
- list = PyList_New(1);
- PyList_SET_ITEM(list, 0, PyString_FromString(exif.m_szLastError));
+ case F_PNG: m_filepara->pic_buffer = png_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
+ case F_JPEG: m_filepara->pic_buffer = jpeg_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
+ case F_BMP: m_filepara->pic_buffer = bmp_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
+ case F_GIF: m_filepara->pic_buffer = gif_load(m_filepara->file, &m_filepara->ox, &m_filepara->oy); break;
}
+
+ if(exif_thumbnail)
+ ::unlink(THUMBNAILTMPFILE);
+
+ if(m_filepara->pic_buffer != NULL)
+ {
+ //save cachefile
+ if(m_conf.usecache && (! exif_thumbnail) && (! cachefile_found))
+ {
+ if(access(cachedir.c_str(), R_OK))
+ ::mkdir(cachedir.c_str(), 0755);
+
+ //resize for Thumbnail
+ int imx, imy;
+ if (m_filepara->ox <= m_filepara->oy)
+ {
+ imy = m_conf.thumbnailsize;
+ imx = (int)( (m_conf.thumbnailsize * ((double)m_filepara->ox)) / ((double)m_filepara->oy) );
+ }
+ else
+ {
+ imx = m_conf.thumbnailsize;
+ imy = (int)( (m_conf.thumbnailsize * ((double)m_filepara->oy)) / ((double)m_filepara->ox) );
+ }
- return list ? (PyObject*)list : (PyObject*)PyList_New(0);
-}
+ m_filepara->pic_buffer = color_resize(m_filepara->pic_buffer, m_filepara->ox, m_filepara->oy, imx, imy);
+ m_filepara->ox = imx;
+ m_filepara->oy = imy;
-//---------------------------------------------------------------------------------------------
-enum {F_NONE, F_PNG, F_JPEG, F_BMP, F_GIF};
+ if(jpeg_save(cachefile.c_str(), m_filepara->ox, m_filepara->oy, m_filepara->pic_buffer))
+ eDebug("[Picload] error saving cachefile");
+ }
-static int pic_id(const char *name)
+ resizePic();
+ }
+}
+
+void ePicLoad::resizePic()
{
- unsigned char id[10];
- int fd = open(name, O_RDONLY);
- if (fd == -1)
- return F_NONE;
- read(fd, id, 10);
- close(fd);
+ int imx, imy;
- if(id[1] == 'P' && id[2] == 'N' && id[3] == 'G')
- return F_PNG;
- else if(id[6] == 'J' && id[7] == 'F' && id[8] == 'I' && id[9] == 'F')
- return F_JPEG;
- else if(id[0] == 0xff && id[1] == 0xd8 && id[2] == 0xff)
- return F_JPEG;
- else if(id[0] == 'B' && id[1] == 'M' )
- return F_BMP;
- else if(id[0] == 'G' && id[1] == 'I' && id[2] == 'F')
- return F_GIF;
- return F_NONE;
+ if((m_conf.aspect_ratio * m_filepara->oy * m_filepara->max_x / m_filepara->ox) <= m_filepara->max_y)
+ {
+ imx = m_filepara->max_x;
+ imy = (int)(m_conf.aspect_ratio * m_filepara->oy * m_filepara->max_x / m_filepara->ox);
+ }
+ else
+ {
+ imx = (int)((1.0/m_conf.aspect_ratio) * m_filepara->ox * m_filepara->max_y / m_filepara->oy);
+ imy = m_filepara->max_y;
+ }
+
+ if(m_conf.resizetype)
+ m_filepara->pic_buffer = color_resize(m_filepara->pic_buffer, m_filepara->ox, m_filepara->oy, imx, imy);
+ else
+ m_filepara->pic_buffer = simple_resize(m_filepara->pic_buffer, m_filepara->ox, m_filepara->oy, imx, imy);
+
+ m_filepara->ox = imx;
+ m_filepara->oy = imy;
}
-int loadPic(ePtr<gPixmap> &result, std::string filename, int w, int h, int aspect, int resize_mode, int rotate, int background, std::string cachefile, int thumbnail)
+void ePicLoad::gotMessage(const Message &msg)
{
- result = 0;
- int ox=0, oy=0, imx, imy;
- pic_buffer=NULL;
- bool cache=false;
+ switch (msg.type)
+ {
+ case Message::decode_Pic:
+ decodePic();
+ msg_main.send(Message(Message::decode_finished));
+ break;
+ case Message::decode_Thumb:
+ decodeThumb();
+ msg_main.send(Message(Message::decode_finished));
+ break;
+ case Message::quit: // called from decode thread
+ eDebug("[Picload] decode thread ... got quit msg");
+ quit(0);
+ break;
+ case Message::decode_finished: // called from main thread
+ //eDebug("[Picload] decode finished... %s", m_filepara->file);
+ if(m_filepara->callback)
+ {
+ PictureData(m_filepara->picinfo.c_str());
+ }
+ else
+ {
+ if(m_filepara != NULL)
+ {
+ delete m_filepara;
+ m_filepara = NULL;
+ }
+ }
+ break;
+ default:
+ eDebug("unhandled thread message");
+ }
+}
- if(cachefile.length())
+int ePicLoad::startThread(int what, const char *file, int x, int y, bool async)
+{
+ if(async && threadrunning && m_filepara != NULL)
+ {
+ eDebug("[Picload] thread running");
+ m_filepara->callback = false;
+ return 1;
+ }
+
+ if(m_filepara != NULL)
+ {
+ delete m_filepara;
+ m_filepara = NULL;
+ }
+
+ int file_id = -1;
+ unsigned char id[10];
+ int fd = ::open(file, O_RDONLY);
+ if (fd == -1) return 1;
+ ::read(fd, id, 10);
+ ::close(fd);
+
+ if(id[1] == 'P' && id[2] == 'N' && id[3] == 'G') file_id = F_PNG;
+ else if(id[6] == 'J' && id[7] == 'F' && id[8] == 'I' && id[9] == 'F') file_id = F_JPEG;
+ else if(id[0] == 0xff && id[1] == 0xd8 && id[2] == 0xff) file_id = F_JPEG;
+ else if(id[0] == 'B' && id[1] == 'M' ) file_id = F_BMP;
+ else if(id[0] == 'G' && id[1] == 'I' && id[2] == 'F') file_id = F_GIF;
+
+ if(file_id < 0)
{
- if(png_load(cachefile.c_str(), &ox, &oy))
- eDebug("[CACHEPIC] x-size=%d, y-size=%d", ox, oy);
+ eDebug("[Picload] <format not supportet>");
+ return 1;
}
- if(pic_buffer==NULL)
+ m_filepara = new Cfilepara(file, file_id, getSize(file));
+ x > 0 ? m_filepara->max_x = x : m_filepara->max_x = m_conf.max_x;
+ y > 0 ? m_filepara->max_y = y : m_filepara->max_y = m_conf.max_y;
+
+ if(m_filepara->max_x <= 0 || m_filepara->max_y <= 0)
{
- switch(pic_id(filename.c_str()))
- {
- case F_PNG: png_load(filename.c_str(), &ox, &oy);break;
- case F_JPEG: {
- if (thumbnail)
- jpeg_load_thumb(filename.c_str(), &ox, &oy);
- else
- jpeg_load(filename.c_str(), &ox, &oy);
- pic_buffer = conv24to32(pic_buffer, ox*oy, 1);
- break; }
- case F_BMP: bmp_load(filename.c_str(), &ox, &oy);pic_buffer = conv24to32(pic_buffer, ox*oy, 1); break;
- case F_GIF: gif_load(filename.c_str(), &ox, &oy);pic_buffer = conv24to32(pic_buffer, ox*oy, 1); break;
- default:
- eDebug("[PIC] <format not supportet>");
- return 0;
- }
+ delete m_filepara;
+ m_filepara = NULL;
+ eDebug("[Picload] <error in Para>");
+ return 1;
+ }
- if(pic_buffer==NULL)
- return 0;
+ if (async) {
+ if(what==1)
+ msg_thread.send(Message(Message::decode_Pic));
+ else
+ msg_thread.send(Message(Message::decode_Thumb));
+ run();
+ }
+ else if (what == 1)
+ decodePic();
+ else
+ decodeThumb();
+ return 0;
+}
- double aspect_ratio;
- switch(aspect)
- {
- case 1: aspect_ratio = 1.778 / ((double)720/576); break; //16:9
- case 2: aspect_ratio = 1.600 / ((double)720/576); break; //16:10
- case 3: aspect_ratio = 1.250 / ((double)720/576); break; //5:4
- default: aspect_ratio = 1.333 / ((double)720/576); //4:3
- }
+RESULT ePicLoad::startDecode(const char *file, int x, int y, bool async)
+{
+ return startThread(1, file, x, y, async);
+}
+
+RESULT ePicLoad::getThumbnail(const char *file, int x, int y, bool async)
+{
+ return startThread(0, file, x, y, async);
+}
- if((aspect_ratio * oy * w / ox) <= h)
+PyObject *ePicLoad::getInfo(const char *filename)
+{
+ ePyObject list;
+
+ Cexif *exif = new Cexif;
+ if(exif->DecodeExif(filename))
+ {
+ if(exif->m_exifinfo->IsExif)
{
- imx = w;
- imy = (int)(aspect_ratio*oy*w/ox);
+ char tmp[256];
+ int pos=0;
+ list = PyList_New(23);
+ PyList_SET_ITEM(list, pos++, PyString_FromString(filename));
+ PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->Version));
+ PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->CameraMake));
+ PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->CameraModel));
+ PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->DateTime));
+ PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d x %d", exif->m_exifinfo->Width, exif->m_exifinfo->Height));
+ PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->FlashUsed));
+ PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->Orientation));
+ PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->Comments));
+ PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->MeteringMode));
+ PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->ExposureProgram));
+ PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->LightSource));
+ PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", exif->m_exifinfo->CompressionLevel));
+ PyList_SET_ITEM(list, pos++, PyString_FromFormat("%d", exif->m_exifinfo->ISOequivalent));
+ sprintf(tmp, "%.2f", exif->m_exifinfo->Xresolution);
+ PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
+ sprintf(tmp, "%.2f", exif->m_exifinfo->Yresolution);
+ PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
+ PyList_SET_ITEM(list, pos++, PyString_FromString(exif->m_exifinfo->ResolutionUnit));
+ sprintf(tmp, "%.2f", exif->m_exifinfo->Brightness);
+ PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
+ sprintf(tmp, "%.5f sec.", exif->m_exifinfo->ExposureTime);
+ PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
+ sprintf(tmp, "%.5f", exif->m_exifinfo->ExposureBias);
+ PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
+ sprintf(tmp, "%.5f", exif->m_exifinfo->Distance);
+ PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
+ sprintf(tmp, "%.5f", exif->m_exifinfo->CCDWidth);
+ PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
+ sprintf(tmp, "%.2f", exif->m_exifinfo->ApertureFNumber);
+ PyList_SET_ITEM(list, pos++, PyString_FromString(tmp));
}
else
{
- imx = (int)((1.0/aspect_ratio)*ox*h/oy);
- imy = h;
+ list = PyList_New(2);
+ PyList_SET_ITEM(list, 0, PyString_FromString(filename));
+ PyList_SET_ITEM(list, 1, PyString_FromString(exif->m_szLastError));
}
+ exif->ClearExif();
+ }
+ else
+ {
+ list = PyList_New(2);
+ PyList_SET_ITEM(list, 0, PyString_FromString(filename));
+ PyList_SET_ITEM(list, 1, PyString_FromString(exif->m_szLastError));
+ }
+ delete exif;
- if(resize_mode) pic_buffer = color_resize(pic_buffer, ox, oy, imx, imy);
- else pic_buffer = simple_resize(pic_buffer, ox, oy, imx, imy);
+ return list ? (PyObject*)list : (PyObject*)PyList_New(0);
+}
- ox = imx;
- oy = imy;
- }
- else cache = true;
+int ePicLoad::getData(ePtr<gPixmap> &result)
+{
+ result = 0;
+ if(m_filepara->pic_buffer == NULL) return 0;
+
+ m_filepara->pic_buffer = conv24to32(m_filepara->pic_buffer, m_filepara->ox * m_filepara->oy);
- result=new gPixmap(eSize(w, h), 32);
+ result=new gPixmap(eSize(m_filepara->max_x, m_filepara->max_y), 32);
gSurface *surface = result->surface;
int a=0, b=0;
int nc=0, oc=0;
int o_y=0, u_y=0, v_x=0, h_x=0;
- unsigned char clear[4] = {0x00,0x00,0x00,0x00};
- if(background) clear[3]=0xFF;
- unsigned char *tmp_buffer=((unsigned char *)(surface->data));
- if(oy < h)
+ unsigned char *tmp_buffer=((unsigned char *)(surface->data));
+
+ if(m_filepara->oy < m_filepara->max_y)
{
- o_y=(h-oy)/2;
- u_y=h-oy-o_y;
+ o_y = (m_filepara->max_y - m_filepara->oy) / 2;
+ u_y = m_filepara->max_y - m_filepara->oy - o_y;
}
- if(ox < w)
+ if(m_filepara->ox < m_filepara->max_x)
{
- v_x=(w-ox)/2;
- h_x=w-ox-v_x;
+ v_x = (m_filepara->max_x - m_filepara->ox) / 2;
+ h_x = m_filepara->max_x - m_filepara->ox - v_x;
}
- //eDebug("o_y=%d u_y=%d v_x=%d h_x=%d", o_y, u_y, v_x, h_x);
-
- if(oy < h)
- for(a=0; a<(o_y*ox); a++, nc+=4)
+ if(m_filepara->oy < m_filepara->max_y)
+ {
+ for(a=0; a<(o_y*m_filepara->ox); a++, nc+=4)
{
tmp_buffer=((unsigned char *)(surface->data)) + nc;
- memcpy(tmp_buffer, clear, sizeof(clear));
+ memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background));
}
-
- for(a=0; a<oy; a++)
+ }
+
+ for(a=0; a<m_filepara->oy; a++)
{
- if(ox < w)
+ if(m_filepara->ox < m_filepara->max_x)
+ {
for(b=0; b<v_x; b++, nc+=4)
{
tmp_buffer=((unsigned char *)(surface->data)) + nc;
- memcpy(tmp_buffer, clear, sizeof(clear));
+ memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background));
}
+ }
- for(b=0; b<(ox*4); b+=4, nc+=4)
+ for(b=0; b<(m_filepara->ox*4); b+=4, nc+=4)
{
tmp_buffer=((unsigned char *)(surface->data)) + nc;
- tmp_buffer[2]=pic_buffer[oc++];
- tmp_buffer[1]=pic_buffer[oc++];
- tmp_buffer[0]=pic_buffer[oc++];
- tmp_buffer[3]=pic_buffer[oc++];
-
+ tmp_buffer[2] = m_filepara->pic_buffer[oc++];
+ tmp_buffer[1] = m_filepara->pic_buffer[oc++];
+ tmp_buffer[0] = m_filepara->pic_buffer[oc++];
+ tmp_buffer[3] = m_filepara->pic_buffer[oc++];
}
- if(ox < w)
+ if(m_filepara->ox < m_filepara->max_x)
+ {
for(b=0; b<h_x; b++, nc+=4)
{
tmp_buffer=((unsigned char *)(surface->data)) + nc;
- memcpy(tmp_buffer, clear, sizeof(clear));
+ memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background));
}
+ }
}
-
- if(oy < h)
- for(a=0; a<(u_y*ox); a++, nc+=4)
+
+ if(m_filepara->oy < m_filepara->max_y)
+ {
+ for(a=0; a<(u_y*m_filepara->ox); a++, nc+=4)
{
tmp_buffer=((unsigned char *)(surface->data)) + nc;
- memcpy(tmp_buffer, clear, sizeof(clear));
+ memcpy(tmp_buffer, m_conf.background, sizeof(m_conf.background));
}
-
- //eDebug("[PIC] buffer=%d, nc=%d oc=%d ox=%d, oy=%d",w*h*4, nc, oc, ox, oy);
+ }
surface->clut.data=0;
surface->clut.colors=0;
surface->clut.start=0;
+
+ delete m_filepara;
+ m_filepara = NULL;
+
+ return 0;
+}
+
+RESULT ePicLoad::setPara(PyObject *val)
+{
+ if (!PySequence_Check(val))
+ return 0;
+ if (PySequence_Size(val) < 7)
+ return 0;
+ else {
+ ePyObject fast = PySequence_Fast(val, "");
+ m_conf.max_x = PyInt_AsLong( PySequence_Fast_GET_ITEM(fast, 0));
+ m_conf.max_y = PyInt_AsLong( PySequence_Fast_GET_ITEM(fast, 1));
+ m_conf.aspect_ratio = (double)PyInt_AsLong( PySequence_Fast_GET_ITEM(fast, 2)) / PyInt_AsLong(PySequence_Fast_GET_ITEM(fast, 3));
+ m_conf.usecache = PyInt_AsLong( PySequence_Fast_GET_ITEM(fast, 4));
+ m_conf.resizetype = PyInt_AsLong( PySequence_Fast_GET_ITEM(fast, 5));
+ const char *bg_str = PyString_AsString( PySequence_Fast_GET_ITEM(fast, 6));
- delete [] pic_buffer;
+ if(bg_str[0] == '#' && strlen(bg_str)==9)
+ {
+ int bg = strtoul(bg_str+1, NULL, 16);
+ m_conf.background[0] = bg&0xFF; //BB
+ m_conf.background[1] = (bg>>8)&0xFF; //GG
+ m_conf.background[2] = (bg>>16)&0xFF; //RR
+ m_conf.background[3] = bg>>24; //AA
+ }
+ eDebug("[Picload] setPara max-X=%d max-Y=%d aspect_ratio=%lf cache=%d resize=%d bg=#%02X%02X%02X%02X", m_conf.max_x, m_conf.max_y, m_conf.aspect_ratio, (int)m_conf.usecache, (int)m_conf.resizetype, m_conf.background[3], m_conf.background[2], m_conf.background[1], m_conf.background[0]);
+ }
+ return 1;
+}
+
+//------------------------------------------------------------------------------------
- if(cachefile.length() && !cache)
+//for old plugins
+SWIG_VOID(int) loadPic(ePtr<gPixmap> &result, std::string filename, int x, int y, int aspect, int resize_mode, int rotate, int background, std::string cachefile)
+{
+ long asp1, asp2;
+ result = 0;
+ eDebug("deprecated loadPic function used!!! please use the non blocking version! you can see demo code in Pictureplayer plugin... this function is removed in the near future!");
+ ePicLoad mPL;
+
+ switch(aspect)
{
- savePNG( cachefile.c_str(), result);
- eDebug("[SAVEPIC] x-size=%d, y-size=%d", ox, oy);
+ case 1: asp1 = 16*576, asp2 = 9*720; break; //16:9
+ case 2: asp1 = 16*576, asp2 = 10*720; break; //16:10
+ case 3: asp1 = 5*576, asp2 = 4*720; break; //5:4
+ default: asp1 = 4*576, asp2 = 3*720; break; //4:3
}
+ ePyObject tuple = PyTuple_New(7);
+ PyTuple_SET_ITEM(tuple, 0, PyLong_FromLong(x));
+ PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(y));
+ PyTuple_SET_ITEM(tuple, 2, PyLong_FromLong(asp1));
+ PyTuple_SET_ITEM(tuple, 3, PyLong_FromLong(asp2));
+ PyTuple_SET_ITEM(tuple, 4, PyLong_FromLong(0));
+ PyTuple_SET_ITEM(tuple, 5, PyLong_FromLong(resize_mode));
+ if(background)
+ PyTuple_SET_ITEM(tuple, 6, PyString_FromString("#ff000000"));
+ else
+ PyTuple_SET_ITEM(tuple, 6, PyString_FromString("#00000000"));
+
+ mPL.setPara(tuple);
+
+ if(!mPL.startDecode(filename.c_str(), 0, 0, false))
+ mPL.getData(result);
+
return 0;
}
diff --git a/lib/gdi/picload.h b/lib/gdi/picload.h
index 7bb9adf1..f64fd2f9 100644
--- a/lib/gdi/picload.h
+++ b/lib/gdi/picload.h
@@ -1,11 +1,107 @@
#ifndef __picload_h__
#define __picload_h__
-#include "Python.h"
#include <lib/gdi/gpixmap.h>
-#include <lib/gdi/epng.h>
+#include <lib/base/thread.h>
+#include <lib/python/python.h>
+#include <lib/base/message.h>
+#include <lib/base/ebase.h>
-SWIG_VOID(int) loadPic(ePtr<gPixmap> &SWIG_OUTPUT, std::string filename, int x, int y, int aspect, int resize_mode=0, int rotate=0, int background=0, std::string cachefile="", int thumbnail=0);
-PyObject *getExif(const char *filename);
+#ifndef SWIG
+class Cfilepara
+{
+public:
+ int max_x;
+ int max_y;
+ bool callback;
+
+ const char *file;
+ int id;
+ int ox;
+ int oy;
+ unsigned char *pic_buffer;
+ std::string picinfo;
+ int test;
+
+ Cfilepara(const char *mfile, int mid, std::string size)
+ {
+ file = strdup(mfile);
+ id = mid;
+ pic_buffer = NULL;
+ callback = true;
+ picinfo = mfile;
+ picinfo += + "\n" + size + "\n";
+ }
+
+ ~Cfilepara()
+ {
+ if(pic_buffer != NULL) delete pic_buffer;
+ picinfo.clear();
+ }
+
+ void addExifInfo(std::string val) { picinfo += val + "\n"; }
+};
+#endif
+
+class ePicLoad: public eMainloop, public eThread, public Object, public iObject
+{
+ DECLARE_REF(ePicLoad);
+
+ enum{ F_PNG, F_JPEG, F_BMP, F_GIF};
+
+ void decodePic();
+ void decodeThumb();
+ void resizePic();
+
+ Cfilepara *m_filepara;
+ bool threadrunning;
+
+ struct PConf
+ {
+ int max_x;
+ int max_y;
+ double aspect_ratio;
+ unsigned char background[4];
+ bool resizetype;
+ bool usecache;
+ int thumbnailsize;
+ int test;
+ } m_conf;
+
+ struct Message
+ {
+ int type;
+ enum
+ {
+ decode_Pic,
+ decode_Thumb,
+ decode_finished,
+ quit
+ };
+ Message(int type=0)
+ :type(type) {}
+ };
+ eFixedMessagePump<Message> msg_thread, msg_main;
+
+ void gotMessage(const Message &message);
+ void thread();
+ int startThread(int what, const char *file, int x, int y, bool async=true);
+ void thread_finished();
+public:
+ void waitFinished();
+ PSignal1<void, const char*> PictureData;
+
+ ePicLoad();
+ ~ePicLoad();
+
+ RESULT startDecode(const char *filename, int x=0, int y=0, bool async=true);
+ RESULT getThumbnail(const char *filename, int x=0, int y=0, bool async=true);
+ RESULT setPara(PyObject *val);
+ PyObject *getInfo(const char *filename);
+ SWIG_VOID(int) getData(ePtr<gPixmap> &SWIG_OUTPUT);
+};
+
+//for old plugins
+SWIG_VOID(int) loadPic(ePtr<gPixmap> &SWIG_OUTPUT, std::string filename, int x, int y, int aspect, int resize_mode=0, int rotate=0, int background=0, std::string cachefile="");
#endif // __picload_h__
diff --git a/lib/gui/elistbox.cpp b/lib/gui/elistbox.cpp
index 5b05c028..e8a0dada 100644
--- a/lib/gui/elistbox.cpp
+++ b/lib/gui/elistbox.cpp
@@ -279,7 +279,7 @@ void eListbox::updateScrollBar()
if ((pages*m_items_per_page) < entries)
++pages;
int start=(m_top*100)/(pages*m_items_per_page);
- int vis=(m_items_per_page*100)/(pages*m_items_per_page);
+ int vis=(m_items_per_page*100+pages*m_items_per_page-1)/(pages*m_items_per_page);
if (vis < 3)
vis=3;
m_scrollbar->setStartEnd(start,start+vis);
diff --git a/lib/gui/elistboxcontent.cpp b/lib/gui/elistboxcontent.cpp
index beb12044..44973af7 100644
--- a/lib/gui/elistboxcontent.cpp
+++ b/lib/gui/elistboxcontent.cpp
@@ -467,7 +467,8 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
/* type is borrowed */
} else
eWarning("eListboxPythonConfigContent: second value of tuple is not a tuple.");
- /* value is borrowed */
+ if (value)
+ Py_DECREF(value);
}
if (selected && (!local_style || !local_style->m_selection))
@@ -522,7 +523,7 @@ static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *l
style.setStyle(painter, eWindowStyle::styleListboxNormal);
if (pbackColor)
{
- int color = PyInt_AsLong(pbackColor);
+ unsigned int color = PyInt_AsUnsignedLongMask(pbackColor);
painter.setBackgroundColor(gRGB(color));
} // transparent background?
// if we have a local background color set, use that.
@@ -542,7 +543,7 @@ static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *l
style.setStyle(painter, eWindowStyle::styleListboxSelected);
if (pbackColorSelected)
{
- int color = PyInt_AsLong(pbackColorSelected);
+ unsigned int color = PyInt_AsUnsignedLongMask(pbackColorSelected);
painter.setBackgroundColor(gRGB(color));
}
else if (local_style && local_style->m_background_color_selected_set)
@@ -559,7 +560,7 @@ static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *l
style.setStyle(painter, eWindowStyle::styleListboxSelected);
if (pbackColorSelected)
{
- int color = PyInt_AsLong(pbackColorSelected);
+ unsigned int color = PyInt_AsUnsignedLongMask(pbackColorSelected);
painter.setBackgroundColor(gRGB(color));
}
else if (local_style && local_style->m_background_color_selected_set)
@@ -571,7 +572,7 @@ static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *l
style.setStyle(painter, eWindowStyle::styleListboxNormal);
if (pbackColor)
{
- int color = PyInt_AsLong(pbackColor);
+ unsigned int color = PyInt_AsUnsignedLongMask(pbackColor);
painter.setBackgroundColor(gRGB(color));
}/* if we have a local background color set, use that. */
else if (local_style && local_style->m_background_color_set)
@@ -587,7 +588,7 @@ static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *l
{
if (pforeColorSelected)
{
- int color = PyInt_AsLong(pforeColorSelected);
+ unsigned int color = PyInt_AsUnsignedLongMask(pforeColorSelected);
painter.setForegroundColor(gRGB(color));
}
/* if we have a local foreground color set, use that. */
@@ -598,7 +599,7 @@ static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *l
{
if (pforeColor)
{
- int color = PyInt_AsLong(pforeColor);
+ unsigned int color = PyInt_AsUnsignedLongMask(pforeColor);
painter.setForegroundColor(gRGB(color));
}
/* if we have a local foreground color set, use that. */
@@ -607,6 +608,30 @@ static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *l
}
}
+static ePyObject lookupColor(ePyObject color, ePyObject data)
+{
+ if (color == Py_None)
+ return ePyObject();
+
+ if ((!color) && (!data))
+ return color;
+
+ unsigned int icolor = PyInt_AsUnsignedLongMask(color);
+
+ /* check if we have the "magic" template color */
+ if ((icolor & 0xFF000000) == 0xFF000000)
+ {
+ int index = icolor & 0xFFFFFF;
+ eDebug("[eListboxPythonMultiContent] template color index: %d", index);
+ return PyTuple_GetItem(data, index);
+ }
+
+ if (color == Py_None)
+ return ePyObject();
+
+ return color;
+}
+
void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
{
gRegion itemregion(eRect(offset, m_itemsize));
@@ -622,7 +647,7 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
painter.clip(itemregion);
clearRegion(painter, style, local_style, ePyObject(), ePyObject(), ePyObject(), ePyObject(), selected, itemregion, sel_clip);
- ePyObject items;
+ ePyObject items, buildfunc_ret;
if (m_list && cursorValid())
{
@@ -638,7 +663,7 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
if (PyCallable_Check(m_buildFunc)) // when we have a buildFunc then call it
{
if (PyTuple_Check(items))
- items = PyObject_CallObject(m_buildFunc, items);
+ buildfunc_ret = items = PyObject_CallObject(m_buildFunc, items);
else
eDebug("items is no tuple");
}
@@ -731,29 +756,17 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
}
if (size > 8)
- {
- pforeColor = PyTuple_GET_ITEM(item, 8);
- if (pforeColor == Py_None)
- pforeColor=ePyObject();
- }
+ pforeColor = lookupColor(PyTuple_GET_ITEM(item, 8), data);
+
if (size > 9)
- {
- pforeColorSelected = PyTuple_GET_ITEM(item, 9);
- if (pforeColorSelected == Py_None)
- pforeColorSelected=ePyObject();
- }
+ pforeColorSelected = lookupColor(PyTuple_GET_ITEM(item, 9), data);
+
if (size > 10)
- {
- pbackColor = PyTuple_GET_ITEM(item, 10);
- if (pbackColor == Py_None)
- pbackColor=ePyObject();
- }
+ pbackColor = lookupColor(PyTuple_GET_ITEM(item, 10), data);
+
if (size > 11)
- {
- pbackColorSelected = PyTuple_GET_ITEM(item, 11);
- if (pbackColorSelected == Py_None)
- pbackColorSelected=ePyObject();
- }
+ pbackColorSelected = lookupColor(PyTuple_GET_ITEM(item, 11), data);
+
if (size > 12)
{
pborderWidth = PyTuple_GET_ITEM(item, 12);
@@ -761,11 +774,7 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
pborderWidth=ePyObject();
}
if (size > 13)
- {
- pborderColor = PyTuple_GET_ITEM(item, 13);
- if (pborderColor == Py_None)
- pborderColor=ePyObject();
- }
+ pborderColor = lookupColor(PyTuple_GET_ITEM(item, 13), data);
if (PyInt_Check(pstring) && data) /* if the string is in fact a number, it refers to the 'data' list. */
pstring = PyTuple_GetItem(data, PyInt_AsLong(pstring));
@@ -804,7 +813,7 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
painter.clip(rect);
if (pborderColor)
{
- int color = PyInt_AsLong(pborderColor);
+ unsigned int color = PyInt_AsUnsignedLongMask(pborderColor);
painter.setForegroundColor(gRGB(color));
}
@@ -948,17 +957,10 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
}
if (size > 6)
- {
- pbackColor = PyTuple_GET_ITEM(item, 6);
- if (pbackColor == Py_None)
- pbackColor=ePyObject();
- }
+ pbackColor = lookupColor(PyTuple_GET_ITEM(item, 6), data);
+
if (size > 7)
- {
- pbackColorSelected = PyTuple_GET_ITEM(item, 7);
- if (pbackColorSelected == Py_None)
- pbackColorSelected=ePyObject();
- }
+ pbackColorSelected = lookupColor(PyTuple_GET_ITEM(item, 7), data);
eRect rect(x, y, width, height);
painter.clip(rect);
@@ -983,8 +985,8 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);
error_out:
- if (m_buildFunc && PyCallable_Check(m_buildFunc) && items)
- Py_DECREF(items);
+ if (buildfunc_ret)
+ Py_DECREF(buildfunc_ret);
painter.clippop();
}
@@ -1015,7 +1017,11 @@ int eListboxPythonMultiContent::currentCursorSelectable()
{
ePyObject ret = PyObject_CallObject(m_selectableFunc, args);
if (ret)
- return ret == Py_True;
+ {
+ bool retval = ret == Py_True;
+ Py_DECREF(ret);
+ return ret;
+ }
eDebug("call m_selectableFunc failed!!! assume not callable");
}
else
diff --git a/lib/gui/eslider.cpp b/lib/gui/eslider.cpp
index dd2aac9e..19097ad4 100644
--- a/lib/gui/eslider.cpp
+++ b/lib/gui/eslider.cpp
@@ -1,7 +1,7 @@
#include <lib/gui/eslider.h>
eSlider::eSlider(eWidget *parent)
- :eWidget(parent), m_have_border_color(false), m_start(0), m_orientation(orHorizontal), m_border_width(0)
+ :eWidget(parent), m_have_border_color(false), m_start(0), m_orientation(orHorizontal), m_orientation_swapped(0), m_border_width(0)
{
}
@@ -70,10 +70,14 @@ int eSlider::event(int event, void *data, void *data2)
if (m_min < m_max)
{
- num_pix = pixsize * (m_value - m_start) / (m_max - m_min);
- start_pix = pixsize * m_start / (m_max - m_min);
+ int val_range = m_max - m_min;
+ num_pix = (pixsize * (m_value - m_start) + val_range - 1) / val_range; /* properly round up */
+ start_pix = (pixsize * m_start + val_range - 1) / val_range;
+
+ if (m_orientation_swapped)
+ start_pix = pixsize - num_pix - start_pix;
}
-
+
if (start_pix < 0)
{
num_pix += start_pix;
@@ -113,9 +117,10 @@ void eSlider::setStartEnd(int start, int end)
event(evtChangedSlider);
}
-void eSlider::setOrientation(int orientation)
+void eSlider::setOrientation(int orientation, int swapped)
{
m_orientation = orientation;
+ m_orientation_swapped = swapped;
event(evtChangedSlider);
}
diff --git a/lib/gui/eslider.h b/lib/gui/eslider.h
index c5440726..9a3e8395 100644
--- a/lib/gui/eslider.h
+++ b/lib/gui/eslider.h
@@ -11,7 +11,7 @@ public:
void setStartEnd(int start, int end);
void setRange(int min, int max);
enum { orHorizontal, orVertical };
- void setOrientation(int orientation);
+ void setOrientation(int orientation, int swapped = 0);
void setBorderWidth(int pixel);
void setBorderColor(const gRGB &color);
void setPixmap(gPixmap *pixmap);
@@ -24,7 +24,7 @@ private:
evtChangedSlider = evtUserWidget
};
bool m_have_border_color;
- int m_min, m_max, m_value, m_start, m_orientation, m_border_width;
+ int m_min, m_max, m_value, m_start, m_orientation, m_orientation_swapped, m_border_width;
ePtr<gPixmap> m_pixmap;
gRegion m_currently_filled;
diff --git a/lib/gui/esubtitle.cpp b/lib/gui/esubtitle.cpp
index c837afc6..085a749a 100644
--- a/lib/gui/esubtitle.cpp
+++ b/lib/gui/esubtitle.cpp
@@ -16,6 +16,7 @@ eSubtitleWidget::eSubtitleWidget(eWidget *parent)
setBackgroundColor(gRGB(0,0,0,255));
m_page_ok = 0;
m_dvb_page_ok = 0;
+ m_pango_page_ok = 0;
CONNECT(m_hide_subtitles_timer->timeout, eSubtitleWidget::clearPage);
}
diff --git a/lib/nav/core.cpp b/lib/nav/core.cpp
index 062a7d00..90650f68 100644
--- a/lib/nav/core.cpp
+++ b/lib/nav/core.cpp
@@ -72,7 +72,7 @@ RESULT eNavigation::stopService(void)
return 0;
}
-RESULT eNavigation::recordService(const eServiceReference &ref, ePtr<iRecordableService> &service)
+RESULT eNavigation::recordService(const eServiceReference &ref, ePtr<iRecordableService> &service, bool simulate)
{
assert(m_servicehandler);
RESULT res = m_servicehandler->record(ref, service);
@@ -81,9 +81,14 @@ RESULT eNavigation::recordService(const eServiceReference &ref, ePtr<iRecordable
service = 0;
else
{
- ePtr<eConnection> conn;
- service->connectEvent(slot(*this, &eNavigation::recordEvent), conn);
- m_recordings[service]=conn;
+ if (simulate)
+ m_simulate_recordings.insert(service);
+ else
+ {
+ ePtr<eConnection> conn;
+ service->connectEvent(slot(*this, &eNavigation::recordEvent), conn);
+ m_recordings[service]=conn;
+ }
}
return res;
}
@@ -91,26 +96,40 @@ RESULT eNavigation::recordService(const eServiceReference &ref, ePtr<iRecordable
RESULT eNavigation::stopRecordService(ePtr<iRecordableService> &service)
{
service->stop();
- std::map<ePtr<iRecordableService>, ePtr<eConnection> >::iterator it =
- m_recordings.find(service);
- if (it != m_recordings.end())
+ std::set<ePtr<iRecordableService> >::iterator it =
+ m_simulate_recordings.find(service);
+ if (it != m_simulate_recordings.end())
{
- m_recordings.erase(it);
- /* send stop event */
- m_record_event(service, iRecordableService::evEnd);
+ m_simulate_recordings.erase(it);
return 0;
}
+ else
+ {
+ std::map<ePtr<iRecordableService>, ePtr<eConnection> >::iterator it =
+ m_recordings.find(service);
+ if (it != m_recordings.end())
+ {
+ m_recordings.erase(it);
+ /* send stop event */
+ m_record_event(service, iRecordableService::evEnd);
+ return 0;
+ }
+ }
eDebug("try to stop non running recording!!"); // this should not happen
return -1;
}
-PyObject *eNavigation::getRecordings(void)
+PyObject *eNavigation::getRecordings(bool simulate)
{
- ePyObject result = PyList_New(m_recordings.size());
+ ePyObject result = PyList_New(simulate ? m_simulate_recordings.size() : m_recordings.size());
int pos=0;
- for (std::map<ePtr<iRecordableService>, ePtr<eConnection> >::iterator it(m_recordings.begin()); it != m_recordings.end(); ++it)
- PyList_SET_ITEM(result, pos++, NEW_iRecordableServicePtr(it->first));
+ if (simulate)
+ for (std::set<ePtr<iRecordableService> >::iterator it(m_simulate_recordings.begin()); it != m_simulate_recordings.end(); ++it)
+ PyList_SET_ITEM(result, pos++, NEW_iRecordableServicePtr(*it));
+ else
+ for (std::map<ePtr<iRecordableService>, ePtr<eConnection> >::iterator it(m_recordings.begin()); it != m_recordings.end(); ++it)
+ PyList_SET_ITEM(result, pos++, NEW_iRecordableServicePtr(it->first));
return result;
}
diff --git a/lib/nav/core.h b/lib/nav/core.h
index 01efe9af..9f7be884 100644
--- a/lib/nav/core.h
+++ b/lib/nav/core.h
@@ -5,6 +5,7 @@
#include <lib/service/iservice.h>
#include <connection.h>
#include <map>
+#include <set>
class eNavigation: public iObject, public Object
{
@@ -17,6 +18,8 @@ class eNavigation: public iObject, public Object
void serviceEvent(iPlayableService* service, int event);
std::map<ePtr<iRecordableService>, ePtr<eConnection>, std::less<iRecordableService*> > m_recordings;
+ std::set<ePtr<iRecordableService>, std::less<iRecordableService*> > m_simulate_recordings;
+
Signal2<void,ePtr<iRecordableService>,int> m_record_event;
void recordEvent(iRecordableService* service, int event);
public:
@@ -28,9 +31,9 @@ public:
RESULT getCurrentService(ePtr<iPlayableService> &service);
RESULT stopService(void);
- RESULT recordService(const eServiceReference &ref, ePtr<iRecordableService> &service);
+ RESULT recordService(const eServiceReference &ref, ePtr<iRecordableService> &service, bool simulate=false);
RESULT stopRecordService(ePtr<iRecordableService> &service);
- PyObject *getRecordings(void);
+ PyObject *getRecordings(bool simulate=false);
RESULT pause(int p);
eNavigation(iServiceHandler *serviceHandler);
diff --git a/lib/nav/pcore.cpp b/lib/nav/pcore.cpp
index a6ed35f6..b38e5597 100644
--- a/lib/nav/pcore.cpp
+++ b/lib/nav/pcore.cpp
@@ -37,9 +37,9 @@ RESULT pNavigation::stopService()
return m_core->stopService();
}
-RESULT pNavigation::recordService(const eServiceReference &ref, ePtr<iRecordableService> &service)
+RESULT pNavigation::recordService(const eServiceReference &ref, ePtr<iRecordableService> &service, bool simulate)
{
- return m_core->recordService(ref, service);
+ return m_core->recordService(ref, service, simulate);
}
RESULT pNavigation::stopRecordService(ePtr<iRecordableService> &service)
@@ -47,9 +47,9 @@ RESULT pNavigation::stopRecordService(ePtr<iRecordableService> &service)
return m_core->stopRecordService(service);
}
-PyObject *pNavigation::getRecordings(void)
+PyObject *pNavigation::getRecordings(bool simulate)
{
- return m_core->getRecordings();
+ return m_core->getRecordings(simulate);
}
void pNavigation::navEvent(int event)
diff --git a/lib/nav/pcore.h b/lib/nav/pcore.h
index 1d314b19..c157e0dc 100644
--- a/lib/nav/pcore.h
+++ b/lib/nav/pcore.h
@@ -20,9 +20,9 @@ public:
RESULT pause(int p);
SWIG_VOID(RESULT) getCurrentService(ePtr<iPlayableService> &SWIG_OUTPUT);
- SWIG_VOID(RESULT) recordService(const eServiceReference &ref, ePtr<iRecordableService> &SWIG_OUTPUT);
+ SWIG_VOID(RESULT) recordService(const eServiceReference &ref, ePtr<iRecordableService> &SWIG_OUTPUT, bool simulate);
RESULT stopRecordService(ePtr<iRecordableService> &service);
- PyObject *getRecordings(void);
+ PyObject *getRecordings(bool simulate=false);
private:
ePtr<eNavigation> m_core;
diff --git a/lib/python/Components/AVSwitch.py b/lib/python/Components/AVSwitch.py
index 8f99b98e..3188469a 100644
--- a/lib/python/Components/AVSwitch.py
+++ b/lib/python/Components/AVSwitch.py
@@ -1,33 +1,43 @@
from config import config, ConfigSlider, ConfigSelection, ConfigYesNo, ConfigEnableDisable, ConfigSubsection, ConfigBoolean
-from enigma import eAVSwitch
+from enigma import eAVSwitch, getDesktop
from SystemInfo import SystemInfo
class AVSwitch:
- INPUT = { "ENCODER": (0, 4), "SCART": (1, 3), "AUX": (2, 4) }
-
def setInput(self, input):
- eAVSwitch.getInstance().setInput(self.INPUT[input][0])
- if self.INPUT[input][1] == 4:
- aspect = self.getAspectRatioSetting()
- self.setAspectWSS(aspect)
- self.setAspectSlowBlank(aspect)
- else:
- eAVSwitch.getInstance().setSlowblank(self.INPUT[input][1])
- # FIXME why do we have to reset the colorformat? bug in avs-driver?
- map = {"cvbs": 0, "rgb": 1, "svideo": 2, "yuv": 3}
- eAVSwitch.getInstance().setColorFormat(map[config.av.colorformat.value])
+ INPUT = { "ENCODER": 0, "SCART": 1, "AUX": 2 }
+ eAVSwitch.getInstance().setInput(INPUT[input])
def setColorFormat(self, value):
eAVSwitch.getInstance().setColorFormat(value)
def setAspectRatio(self, value):
eAVSwitch.getInstance().setAspectRatio(value)
- self.setAspectWSS(value)
- self.setAspectSlowBlank(value)
def setSystem(self, value):
eAVSwitch.getInstance().setVideomode(value)
+ def getOutputAspect(self):
+ valstr = config.av.aspectratio.value
+ if valstr in ("4_3_letterbox", "4_3_panscan"): # 4:3
+ return (4,3)
+ elif valstr == "16_9": # auto ... 4:3 or 16:9
+ try:
+ aspect_str = open("/proc/stb/vmpeg/0/aspect", "r").read()
+ if aspect_str == "1": # 4:3
+ return (4,3)
+ except IOError:
+ pass
+ elif valstr in ("16_9_always", "16_9_letterbox"): # 16:9
+ pass
+ elif valstr in ("16_10_letterbox", "16_10_panscan"): # 16:10
+ return (16,10)
+ return (16,9)
+
+ def getFramebufferScale(self):
+ aspect = self.getOutputAspect()
+ fb_size = getDesktop(0).size()
+ return (aspect[0] * fb_size.height(), aspect[1] * fb_size.width())
+
def getAspectRatioSetting(self):
valstr = config.av.aspectratio.value
if valstr == "4_3_letterbox":
@@ -47,35 +57,12 @@ class AVSwitch:
return val
def setAspectWSS(self, aspect=None):
- if aspect is None:
- aspect = self.getAspectRatioSetting()
- if aspect == 0 or aspect == 1: # letterbox or panscan
- if not config.av.wss.value:
- value = 0 # wss off
- else:
- value = 3 # 4:3_full_format
- elif aspect == 2: # 16:9
- if not config.av.wss.value:
- value = 2 # auto(4:3_off)
- else:
- value = 1 # auto
- elif aspect == 3 or aspect == 6: # always 16:9
- value = 4 # 16:9_full_format
- elif aspect == 4 or aspect == 5: # 16:10
- value = 10 # 14:9_full_format
+ if not config.av.wss.value:
+ value = 2 # auto(4:3_off)
+ else:
+ value = 1 # auto
eAVSwitch.getInstance().setWSS(value)
- def setAspectSlowBlank(self, aspect=None):
- if aspect is None:
- aspect = self.getAspectRatioSetting()
- if aspect == 0 or aspect == 1: # letterbox or panscan
- value = 2 # 12 V
- elif aspect == 2: # 16:9
- value = 4 # auto
- elif aspect == 3 or aspect == 4 or aspect == 5 or aspect == 6: # always 16:9
- value = 1 # 6V
- eAVSwitch.getInstance().setSlowblank(value)
-
def InitAVSwitch():
config.av = ConfigSubsection()
config.av.yuvenabled = ConfigBoolean(default=False)
diff --git a/lib/python/Components/Console.py b/lib/python/Components/Console.py
index c5fa5f98..f1f3fd95 100644
--- a/lib/python/Components/Console.py
+++ b/lib/python/Components/Console.py
@@ -8,7 +8,7 @@ class Console(object):
self.callbacks = {}
self.extra_args = {}
- def ePopen(self, cmd, callback, extra_args=[]):
+ def ePopen(self, cmd, callback=None, extra_args=[]):
name = cmd
i = 0
while self.appContainers.has_key(name):
@@ -21,7 +21,9 @@ class Console(object):
self.appContainers[name] = eConsoleAppContainer()
self.appContainers[name].dataAvail.append(boundFunction(self.dataAvailCB,name))
self.appContainers[name].appClosed.append(boundFunction(self.finishedCB,name))
- retval = self.appContainers[name].execute(cmd)
+ if isinstance(cmd, str): # until .execute supports a better api
+ cmd = [cmd]
+ retval = self.appContainers[name].execute(*cmd)
if retval:
self.finishedCB(name, retval)
@@ -50,5 +52,6 @@ class Console(object):
extra_args = self.extra_args[name]
del self.appContainers[name]
del self.extra_args[name]
- self.callbacks[name](data,retval,extra_args)
+ if self.callbacks[name]:
+ self.callbacks[name](data,retval,extra_args)
del self.callbacks[name]
diff --git a/lib/python/Components/Converter/EventTime.py b/lib/python/Components/Converter/EventTime.py
index 966f2ca8..41f1ebf3 100644
--- a/lib/python/Components/Converter/EventTime.py
+++ b/lib/python/Components/Converter/EventTime.py
@@ -1,7 +1,7 @@
from Converter import Converter
from Poll import Poll
from time import time
-from Components.Element import cached
+from Components.Element import cached, ElementError
class EventTime(Poll, Converter, object):
STARTTIME = 0
@@ -28,7 +28,7 @@ class EventTime(Poll, Converter, object):
self.poll_interval = 30*1000
self.poll_enabled = True
else:
- raise str("'%s' is not <StartTime|EndTime|Remaining|Duration|Progress> for EventTime converter" % type)
+ raise ElementError("'%s' is not <StartTime|EndTime|Remaining|Duration|Progress> for EventTime converter" % type)
@cached
def getTime(self):
diff --git a/lib/python/Components/Converter/MovieInfo.py b/lib/python/Components/Converter/MovieInfo.py
index 068d24d3..be28dcce 100644
--- a/lib/python/Components/Converter/MovieInfo.py
+++ b/lib/python/Components/Converter/MovieInfo.py
@@ -1,5 +1,5 @@
from Components.Converter.Converter import Converter
-from Components.Element import cached
+from Components.Element import cached, ElementError
from enigma import iServiceInformation
from ServiceReference import ServiceReference
@@ -16,7 +16,7 @@ class MovieInfo(Converter, object):
elif type == "RecordServiceName":
self.type = self.MOVIE_REC_SERVICE_NAME
else:
- raise str("'%s' is not <ShortDescription|MetaDescription|RecordServiceName> for MovieInfo converter" % type)
+ raise ElementError("'%s' is not <ShortDescription|MetaDescription|RecordServiceName> for MovieInfo converter" % type)
Converter.__init__(self, type)
@cached
diff --git a/lib/python/Components/Converter/RemainingToText.py b/lib/python/Components/Converter/RemainingToText.py
index adefe9cf..4249e30a 100644
--- a/lib/python/Components/Converter/RemainingToText.py
+++ b/lib/python/Components/Converter/RemainingToText.py
@@ -2,19 +2,43 @@ from Components.Converter.Converter import Converter
from Components.Element import cached
class RemainingToText(Converter, object):
+ DEFAULT = 0
+ WITH_SECONDS = 1
+ NO_SECONDS = 2
+
def __init__(self, type):
Converter.__init__(self, type)
+ if type == "WithSeconds":
+ self.type = self.WITH_SECONDS
+ elif type == "NoSeconds":
+ self.type = self.NO_SECONDS
+ else:
+ self.type = self.DEFAULT
@cached
def getText(self):
- r = self.source.time
- if r is None:
+ time = self.source.time
+ if time is None:
return ""
(duration, remaining) = self.source.time
- if remaining is not None:
- return "+%d min" % (remaining / 60)
+
+ if self.type == self.WITH_SECONDS:
+ if remaining is not None:
+ return "%d:%02d:%02d" % (remaining / 3600, (remaining / 60) - ((remaining / 3600) * 60), remaining % 60)
+ else:
+ return "%02d:%02d:%02d" % (duration / 3600, (duration / 60) - ((duration / 3600) * 60), duration % 60)
+ elif self.type == self.NO_SECONDS:
+ if remaining is not None:
+ return "+%d:%02d" % (remaining / 3600, (remaining / 60) - ((remaining / 3600) * 60))
+ else:
+ return "%02d:%02d" % (duration / 3600, (duration / 60) - ((duration / 3600) * 60))
+ elif self.type == self.DEFAULT:
+ if remaining is not None:
+ return "+%d min" % (remaining / 60)
+ else:
+ return "%d min" % (duration / 60)
else:
- return "%d min" % (duration / 60)
+ return "???"
text = property(getText)
diff --git a/lib/python/Components/Converter/ServicePosition.py b/lib/python/Components/Converter/ServicePosition.py
index b488258b..2bcc5492 100644
--- a/lib/python/Components/Converter/ServicePosition.py
+++ b/lib/python/Components/Converter/ServicePosition.py
@@ -1,7 +1,7 @@
from Converter import Converter
from Poll import Poll
from enigma import iPlayableService
-from Components.Element import cached
+from Components.Element import cached, ElementError
class ServicePosition(Converter, Poll, object):
TYPE_LENGTH = 0
@@ -19,6 +19,7 @@ class ServicePosition(Converter, Poll, object):
self.negate = 'Negate' in args
self.detailed = 'Detailed' in args
self.showHours = 'ShowHours' in args
+ self.showNoSeconds = 'ShowNoSeconds' in args
if self.detailed:
self.poll_interval = 100
@@ -34,7 +35,7 @@ class ServicePosition(Converter, Poll, object):
elif type == "Gauge":
self.type = self.TYPE_GAUGE
else:
- raise "type must be {Length|Position|Remaining|Gauge} with optional arguments {Negate|Detailed|ShowHours}"
+ raise ElementError("type must be {Length|Position|Remaining|Gauge} with optional arguments {Negate|Detailed|ShowHours|NoSeconds}")
self.poll_enabled = self.type != self.TYPE_LENGTH
@@ -94,9 +95,15 @@ class ServicePosition(Converter, Poll, object):
if not self.detailed:
if self.showHours:
- return sign + "%d:%02d:%02d" % (l/3600, l%3600/60, l%60)
+ if self.showNoSeconds:
+ return sign + "%d:%02d" % (l/3600, l%3600/60)
+ else:
+ return sign + "%d:%02d:%02d" % (l/3600, l%3600/60, l%60)
else:
- return sign + "%d:%02d" % (l/60, l%60)
+ if self.showNoSeconds:
+ return sign + "%d" % (l/60)
+ else:
+ return sign + "%d:%02d" % (l/60, l%60)
else:
if self.showHours:
return sign + "%d:%02d:%02d:%03d" % ((l/3600/90000), (l/90000)%3600/60, (l/90000)%60, (l%90000)/90)
diff --git a/lib/python/Components/Converter/ServiceTime.py b/lib/python/Components/Converter/ServiceTime.py
index 16bcae3a..89965067 100644
--- a/lib/python/Components/Converter/ServiceTime.py
+++ b/lib/python/Components/Converter/ServiceTime.py
@@ -1,5 +1,5 @@
from Converter import Converter
-from Components.Element import cached
+from Components.Element import cached, ElementError
from enigma import iServiceInformation
class ServiceTime(Converter, object):
@@ -16,7 +16,7 @@ class ServiceTime(Converter, object):
elif type == "Duration":
self.type = self.DURATION
else:
- raise str("'%s' is not <StartTime|EndTime|Duration> for eEventTime converter" % type)
+ raise ElementError("'%s' is not <StartTime|EndTime|Duration> for eEventTime converter" % type)
@cached
def getTime(self):
diff --git a/lib/python/Components/Converter/TemplatedMultiContent.py b/lib/python/Components/Converter/TemplatedMultiContent.py
index a1b601d6..5f1d4f24 100644
--- a/lib/python/Components/Converter/TemplatedMultiContent.py
+++ b/lib/python/Components/Converter/TemplatedMultiContent.py
@@ -5,22 +5,27 @@ class TemplatedMultiContent(StringList):
def __init__(self, args):
StringList.__init__(self, args)
from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT, RT_HALIGN_CENTER, RT_HALIGN_RIGHT, RT_VALIGN_TOP, RT_VALIGN_CENTER, RT_VALIGN_BOTTOM
- from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmap, MultiContentEntryPixmapAlphaTest
+ from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmap, MultiContentEntryPixmapAlphaTest, MultiContentTemplateColor
l = locals()
del l["self"] # cleanup locals a bit
del l["args"]
self.template = eval(args, {}, l)
+ self.active_style = None
assert "fonts" in self.template
assert "itemHeight" in self.template
- assert "template" in self.template
+ assert "template" in self.template or "templates" in self.template
+ assert "template" in self.template or "default" in self.template["templates"] # we need to have a default template
+
+ if not "template" in self.template: # default template can be ["template"] or ["templates"]["default"]
+ self.template["template"] = self.template["templates"]["default"]
def changed(self, what):
if not self.content:
from enigma import eListboxPythonMultiContent
self.content = eListboxPythonMultiContent()
self.content.setItemHeight(self.template["itemHeight"])
- self.content.setTemplate(self.template["template"])
+ self.setTemplate()
# also setup fonts (also given by source)
index = 0
@@ -28,7 +33,28 @@ class TemplatedMultiContent(StringList):
self.content.setFont(index, f)
index += 1
+ # if only template changed, don't reload list
+ if what[0] == self.CHANGED_SPECIFIC and what[1] == "style":
+ self.setTemplate()
+ return
+
if self.source:
self.content.setList(self.source.list)
+ self.setTemplate()
self.downstream_elements.changed(what)
+
+ def setTemplate(self):
+ if self.source:
+ style = self.source.style
+ if style == self.active_style:
+ return # style did not change
+
+ # if skin defined "templates", that means that it defines multiple styles in a dict. template should still be a default
+ templates = self.template.get("templates")
+ template = self.template.get("template")
+
+ if templates and style: # if we have a custom style defined in the source, and different templates in the skin, look it up
+ template = templates.get(self.source.style, template) # default to default template
+
+ self.content.setTemplate(template)
diff --git a/lib/python/Components/Element.py b/lib/python/Components/Element.py
index 2af57793..f4a8f127 100644
--- a/lib/python/Components/Element.py
+++ b/lib/python/Components/Element.py
@@ -16,6 +16,13 @@ def cached(f):
return cache[name][1]
return wrapper
+class ElementError(Exception):
+ def __init__(self, message):
+ self.message = message
+
+ def __str__(self):
+ return self.message
+
class Element(object):
CHANGED_DEFAULT = 0 # initial "pull" state
CHANGED_ALL = 1 # really everything changed
diff --git a/lib/python/Components/EpgList.py b/lib/python/Components/EpgList.py
index dbcd572b..8a7c8d45 100644
--- a/lib/python/Components/EpgList.py
+++ b/lib/python/Components/EpgList.py
@@ -52,6 +52,10 @@ class EPGList(HTMLComponent, GUIComponent):
self.l.setBuildFunc(self.buildSimilarEntry)
self.epgcache = eEPGCache.getInstance()
self.clock_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock.png'))
+ self.clock_add_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_add.png'))
+ self.clock_pre_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_pre.png'))
+ self.clock_post_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_post.png'))
+ self.clock_prepost_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_prepost.png'))
def getEventFromId(self, service, eventid):
event = None
@@ -60,7 +64,7 @@ class EPGList(HTMLComponent, GUIComponent):
return event
def getCurrentChangeCount(self):
- if self.type == EPG_TYPE_MULTI:
+ if self.type == EPG_TYPE_MULTI and self.l.getCurrentSelection() is not None:
return self.l.getCurrentSelection()[0]
return 0
@@ -92,11 +96,12 @@ class EPGList(HTMLComponent, GUIComponent):
def selectionChanged(self):
for x in self.onSelChanged:
if x is not None:
- try:
- x()
- except: # FIXME!!!
- print "FIXME in EPGList.selectionChanged"
- pass
+ x()
+# try:
+# x()
+# except: # FIXME!!!
+# print "FIXME in EPGList.selectionChanged"
+# pass
GUI_WIDGET = eListbox
@@ -135,8 +140,32 @@ class EPGList(HTMLComponent, GUIComponent):
self.datetime_rect = Rect(width/20*2, 0, width/20*5-15, height)
self.service_rect = Rect(width/20*7, 0, width/20*13, height)
+ def getClockPixmap(self, refstr, beginTime, duration, eventId):
+ pre_clock = 1
+ post_clock = 2
+ clock_type = 0
+ endTime = beginTime + duration
+ for x in self.timer.timer_list:
+ if x.service_ref.ref.toString() == refstr:
+ if x.eit == eventId:
+ return self.clock_pixmap
+ beg = x.begin
+ end = x.end
+ if beginTime > beg and beginTime < end and endTime > end:
+ clock_type |= pre_clock
+ elif beginTime < beg and endTime > beg and endTime < end:
+ clock_type |= post_clock
+ if clock_type == 0:
+ return self.clock_add_pixmap
+ elif clock_type == pre_clock:
+ return self.clock_pre_pixmap
+ elif clock_type == post_clock:
+ return self.clock_post_pixmap
+ else:
+ return self.clock_prepost_pixmap
+
def buildSingleEntry(self, service, eventId, beginTime, duration, EventName):
- rec=beginTime and (self.timer.isInTimer(eventId, beginTime, duration, service) > ((duration/10)*8))
+ rec=beginTime and (self.timer.isInTimer(eventId, beginTime, duration, service))
r1=self.weekday_rect
r2=self.datetime_rect
r3=self.descr_rect
@@ -145,14 +174,15 @@ class EPGList(HTMLComponent, GUIComponent):
res.append((eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width(), r1.height(), 0, RT_HALIGN_RIGHT, self.days[t[6]]))
res.append((eListboxPythonMultiContent.TYPE_TEXT, r2.left(), r2.top(), r2.width(), r1.height(), 0, RT_HALIGN_RIGHT, "%02d.%02d, %02d:%02d"%(t[2],t[1],t[3],t[4])))
if rec:
- res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left(), r3.top(), 21, 21, self.clock_pixmap))
+ clock_pic = self.getClockPixmap(service, beginTime, duration, eventId)
+ res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left(), r3.top(), 21, 21, clock_pic))
res.append((eListboxPythonMultiContent.TYPE_TEXT, r3.left() + 25, r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, EventName))
else:
res.append((eListboxPythonMultiContent.TYPE_TEXT, r3.left(), r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, EventName))
return res
def buildSimilarEntry(self, service, eventId, beginTime, service_name, duration):
- rec=beginTime and (self.timer.isInTimer(eventId, beginTime, duration, service) > ((duration/10)*8))
+ rec=beginTime and (self.timer.isInTimer(eventId, beginTime, duration, service))
r1=self.weekday_rect
r2=self.datetime_rect
r3=self.service_rect
@@ -161,22 +191,24 @@ class EPGList(HTMLComponent, GUIComponent):
res.append((eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width(), r1.height(), 0, RT_HALIGN_RIGHT, self.days[t[6]]))
res.append((eListboxPythonMultiContent.TYPE_TEXT, r2.left(), r2.top(), r2.width(), r1.height(), 0, RT_HALIGN_RIGHT, "%02d.%02d, %02d:%02d"%(t[2],t[1],t[3],t[4])))
if rec:
- res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left(), r3.top(), 21, 21, self.clock_pixmap))
+ clock_pic = self.getClockPixmap(service, beginTime, duration, eventId)
+ res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left(), r3.top(), 21, 21, clock_pic))
res.append((eListboxPythonMultiContent.TYPE_TEXT, r3.left() + 25, r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, service_name))
else:
res.append((eListboxPythonMultiContent.TYPE_TEXT, r3.left(), r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, service_name))
return res
def buildMultiEntry(self, changecount, service, eventId, begTime, duration, EventName, nowTime, service_name):
- rec=begTime and (self.timer.isInTimer(eventId, begTime, duration, service) > ((duration/10)*8))
+ rec=begTime and (self.timer.isInTimer(eventId, begTime, duration, service))
r1=self.service_rect
r2=self.progress_rect
r3=self.descr_rect
r4=self.start_end_rect
res = [ None ] # no private data needed
if rec:
+ clock_pic = self.getClockPixmap(service, begTime, duration, eventId)
res.append((eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width()-21, r1.height(), 0, RT_HALIGN_LEFT, service_name))
- res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r1.left()+r1.width()-16, r1.top(), 21, 21, self.clock_pixmap))
+ res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r1.left()+r1.width()-16, r1.top(), 21, 21, clock_pic))
else:
res.append((eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width(), r1.height(), 0, RT_HALIGN_LEFT, service_name))
if begTime is not None:
@@ -252,6 +284,12 @@ class EPGList(HTMLComponent, GUIComponent):
x = self.l.getCurrentSelection()
return x and x[1]
+ def moveToService(self,serviceref):
+ for x in range(len(self.list)):
+ if self.list[x][1] == serviceref.toString():
+ self.instance.moveSelectionTo(x)
+ break
+
def moveToEventId(self, eventId):
index = 0
for x in self.list:
diff --git a/lib/python/Components/FileList.py b/lib/python/Components/FileList.py
index e028ec3a..84abf328 100644
--- a/lib/python/Components/FileList.py
+++ b/lib/python/Components/FileList.py
@@ -10,6 +10,7 @@ from enigma import RT_HALIGN_LEFT, eListboxPythonMultiContent, \
from Tools.LoadPixmap import LoadPixmap
EXTENSIONS = {
+ "m4a": "music",
"mp2": "music",
"mp3": "music",
"wav": "music",
@@ -21,6 +22,7 @@ EXTENSIONS = {
"bmp": "picture",
"ts": "movie",
"avi": "movie",
+ "divx": "movie",
"mpg": "movie",
"mpeg": "movie",
"mkv": "movie",
@@ -117,8 +119,6 @@ class FileList(MenuList):
def changeDir(self, directory, select = None):
self.list = []
- if directory and not os_path.isdir(directory):
- directory = None
# if we are just entering from the list of mount points:
if self.current_directory is None:
if directory and self.showMountpoints:
@@ -136,6 +136,9 @@ class FileList(MenuList):
self.list.append(FileEntryComponent(name = p.description, absolute = path, isDir = True))
files = [ ]
directories = [ ]
+ elif directory is None:
+ files = [ ]
+ directories = [ ]
elif self.useServiceRef:
root = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + directory)
if self.additional_extensions:
diff --git a/lib/python/Components/Harddisk.py b/lib/python/Components/Harddisk.py
index f7c3a7cb..6c6c3c6c 100644
--- a/lib/python/Components/Harddisk.py
+++ b/lib/python/Components/Harddisk.py
@@ -2,6 +2,8 @@ from os import system, listdir, statvfs, popen, makedirs, readlink, stat, major,
from Tools.Directories import SCOPE_HDD, resolveFilename
from Tools.CList import CList
from SystemInfo import SystemInfo
+import string, time
+from Components.Console import Console
def tryOpen(filename):
try:
@@ -17,22 +19,33 @@ class Harddisk:
tmp = procfile.readline().split(':')
s_major = int(tmp[0])
s_minor = int(tmp[1])
+ self.max_idle_time = 0
+ self.idle_running = False
+ self.timer = None
for disc in listdir("/dev/discs"):
path = readlink('/dev/discs/'+disc)
- devidex = '/dev'+path[2:]+'/'
- disc = devidex+'disc'
+ devidex = '/dev/discs/'+disc+'/'
+ devidex2 = '/dev'+path[2:]+'/'
+ disc = devidex2+'disc'
ret = stat(disc).st_rdev
if s_major == major(ret) and s_minor == minor(ret):
self.devidex = devidex
- print "new Harddisk", device, self.devidex
+ self.devidex2 = devidex2
+ print "new Harddisk", device, '->', self.devidex, '->', self.devidex2
+ self.startIdle()
break
def __lt__(self, ob):
return self.device < ob.device
+ def stop(self):
+ if self.timer:
+ self.timer.stop()
+ self.timer.callback.remove(self.runIdle)
+
def bus(self):
- ide_cf = self.device.find("hd") == 0 and self.devidex.find("host0") == -1 # 7025 specific
- internal = self.device.find("hd") == 0 and self.devidex
+ ide_cf = self.device.find("hd") == 0 and self.devidex2.find("host0") == -1 # 7025 specific
+ internal = self.device.find("hd") == 0
if ide_cf:
ret = "External (CF)"
elif internal:
@@ -90,7 +103,7 @@ class Harddisk:
line = procfile.readline()
if line == "":
break
- if line.startswith(self.devidex):
+ if line.startswith(self.devidex) or line.startswith(self.devidex2):
parts = line.strip().split(" ")
try:
stat = statvfs(parts[1])
@@ -123,7 +136,7 @@ class Harddisk:
cmd = "/bin/umount"
for line in procfile:
- if line.startswith(self.devidex):
+ if line.startswith(self.devidex) or line.startswith(self.devidex2):
parts = line.split()
cmd = ' '.join([cmd, parts[1]])
@@ -210,12 +223,77 @@ class Harddisk:
def getDeviceName(self):
return self.getDeviceDir() + "disc"
+ # the HDD idle poll daemon.
+ # as some harddrives have a buggy standby timer, we are doing this by hand here.
+ # first, we disable the hardware timer. then, we check every now and then if
+ # any access has been made to the disc. If there has been no access over a specifed time,
+ # we set the hdd into standby.
+ def readStats(self):
+ l = open("/sys/block/%s/stat" % self.device).read()
+ nr_read = int(l[:8].strip())
+ nr_write = int(l[4*9:4*9+8].strip())
+ return nr_read, nr_write
+
+ def startIdle(self):
+ self.last_access = time.time()
+ self.last_stat = 0
+ self.is_sleeping = False
+ from enigma import eTimer
+
+ # disable HDD standby timer
+ Console().ePopen(("hdparm", "hdparm", "-S0", (self.devidex + "disc")))
+ self.timer = eTimer()
+ self.timer.callback.append(self.runIdle)
+ self.idle_running = True
+ self.setIdleTime(self.max_idle_time) # kick the idle polling loop
+
+ def runIdle(self):
+ if not self.max_idle_time:
+ return
+ t = time.time()
+
+ idle_time = t - self.last_access
+
+ stats = self.readStats()
+ print "nr_read", stats[0], "nr_write", stats[1]
+ l = sum(stats)
+ print "sum", l, "prev_sum", self.last_stat
+
+ if l != self.last_stat: # access
+ print "hdd was accessed since previous check!"
+ self.last_stat = l
+ self.last_access = t
+ idle_time = 0
+ self.is_sleeping = False
+ else:
+ print "hdd IDLE!"
+
+ print "[IDLE]", idle_time, self.max_idle_time, self.is_sleeping
+ if idle_time >= self.max_idle_time and not self.is_sleeping:
+ self.setSleep()
+ self.is_sleeping = True
+
+ def setSleep(self):
+ Console().ePopen(("hdparm", "hdparm", "-y", (self.devidex + "disc")))
+
+ def setIdleTime(self, idle):
+ self.max_idle_time = idle
+ if self.idle_running:
+ if not idle:
+ self.timer.stop()
+ else:
+ self.timer.start(idle * 100, False) # poll 10 times per period.
+
+ def isSleeping(self):
+ return self.is_sleeping
+
class Partition:
- def __init__(self, mountpoint, description = "", force_mounted = False):
+ def __init__(self, mountpoint, device = None, description = "", force_mounted = False):
self.mountpoint = mountpoint
self.description = description
self.force_mounted = force_mounted
self.is_hotplug = force_mounted # so far; this might change.
+ self.device = device
def stat(self):
return statvfs(self.mountpoint)
@@ -245,6 +323,15 @@ class Partition:
return True
return False
+DEVICEDB = \
+ {
+ # dm8000:
+ "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.1/1-1.1:1.0": "Front USB Slot",
+ "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0": "Back, upper USB Slot",
+ "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.3/1-1.3:1.0": "Back, lower USB Slot",
+ "/devices/platform/brcm-ehci-1.1/usb2/2-1/2-1:1.0/host1/target1:0:0/1:0:0:0": "DVD Drive",
+ }
+
class HarddiskManager:
def __init__(self):
self.hdd = [ ]
@@ -305,37 +392,62 @@ class HarddiskManager:
self.cd = blockdev
except IOError:
error = True
- return error, blacklisted, removable, is_cdrom, partitions
+ # check for medium
+ medium_found = True
+ try:
+ open("/dev/" + blockdev).close()
+ except IOError, err:
+ if err.errno == 159: # no medium present
+ medium_found = False
+
+ return error, blacklisted, removable, is_cdrom, partitions, medium_found
def enumerateBlockDevices(self):
print "enumerating block devices..."
for blockdev in listdir("/sys/block"):
- error, blacklisted, removable, is_cdrom, partitions = self.getBlockDevInfo(blockdev)
+ error, blacklisted, removable, is_cdrom, partitions, medium_found = self.getBlockDevInfo(blockdev)
print "found block device '%s':" % blockdev,
if error:
print "error querying properties"
elif blacklisted:
print "blacklisted"
+ elif not medium_found:
+ print "no medium"
else:
print "ok, removable=%s, cdrom=%s, partitions=%s, device=%s" % (removable, is_cdrom, partitions, blockdev)
- self.addHotplugPartition(blockdev, blockdev)
+
+ self.addHotplugPartition(blockdev)
for part in partitions:
- self.addHotplugPartition(part, part)
+ self.addHotplugPartition(part)
def getAutofsMountpoint(self, device):
return "/autofs/%s/" % (device)
- def addHotplugPartition(self, device, description):
- p = Partition(mountpoint = self.getAutofsMountpoint(device), description = description, force_mounted = True)
+ def addHotplugPartition(self, device, physdev = None):
+ if not physdev:
+ dev, part = self.splitDeviceName(device)
+ try:
+ physdev = readlink("/sys/block/" + dev + "/device")[5:]
+ except OSError:
+ physdev = dev
+ print "couldn't determine blockdev physdev for device", device
+
+ # device is the device name, without /dev
+ # physdev is the physical device path, which we (might) use to determine the userfriendly name
+ description = self.getUserfriendlyDeviceName(device, physdev)
+
+ p = Partition(mountpoint = self.getAutofsMountpoint(device), description = description, force_mounted = True, device = device)
self.partitions.append(p)
self.on_partition_list_change("add", p)
+
+ # see if this is a harddrive
l = len(device)
- if l and device[l-1] not in ('0','1','2','3','4','5','6','7','8','9'):
- error, blacklisted, removable, is_cdrom, partitions = self.getBlockDevInfo(device)
- if not blacklisted and not removable and not is_cdrom:
+ if l and device[l-1] not in string.digits:
+ error, blacklisted, removable, is_cdrom, partitions, medium_found = self.getBlockDevInfo(device)
+ if not blacklisted and not removable and not is_cdrom and medium_found:
self.hdd.append(Harddisk(device))
self.hdd.sort()
- SystemInfo["Harddisc"] = len(self.hdd) > 0
+ SystemInfo["Harddisk"] = len(self.hdd) > 0
def removeHotplugPartition(self, device):
mountpoint = self.getAutofsMountpoint(device)
@@ -344,13 +456,14 @@ class HarddiskManager:
self.partitions.remove(x)
self.on_partition_list_change("remove", x)
l = len(device)
- if l and device[l-1] not in ('0','1','2','3','4','5','6','7','8','9'):
+ if l and device[l-1] not in string.digits:
idx = 0
for hdd in self.hdd:
if hdd.device == device:
+ self.hdd[x].stop()
del self.hdd[idx]
break
- SystemInfo["Harddisc"] = len(self.hdd) > 0
+ SystemInfo["Harddisk"] = len(self.hdd) > 0
def HDDCount(self):
return len(self.hdd)
@@ -369,6 +482,41 @@ class HarddiskManager:
return self.cd
def getMountedPartitions(self, onlyhotplug = False):
- return [x for x in self.partitions if (x.is_hotplug or not onlyhotplug) and x.mounted()]
+ parts = [x for x in self.partitions if (x.is_hotplug or not onlyhotplug) and x.mounted()]
+ devs = set([x.device for x in parts])
+ for devname in devs.copy():
+ if not devname:
+ continue
+ dev, part = self.splitDeviceName(devname)
+ if part and dev in devs: # if this is a partition and we still have the wholedisk, remove wholedisk
+ devs.remove(dev)
+
+ # return all devices which are not removed due to being a wholedisk when a partition exists
+ return [x for x in parts if not x.device or x.device in devs]
+
+ def splitDeviceName(self, devname):
+ # this works for: sdaX, hdaX, sr0 (which is in fact dev="sr0", part=""). It doesn't work for other names like mtdblock3, but they are blacklisted anyway.
+ dev = devname[:3]
+ part = devname[3:]
+ for p in part:
+ if p not in string.digits:
+ return devname, 0
+ return dev, part and int(part) or 0
+
+ def getUserfriendlyDeviceName(self, dev, phys):
+ dev, part = self.splitDeviceName(dev)
+ description = "External Storage %s" % dev
+ try:
+ description = open("/sys" + phys + "/model").read().strip()
+ except IOError, s:
+ print "couldn't read model: ", s
+ for physdevprefix, pdescription in DEVICEDB.items():
+ if phys.startswith(physdevprefix):
+ description = pdescription
+
+ # not wholedisk and not partition 1
+ if part and part != 1:
+ description += " (Partition %d)" % part
+ return description
harddiskmanager = HarddiskManager()
diff --git a/lib/python/Components/Language.py b/lib/python/Components/Language.py
index 6d1e31f3..395f6829 100644
--- a/lib/python/Components/Language.py
+++ b/lib/python/Components/Language.py
@@ -36,6 +36,7 @@ class Language:
self.addLanguage(_("Swedish"), "sv", "SE")
self.addLanguage(_("Turkish"), "tr", "TR")
self.addLanguage(_("Ukrainian"), "uk", "UA")
+ self.addLanguage(_("Frisian"), "fy", "x-FY") # there is no separate country for frisian
self.callbacks = []
diff --git a/lib/python/Components/Makefile.am b/lib/python/Components/Makefile.am
index fda58bf3..67cec18d 100644
--- a/lib/python/Components/Makefile.am
+++ b/lib/python/Components/Makefile.am
@@ -18,4 +18,4 @@ install_PYTHON = \
MultiContent.py MediaPlayer.py TunerInfo.py VideoWindow.py ChoiceList.py \
Element.py Playlist.py ParentalControl.py ParentalControlList.py \
Ipkg.py SelectionList.py Scanner.py SystemInfo.py DreamInfoHandler.py \
- Task.py language_cache.py Console.py
+ Task.py language_cache.py Console.py ResourceManager.py TuneTest.py
diff --git a/lib/python/Components/MovieList.py b/lib/python/Components/MovieList.py
index 8568f3d6..5c98e4be 100644
--- a/lib/python/Components/MovieList.py
+++ b/lib/python/Components/MovieList.py
@@ -93,10 +93,7 @@ class MovieList(GUIComponent):
if len > 0:
len = "%d:%02d" % (len / 60, len % 60)
else:
- if config.usage.load_length_of_movies_in_moviellist.value:
- len = "?:??"
- else:
- len = "X:XX"
+ len = ""
res = [ None ]
diff --git a/lib/python/Components/MultiContent.py b/lib/python/Components/MultiContent.py
index 71096df8..ff0219ff 100644
--- a/lib/python/Components/MultiContent.py
+++ b/lib/python/Components/MultiContent.py
@@ -1,5 +1,7 @@
from enigma import eListboxPythonMultiContent, RT_HALIGN_LEFT, RT_VALIGN_TOP
+def MultiContentTemplateColor(n): return 0xff000000 | n
+
def MultiContentEntryText(pos = (0, 0), size = (0, 0), font = 0, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP, text = "", color = None, color_sel = None, backcolor = None, backcolor_sel = None, border_width = None, border_color = None):
return (eListboxPythonMultiContent.TYPE_TEXT, pos[0], pos[1], size[0], size[1], font, flags, text, color, color_sel, backcolor, backcolor_sel, border_width, border_color)
diff --git a/lib/python/Components/NimManager.py b/lib/python/Components/NimManager.py
index f4e91083..4be10d53 100644
--- a/lib/python/Components/NimManager.py
+++ b/lib/python/Components/NimManager.py
@@ -14,8 +14,6 @@ from enigma import eDVBSatelliteEquipmentControl as secClass, \
from time import localtime, mktime
from datetime import datetime
-from sets import Set
-
def getConfigSatlist(orbpos, satlist):
default_orbpos = None
for x in satlist:
@@ -39,7 +37,7 @@ class SecConfigure:
sec.addSatellite(orbpos)
self.configuredSatellites.add(orbpos)
- def addLNBSimple(self, sec, slotid, diseqcmode, toneburstmode = diseqcParam.NO, diseqcpos = diseqcParam.SENDNO, orbpos = 0, longitude = 0, latitude = 0, loDirection = 0, laDirection = 0, turningSpeed = rotorParam.FAST, useInputPower=True, inputPowerDelta=50, fastDiSEqC = False, setVoltageTone = True):
+ def addLNBSimple(self, sec, slotid, diseqcmode, toneburstmode = diseqcParam.NO, diseqcpos = diseqcParam.SENDNO, orbpos = 0, longitude = 0, latitude = 0, loDirection = 0, laDirection = 0, turningSpeed = rotorParam.FAST, useInputPower=True, inputPowerDelta=50, fastDiSEqC = False, setVoltageTone = True, diseqc13V = False):
if orbpos is None or orbpos == 3601:
return
#simple defaults
@@ -51,6 +49,8 @@ class SecConfigure:
elif self.linked.has_key(slotid):
for slot in self.linked[slotid]:
tunermask |= (1 << slot)
+ sec.setLNBSatCR(-1)
+ sec.setLNBNum(1)
sec.setLNBLOFL(9750000)
sec.setLNBLOFH(10600000)
sec.setLNBThreshold(11700000)
@@ -70,7 +70,10 @@ class SecConfigure:
if 0 <= diseqcmode < 3:
self.addSatellite(sec, orbpos)
if setVoltageTone:
- sec.setVoltageMode(switchParam.HV)
+ if diseqc13V:
+ sec.setVoltageMode(switchParam.HV_13)
+ else:
+ sec.setVoltageMode(switchParam.HV)
sec.setToneMode(switchParam.HILO)
else:
sec.setVoltageMode(switchParam._14V)
@@ -90,7 +93,10 @@ class SecConfigure:
for x in self.NimManager.satList:
print "Add sat " + str(x[0])
self.addSatellite(sec, int(x[0]))
- sec.setVoltageMode(switchParam.HV)
+ if diseqc13V:
+ sec.setVoltageMode(switchParam.HV_13)
+ else:
+ sec.setVoltageMode(switchParam.HV)
sec.setToneMode(switchParam.HILO)
sec.setRotorPosNum(0) # USALS
@@ -115,7 +121,7 @@ class SecConfigure:
def update(self):
sec = secClass.getInstance()
- self.configuredSatellites = Set()
+ self.configuredSatellites = set()
sec.clear() ## this do unlinking NIMs too !!
print "sec config cleared"
@@ -172,24 +178,24 @@ class SecConfigure:
print "diseqcmode: ", nim.diseqcMode.value
if nim.diseqcMode.value == "single": #single
if nim.simpleSingleSendDiSEqC.value:
- self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AA)
+ self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AA, diseqc13V = nim.diseqc13V.value)
else:
- self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.NONE, diseqcpos = diseqcParam.SENDNO)
+ self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.NONE, diseqcpos = diseqcParam.SENDNO, diseqc13V = nim.diseqc13V.value)
elif nim.diseqcMode.value == "toneburst_a_b": #Toneburst A/B
- self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.A, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.SENDNO)
- self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcB.orbital_position, toneburstmode = diseqcParam.B, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.SENDNO)
+ self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.A, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.SENDNO, diseqc13V = nim.diseqc13V.value)
+ self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcB.orbital_position, toneburstmode = diseqcParam.B, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.SENDNO, diseqc13V = nim.diseqc13V.value)
elif nim.diseqcMode.value == "diseqc_a_b": #DiSEqC A/B
fastDiSEqC = nim.simpleDiSEqCOnlyOnSatChange.value
setVoltageTone = nim.simpleDiSEqCSetVoltageTone.value
- self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AA, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone)
- self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcB.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AB, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone)
+ self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AA, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone, diseqc13V = nim.diseqc13V.value)
+ self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcB.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AB, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone, diseqc13V = nim.diseqc13V.value)
elif nim.diseqcMode.value == "diseqc_a_b_c_d": #DiSEqC A/B/C/D
fastDiSEqC = nim.simpleDiSEqCOnlyOnSatChange.value
setVoltageTone = nim.simpleDiSEqCSetVoltageTone.value
- self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AA, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone)
- self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcB.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AB, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone)
- self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcC.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.BA, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone)
- self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcD.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.BB, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone)
+ self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcA.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AA, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone, diseqc13V = nim.diseqc13V.value)
+ self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcB.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.AB, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone, diseqc13V = nim.diseqc13V.value)
+ self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcC.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.BA, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone, diseqc13V = nim.diseqc13V.value)
+ self.addLNBSimple(sec, slotid = x, orbpos = nim.diseqcD.orbital_position, toneburstmode = diseqcParam.NO, diseqcmode = diseqcParam.V1_0, diseqcpos = diseqcParam.BB, fastDiSEqC = fastDiSEqC, setVoltageTone = setVoltageTone, diseqc13V = nim.diseqc13V.value)
elif nim.diseqcMode.value == "positioner": #Positioner
if nim.latitudeOrientation.value == "north":
laValue = rotorParam.NORTH
@@ -219,7 +225,8 @@ class SecConfigure:
laDirection = laValue,
turningSpeed = turning_speed,
useInputPower = useInputPower,
- inputPowerDelta = inputPowerDelta)
+ inputPowerDelta = inputPowerDelta,
+ diseqc13V = nim.diseqc13V.value)
elif nim.configMode.value == "advanced": #advanced config
self.updateAdvanced(sec, x)
print "sec config completed"
@@ -248,6 +255,9 @@ class SecConfigure:
currLnb = config.Nims[slotid].advanced.lnb[x]
sec.addLNB()
+ if x < 33:
+ sec.setLNBNum(x)
+
tunermask = 1 << slotid
if self.equal.has_key(slotid):
for slot in self.equal[slotid]:
@@ -256,10 +266,32 @@ class SecConfigure:
for slot in self.linked[slotid]:
tunermask |= (1 << slot)
+ if currLnb.lof.value != "unicable":
+ sec.setLNBSatCR(-1)
+
if currLnb.lof.value == "universal_lnb":
sec.setLNBLOFL(9750000)
sec.setLNBLOFH(10600000)
sec.setLNBThreshold(11700000)
+ elif currLnb.lof.value == "unicable":
+ sec.setLNBLOFL(9750000)
+ sec.setLNBLOFH(10600000)
+ sec.setLNBThreshold(11700000)
+ if currLnb.unicable.value == "unicable_user":
+ sec.setLNBSatCR(currLnb.satcruser.index)
+ sec.setLNBSatCRvco(currLnb.satcrvcouser[currLnb.satcruser.index].value*1000)
+ elif currLnb.unicable.value == "unicable_matrix":
+ manufacturer_name = currLnb.unicableMatrixManufacturer.value
+ manufacturer = currLnb.unicableMatrix[manufacturer_name]
+ product_name = manufacturer.product.value
+ sec.setLNBSatCR(manufacturer.scr[product_name].index)
+ sec.setLNBSatCRvco(manufacturer.vco[product_name][manufacturer.scr[product_name].index].value*1000)
+ elif currLnb.unicable.value == "unicable_lnb":
+ manufacturer_name = currLnb.unicableMatrixManufacturer.value
+ manufacturer = currLnb.unicableMatrix[manufacturer_name]
+ product_name = manufacturer.product.value
+ sec.setLNBSatCR(manufacturer.scr[product_name].index)
+ sec.setLNBSatCRvco(manufacturer.vco[product_name][manufacturer.scr[product_name].index].value*1000)
elif currLnb.lof.value == "c_band":
sec.setLNBLOFL(5150000)
sec.setLNBLOFH(5150000)
@@ -374,6 +406,8 @@ class SecConfigure:
sec.setLNBSlotMask(tunermask)
+ sec.setLNBPrio(int(currLnb.prio.value))
+
# finally add the orbital positions
for y in lnbSat[x]:
self.addSatellite(sec, y)
@@ -383,7 +417,10 @@ class SecConfigure:
satpos = y
currSat = config.Nims[slotid].advanced.sat[satpos]
if currSat.voltage.value == "polarization":
- sec.setVoltageMode(switchParam.HV)
+ if config.Nims[slotid].diseqc13V.value:
+ sec.setVoltageMode(switchParam.HV_13)
+ else:
+ sec.setVoltageMode(switchParam.HV)
elif currSat.voltage.value == "13V":
sec.setVoltageMode(switchParam._14V)
elif currSat.voltage.value == "18V":
@@ -403,7 +440,7 @@ class SecConfigure:
def __init__(self, nimmgr):
self.NimManager = nimmgr
- self.configuredSatellites = Set()
+ self.configuredSatellites = set()
self.update()
class NIM(object):
@@ -880,61 +917,197 @@ def InitNimManager(nimmgr):
for x in range(len(nimmgr.nim_slots)):
config.Nims.append(ConfigSubsection())
+ lnb_choices = {
+ "universal_lnb": _("Universal LNB"),
+ "unicable": _("Unicable"),
+ "c_band": _("C-Band"),
+ "user_defined": _("User defined")}
+ lnb_choices_default = "universal_lnb"
+
+ unicablelnbproducts = {
+ "Humax": {"150 SCR":["1210","1420","1680","2040"]},
+ "Inverto": {"IDLP-40UNIQD+S":["1680","1420","2040","1210"]},
+ "Kathrein": {"UAS481":["1400","1516","1632","1748"]},
+ "Kreiling": {"KR1440":["1680","1420","2040","1210"]},
+ "Radix": {"Unicable LNB":["1680","1420","2040","1210"]},
+ "Wisi": {"OC 05":["1210","1420","1680","2040"]}}
+ UnicableLnbManufacturers = unicablelnbproducts.keys()
+ UnicableLnbManufacturers.sort()
+
+ unicablematrixproducts = {
+ "Ankaro": {
+ "UCS 51440":["1400","1632","1284","1516"],
+ "UCS 51820":["1400","1632","1284","1516","1864","2096","1748","1980"],
+ "UCS 51840":["1400","1632","1284","1516","1864","2096","1748","1980"],
+ "UCS 52240":["1400","1632"],
+ "UCS 52420":["1400","1632","1284","1516"],
+ "UCS 52440":["1400","1632","1284","1516"],
+ "UCS 91440":["1400","1632","1284","1516"],
+ "UCS 91820":["1400","1632","1284","1516","1864","2096","1748","1980"],
+ "UCS 91840":["1400","1632","1284","1516","1864","2096","1748","1980"],
+ "UCS 92240":["1400","1632"],
+ "UCS 92420":["1400","1632","1284","1516"],
+ "UCS 92440":["1400","1632","1284","1516"]},
+ "DCT Delta": {
+ "SUM518":["1284","1400","1516","1632","1748","1864","1980","2096"],
+ "SUM918":["1284","1400","1516","1632","1748","1864","1980","2096"],
+ "SUM928":["1284","1400","1516","1632","1748","1864","1980","2096"]},
+ "Inverto": {
+ "IDLP-UST11O-CUO1O-8PP":["1076","1178","1280","1382","1484","1586","1688","1790"]},
+ "Kathrein": {
+ "EXR501":["1400","1516","1632","1748"],
+ "EXR551":["1400","1516","1632","1748"],
+ "EXR552":["1400","1516"]},
+ "ROTEK": {
+ "EKL2/1":["1400","1516"],
+ "EKL2/1E":["0","0","1632","1748"]},
+ "Smart": {
+ "DPA 51":["1284","1400","1516","1632","1748","1864","1980","2096"]},
+ "Technisat": {
+ "TechniRouter 5/1x8 G":["1284","1400","1516","1632","1748","1864","1980","2096"],
+ "TechniRouter 5/1x8 K":["1284","1400","1516","1632","1748","1864","1980","2096"],
+ "TechniRouter 5/2x4 G":["1284","1400","1516","1632"],
+ "TechniRouter 5/2x4 K":["1284","1400","1516","1632"]},
+ "Telstar": {
+ "SCR 5/1x8 G":["1284","1400","1516","1632","1748","1864","1980","2096"],
+ "SCR 5/1x8 K":["1284","1400","1516","1632","1748","1864","1980","2096"],
+ "SCR 5/2x4 G":["1284","1400","1516","1632"],
+ "SCR 5/2x4 K":["1284","1400","1516","1632"]}}
+ UnicableMatrixManufacturers = unicablematrixproducts.keys()
+ UnicableMatrixManufacturers.sort()
+
+ unicable_choices = {
+ "unicable_lnb": _("Unicable LNB"),
+ "unicable_matrix": _("Unicable Martix"),
+ "unicable_user": "Unicable "+_("User defined")}
+ unicable_choices_default = "unicable_lnb"
+
+ unicableLnb = ConfigSubDict()
+ for y in unicablelnbproducts:
+ products = unicablelnbproducts[y].keys()
+ products.sort()
+ unicableLnb[y] = ConfigSubsection()
+ unicableLnb[y].product = ConfigSelection(choices = products, default = products[0])
+ unicableLnb[y].scr = ConfigSubDict()
+ unicableLnb[y].vco = ConfigSubDict()
+ for z in products:
+ scrlist = []
+ vcolist = unicablelnbproducts[y][z]
+ unicableLnb[y].vco[z] = ConfigSubList()
+ for cnt in range(1,1+len(vcolist)):
+ scrlist.append(("%d" %cnt,"SCR %d" %cnt))
+ vcofreq = int(vcolist[cnt-1])
+ unicableLnb[y].vco[z].append(ConfigInteger(default=vcofreq, limits = (vcofreq, vcofreq)))
+ unicableLnb[y].scr[z] = ConfigSelection(choices = scrlist, default = scrlist[0][0])
+
+ unicableMatrix = ConfigSubDict()
+
+ for y in unicablematrixproducts:
+ products = unicablematrixproducts[y].keys()
+ products.sort()
+ unicableMatrix[y] = ConfigSubsection()
+ unicableMatrix[y].product = ConfigSelection(choices = products, default = products[0])
+ unicableMatrix[y].scr = ConfigSubDict()
+ unicableMatrix[y].vco = ConfigSubDict()
+ for z in products:
+ scrlist = []
+ vcolist = unicablematrixproducts[y][z]
+ unicableMatrix[y].vco[z] = ConfigSubList()
+ for cnt in range(1,1+len(vcolist)):
+ vcofreq = int(vcolist[cnt-1])
+ if vcofreq == 0:
+ scrlist.append(("%d" %cnt,"SCR %d " %cnt +_("not used")))
+ else:
+ scrlist.append(("%d" %cnt,"SCR %d" %cnt))
+ unicableMatrix[y].vco[z].append(ConfigInteger(default=vcofreq, limits = (vcofreq, vcofreq)))
+ unicableMatrix[y].scr[z] = ConfigSelection(choices = scrlist, default = scrlist[0][0])
+
+ advanced_lnb_satcruser_choices = [ ("1", "SatCR 1"), ("2", "SatCR 2"), ("3", "SatCR 3"), ("4", "SatCR 4"),
+ ("5", "SatCR 5"), ("6", "SatCR 6"), ("7", "SatCR 7"), ("8", "SatCR 8")]
+
+ satcrvcouser = ConfigSubList()
+ satcrvcouser.append(ConfigInteger(default=1284, limits = (0, 9999)))
+ satcrvcouser.append(ConfigInteger(default=1400, limits = (0, 9999)))
+ satcrvcouser.append(ConfigInteger(default=1516, limits = (0, 9999)))
+ satcrvcouser.append(ConfigInteger(default=1632, limits = (0, 9999)))
+ satcrvcouser.append(ConfigInteger(default=1748, limits = (0, 9999)))
+ satcrvcouser.append(ConfigInteger(default=1864, limits = (0, 9999)))
+ satcrvcouser.append(ConfigInteger(default=1980, limits = (0, 9999)))
+ satcrvcouser.append(ConfigInteger(default=2096, limits = (0, 9999)))
+
+ prio_list = [ ("-1", _("Auto")) ]
+ prio_list += [(str(prio), str(prio)) for prio in range(65)+range(14000,14065)+range(19000,19065)]
+
+ advanced_lnb_csw_choices = [("none", _("None")), ("AA", _("AA")), ("AB", _("AB")), ("BA", _("BA")), ("BB", _("BB"))]
+ advanced_lnb_csw_choices += [(str(0xF0|y), "Input " + str(y+1)) for y in range(0, 16)]
+
+ advanced_lnb_ucsw_choices = [("0", _("None"))] + [(str(y), "Input " + str(y)) for y in range(1, 17)]
+
+ diseqc_mode_choices = [
+ ("single", _("Single")), ("toneburst_a_b", _("Toneburst A/B")),
+ ("diseqc_a_b", _("DiSEqC A/B")), ("diseqc_a_b_c_d", _("DiSEqC A/B/C/D")),
+ ("positioner", _("Positioner"))]
+
+ positioner_mode_choices = [("usals", _("USALS")), ("manual", _("manual"))]
+
+ diseqc_satlist_choices = [(3601, _('nothing connected'), 1)] + nimmgr.satList
+
+ longitude_orientation_choices = [("east", _("East")), ("west", _("West"))]
+ latitude_orientation_choices = [("north", _("North")), ("south", _("South"))]
+ turning_speed_choices = [("fast", _("Fast")), ("slow", _("Slow")), ("fast epoch", _("Fast epoch"))]
+
+ advanced_satlist_choices = nimmgr.satList + [
+ (3601, _('All Satellites')+' 1', 1), (3602, _('All Satellites')+' 2', 1),
+ (3603, _('All Satellites')+' 3', 1), (3604, _('All Satellites')+' 4', 1)]
+ advanced_lnb_choices = [("0", "not available")] + [(str(y), "LNB " + str(y)) for y in range(1, 33)]
+ advanced_voltage_choices = [("polarization", _("Polarization")), ("13V", _("13 V")), ("18V", _("18 V"))]
+ advanced_tonemode_choices = [("band", _("Band")), ("on", _("On")), ("off", _("Off"))]
+ advanced_lnb_toneburst_choices = [("none", _("None")), ("A", _("A")), ("B", _("B"))]
+ advanced_lnb_allsat_diseqcmode_choices = [("1_2", _("1.2"))]
+ advanced_lnb_diseqcmode_choices = [("none", _("None")), ("1_0", _("1.0")), ("1_1", _("1.1")), ("1_2", _("1.2"))]
+ advanced_lnb_commandOrder1_0_choices = [("ct", "committed, toneburst"), ("tc", "toneburst, committed")]
+ advanced_lnb_commandOrder_choices = [
+ ("ct", "committed, toneburst"), ("tc", "toneburst, committed"),
+ ("cut", "committed, uncommitted, toneburst"), ("tcu", "toneburst, committed, uncommitted"),
+ ("uct", "uncommitted, committed, toneburst"), ("tuc", "toneburst, uncommitted, commmitted")]
+ advanced_lnb_diseqc_repeat_choices = [("none", _("None")), ("one", _("One")), ("two", _("Two")), ("three", _("Three"))]
+ advanced_lnb_fast_turning_btime = mktime(datetime(1970, 1, 1, 7, 0).timetuple());
+ advanced_lnb_fast_turning_etime = mktime(datetime(1970, 1, 1, 19, 0).timetuple());
for slot in nimmgr.nim_slots:
x = slot.slot
nim = config.Nims[x]
if slot.isCompatible("DVB-S"):
- choices = { "nothing": _("nothing connected"),
- "simple": _("simple"),
- "advanced": _("advanced")}
+ config_mode_choices = [ ("nothing", _("nothing connected")),
+ ("simple", _("simple")), ("advanced", _("advanced"))]
if len(nimmgr.getNimListOfType(slot.type, exception = x)) > 0:
- choices["equal"] = _("equal to")
- choices["satposdepends"] = _("second cable of motorized LNB")
+ config_mode_choices.append(("equal", _("equal to")))
+ config_mode_choices.append(("satposdepends", _("second cable of motorized LNB")))
if len(nimmgr.canConnectTo(x)) > 0:
- choices["loopthrough"] = _("loopthrough to")
- nim.configMode = ConfigSelection(choices = choices, default = "nothing")
-
-# for y in nimmgr.nim_slots:
-# if y.slot == 0:
-# if not y.isCompatible("DVB-S"):
-# # reset to simple
-# nim.configMode.value = "simple"
-# nim.configMode.save()
-
- nim.diseqcMode = ConfigSelection(
- choices = [
- ("single", _("Single")),
- ("toneburst_a_b", _("Toneburst A/B")),
- ("diseqc_a_b", _("DiSEqC A/B")),
- ("diseqc_a_b_c_d", _("DiSEqC A/B/C/D")),
- ("positioner", _("Positioner"))],
- default = "diseqc_a_b")
-
- choices = []
- for id in nimmgr.getNimListOfType("DVB-S"):
- if id != x:
- choices.append((str(id), nimmgr.getNimDescription(id)))
- nim.connectedTo = ConfigSelection(choices = choices)
- nim.simpleSingleSendDiSEqC = ConfigYesNo(default=False)
- nim.simpleDiSEqCSetVoltageTone = ConfigYesNo(default=True)
- nim.simpleDiSEqCOnlyOnSatChange = ConfigYesNo(default=False)
- nim.diseqcA = getConfigSatlist(192, [(3601, _('nothing connected'), 1)] + nimmgr.satList)
- nim.diseqcB = getConfigSatlist(130, [(3601, _('nothing connected'), 1)] + nimmgr.satList)
- nim.diseqcC = ConfigSatlist(list = [(3601, _('nothing connected'), 1)] + nimmgr.satList)
- nim.diseqcD = ConfigSatlist(list = [(3601, _('nothing connected'), 1)] + nimmgr.satList)
- nim.positionerMode = ConfigSelection(
- choices = [
- ("usals", _("USALS")),
- ("manual", _("manual"))],
- default = "usals")
+ config_mode_choices.append(("loopthrough", _("loopthrough to")))
+ nim.configMode = ConfigSelection(config_mode_choices, "nothing")
+
+ nim.diseqc13V = ConfigYesNo(False)
+
+ nim.diseqcMode = ConfigSelection(diseqc_mode_choices, "diseqc_a_b")
+
+ nim.connectedTo = ConfigSelection([(str(id), nimmgr.getNimDescription(id)) for id in nimmgr.getNimListOfType("DVB-S") if id != x])
+
+ nim.simpleSingleSendDiSEqC = ConfigYesNo(False)
+ nim.simpleDiSEqCSetVoltageTone = ConfigYesNo(True)
+ nim.simpleDiSEqCOnlyOnSatChange = ConfigYesNo(False)
+ nim.diseqcA = getConfigSatlist(192, diseqc_satlist_choices)
+ nim.diseqcB = getConfigSatlist(130, diseqc_satlist_choices)
+ nim.diseqcC = ConfigSatlist(list = diseqc_satlist_choices)
+ nim.diseqcD = ConfigSatlist(list = diseqc_satlist_choices)
+ nim.positionerMode = ConfigSelection(positioner_mode_choices, "usals")
nim.longitude = ConfigFloat(default=[5,100], limits=[(0,359),(0,999)])
- nim.longitudeOrientation = ConfigSelection(choices={"east": _("East"), "west": _("West")}, default = "east")
+ nim.longitudeOrientation = ConfigSelection(longitude_orientation_choices, "east")
nim.latitude = ConfigFloat(default=[50,767], limits=[(0,359),(0,999)])
- nim.latitudeOrientation = ConfigSelection(choices={"north": _("North"), "south": _("South")}, default="north")
- nim.powerMeasurement = ConfigYesNo(default=True)
+ nim.latitudeOrientation = ConfigSelection(latitude_orientation_choices, "north")
+ nim.powerMeasurement = ConfigYesNo(True)
nim.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm8000" and 15 or 50, limits=(0, 100))
- nim.turningSpeed = ConfigSelection(choices = [("fast", _("Fast")), ("slow", _("Slow")), ("fast epoch", _("Fast epoch")) ], default = "fast")
+ nim.turningSpeed = ConfigSelection(turning_speed_choices, "fast")
btime = datetime(1970, 1, 1, 7, 0);
nim.fastTurningBegin = ConfigDateTime(default = mktime(btime.timetuple()), formatstring = _("%H:%M"), increment = 900)
etime = datetime(1970, 1, 1, 19, 0);
@@ -942,78 +1115,72 @@ def InitNimManager(nimmgr):
# advanced config:
nim.advanced = ConfigSubsection()
- tmp = [(3601, _('All Satellites')+' 1', 1), (3602, _('All Satellites')+' 2', 1), (3603, _('All Satellites')+' 3', 1), (3604, _('All Satellites')+' 4', 1)]
- nim.advanced.sats = getConfigSatlist(192,nimmgr.satList+tmp)
+ nim.advanced.sats = getConfigSatlist(192, advanced_satlist_choices)
nim.advanced.sat = ConfigSubDict()
- lnbs = [("0", "not available")]
- for y in range(1, 33):
- lnbs.append((str(y), "LNB " + str(y)))
for x in nimmgr.satList:
nim.advanced.sat[x[0]] = ConfigSubsection()
- nim.advanced.sat[x[0]].voltage = ConfigSelection(choices={"polarization": _("Polarization"), "13V": _("13 V"), "18V": _("18 V")}, default = "polarization")
- nim.advanced.sat[x[0]].tonemode = ConfigSelection(choices={"band": _("Band"), "on": _("On"), "off": _("Off")}, default = "band")
- nim.advanced.sat[x[0]].usals = ConfigYesNo(default=True)
+ nim.advanced.sat[x[0]].voltage = ConfigSelection(advanced_voltage_choices, "polarization")
+ nim.advanced.sat[x[0]].tonemode = ConfigSelection(advanced_tonemode_choices, "band")
+ nim.advanced.sat[x[0]].usals = ConfigYesNo(True)
nim.advanced.sat[x[0]].rotorposition = ConfigInteger(default=1, limits=(1, 255))
- nim.advanced.sat[x[0]].lnb = ConfigSelection(choices = lnbs)
+ nim.advanced.sat[x[0]].lnb = ConfigSelection(advanced_lnb_choices, "0")
for x in range(3601, 3605):
nim.advanced.sat[x] = ConfigSubsection()
- nim.advanced.sat[x].voltage = ConfigSelection(choices={"polarization": _("Polarization"), "13V": _("13 V"), "18V": _("18 V")}, default = "polarization")
- nim.advanced.sat[x].tonemode = ConfigSelection(choices={"band": _("Band"), "on": _("On"), "off": _("Off")}, default = "band")
+ nim.advanced.sat[x].voltage = ConfigSelection(advanced_voltage_choices, "polarization")
+ nim.advanced.sat[x].tonemode = ConfigSelection(advanced_tonemode_choices, "band")
nim.advanced.sat[x].usals = ConfigYesNo(default=True)
nim.advanced.sat[x].rotorposition = ConfigInteger(default=1, limits=(1, 255))
lnbnum = 33+x-3601
- nim.advanced.sat[x].lnb = ConfigSelection(choices = [("0", "not available"), (str(lnbnum), "LNB %d"%(lnbnum))], default="0")
-
- csw = [("none", _("None")), ("AA", _("AA")), ("AB", _("AB")), ("BA", _("BA")), ("BB", _("BB"))]
- for y in range(0, 16):
- csw.append((str(0xF0|y), "Input " + str(y+1)))
-
- ucsw = [("0", _("None"))]
- for y in range(1, 17):
- ucsw.append((str(y), "Input " + str(y)))
+ nim.advanced.sat[x].lnb = ConfigSelection([("0", "not available"), (str(lnbnum), "LNB %d"%(lnbnum))], "0")
nim.advanced.lnb = ConfigSubList()
nim.advanced.lnb.append(ConfigNothing())
+
for x in range(1, 37):
nim.advanced.lnb.append(ConfigSubsection())
- nim.advanced.lnb[x].lof = ConfigSelection(choices={"universal_lnb": _("Universal LNB"), "c_band": _("C-Band"), "user_defined": _("User defined")}, default="universal_lnb")
+ nim.advanced.lnb[x].lof = ConfigSelection(lnb_choices, lnb_choices_default)
+
nim.advanced.lnb[x].lofl = ConfigInteger(default=9750, limits = (0, 99999))
nim.advanced.lnb[x].lofh = ConfigInteger(default=10600, limits = (0, 99999))
nim.advanced.lnb[x].threshold = ConfigInteger(default=11700, limits = (0, 99999))
+
+ nim.advanced.lnb[x].unicable = ConfigSelection(unicable_choices, unicable_choices_default)
+
+ nim.advanced.lnb[x].unicableLnb = unicableLnb # is this okay? all lnb use the same ConfigSubDict ? ! ?
+ nim.advanced.lnb[x].unicableLnbManufacturer = ConfigSelection(UnicableLnbManufacturers, UnicableLnbManufacturers[0])
+
+ nim.advanced.lnb[x].unicableMatrix = unicableMatrix # is this okay? all lnb use the same ConfigSubDict ? ! ?
+ nim.advanced.lnb[x].unicableMatrixManufacturer = ConfigSelection(UnicableMatrixManufacturers, UnicableMatrixManufacturers[0])
+
+ nim.advanced.lnb[x].satcruser = ConfigSelection(advanced_lnb_satcruser_choices, "1")
+ nim.advanced.lnb[x].satcrvcouser = satcrvcouser # is this okay? all lnb use the same ConfigSubDict ? ! ?
+
# nim.advanced.lnb[x].output_12v = ConfigSelection(choices = [("0V", _("0 V")), ("12V", _("12 V"))], default="0V")
- nim.advanced.lnb[x].increased_voltage = ConfigYesNo(default=False)
- nim.advanced.lnb[x].toneburst = ConfigSelection(choices = [("none", _("None")), ("A", _("A")), ("B", _("B"))], default = "none")
+ nim.advanced.lnb[x].increased_voltage = ConfigYesNo(False)
+ nim.advanced.lnb[x].toneburst = ConfigSelection(advanced_lnb_toneburst_choices, "none")
if x > 32:
- nim.advanced.lnb[x].diseqcMode = ConfigSelection(choices = [("1_2", _("1.2"))], default = "1_2")
+ nim.advanced.lnb[x].diseqcMode = ConfigSelection(advanced_lnb_allsat_diseqcmode_choices, "1_2")
else:
- nim.advanced.lnb[x].diseqcMode = ConfigSelection(choices = [("none", _("None")), ("1_0", _("1.0")), ("1_1", _("1.1")), ("1_2", _("1.2"))], default = "none")
- nim.advanced.lnb[x].commitedDiseqcCommand = ConfigSelection(choices = csw)
- nim.advanced.lnb[x].fastDiseqc = ConfigYesNo(default=False)
- nim.advanced.lnb[x].sequenceRepeat = ConfigYesNo(default=False)
- nim.advanced.lnb[x].commandOrder1_0 = ConfigSelection(choices = [("ct", "committed, toneburst"), ("tc", "toneburst, committed")], default = "ct")
- nim.advanced.lnb[x].commandOrder = ConfigSelection(choices = [
- ("ct", "committed, toneburst"),
- ("tc", "toneburst, committed"),
- ("cut", "committed, uncommitted, toneburst"),
- ("tcu", "toneburst, committed, uncommitted"),
- ("uct", "uncommitted, committed, toneburst"),
- ("tuc", "toneburst, uncommitted, commmitted")],
- default="ct")
- nim.advanced.lnb[x].uncommittedDiseqcCommand = ConfigSelection(choices = ucsw)
- nim.advanced.lnb[x].diseqcRepeats = ConfigSelection(choices = [("none", _("None")), ("one", _("One")), ("two", _("Two")), ("three", _("Three"))], default = "none")
+ nim.advanced.lnb[x].diseqcMode = ConfigSelection(advanced_lnb_diseqcmode_choices, "none")
+ nim.advanced.lnb[x].commitedDiseqcCommand = ConfigSelection(advanced_lnb_csw_choices)
+ nim.advanced.lnb[x].fastDiseqc = ConfigYesNo(False)
+ nim.advanced.lnb[x].sequenceRepeat = ConfigYesNo(False)
+ nim.advanced.lnb[x].commandOrder1_0 = ConfigSelection(advanced_lnb_commandOrder1_0_choices, "ct")
+ nim.advanced.lnb[x].commandOrder = ConfigSelection(advanced_lnb_commandOrder_choices, "ct")
+ nim.advanced.lnb[x].uncommittedDiseqcCommand = ConfigSelection(advanced_lnb_ucsw_choices)
+ nim.advanced.lnb[x].diseqcRepeats = ConfigSelection(advanced_lnb_diseqc_repeat_choices, "none")
nim.advanced.lnb[x].longitude = ConfigFloat(default = [5,100], limits = [(0,359),(0,999)])
- nim.advanced.lnb[x].longitudeOrientation = ConfigSelection(choices = [("east", _("East")), ("west", _("West"))], default = "east")
+ nim.advanced.lnb[x].longitudeOrientation = ConfigSelection(longitude_orientation_choices, "east")
nim.advanced.lnb[x].latitude = ConfigFloat(default = [50,767], limits = [(0,359),(0,999)])
- nim.advanced.lnb[x].latitudeOrientation = ConfigSelection(choices = [("north", _("North")), ("south", _("South"))], default = "north")
+ nim.advanced.lnb[x].latitudeOrientation = ConfigSelection(latitude_orientation_choices, "north")
nim.advanced.lnb[x].powerMeasurement = ConfigYesNo(default=True)
nim.advanced.lnb[x].powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm8000" and 15 or 50, limits=(0, 100))
- nim.advanced.lnb[x].turningSpeed = ConfigSelection(choices = [("fast", _("Fast")), ("slow", _("Slow")), ("fast epoch", _("Fast epoch"))], default = "fast")
- btime = datetime(1970, 1, 1, 7, 0);
- nim.advanced.lnb[x].fastTurningBegin = ConfigDateTime(default=mktime(btime.timetuple()), formatstring = _("%H:%M"), increment = 600)
- etime = datetime(1970, 1, 1, 19, 0);
- nim.advanced.lnb[x].fastTurningEnd = ConfigDateTime(default=mktime(etime.timetuple()), formatstring = _("%H:%M"), increment = 600)
+ nim.advanced.lnb[x].turningSpeed = ConfigSelection(turning_speed_choices, "fast")
+ nim.advanced.lnb[x].fastTurningBegin = ConfigDateTime(default=advanced_lnb_fast_turning_btime, formatstring = _("%H:%M"), increment = 600)
+ nim.advanced.lnb[x].fastTurningEnd = ConfigDateTime(default=advanced_lnb_fast_turning_etime, formatstring = _("%H:%M"), increment = 600)
+ nim.advanced.lnb[x].prio = ConfigSelection(prio_list, "-1")
elif slot.isCompatible("DVB-C"):
nim.configMode = ConfigSelection(
choices = {
diff --git a/lib/python/Components/Renderer/Canvas.py b/lib/python/Components/Renderer/Canvas.py
index bd7ffb5e..acf0dbf7 100644
--- a/lib/python/Components/Renderer/Canvas.py
+++ b/lib/python/Components/Renderer/Canvas.py
@@ -35,7 +35,7 @@ class Canvas(Renderer):
self.instance.writeText(eRect(l[1], l[2], l[3], l[4]), gRGB(l[5]), gRGB(l[6]), l[7], l[8], l[9])
else:
print "drawlist entry:", l
- raise "invalid drawlist entry"
+ raise RuntimeError("invalid drawlist entry")
def changed(self, what):
self.pull_updates()
diff --git a/lib/python/Components/ResourceManager.py b/lib/python/Components/ResourceManager.py
new file mode 100644
index 00000000..fb6be4a8
--- /dev/null
+++ b/lib/python/Components/ResourceManager.py
@@ -0,0 +1,23 @@
+class ResourceManager:
+ def __init__(self):
+ self.resourceList = {}
+
+ def addResource(self, name, resource):
+ print "adding Resource", name
+ self.resourceList[name] = resource
+ print "resources:", self.resourceList
+
+
+ def getResource(self, name):
+ if not self.hasResource(name):
+ return None
+ return self.resourceList[name]
+
+ def hasResource(self, name):
+ return self.resourceList.has_key(name)
+
+ def removeResource(self, name):
+ if self.hasResource(name):
+ del self.resourceList[name]
+
+resourcemanager = ResourceManager() \ No newline at end of file
diff --git a/lib/python/Components/Scanner.py b/lib/python/Components/Scanner.py
index 766d1966..86a5431d 100644
--- a/lib/python/Components/Scanner.py
+++ b/lib/python/Components/Scanner.py
@@ -135,7 +135,7 @@ def scanDevice(mountpoint):
from Components.Harddisk import harddiskmanager
blockdev = mountpoint.rstrip("/").rsplit('/',1)[-1]
- error, blacklisted, removable, is_cdrom, partitions = harddiskmanager.getBlockDevInfo(blockdev)
+ error, blacklisted, removable, is_cdrom, partitions, medium_found = harddiskmanager.getBlockDevInfo(blockdev)
# now scan the paths
for p in paths_to_scan:
diff --git a/lib/python/Components/ServiceScan.py b/lib/python/Components/ServiceScan.py
index 5a7b3dea..78cd758e 100644
--- a/lib/python/Components/ServiceScan.py
+++ b/lib/python/Components/ServiceScan.py
@@ -36,54 +36,58 @@ class ServiceScan:
tp_text = ""
if transponder:
tp_type = transponder.getSystem()
- if not tp_type[0]:
- tp_type = tp_type[1]
- if tp_type == iDVBFrontend.feSatellite:
- network = _("Satellite")
- tp = transponder.getDVBS()
- if not tp[0]:
- tp = tp[1]
- orb_pos = tp.orbital_position
- try:
- sat_name = str(nimmgr.getSatDescription(orb_pos))
- except KeyError:
- sat_name = ""
- if orb_pos > 1800: # west
- orb_pos = 3600 - orb_pos
- h = _("W")
- else:
- h = _("E")
- if sat_name.find("%d.%d" % (orb_pos/10, orb_pos%10)) != -1:
- network = sat_name
- else:
- network = ("%s %d.%d %s") % (sat_name, orb_pos / 10, orb_pos % 10, h)
- tp_text = ("%s %s %d%c / %d / %s") %( { 0 : "DVB-S", 1 : "DVB-S2" }[tp.system],
- { 0 : "Auto", 1 : "QPSK", 2 : "M8PSK", 3 : "QAM16" }[tp.modulation],
- tp.frequency/1000,
- { 0 : 'H', 1 : 'V', 2 : 'L', 3 : 'R' }[tp.polarisation],
- tp.symbol_rate/1000,
- { 0 : "AUTO", 1 : "1/2", 2 : "2/3", 3 : "3/4", 4 : "5/6",
- 5 : "7/8", 6 : "8/9", 7 : "3/5", 8 : "4/5", 9 : "9/10",
- 15 : "NONE" }[tp.fec] )
- elif tp_type == iDVBFrontend.feCable:
- network = _("Cable")
- tp = transponder.getDVBC()
- if not tp[0]:
- tp = tp[1]
- tp_text = ("DVB-C %s %d / %d / %s") %( { 0 : "AUTO", 1 : "QAM16", 2 : "QAM32", 3 : "QAM64", 4 : "QAM128", 5 : "QAM256" }[tp.modulation],
- tp.frequency,
- tp.symbol_rate/1000,
- { 0 : "AUTO", 1 : "1/2", 2 : "2/3", 3 : "3/4", 4 : "5/6", 5 : "7/8", 6 : "8/9", 15 : "NONE" }[tp.fec_inner] )
- elif tp_type == iDVBFrontend.feTerrestrial:
- network = _("Terrestrial")
- tp = transponder.getDVBT()
- if not tp[0]:
- tp = tp[1]
- tp_text = ("DVB-T %s %d %s") %( { 0 : "QPSK", 1 : "QAM16", 2 : "QAM64", 3 : "AUTO"}[tp.modulation],
- tp.frequency,
- { 0 : "Bw 8MHz", 1 : "Bw 7MHz", 2 : "Bw 6MHz", 3 : "Bw Auto" }[tp.bandwidth])
+ if tp_type == iDVBFrontend.feSatellite:
+ network = _("Satellite")
+ tp = transponder.getDVBS()
+ orb_pos = tp.orbital_position
+ try:
+ sat_name = str(nimmgr.getSatDescription(orb_pos))
+ except KeyError:
+ sat_name = ""
+ if orb_pos > 1800: # west
+ orb_pos = 3600 - orb_pos
+ h = _("W")
else:
- print "unknown transponder type in scanStatusChanged"
+ h = _("E")
+ if sat_name.find("%d.%d" % (orb_pos/10, orb_pos%10)) != -1:
+ network = sat_name
+ else:
+ network = ("%s %d.%d %s") % (sat_name, orb_pos / 10, orb_pos % 10, h)
+ tp_text = ("%s %s %d%c / %d / %s") %( { tp.System_DVB_S : "DVB-S",
+ tp.System_DVB_S2 : "DVB-S2" }.get(tp.system, tp.System_DVB_S),
+ { tp.Modulation_Auto : "Auto", tp.Modulation_QPSK : "QPSK",
+ tp.Modulation_8PSK : "8PSK", tp.Modulation_QAM16 : "QAM16" }.get(tp.modulation, tp.Modulation_QPSK),
+ tp.frequency/1000,
+ { tp.Polarisation_Horizontal : 'H', tp.Polarisation_Vertical : 'V', tp.Polarisation_CircularLeft : 'L',
+ tp.Polarisation_CircularRight : 'R' }.get(tp.polarisation, tp.Polarisation_Horizontal),
+ tp.symbol_rate/1000,
+ { tp.FEC_Auto : "AUTO", tp.FEC_1_2 : "1/2", tp.FEC_2_3 : "2/3",
+ tp.FEC_3_4 : "3/4", tp.FEC_5_6 : "5/6", tp.FEC_7_8 : "7/8",
+ tp.FEC_8_9 : "8/9", tp.FEC_3_5 : "3/5", tp.FEC_4_5 : "4/5",
+ tp.FEC_9_10 : "9/10", tp.FEC_None : "NONE" }.get(tp.fec, tp.FEC_Auto))
+ elif tp_type == iDVBFrontend.feCable:
+ network = _("Cable")
+ tp = transponder.getDVBC()
+ tp_text = ("DVB-C %s %d / %d / %s") %( { tp.Modulation_Auto : "AUTO",
+ tp.Modulation_QAM16 : "QAM16", tp.Modulation_QAM32 : "QAM32",
+ tp.Modulation_QAM64 : "QAM64", tp.Modulation_QAM128 : "QAM128",
+ tp.Modulation_QAM256 : "QAM256" }.get(tp.modulation, tp.Modulation_Auto),
+ tp.frequency,
+ tp.symbol_rate/1000,
+ { tp.FEC_Auto : "AUTO", tp.FEC_1_2 : "1/2", tp.FEC_2_3 : "2/3",
+ tp.FEC_3_4 : "3/4", tp.FEC_5_6 : "5/6", tp.FEC_7_8 : "7/8",
+ tp.FEC_8_9 : "8/9", tp.FEC_None : "NONE" }.get(tp.fec_inner, tp.FEC_Auto))
+ elif tp_type == iDVBFrontend.feTerrestrial:
+ network = _("Terrestrial")
+ tp = transponder.getDVBT()
+ tp_text = ("DVB-T %s %d %s") %( { tp.Modulation_QPSK : "QPSK",
+ tp.Modulation_QAM16 : "QAM16", tp.Modulation_QAM64 : "QAM64",
+ tp.Modulation_Auto : "AUTO" }.get(tp.modulation, tp.Modulation_Auto),
+ tp.frequency,
+ { tp.Bandwidth_8MHz : "Bw 8MHz", tp.Bandwidth_7MHz : "Bw 7MHz", tp.Bandwidth_6MHz : "Bw 6MHz",
+ tp.Bandwidth_Auto : "Bw Auto" }.get(tp.bandwidth, tp.Bandwidth_Auto))
+ else:
+ print "unknown transponder type in scanStatusChanged"
self.network.setText(network)
self.transponder.setText(tp_text)
diff --git a/lib/python/Components/Sources/List.py b/lib/python/Components/Sources/List.py
index ef9c1c89..23b53957 100644
--- a/lib/python/Components/Sources/List.py
+++ b/lib/python/Components/Sources/List.py
@@ -17,6 +17,7 @@ to generate HTML."""
self.fonts = fonts
self.disable_callbacks = False
self.enableWrapAround = enableWrapAround
+ self.__style = "default" # style might be an optional string which can be used to define different visualisations in the skin
def setList(self, list):
self.__list = list
@@ -27,7 +28,11 @@ to generate HTML."""
def entry_changed(self, index):
if not self.disable_callbacks:
self.downstream_elements.entry_changed(self, index)
-
+
+ def modifyEntry(self, index, data):
+ self.__list[index] = data
+ self.entry_changed(index)
+
def count(self):
return len(self.__list)
@@ -76,17 +81,21 @@ to generate HTML."""
self.index -= 1
self.setIndex(self.index)
+ @cached
+ def getStyle(self):
+ return self.__style
+
+ def setStyle(self, style):
+ self.__style = style
+ self.changed((self.CHANGED_SPECIFIC, "style"))
+
+ style = property(getStyle, setStyle)
+
def updateList(self, list):
"""Changes the list without changing the selection or emitting changed Events"""
assert len(list) == len(self.__list)
- print "get old index"
old_index = self.index
- print "disable callback"
self.disable_callbacks = True
- print "set list"
self.list = list
- print "set index"
self.index = old_index
- print "reenable callbacks"
self.disable_callbacks = False
- print "done"
diff --git a/lib/python/Components/Sources/Progress.py b/lib/python/Components/Sources/Progress.py
index b96065b3..d57a6179 100644
--- a/lib/python/Components/Sources/Progress.py
+++ b/lib/python/Components/Sources/Progress.py
@@ -12,5 +12,12 @@ class Progress(Source):
def setValue(self, value):
self.__value = value
self.changed((self.CHANGED_ALL,))
+
+ def setRange(self, range = 100):
+ self.range = range
+ self.changed((self.CHANGED_ALL,))
+
+ def getRange(self):
+ return self.range
value = property(getValue, setValue)
diff --git a/lib/python/Components/Task.py b/lib/python/Components/Task.py
index 9a768425..df94f8a6 100644
--- a/lib/python/Components/Task.py
+++ b/lib/python/Components/Task.py
@@ -127,9 +127,11 @@ class Task(object):
self.cmd = None
self.cwd = "/tmp"
self.args = [ ]
+ self.cmdline = None
self.task_progress_changed = None
self.output_line = ""
job.addTask(self)
+ self.container = None
def setCommandline(self, cmd, args):
self.cmd = cmd
@@ -141,6 +143,9 @@ class Task(object):
self.global_preconditions.append(ToolExistsPrecondition())
self.postconditions.append(ReturncodePostcondition())
+ def setCmdline(self, cmdline):
+ self.cmdline = cmdline
+
def checkPreconditions(self, immediate = False):
not_met = [ ]
if immediate:
@@ -166,13 +171,15 @@ class Task(object):
self.container.stdoutAvail.append(self.processStdout)
self.container.stderrAvail.append(self.processStderr)
- assert self.cmd is not None
- assert len(self.args) >= 1
-
if self.cwd is not None:
self.container.setCWD(self.cwd)
- print "execute:", self.container.execute(self.cmd, *self.args), self.cmd, self.args
+ if not self.cmd and self.cmdline:
+ print "execute:", self.container.execute(self.cmdline), self.cmdline
+ else:
+ assert self.cmd is not None
+ assert len(self.args) >= 1
+ print "execute:", self.container.execute(self.cmd, *self.args), ' '.join(self.args)
if self.initial_input:
self.writeInput(self.initial_input)
@@ -205,7 +212,8 @@ class Task(object):
self.finish()
def abort(self):
- self.container.kill()
+ if self.container:
+ self.container.kill()
self.finish(aborted = True)
def finish(self, aborted = False):
diff --git a/lib/python/Components/TimerSanityCheck.py b/lib/python/Components/TimerSanityCheck.py
index 031c9cae..99b2fba5 100644
--- a/lib/python/Components/TimerSanityCheck.py
+++ b/lib/python/Components/TimerSanityCheck.py
@@ -173,8 +173,7 @@ class TimerSanityCheck:
def getServiceType(ref): # helper function to get a service type of a service reference
serviceInfo = serviceHandler.info(ref)
serviceInfo = serviceInfo and serviceInfo.getInfoObject(ref, iServiceInformation.sTransponderData)
- if serviceInfo:
- return { "Satellite" : "DVB-S", "Cable" : "DVB-C", "Terrestrial" : "DVB-T"}[serviceInfo["type"]]
+ return serviceInfo and serviceInfo["tuner_type"] or ""
ref = timer.service_ref.ref
if ref.flags & eServiceReference.isGroup: # service group ?
@@ -200,7 +199,7 @@ class TimerSanityCheck:
if timer == fakeRec[0] and fakeRec[1]:
NavigationInstance.instance.stopRecordService(fakeRec[1])
fakeRecList.remove(fakeRec)
- del fakeRec
+ fakeRec = None
for entry in overlaplist:
if entry[1] == timer:
overlaplist.remove(entry)
diff --git a/lib/python/Components/TuneTest.py b/lib/python/Components/TuneTest.py
new file mode 100644
index 00000000..de7b0098
--- /dev/null
+++ b/lib/python/Components/TuneTest.py
@@ -0,0 +1,235 @@
+from enigma import eDVBFrontendParametersSatellite, eDVBFrontendParameters, eDVBResourceManager, eTimer
+
+class Tuner:
+ def __init__(self, frontend):
+ self.frontend = frontend
+
+ # transponder = (frequency, symbolrate, polarisation, fec, inversion, orbpos, system, modulation)
+ # 0 1 2 3 4 5 6 7
+ def tune(self, transponder):
+ if self.frontend:
+ print "tuning to transponder with data", transponder
+ parm = eDVBFrontendParametersSatellite()
+ parm.frequency = transponder[0] * 1000
+ parm.symbol_rate = transponder[1] * 1000
+ parm.polarisation = transponder[2]
+ parm.fec = transponder[3]
+ parm.inversion = transponder[4]
+ parm.orbital_position = transponder[5]
+ parm.system = transponder[6]
+ parm.modulation = transponder[7]
+ parm.rolloff = transponder[8]
+ parm.pilot = transponder[9]
+ feparm = eDVBFrontendParameters()
+ feparm.setDVBS(parm)
+ self.lastparm = feparm
+ self.frontend.tune(feparm)
+
+ def retune(self):
+ if self.frontend:
+ self.frontend.tune(self.lastparm)
+
+ def getTransponderData(self):
+ ret = { }
+ if self.frontend:
+ self.frontend.getTransponderData(ret, True)
+ return ret
+
+# tunes a list of transponders and checks, if they lock and optionally checks the onid/tsid combination
+# 1) add transponders with addTransponder()
+# 2) call run(<checkPIDs = True>)
+# 3) finishedChecking() is called, when the run is finished
+class TuneTest:
+ def __init__(self, feid, stopOnSuccess = -1, stopOnError = -1):
+ self.stopOnSuccess = stopOnSuccess
+ self.stopOnError = stopOnError
+ self.feid = feid
+ self.transponderlist = []
+ self.currTuned = None
+ print "TuneTest for feid %d" % self.feid
+ if not self.openFrontend():
+ self.oldref = self.session.nav.getCurrentlyPlayingServiceReference()
+ self.session.nav.stopService() # try to disable foreground service
+ if not self.openFrontend():
+ if self.session.pipshown: # try to disable pip
+ self.session.pipshown = False
+ del self.session.pip
+ if not self.openFrontend():
+ self.frontend = None # in normal case this should not happen
+ self.tuner = Tuner(self.frontend)
+ self.timer = eTimer()
+ self.timer.callback.append(self.updateStatus)
+
+ def gotTsidOnid(self, tsid, onid):
+ print "******** got tsid, onid:", tsid, onid
+ if tsid is not None and onid is not None:
+ self.pidStatus = self.INTERNAL_PID_STATUS_SUCCESSFUL
+ self.tsid = tsid
+ self.onid = onid
+ else:
+ self.pidStatus = self.INTERNAL_PID_STATUS_FAILED
+ self.tsid = -1
+ self.onid = -1
+ self.timer.start(100, True)
+
+ def updateStatus(self):
+ dict = {}
+ self.frontend.getFrontendStatus(dict)
+ stop = False
+
+ print "status:", dict
+ if dict["tuner_state"] == "TUNING":
+ print "TUNING"
+ self.timer.start(100, True)
+ self.progressCallback((self.getProgressLength(), self.tuningtransponder, self.STATUS_TUNING, self.currTuned))
+ elif self.checkPIDs and self.pidStatus == self.INTERNAL_PID_STATUS_NOOP:
+ print "2nd choice"
+ if dict["tuner_state"] == "LOCKED":
+ print "acquiring TSID/ONID"
+ self.raw_channel.requestTsidOnid(self.gotTsidOnid)
+ self.pidStatus = self.INTERNAL_PID_STATUS_WAITING
+ else:
+ self.pidStatus = self.INTERNAL_PID_STATUS_FAILED
+ elif self.checkPIDs and self.pidStatus == self.INTERNAL_PID_STATUS_WAITING:
+ print "waiting for pids"
+ else:
+ if dict["tuner_state"] == "LOSTLOCK" or dict["tuner_state"] == "FAILED":
+ self.tuningtransponder = self.nextTransponder()
+ self.failedTune.append([self.currTuned, self.oldTuned, "tune_failed"])
+ if self.stopOnError != -1 and self.stopOnError <= len(self.failedTune):
+ stop = True
+ elif dict["tuner_state"] == "LOCKED":
+ pidsFailed = False
+ if self.checkPIDs:
+ if self.currTuned is not None:
+ if self.tsid != self.currTuned[8] or self.onid != self.currTuned[9]:
+ self.failedTune.append([self.currTuned, self.oldTuned, "pids_failed", {"real": (self.tsid, self.onid), "expected": (self.currTuned[8], self.currTuned[9])}])
+ pidsFailed = True
+ else:
+ self.successfullyTune.append([self.currTuned, self.oldTuned])
+ if self.stopOnSuccess != -1 and self.stopOnSuccess <= len(self.successfullyTune):
+ stop = True
+ elif not self.checkPIDs or (self.checkPids and not pidsFailed):
+ self.successfullyTune.append([self.currTuned, self.oldTuned])
+ if self.stopOnSuccess != -1 and self.stopOnSuccess <= len(self.successfullyTune):
+ stop = True
+ self.tuningtransponder = self.nextTransponder()
+ else:
+ print "************* tuner_state:", dict["tuner_state"]
+
+ self.progressCallback((self.getProgressLength(), self.tuningtransponder, self.STATUS_NOOP, self.currTuned))
+
+ if not stop:
+ self.tune()
+ if self.tuningtransponder < len(self.transponderlist) and not stop:
+ if self.pidStatus != self.INTERNAL_PID_STATUS_WAITING:
+ self.timer.start(100, True)
+ print "restart timer"
+ else:
+ print "not restarting timers (waiting for pids)"
+ else:
+ self.progressCallback((self.getProgressLength(), len(self.transponderlist), self.STATUS_DONE, self.currTuned))
+ print "finishedChecking"
+ self.finishedChecking()
+
+ def firstTransponder(self):
+ print "firstTransponder:"
+ index = 0
+ if self.checkPIDs:
+ print "checkPIDs-loop"
+ # check for tsid != -1 and onid != -1
+ print "index:", index
+ print "len(self.transponderlist):", len(self.transponderlist)
+ while (index < len(self.transponderlist) and (self.transponderlist[index][8] == -1 or self.transponderlist[index][9] == -1)):
+ index += 1
+ print "FirstTransponder final index:", index
+ return index
+
+ def nextTransponder(self):
+ print "getting next transponder", self.tuningtransponder
+ index = self.tuningtransponder + 1
+ if self.checkPIDs:
+ print "checkPIDs-loop"
+ # check for tsid != -1 and onid != -1
+ print "index:", index
+ print "len(self.transponderlist):", len(self.transponderlist)
+ while (index < len(self.transponderlist) and (self.transponderlist[index][8] == -1 or self.transponderlist[index][9] == -1)):
+ index += 1
+
+ print "next transponder index:", index
+ return index
+
+ def finishedChecking(self):
+ print "finished testing"
+ print "successfull:", self.successfullyTune
+ print "failed:", self.failedTune
+
+ def openFrontend(self):
+ res_mgr = eDVBResourceManager.getInstance()
+ if res_mgr:
+ self.raw_channel = res_mgr.allocateRawChannel(self.feid)
+ if self.raw_channel:
+ self.frontend = self.raw_channel.getFrontend()
+ if self.frontend:
+ return True
+ else:
+ print "getFrontend failed"
+ else:
+ print "getRawChannel failed"
+ else:
+ print "getResourceManager instance failed"
+ return False
+
+ def tune(self):
+ print "tuning to", self.tuningtransponder
+ if self.tuningtransponder < len(self.transponderlist):
+ self.pidStatus = self.INTERNAL_PID_STATUS_NOOP
+ self.oldTuned = self.currTuned
+ self.currTuned = self.transponderlist[self.tuningtransponder]
+ self.tuner.tune(self.transponderlist[self.tuningtransponder])
+
+ INTERNAL_PID_STATUS_NOOP = 0
+ INTERNAL_PID_STATUS_WAITING = 1
+ INTERNAL_PID_STATUS_SUCCESSFUL = 2
+ INTERNAL_PID_STATUS_FAILED = 3
+
+ def run(self, checkPIDs = False):
+ self.checkPIDs = checkPIDs
+ self.pidStatus = self.INTERNAL_PID_STATUS_NOOP
+ self.failedTune = []
+ self.successfullyTune = []
+ self.tuningtransponder = self.firstTransponder()
+ self.tune()
+ self.progressCallback((self.getProgressLength(), self.tuningtransponder, self.STATUS_START, self.currTuned))
+ self.timer.start(100, True)
+
+ # transponder = (frequency, symbolrate, polarisation, fec, inversion, orbpos, <system>, <modulation>, <tsid>, <onid>)
+ # 0 1 2 3 4 5 6 7 8 9
+ def addTransponder(self, transponder):
+ self.transponderlist.append(transponder)
+
+ def clearTransponder(self):
+ self.transponderlist = []
+
+ def getProgressLength(self):
+ count = 0
+ if self.stopOnError == -1:
+ count = len(self.transponderlist)
+ else:
+ if count < self.stopOnError:
+ count = self.stopOnError
+ if self.stopOnSuccess == -1:
+ count = len(self.transponderlist)
+ else:
+ if count < self.stopOnSuccess:
+ count = self.stopOnSuccess
+ return count
+
+ STATUS_START = 0
+ STATUS_TUNING = 1
+ STATUS_DONE = 2
+ STATUS_NOOP = 3
+ # can be overwritten
+ # progress = (range, value, status, transponder)
+ def progressCallback(self, progress):
+ pass \ No newline at end of file
diff --git a/lib/python/Components/TunerInfo.py b/lib/python/Components/TunerInfo.py
index d8b4d064..39f54c0b 100644
--- a/lib/python/Components/TunerInfo.py
+++ b/lib/python/Components/TunerInfo.py
@@ -10,13 +10,14 @@ class TunerInfo(GUIComponent):
BER = 2
LOCK = 3
SNR_PERCENTAGE = 0
- AGC_PERCENTAGE = 1
- BER_VALUE = 2
- SNR_BAR = 3
- AGC_BAR = 4
- BER_BAR = 5
- LOCK_STATE = 6
- SYNC_STATE = 7
+ SNR_DB = 1
+ AGC_PERCENTAGE = 2
+ BER_VALUE = 3
+ SNR_BAR = 4
+ AGC_BAR = 5
+ BER_BAR = 6
+ LOCK_STATE = 7
+ SYNC_STATE = 8
def __init__(self, type, servicefkt = None, frontendfkt = None, statusDict = None):
GUIComponent.__init__(self)
@@ -47,7 +48,9 @@ class TunerInfo(GUIComponent):
return val*100/65535
def update(self):
- if self.type == self.SNR_PERCENTAGE or self.type == self.SNR_BAR:
+ if self.type == self.SNR_DB:
+ value = self.getValue(self.SNR_DB)
+ elif self.type == self.SNR_PERCENTAGE or self.type == self.SNR_BAR:
value = self.getValue(self.SNR) * 100 / 65536
elif self.type == self.AGC_PERCENTAGE or self.type == self.AGC_BAR:
value = self.getValue(self.AGC) * 100 / 65536
@@ -55,8 +58,13 @@ class TunerInfo(GUIComponent):
value = self.getValue(self.BER)
elif self.type == self.LOCK_STATE:
value = self.getValue(self.LOCK)
-
- if self.type == self.SNR_PERCENTAGE or self.type == self.AGC_PERCENTAGE:
+
+ if self.type == self.SNR_DB:
+ if value != 0x12345678:
+ self.setText("%3.02f dB" % (value / 100.0))
+ else:
+ self.setText("")
+ elif self.type == self.SNR_PERCENTAGE or self.type == self.AGC_PERCENTAGE:
self.setText("%d%%" % (value))
elif self.type == self.BER_VALUE:
self.setText("%d" % (value))
@@ -72,7 +80,9 @@ class TunerInfo(GUIComponent):
def getValue(self, what):
if self.statusDict:
- if what == self.SNR:
+ if what == self.SNR_DB:
+ return self.statusDict.get("tuner_signal_quality_db", 0x12345678)
+ elif what == self.SNR:
return self.statusDict.get("tuner_signal_quality", 0)
elif what == self.AGC:
return self.statusDict.get("tuner_signal_power", 0)
@@ -85,7 +95,9 @@ class TunerInfo(GUIComponent):
if service is not None:
feinfo = service.frontendInfo()
if feinfo is not None:
- if what == self.SNR:
+ if what == self.SNR_DB:
+ return feinfo.getFrontendInfo(iFrontendInformation.signalQualitydB)
+ elif what == self.SNR:
return feinfo.getFrontendInfo(iFrontendInformation.signalQuality)
elif what == self.AGC:
return feinfo.getFrontendInfo(iFrontendInformation.signalPower)
@@ -96,7 +108,9 @@ class TunerInfo(GUIComponent):
elif self.frontendfkt:
frontend = self.frontendfkt()
if frontend:
- if what == self.SNR:
+ if what == self.SNR_DB:
+ return frontend.readFrontendData(iFrontendInformation.signalQualitydB)
+ elif what == self.SNR:
return frontend.readFrontendData(iFrontendInformation.signalQuality)
elif what == self.AGC:
return frontend.readFrontendData(iFrontendInformation.signalPower)
diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py
index 6ed87840..21e057f2 100644
--- a/lib/python/Components/UsageConfig.py
+++ b/lib/python/Components/UsageConfig.py
@@ -17,12 +17,12 @@ def InitUsageConfig():
config.usage.show_infobar_on_zap = ConfigYesNo(default = True)
config.usage.show_infobar_on_skip = ConfigYesNo(default = True)
config.usage.show_infobar_on_event_change = ConfigYesNo(default = True)
- config.usage.hdd_standby = ConfigSelection(default = "120", choices = [
- ("0", _("no standby")), ("2", "10 " + _("seconds")), ("6", "30 " + _("seconds")),
- ("12", "1 " + _("minute")), ("24", "2 " + _("minutes")),
- ("60", "5 " + _("minutes")), ("120", "10 " + _("minutes")), ("240", "20 " + _("minutes")),
- ("241", "30 " + _("minutes")), ("242", "1 " + _("hour")), ("244", "2 " + _("hours")),
- ("248", "4 " + _("hours")) ])
+ config.usage.hdd_standby = ConfigSelection(default = "600", choices = [
+ ("0", _("no standby")), ("10", "10 " + _("seconds")), ("30", "30 " + _("seconds")),
+ ("60", "1 " + _("minute")), ("120", "2 " + _("minutes")),
+ ("300", "5 " + _("minutes")), ("600", "10 " + _("minutes")), ("1200", "20 " + _("minutes")),
+ ("1800", "30 " + _("minutes")), ("3600", "1 " + _("hour")), ("7200", "2 " + _("hours")),
+ ("14400", "4 " + _("hours")) ])
config.usage.output_12V = ConfigSelection(default = "do not change", choices = [
("do not change", _("do not change")), ("off", _("off")), ("on", _("on")) ])
@@ -66,7 +66,7 @@ def InitUsageConfig():
def setHDDStandby(configElement):
for hdd in harddiskmanager.HDDList():
- os.system("hdparm -S%s %s" % (configElement.value, hdd[1].getDeviceName()))
+ hdd[1].setIdleTime(int(configElement.value))
config.usage.hdd_standby.addNotifier(setHDDStandby)
def set12VOutput(configElement):
@@ -89,8 +89,8 @@ def InitUsageConfig():
config.seek.speeds_backward = ConfigSet(default=[8, 16, 32, 64, 128], choices=[1, 2, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128])
config.seek.speeds_slowmotion = ConfigSet(default=[2, 4, 8], choices=[2, 4, 6, 8, 12, 16, 25])
- config.seek.enter_forward = ConfigSelection(default = "2", choices = ["2"])
- config.seek.enter_backward = ConfigSelection(default = "2", choices = ["2"])
+ config.seek.enter_forward = ConfigSelection(default = "2", choices = ["2", "4", "6", "8", "12", "16", "24", "32", "48", "64", "96", "128"])
+ config.seek.enter_backward = ConfigSelection(default = "1", choices = ["1", "2", "4", "6", "8", "12", "16", "24", "32", "48", "64", "96", "128"])
config.seek.stepwise_minspeed = ConfigSelection(default = "16", choices = ["Never", "2", "4", "6", "8", "12", "16", "24", "32", "48", "64", "96", "128"])
config.seek.stepwise_repeat = ConfigSelection(default = "3", choices = ["2", "3", "4", "5", "6"])
@@ -104,14 +104,14 @@ def InitUsageConfig():
configElement.value = [2]
updateChoices(config.seek.enter_forward, configElement.value)
- config.seek.speeds_forward.addNotifier(updateEnterForward)
+ config.seek.speeds_forward.addNotifier(updateEnterForward, immediate_feedback = False)
def updateEnterBackward(configElement):
if not configElement.value:
configElement.value = [2]
updateChoices(config.seek.enter_backward, configElement.value)
- config.seek.speeds_backward.addNotifier(updateEnterBackward)
+ config.seek.speeds_backward.addNotifier(updateEnterBackward, immediate_feedback = False)
def updateChoices(sel, choices):
if choices:
diff --git a/lib/python/Components/config.py b/lib/python/Components/config.py
index 4d57bbb9..eaf07180 100755
--- a/lib/python/Components/config.py
+++ b/lib/python/Components/config.py
@@ -1,10 +1,10 @@
-import time
from enigma import getPrevAsciiCode
from Tools.NumericalTextInput import NumericalTextInput
from Tools.Directories import resolveFilename, SCOPE_CONFIG
from Components.Harddisk import harddiskmanager
-import copy
-import os
+from copy import copy as copy_copy
+from os import path as os_path
+from time import localtime, strftime
# ConfigElement, the base class of all ConfigElements.
@@ -28,11 +28,12 @@ import os
#
class ConfigElement(object):
def __init__(self):
-
object.__init__(self)
self.saved_value = None
+ self.last_value = None
self.save_disabled = False
self.notifiers = []
+ self.notifiers_final = []
self.enabled = True
self.callNotifiersOnSaveAndCancel = False
@@ -85,10 +86,16 @@ class ConfigElement(object):
for x in self.notifiers:
x(self)
- def addNotifier(self, notifier, initial_call = True):
+ def changedFinal(self):
+ for x in self.notifiers_final:
+ x(self)
+
+ def addNotifier(self, notifier, initial_call = True, immediate_feedback = True):
assert callable(notifier), "notifiers must be callable"
- self.notifiers.append(notifier)
-
+ if immediate_feedback:
+ self.notifiers.append(notifier)
+ else:
+ self.notifiers_final.append(notifier)
# CHECKME:
# do we want to call the notifier
# - at all when adding it? (yes, though optional)
@@ -110,7 +117,9 @@ class ConfigElement(object):
pass
def onDeselect(self, session):
- pass
+ if not self.last_value == self.value:
+ self.changedFinal()
+ self.last_value = self.value
KEY_LEFT = 0
KEY_RIGHT = 1
@@ -130,6 +139,107 @@ def getKeyNumber(key):
assert key in KEY_NUMBERS
return key - KEY_0
+class choicesList(object): # XXX: we might want a better name for this
+ LIST_TYPE_LIST = 1
+ LIST_TYPE_DICT = 2
+
+ def __init__(self, choices, type = None):
+ object.__init__(self)
+ self.choices = choices
+ if type is None:
+ if isinstance(choices, list):
+ self.type = choicesList.LIST_TYPE_LIST
+ elif isinstance(choices, dict):
+ self.type = choicesList.LIST_TYPE_DICT
+ else:
+ assert False, "choices must be dict or list!"
+ else:
+ self.type = type
+
+ def __list__(self):
+ if self.type == choicesList.LIST_TYPE_LIST:
+ ret = [isinstance(x, tuple) and x[0] or x for x in self.choices]
+ else:
+ ret = self.choices.keys()
+ return ret or [""]
+
+ def __iter__(self):
+ if self.type == choicesList.LIST_TYPE_LIST:
+ ret = [isinstance(x, tuple) and x[0] or x for x in self.choices]
+ else:
+ ret = self.choices
+ return iter(ret or [""])
+
+ def __len__(self):
+ return len(self.choices) or 1
+
+ def __getitem__(self, index):
+ if self.type == choicesList.LIST_TYPE_LIST:
+ ret = self.choices[index]
+ if isinstance(ret, tuple):
+ ret = ret[0]
+ return ret
+ return self.choices.keys()[index]
+
+ def index(self, value):
+ return self.__list__().index(value)
+
+ def __setitem__(self, index, value):
+ if self.type == choicesList.LIST_TYPE_LIST:
+ orig = self.choices[index]
+ if isinstance(orig, tuple):
+ self.choices[index] = (value, orig[1])
+ else:
+ self.choices[index] = value
+ else:
+ key = self.choices.keys()[index]
+ orig = self.choices[key]
+ del self.choices[key]
+ self.choices[value] = orig
+
+ def default(self):
+ if self.type is choicesList.LIST_TYPE_LIST:
+ default = self.choices[0]
+ if isinstance(default, tuple):
+ default = default[0]
+ else:
+ default = self.choices.keys()[0]
+ return default
+
+class descriptionList(choicesList): # XXX: we might want a better name for this
+ def __list__(self):
+ if self.type == choicesList.LIST_TYPE_LIST:
+ ret = [isinstance(x, tuple) and x[1] or x for x in self.choices]
+ else:
+ ret = self.choices.values()
+ return ret or [""]
+
+ def __iter__(self):
+ return iter(self.__list__())
+
+ def __getitem__(self, index):
+ if self.type == choicesList.LIST_TYPE_LIST:
+ for x in self.choices:
+ if isinstance(x, tuple):
+ if x[0] == index:
+ return str(x[1])
+ elif x == index:
+ return str(x)
+ return str(index) # Fallback!
+ else:
+ return str(self.choices.get(index, ""))
+
+ def __setitem__(self, index, value):
+ if self.type == choicesList.LIST_TYPE_LIST:
+ i = self.index(index)
+ orig = self.choices[i]
+ if isinstance(orig, tuple):
+ self.choices[i] = (orig[0], value)
+ else:
+ self.choices[i] = value
+ else:
+ self.choices[index] = value
+
#
# ConfigSelection is a "one of.."-type.
# it has the "choices", usually a list, which contains
@@ -141,43 +251,21 @@ def getKeyNumber(key):
class ConfigSelection(ConfigElement):
def __init__(self, choices, default = None):
ConfigElement.__init__(self)
- self._value = None
- self.setChoices(choices, default)
+ self.choices = choicesList(choices)
+
+ if default is None:
+ default = self.choices.default()
+
+ self.default = self._value = self.last_value = default
+ self.changed()
def setChoices(self, choices, default = None):
- self.choices = []
- self.description = {}
-
- if isinstance(choices, list):
- for x in choices:
- if isinstance(x, tuple):
- self.choices.append(x[0])
- self.description[x[0]] = x[1]
- else:
- self.choices.append(x)
- self.description[x] = x
- elif isinstance(choices, dict):
- for (key, val) in choices.items():
- self.choices.append(key)
- self.description[key] = val
- else:
- assert False, "ConfigSelection choices must be dict or list!"
-
- #assert len(self.choices), "you can't have an empty configselection"
- if len(self.choices) == 0:
- self.choices = [""]
- self.description[""] = ""
+ self.choices = choicesList(choices)
if default is None:
- default = self.choices[0]
-
- assert default in self.choices, "default must be in choice list, but " + repr(default) + " is not!"
- for x in self.choices:
- assert isinstance(x, str), "ConfigSelection choices must be strings"
-
- self.default = default
+ default = self.choices.default()
- if self.value == None or not self.value in self.choices:
+ if self.value not in self.choices:
self.value = default
def setValue(self, value):
@@ -185,7 +273,6 @@ class ConfigSelection(ConfigElement):
self._value = value
else:
self._value = self.default
-
self.changed()
def tostring(self, val):
@@ -196,7 +283,6 @@ class ConfigSelection(ConfigElement):
def setCurrentText(self, text):
i = self.choices.index(self.value)
- del self.description[self.choices[i]]
self.choices[i] = text
self.description[text] = text
self._value = text
@@ -220,7 +306,7 @@ class ConfigSelection(ConfigElement):
self.value = self.choices[0]
elif key == KEY_END:
self.value = self.choices[nchoices - 1]
-
+
def selectNext(self):
nchoices = len(self.choices)
i = self.choices.index(self.value)
@@ -242,27 +328,32 @@ class ConfigSelection(ConfigElement):
def getHTML(self, id):
res = ""
for v in self.choices:
+ descr = self.description[v]
if self.value == v:
checked = 'checked="checked" '
else:
checked = ''
- res += '<input type="radio" name="' + id + '" ' + checked + 'value="' + v + '">' + self.description[v] + "</input></br>\n"
+ res += '<input type="radio" name="' + id + '" ' + checked + 'value="' + v + '">' + descr + "</input></br>\n"
return res;
def unsafeAssign(self, value):
# setValue does check if value is in choices. This is safe enough.
self.value = value
+ description = property(lambda self: descriptionList(self.choices.choices, self.choices.type))
+
# a binary decision.
#
# several customized versions exist for different
# descriptions.
#
+boolean_descriptions = {False: "false", True: "true"}
class ConfigBoolean(ConfigElement):
- def __init__(self, default = False, descriptions = {False: "false", True: "true"}):
+ def __init__(self, default = False, descriptions = boolean_descriptions):
ConfigElement.__init__(self)
self.descriptions = descriptions
- self.value = self.default = default
+ self.value = self.last_value = self.default = default
+
def handleKey(self, key):
if key in [KEY_LEFT, KEY_RIGHT]:
self.value = not self.value
@@ -309,24 +400,32 @@ class ConfigBoolean(ConfigElement):
else:
self.value = False
+ def onDeselect(self, session):
+ if not self.last_value == self.value:
+ self.changedFinal()
+ self.last_value = self.value
+
+yes_no_descriptions = {False: _("no"), True: _("yes")}
class ConfigYesNo(ConfigBoolean):
def __init__(self, default = False):
- ConfigBoolean.__init__(self, default = default, descriptions = {False: _("no"), True: _("yes")})
+ ConfigBoolean.__init__(self, default = default, descriptions = yes_no_descriptions)
+on_off_descriptions = {False: _("off"), True: _("on")}
class ConfigOnOff(ConfigBoolean):
def __init__(self, default = False):
- ConfigBoolean.__init__(self, default = default, descriptions = {False: _("off"), True: _("on")})
+ ConfigBoolean.__init__(self, default = default, descriptions = on_off_descriptions)
+enable_disable_descriptions = {False: _("disable"), True: _("enable")}
class ConfigEnableDisable(ConfigBoolean):
def __init__(self, default = False):
- ConfigBoolean.__init__(self, default = default, descriptions = {False: _("disable"), True: _("enable")})
+ ConfigBoolean.__init__(self, default = default, descriptions = enable_disable_descriptions)
class ConfigDateTime(ConfigElement):
def __init__(self, default, formatstring, increment = 86400):
ConfigElement.__init__(self)
self.increment = increment
self.formatstring = formatstring
- self.value = self.default = int(default)
+ self.value = self.last_value = self.default = int(default)
def handleKey(self, key):
if key == KEY_LEFT:
@@ -337,10 +436,10 @@ class ConfigDateTime(ConfigElement):
self.value = self.default
def getText(self):
- return time.strftime(self.formatstring, time.localtime(self.value))
+ return strftime(self.formatstring, localtime(self.value))
def getMulti(self, selected):
- return ("text", time.strftime(self.formatstring, time.localtime(self.value)))
+ return ("text", strftime(self.formatstring, localtime(self.value)))
def fromstring(self, val):
return int(val)
@@ -352,7 +451,7 @@ class ConfigDateTime(ConfigElement):
# several helper exist to ease this up a bit.
#
class ConfigSequence(ConfigElement):
- def __init__(self, seperator, limits, censor_char = "", default = None):
+ def __init__(self, seperator, limits, default, censor_char = ""):
ConfigElement.__init__(self)
assert isinstance(limits, list) and len(limits[0]) == 2, "limits must be [(min, max),...]-tuple-list"
assert censor_char == "" or len(censor_char) == 1, "censor char must be a single char (or \"\")"
@@ -364,11 +463,10 @@ class ConfigSequence(ConfigElement):
self.seperator = seperator
self.limits = limits
self.censor_char = censor_char
-
- self.default = default
- self.value = copy.copy(default)
-
- self.endNotifier = []
+
+ self.last_value = self.default = default
+ self.value = copy_copy(default)
+ self.endNotifier = None
def validate(self):
max_pos = 0
@@ -385,8 +483,9 @@ class ConfigSequence(ConfigElement):
num += 1
if self.marked_pos >= max_pos:
- for x in self.endNotifier:
- x(self)
+ if endNotifier:
+ for x in self.endNotifier:
+ x(self)
self.marked_pos = max_pos - 1
if self.marked_pos < 0:
@@ -395,13 +494,15 @@ class ConfigSequence(ConfigElement):
def validatePos(self):
if self.marked_pos < 0:
self.marked_pos = 0
-
+
total_len = sum([len(str(x[1])) for x in self.limits])
if self.marked_pos >= total_len:
self.marked_pos = total_len - 1
-
+
def addEndNotifier(self, notifier):
+ if endNotifier is None:
+ endNotifier = []
self.endNotifier.append(notifier)
def handleKey(self, key):
@@ -412,7 +513,7 @@ class ConfigSequence(ConfigElement):
if key == KEY_RIGHT:
self.marked_pos += 1
self.validatePos()
-
+
if key == KEY_HOME:
self.marked_pos = 0
self.validatePos()
@@ -425,7 +526,7 @@ class ConfigSequence(ConfigElement):
num += 1
self.marked_pos = max_pos - 1
self.validatePos()
-
+
if key in KEY_NUMBERS or key == KEY_ASCII:
if key == KEY_ASCII:
code = getPrevAsciiCode()
@@ -434,11 +535,11 @@ class ConfigSequence(ConfigElement):
number = code - 48
else:
number = getKeyNumber(key)
-
+
block_len = []
for x in self.limits:
block_len.append(len(str(x[1])))
-
+
total_len = sum(block_len)
pos = 0
@@ -457,17 +558,17 @@ class ConfigSequence(ConfigElement):
# position in the block
posinblock = self.marked_pos - block_len_total[blocknumber]
-
+
oldvalue = self._value[blocknumber]
olddec = oldvalue % 10 ** (number_len - posinblock) - (oldvalue % 10 ** (number_len - posinblock - 1))
newvalue = oldvalue - olddec + (10 ** (number_len - posinblock - 1) * number)
-
+
self._value[blocknumber] = newvalue
self.marked_pos += 1
-
+
self.validate()
self.changed()
-
+
def genText(self):
value = ""
mPos = self.marked_pos
@@ -477,18 +578,17 @@ class ConfigSequence(ConfigElement):
value += self.seperator
if mPos >= len(value) - 1:
mPos += 1
-
if self.censor_char == "":
value += ("%0" + str(len(str(self.limits[num][1]))) + "d") % i
else:
value += (self.censor_char * len(str(self.limits[num][1])))
num += 1
return (value, mPos)
-
+
def getText(self):
(value, mPos) = self.genText()
return value
-
+
def getMulti(self, selected):
(value, mPos) = self.genText()
# only mark cursor when we are selected
@@ -500,16 +600,22 @@ class ConfigSequence(ConfigElement):
def tostring(self, val):
return self.seperator.join([self.saveSingle(x) for x in val])
-
+
def saveSingle(self, v):
return str(v)
def fromstring(self, value):
return [int(x) for x in value.split(self.seperator)]
+ def onDeselect(self, session):
+ if self.last_value != self._value:
+ self.changedFinal()
+ self.last_value = copy_copy(self._value)
+
+ip_limits = [(0,255),(0,255),(0,255),(0,255)]
class ConfigIP(ConfigSequence):
def __init__(self, default, auto_jump = False):
- ConfigSequence.__init__(self, seperator = ".", limits = [(0,255),(0,255),(0,255),(0,255)], default = default)
+ ConfigSequence.__init__(self, seperator = ".", limits = ip_limits, default = default)
self.block_len = []
for x in self.limits:
self.block_len.append(len(str(x[1])))
@@ -590,22 +696,54 @@ class ConfigIP(ConfigSequence):
# we definitely don't want leading zeros
return '.'.join(["%d" % d for d in self.value])
+mac_limits = [(1,255),(1,255),(1,255),(1,255),(1,255),(1,255)]
class ConfigMAC(ConfigSequence):
def __init__(self, default):
- ConfigSequence.__init__(self, seperator = ":", limits = [(1,255),(1,255),(1,255),(1,255),(1,255),(1,255)], default = default)
+ ConfigSequence.__init__(self, seperator = ":", limits = mac_limits, default = default)
class ConfigPosition(ConfigSequence):
def __init__(self, default, args):
ConfigSequence.__init__(self, seperator = ",", limits = [(0,args[0]),(0,args[1]),(0,args[2]),(0,args[3])], default = default)
+clock_limits = [(0,23),(0,59)]
class ConfigClock(ConfigSequence):
def __init__(self, default):
- import time
- t = time.localtime(default)
- ConfigSequence.__init__(self, seperator = ":", limits = [(0,23),(0,59)], default = [t.tm_hour, t.tm_min])
+ t = localtime(default)
+ ConfigSequence.__init__(self, seperator = ":", limits = clock_limits, default = [t.tm_hour, t.tm_min])
+
+ def increment(self):
+ # Check if Minutes maxed out
+ if self._value[1] == 59:
+ # Increment Hour, reset Minutes
+ if self._value[0] < 23:
+ self._value[0] += 1
+ else:
+ self._value[0] = 0
+ self._value[1] = 0
+ else:
+ # Increment Minutes
+ self._value[1] += 1
+ # Trigger change
+ self.changed()
+
+ def decrement(self):
+ # Check if Minutes is minimum
+ if self._value[1] == 0:
+ # Decrement Hour, set Minutes to 59
+ if self._value[0] > 0:
+ self._value[0] -= 1
+ else:
+ self._value[0] = 23
+ self._value[1] = 59
+ else:
+ # Decrement Minutes
+ self._value[1] -= 1
+ # Trigger change
+ self.changed()
+integer_limits = (0, 9999999999)
class ConfigInteger(ConfigSequence):
- def __init__(self, default, limits = (0, 9999999999)):
+ def __init__(self, default, limits = integer_limits):
ConfigSequence.__init__(self, seperator = ":", limits = [limits], default = default)
# you need to override this to do input validation
@@ -615,7 +753,7 @@ class ConfigInteger(ConfigSequence):
def getValue(self):
return self._value[0]
-
+
value = property(getValue, setValue)
def fromstring(self, value):
@@ -657,7 +795,7 @@ class ConfigText(ConfigElement, NumericalTextInput):
self.offset = 0
self.overwrite = fixed_size
self.help_window = None
- self.value = self.default = default
+ self.value = self.last_value = self.default = default
def validateMarker(self):
if self.fixed_size:
@@ -823,6 +961,9 @@ class ConfigText(ConfigElement, NumericalTextInput):
if self.help_window:
session.deleteDialog(self.help_window)
self.help_window = None
+ if not self.last_value == self.value:
+ self.changedFinal()
+ self.last_value = self.value
def getHTML(self, id):
return '<input type="text" name="' + id + '" value="' + self.value + '" /><br>\n'
@@ -897,12 +1038,40 @@ class ConfigNumber(ConfigText):
def onDeselect(self, session):
self.marked_pos = 0
self.offset = 0
+ if not self.last_value == self.value:
+ self.changedFinal()
+ self.last_value = self.value
+
+class ConfigSearchText(ConfigText):
+ def __init__(self, default = "", fixed_size = False, visible_width = False):
+ ConfigText.__init__(self, default = default, fixed_size = fixed_size, visible_width = visible_width)
+ NumericalTextInput.__init__(self, nextFunc = self.nextFunc, handleTimeout = False, search = True)
+
+class ConfigDirectory(ConfigText):
+ def __init__(self, default="", visible_width=60):
+ ConfigText.__init__(self, default, fixed_size = True, visible_width = visible_width)
+ def handleKey(self, key):
+ pass
+ def getValue(self):
+ if self.text == "":
+ return None
+ else:
+ return ConfigText.getValue(self)
+ def setValue(self, val):
+ if val == None:
+ val = ""
+ ConfigText.setValue(self, val)
+ def getMulti(self, selected):
+ if self.text == "":
+ return ("mtext"[1-selected:], _("List of Storage Devices"), range(0))
+ else:
+ return ConfigText.getMulti(self, selected)
# a slider.
class ConfigSlider(ConfigElement):
def __init__(self, default = 0, increment = 1, limits = (0, 100)):
ConfigElement.__init__(self)
- self.value = self.default = default
+ self.value = self.last_value = self.default = default
self.min = limits[0]
self.max = limits[1]
self.increment = increment
@@ -954,28 +1123,17 @@ class ConfigSatlist(ConfigSelection):
class ConfigSet(ConfigElement):
def __init__(self, choices, default = []):
ConfigElement.__init__(self)
- self.choices = []
- self.description = {}
if isinstance(choices, list):
choices.sort()
- for x in choices:
- if isinstance(x, tuple):
- self.choices.append(x[0])
- self.description[x[0]] = str(x[1])
- else:
- self.choices.append(x)
- self.description[x] = str(x)
+ self.choices = choicesList(choices, choicesList.LIST_TYPE_LIST)
else:
assert False, "ConfigSet choices must be a list!"
- if len(self.choices) == 0:
- self.choices = [""]
- self.description[""] = ""
if default is None:
default = []
self.pos = -1
default.sort()
- self.default = default
- self.value = default+[]
+ self.last_value = self.default = default
+ self.value = default[:]
def toggleChoice(self, choice):
if choice in self.value:
@@ -983,6 +1141,7 @@ class ConfigSet(ConfigElement):
else:
self.value.append(choice)
self.value.sort()
+ self.changed()
def handleKey(self, key):
if key in KEY_NUMBERS + [KEY_DELETE, KEY_BACKSPACE]:
@@ -1012,7 +1171,7 @@ class ConfigSet(ConfigElement):
if not selected or self.pos == -1:
return ("text", self.genString(self.value))
else:
- tmp = self.value+[]
+ tmp = self.value[:]
ch = self.choices[self.pos]
mem = ch in self.value
if not mem:
@@ -1029,7 +1188,9 @@ class ConfigSet(ConfigElement):
def onDeselect(self, session):
self.pos = -1
- self.changed()
+ if not self.last_value == self.value:
+ self.changedFinal()
+ self.last_value = self.value[:]
def tostring(self, value):
return str(value)
@@ -1037,6 +1198,8 @@ class ConfigSet(ConfigElement):
def fromstring(self, val):
return eval(val)
+ description = property(lambda self: descriptionList(self.choices.choices, choicesList.LIST_TYPE_LIST))
+
class ConfigLocations(ConfigElement):
def __init__(self, default = [], visible_width = False):
ConfigElement.__init__(self)
@@ -1046,6 +1209,7 @@ class ConfigLocations(ConfigElement):
self.locations = []
self.mountpoints = []
harddiskmanager.on_partition_list_change.append(self.mountpointsChanged)
+ self.value = default+[]
def setValue(self, value):
loc = [x[0] for x in self.locations if x[3]]
@@ -1078,7 +1242,7 @@ class ConfigLocations(ConfigElement):
self.locations = [[x, None, False, False] for x in tmp]
self.refreshMountpoints()
for x in self.locations:
- if os.path.exists(x[0]):
+ if os_path.exists(x[0]):
x[1] = self.getMountpoint(x[0])
x[2] = True
@@ -1107,7 +1271,7 @@ class ConfigLocations(ConfigElement):
for x in self.locations:
if x[1] == mp:
x[2] = True
- elif x[1] == None and os.path.exists(x[0]):
+ elif x[1] == None and os_path.exists(x[0]):
x[1] = self.getMountpoint(x[0])
x[2] = True
@@ -1133,7 +1297,7 @@ class ConfigLocations(ConfigElement):
self.addedMount(x)
def getMountpoint(self, file):
- file = os.path.realpath(file)+"/"
+ file = os_path.realpath(file)+"/"
for m in self.mountpoints:
if file.startswith(m):
return m
@@ -1230,7 +1394,7 @@ class ConfigSubList(list, object):
x.load()
def getSavedValue(self):
- res = {}
+ res = { }
for i in range(len(self)):
sv = self[i].saved_value
if sv is not None:
@@ -1253,10 +1417,7 @@ class ConfigSubList(list, object):
item.load()
def dict(self):
- res = dict()
- for index in range(len(self)):
- res[str(index)] = self[index]
- return res
+ return dict([(str(index), value) for index, value in self.enumerate()])
# same as ConfigSubList, just as a dictionary.
# care must be taken that the 'key' has a proper
@@ -1322,11 +1483,12 @@ class ConfigSubsection(object):
def __setattr__(self, name, value):
if name == "saved_value":
return self.setSavedValue(value)
- assert isinstance(value, ConfigSubsection) or isinstance(value, ConfigElement) or isinstance(value, ConfigSubList) or isinstance(value, ConfigSubDict), "ConfigSubsections can only store ConfigSubsections, ConfigSubLists, ConfigSubDicts or ConfigElements"
+ assert isinstance(value, (ConfigSubsection, ConfigElement, ConfigSubList, ConfigSubDict)), "ConfigSubsections can only store ConfigSubsections, ConfigSubLists, ConfigSubDicts or ConfigElements"
self.content.items[name] = value
- if name in self.content.stored_values:
- #print "ok, now we have a new item,", name, "and have the following value for it:", self.content.stored_values[name]
- value.saved_value = self.content.stored_values[name]
+ x = self.content.stored_values.get(name, None)
+ if x is not None:
+ #print "ok, now we have a new item,", name, "and have the following value for it:", x
+ value.saved_value = x
value.load()
def __getattr__(self, name):
@@ -1344,12 +1506,11 @@ class ConfigSubsection(object):
def setSavedValue(self, values):
values = dict(values)
-
self.content.stored_values = values
-
for (key, val) in self.content.items.items():
- if key in values:
- val.saved_value = values[key]
+ value = values.get(key, None)
+ if value is not None:
+ val.saved_value = value
saved_value = property(getSavedValue, setSavedValue)
@@ -1377,19 +1538,18 @@ class Config(ConfigSubsection):
def pickle_this(self, prefix, topickle, result):
for (key, val) in topickle.items():
- name = prefix + "." + key
-
+ name = ''.join((prefix, '.', key))
if isinstance(val, dict):
self.pickle_this(name, val, result)
elif isinstance(val, tuple):
- result.append(name + "=" + val[0]) # + " ; " + val[1])
+ result += [name, '=', val[0], '\n']
else:
- result.append(name + "=" + val)
+ result += [name, '=', val, '\n']
def pickle(self):
- result = [ ]
+ result = []
self.pickle_this("config", self.saved_value, result)
- return '\n'.join(result) + "\n"
+ return ''.join(result)
def unpickle(self, lines):
tree = { }
diff --git a/lib/python/Components/language_cache.py b/lib/python/Components/language_cache.py
index 046f281d..a9c02bc0 100644
--- a/lib/python/Components/language_cache.py
+++ b/lib/python/Components/language_cache.py
@@ -4,6 +4,7 @@ LANG_TEXT = {
"fr_FR": "French",
"fi_FI": "Finnish",
"pt_PT": "Portuguese",
+ "fy_x-FY": "Frisian",
"it_IT": "Italian",
"no_NO": "Norwegian",
"nl_NL": "Dutch",
@@ -21,6 +22,7 @@ LANG_TEXT = {
"tr_TR": "Turkish",
"de_DE": "German",
"ar_AE": "Arabic",
+ "uk_UA": "Ukrainian",
"sv_SE": "Swedish",
"pl_PL": "Polish",
"T1": "Please use the UP and DOWN keys to select your language. Afterwards press the OK button.",
@@ -30,6 +32,7 @@ LANG_TEXT = {
"fr_FR": "Französisch",
"fi_FI": "Finnisch",
"pt_PT": "portugiesisch",
+ "fy_x-FY": "Frisian",
"it_IT": "Italienisch",
"no_NO": "Norwegisch",
"nl_NL": "Holländisch",
@@ -47,6 +50,7 @@ LANG_TEXT = {
"tr_TR": "Türkisch",
"de_DE": "Deutsch",
"ar_AE": "Arabisch",
+ "uk_UA": "Ukrainian",
"sv_SE": "Schwedisch",
"pl_PL": "Polnisch",
"T1": "Bitte benutzen Sie die Hoch/Runter-Tasten, um Ihre Sprache auszuwählen. Danach drücken Sie bitte OK.",
@@ -56,6 +60,7 @@ LANG_TEXT = {
"fr_FR": "French",
"fi_FI": "Finnish",
"pt_PT": "Portuguese",
+ "fy_x-FY": "Frisian",
"it_IT": "Italian",
"no_NO": "Norwegian",
"nl_NL": "Dutch",
@@ -73,6 +78,7 @@ LANG_TEXT = {
"tr_TR": "Turkish",
"de_DE": "المانـى",
"ar_AE": "Arabic",
+ "uk_UA": "Ukrainian",
"sv_SE": "Swedish",
"pl_PL": "Polish",
"T1": "Please use the UP and DOWN keys to select your language. Afterwards press the OK button.",
@@ -82,6 +88,7 @@ LANG_TEXT = {
"fr_FR": "Francès",
"fi_FI": "Finlandès",
"pt_PT": "Portuguès",
+ "fy_x-FY": "Frisian",
"it_IT": "Italià",
"no_NO": "Noruec",
"nl_NL": "Holandès",
@@ -99,6 +106,7 @@ LANG_TEXT = {
"tr_TR": "Turc",
"de_DE": "Alemany",
"ar_AE": "Àrab",
+ "uk_UA": "Ukrainian",
"sv_SE": "Suec",
"pl_PL": "Polish",
"T1": "Please use the UP and DOWN keys to select your language. Afterwards press the OK button.",
@@ -108,6 +116,7 @@ LANG_TEXT = {
"fr_FR": "Francuski",
"fi_FI": "Finski",
"pt_PT": "Portugalski",
+ "fy_x-FY": "Frisian",
"it_IT": "Talijanski",
"no_NO": "Norveški",
"nl_NL": "Nizozemski",
@@ -125,6 +134,7 @@ LANG_TEXT = {
"tr_TR": "Turski",
"de_DE": "NjemaÄki",
"ar_AE": "Arabski",
+ "uk_UA": "Ukrainian",
"sv_SE": "Å vedski",
"pl_PL": "Poljski",
"T1": "Please use the UP and DOWN keys to select your language. Afterwards press the OK button.",
@@ -134,6 +144,7 @@ LANG_TEXT = {
"fr_FR": "Francouzsky",
"fi_FI": "Finsky",
"pt_PT": "Portugalsky",
+ "fy_x-FY": "Frisian",
"it_IT": "Italsky",
"no_NO": "Norsky",
"nl_NL": "Holandsky",
@@ -151,6 +162,7 @@ LANG_TEXT = {
"tr_TR": "Turecky",
"de_DE": "Německy",
"ar_AE": "Arabsky",
+ "uk_UA": "Ukrainian",
"sv_SE": "Švédsky",
"pl_PL": "Polsky",
"T1": "Please use the UP and DOWN keys to select your language. Afterwards press the OK button.",
@@ -160,6 +172,7 @@ LANG_TEXT = {
"fr_FR": "Fransk",
"fi_FI": "Finsk",
"pt_PT": "Portugisisk",
+ "fy_x-FY": "Frisian",
"it_IT": "Italiensk",
"no_NO": "Norsk",
"nl_NL": "Hollandsk",
@@ -177,6 +190,7 @@ LANG_TEXT = {
"tr_TR": "Tyrkisk",
"de_DE": "Tysk",
"ar_AE": "Arabisk",
+ "uk_UA": "Ukrainian",
"sv_SE": "Svensk",
"pl_PL": "Polsk",
"T1": "Benyt venligst OP og NED tasten til at vælge sprog. Tryk bagefter på OK knappen.",
@@ -186,6 +200,7 @@ LANG_TEXT = {
"fr_FR": "Frans",
"fi_FI": "Fins",
"pt_PT": "Portugees",
+ "fy_x-FY": "Frisian",
"it_IT": "Italiaans",
"no_NO": "Noors",
"nl_NL": "Nederlands",
@@ -203,6 +218,7 @@ LANG_TEXT = {
"tr_TR": "Turks",
"de_DE": "Duits",
"ar_AE": "Arabisch",
+ "uk_UA": "Ukrainian",
"sv_SE": "Zweeds",
"pl_PL": "Pools",
"T1": "Gebruik de omhoog/omlaag toeten om de gewenste taal te selecteren. Druk daarna op OK.",
@@ -212,6 +228,7 @@ LANG_TEXT = {
"fr_FR": "Ranska",
"fi_FI": "Suomi",
"pt_PT": "Portugali",
+ "fy_x-FY": "Frisian",
"it_IT": "Italia",
"no_NO": "Norja",
"nl_NL": "Hollanti",
@@ -229,15 +246,17 @@ LANG_TEXT = {
"tr_TR": "Turkki",
"de_DE": "Saksa",
"ar_AE": "Arabia",
+ "uk_UA": "Ukrainian",
"sv_SE": "Ruotsi",
"pl_PL": "Puola",
- "T1": "Valitse kieli ylös/alas nappuloilla ja paina OK.",
+ "T1": "Valitse kieli ylös/alas näppäimillä ja paina OK-näppäintä.",
"T2": "Kielivalinta",
},
"fr_FR": {
"fr_FR": "Français",
"fi_FI": "Finlandais",
"pt_PT": "Portugais",
+ "fy_x-FY": "Frisian",
"it_IT": "Italien",
"no_NO": "Norvégien",
"nl_NL": "Hollandais",
@@ -255,6 +274,7 @@ LANG_TEXT = {
"tr_TR": "Turke",
"de_DE": "Allemand",
"ar_AE": "Arabe",
+ "uk_UA": "Ukrainian",
"sv_SE": "Suédois",
"pl_PL": "Polonais",
"T1": "Veuillez utiliser les touches HAUT et BAS pour choisir votre langage. Ensuite presser le bouton OK.",
@@ -264,6 +284,7 @@ LANG_TEXT = {
"fr_FR": "Γαλλικά",
"fi_FI": "Φιλλανδικά",
"pt_PT": "ΠοÏτογαλλικά",
+ "fy_x-FY": "Frisian",
"it_IT": "Ιταλικά",
"no_NO": "ÎοÏβηφικά",
"nl_NL": "Ολλανδικά",
@@ -281,6 +302,7 @@ LANG_TEXT = {
"tr_TR": "ΤοÏÏκικα",
"de_DE": "ΓεÏμανικά",
"ar_AE": "ΑÏαβικά",
+ "uk_UA": "Ukrainian",
"sv_SE": "Σουιδεζικά",
"pl_PL": "Πολωνικά",
"T1": "Please use the UP and DOWN keys to select your language. Afterwards press the OK button.",
@@ -290,6 +312,7 @@ LANG_TEXT = {
"fr_FR": "Francia",
"fi_FI": "Finn",
"pt_PT": "Portugál",
+ "fy_x-FY": "Frisian",
"it_IT": "Olasz",
"no_NO": "Norvég",
"nl_NL": "Holland",
@@ -307,6 +330,7 @@ LANG_TEXT = {
"tr_TR": "Török",
"de_DE": "Német",
"ar_AE": "Arab",
+ "uk_UA": "Ukrainian",
"sv_SE": "Svéd",
"pl_PL": "Lengyel",
"T1": "Please use the UP and DOWN keys to select your language. Afterwards press the OK button.",
@@ -316,6 +340,7 @@ LANG_TEXT = {
"fr_FR": "Prancūzų",
"fi_FI": "Suomių",
"pt_PT": "Portugalų",
+ "fy_x-FY": "Frisian",
"it_IT": "Italų",
"no_NO": "Norvegų",
"nl_NL": "Olandų",
@@ -333,6 +358,7 @@ LANG_TEXT = {
"tr_TR": "Turkų",
"de_DE": "VokieÄių",
"ar_AE": "Arabų",
+ "uk_UA": "UkrainieÄių",
"sv_SE": "Švedų",
"pl_PL": "Lenkų",
"T1": "Prašome naudoti AUKŠTYN IR ŽEMYN mygtukus, kad išsirinktumėte savo kalbą. Po to spauskite OK mygtuką.",
@@ -342,6 +368,7 @@ LANG_TEXT = {
"fr_FR": "Franska",
"fi_FI": "Finnska",
"pt_PT": "Portúgalska",
+ "fy_x-FY": "Frisian",
"it_IT": "Ãtalska",
"no_NO": "Norska",
"nl_NL": "Hollenska",
@@ -359,15 +386,17 @@ LANG_TEXT = {
"tr_TR": "Tyrkneska",
"de_DE": "Þýska",
"ar_AE": "Arabíska",
+ "uk_UA": "Ukrainian",
"sv_SE": "Sænskt",
"pl_PL": "Pólska",
- "T1": "Please use the UP and DOWN keys to select your language. Afterwards press the OK button.",
+ "T1": "Vinsamlega notið UP og NIÃUR takka til að velja tungumál. Ãttu svo á OK til að nota.",
"T2": "Val tungumáls",
},
"it_IT": {
"fr_FR": "Francese",
"fi_FI": "Finlandese",
"pt_PT": "Portoghese",
+ "fy_x-FY": "Frisian",
"it_IT": "Italiano",
"no_NO": "Norvegese",
"nl_NL": "Olandese",
@@ -385,6 +414,7 @@ LANG_TEXT = {
"tr_TR": "Turco",
"de_DE": "Tedesco",
"ar_AE": "Arabo",
+ "uk_UA": "Ucraino",
"sv_SE": "Svedese",
"pl_PL": "Polacco",
"T1": "Selezionare la propria lingua utilizzando i tasti Sù/Giù. Premere OK per confermare.",
@@ -394,6 +424,7 @@ LANG_TEXT = {
"fr_FR": "Fransk",
"fi_FI": "Finsk",
"pt_PT": "Portugisisk",
+ "fy_x-FY": "Frisian",
"it_IT": "Italiensk",
"no_NO": "Norsk",
"nl_NL": "Nederlandsk",
@@ -411,6 +442,7 @@ LANG_TEXT = {
"tr_TR": "Tyrkisk",
"de_DE": "Tysk",
"ar_AE": "Arabisk",
+ "uk_UA": "Ukrainian",
"sv_SE": "Svensk",
"pl_PL": "Polsk",
"T1": "Please use the UP and DOWN keys to select your language. Afterwards press the OK button.",
@@ -420,6 +452,7 @@ LANG_TEXT = {
"fr_FR": "Francuski",
"fi_FI": "Fiński",
"pt_PT": "Portugalski",
+ "fy_x-FY": "Frisian",
"it_IT": "Włoski",
"no_NO": "Norweski",
"nl_NL": "Holenderski",
@@ -437,6 +470,7 @@ LANG_TEXT = {
"tr_TR": "Turecki",
"de_DE": "Niemiecki",
"ar_AE": "Arabski",
+ "uk_UA": "Ukrainian",
"sv_SE": "Szwedzki",
"pl_PL": "Polski",
"T1": "W celu wyboru jÄ™zyka użyj klawiszy GÓRA i DÓÅ. Nastepnie nacisnij przycisk OK.",
@@ -446,6 +480,7 @@ LANG_TEXT = {
"fr_FR": "Francês",
"fi_FI": "Finlandês",
"pt_PT": "Português",
+ "fy_x-FY": "Frisian",
"it_IT": "Italiano",
"no_NO": "Norueguês",
"nl_NL": "Holandês",
@@ -463,6 +498,7 @@ LANG_TEXT = {
"tr_TR": "Turco",
"de_DE": "Alemão",
"ar_AE": "Arabe",
+ "uk_UA": "Ukrainian",
"sv_SE": "Sueco",
"pl_PL": "Polaco",
"T1": "Please use the UP and DOWN keys to select your language. Afterwards press the OK button.",
@@ -472,6 +508,7 @@ LANG_TEXT = {
"fr_FR": "ФранцузÑкий",
"fi_FI": "Окончание",
"pt_PT": "Portuguese",
+ "fy_x-FY": "Frisian",
"it_IT": "ИтальÑнÑкий",
"no_NO": "ÐорвежÑкий",
"nl_NL": "ÐидерландÑкий",
@@ -489,6 +526,7 @@ LANG_TEXT = {
"tr_TR": "Турецкий",
"de_DE": "Ðемецкий",
"ar_AE": "ÐрабÑкий",
+ "uk_UA": "Ukrainian",
"sv_SE": "ШведÑкий",
"pl_PL": "Polish",
"T1": "Please use the UP and DOWN keys to select your language. Afterwards press the OK button.",
@@ -498,6 +536,7 @@ LANG_TEXT = {
"fr_FR": "Francés",
"fi_FI": "Finlandés",
"pt_PT": "Portugués",
+ "fy_x-FY": "Frisian",
"it_IT": "Italiano",
"no_NO": "Noruego",
"nl_NL": "Alemán",
@@ -515,6 +554,7 @@ LANG_TEXT = {
"tr_TR": "Turco",
"de_DE": "Alemán",
"ar_AE": "Arábigo",
+ "uk_UA": "Ukrainian",
"sv_SE": "Sueco",
"pl_PL": "Polaco",
"T1": "Use las teclas ARRIBA y ABAJO para seleccionar su idioma. Después, pulse el botón OK.",
@@ -524,6 +564,7 @@ LANG_TEXT = {
"fr_FR": "Franska",
"fi_FI": "Finska",
"pt_PT": "Portugisiska",
+ "fy_x-FY": "Frisian",
"it_IT": "Italienska",
"no_NO": "Norska",
"nl_NL": "Holländska",
@@ -541,6 +582,7 @@ LANG_TEXT = {
"tr_TR": "Turkiska",
"de_DE": "Tyska",
"ar_AE": "Arabiska",
+ "uk_UA": "Ukrainian",
"sv_SE": "Svenska",
"pl_PL": "Polska",
"T1": "Vänligen använd UPP och NER pil för att välja språk. Efter val tryck på OK knappen.",
@@ -548,28 +590,86 @@ LANG_TEXT = {
},
"tr_TR": {
"fr_FR": "Fransızca",
- "fi_FI": "BitiÅŸ",
- "pt_PT": "Portuguese",
- "it_IT": "İtalya",
- "no_NO": "Norveç",
- "nl_NL": "Almanca",
+ "fi_FI": "Fince",
+ "pt_PT": "Portekizce",
+ "fy_x-FY": "Frisian",
+ "it_IT": "İtalyanca",
+ "no_NO": "Norveççe",
+ "nl_NL": "Flemenkçe",
"el_GR": "Greek",
- "hu_HU": "Hungarian",
- "lt_LT": "Lithuanian",
- "hr_HR": "Croatian",
+ "hu_HU": "Macarca",
+ "lt_LT": "Litvanyaca",
+ "hr_HR": "Hırvatça",
"en_EN": "İngilizce",
"es_ES": "İspanyolca",
- "ca_AD": "Catalan",
- "ru_RU": "Russian",
- "is_IS": "izlanda",
- "da_DK": "Çanak",
- "cs_CZ": "Czech",
- "tr_TR": "Turkish",
- "de_DE": "Alman",
+ "ca_AD": "Katalanca",
+ "ru_RU": "Rusça",
+ "is_IS": "İzlandaca",
+ "da_DK": "Danca",
+ "cs_CZ": "Çekçe",
+ "tr_TR": "Türkçe",
+ "de_DE": "Almanca",
"ar_AE": "Arapça",
- "sv_SE": "İsveç",
+ "uk_UA": "Ukraynaca",
+ "sv_SE": "İsveççe",
"pl_PL": "Polish",
- "T1": "Please use the UP and DOWN keys to select your language. Afterwards press the OK button.",
- "T2": "Lisan Seçimi",
+ "T1": "Dil seçiminizi, yapmak için YUKARI ve AŞAĞI tuşlarını, onaylamak için OK tuşunu kullanın.",
+ "T2": "Dil seçimi",
+},
+"uk_UA": {
+ "fr_FR": "Французька",
+ "fi_FI": "ФінÑька",
+ "pt_PT": "ПортугальÑька",
+ "fy_x-FY": "Frisian",
+ "it_IT": "ІталійÑька",
+ "no_NO": "ÐорвежÑька",
+ "nl_NL": "ДанÑька",
+ "el_GR": "Грецька",
+ "hu_HU": "УгорÑька",
+ "lt_LT": "ЛитовÑька",
+ "hr_HR": "ХорватьÑка",
+ "en_EN": "ÐнглійÑька",
+ "es_ES": "ІÑпанÑька",
+ "ca_AD": "КаталонÑька",
+ "ru_RU": "РоÑійÑька",
+ "is_IS": "ІÑландÑька",
+ "da_DK": "ДанÑька",
+ "cs_CZ": "ЧешÑька",
+ "tr_TR": "Турецька",
+ "de_DE": "Ðімецька",
+ "ar_AE": "ÐрабÑький",
+ "uk_UA": "Ukrainian",
+ "sv_SE": "ШведÑька",
+ "pl_PL": "ПольÑька",
+ "T1": "ВикориÑтовуйте кнопки ВВЕРХ Ñ– Ð’ÐИЗ, щоб вибрати Вашу мову. ПіÑÐ»Ñ Ð²Ð¸Ð±Ð¾Ñ€Ñƒ натиÑніть OK.",
+ "T2": "Вибір мови",
+},
+"fy_x-FY": {
+ "fr_FR": "Frans",
+ "fi_FI": "Finsk",
+ "pt_PT": "Portugeesk",
+ "fy_x-FY": "Frisian",
+ "it_IT": "Italiaansk",
+ "no_NO": "Noarsk",
+ "nl_NL": "Nederlansk",
+ "el_GR": "Gryks",
+ "hu_HU": "Hongaarsk",
+ "lt_LT": "Lithuaniansk",
+ "hr_HR": "Kroatysk",
+ "en_EN": "Engelsk",
+ "es_ES": "Spaans",
+ "ca_AD": "Catalânsk",
+ "ru_RU": "Russysk",
+ "is_IS": "Iislansk",
+ "da_DK": "Deensk",
+ "cs_CZ": "Tsjechysk",
+ "tr_TR": "Turks",
+ "de_DE": "Dúts",
+ "ar_AE": "Arabysk",
+ "uk_UA": "Ukrainian",
+ "sv_SE": "Zweeds",
+ "pl_PL": "Poolsk",
+ "T1": "Brúk de op en del toets om jo taal te kiezen. Dernei druk op OK",
+ "T2": "Taal Kieze",
},
}
diff --git a/lib/python/Plugins/DemoPlugins/TestPlugin/plugin.py b/lib/python/Plugins/DemoPlugins/TestPlugin/plugin.py
index a63562c8..69f935e4 100644
--- a/lib/python/Plugins/DemoPlugins/TestPlugin/plugin.py
+++ b/lib/python/Plugins/DemoPlugins/TestPlugin/plugin.py
@@ -51,7 +51,7 @@ class Test(Screen):
def mycallback(self, answer):
print "answer:", answer
if answer:
- raise "test-crash"
+ raise Exception("test-crash")
self.close()
def keyLeft(self):
diff --git a/lib/python/Plugins/Extensions/CutListEditor/plugin.py b/lib/python/Plugins/Extensions/CutListEditor/plugin.py
index 0d2454e4..1ef15a53 100644
--- a/lib/python/Plugins/Extensions/CutListEditor/plugin.py
+++ b/lib/python/Plugins/Extensions/CutListEditor/plugin.py
@@ -12,10 +12,12 @@ from Components.GUIComponent import GUIComponent
from enigma import eListboxPythonMultiContent, eListbox, gFont, iPlayableService, RT_HALIGN_RIGHT
from Screens.FixedMenu import FixedMenu
from Screens.HelpMenu import HelpableScreen
+from ServiceReference import ServiceReference
+from Components.Sources.List import List
+
import bisect
def CutListEntry(where, what):
- res = [ (where, what) ]
w = where / 90
ms = w % 1000
s = (w / 1000) % 60
@@ -23,16 +25,17 @@ def CutListEntry(where, what):
h = w / 3600000
if what == 0:
type = "IN"
+ type_col = 0x004000
elif what == 1:
type = "OUT"
+ type_col = 0x400000
elif what == 2:
type = "MARK"
+ type_col = 0x000040
elif what == 3:
type = "LAST"
- res.append(MultiContentEntryText(size=(400, 20), text = "%dh:%02dm:%02ds:%03d" % (h, m, s, ms)))
- res.append(MultiContentEntryText(pos=(400,0), size=(130, 20), text = type, flags = RT_HALIGN_RIGHT))
-
- return res
+ type_col = 0x000000
+ return ((where, what), "%dh:%02dm:%02ds:%03d" % (h, m, s, ms), type, type_col)
class CutListContextMenu(FixedMenu):
RET_STARTCUT = 0
@@ -42,6 +45,7 @@ class CutListContextMenu(FixedMenu):
RET_DELETEMARK = 4
RET_REMOVEBEFORE = 5
RET_REMOVEAFTER = 6
+ RET_GRABFRAME = 7
SHOW_STARTCUT = 0
SHOW_ENDCUT = 1
@@ -75,6 +79,7 @@ class CutListContextMenu(FixedMenu):
else:
menu.append((_("remove this mark"), self.removeMark))
+ menu.append((("grab this frame as bitmap"), self.grabFrame))
FixedMenu.__init__(self, session, _("Cut"), menu)
self.skinName = "Menu"
@@ -99,50 +104,8 @@ class CutListContextMenu(FixedMenu):
def removeAfter(self):
self.close(self.RET_REMOVEAFTER)
-
-class CutList(GUIComponent):
- def __init__(self, list):
- GUIComponent.__init__(self)
- self.l = eListboxPythonMultiContent()
- self.setList(list)
- self.l.setFont(0, gFont("Regular", 20))
- self.onSelectionChanged = [ ]
-
- def getCurrent(self):
- return self.l.getCurrentSelection()
-
- def getCurrentIndex(self):
- return self.l.getCurrentSelectionIndex()
-
- GUI_WIDGET = eListbox
-
- def postWidgetCreate(self, instance):
- instance.setContent(self.l)
- instance.setItemHeight(30)
- instance.selectionChanged.get().append(self.selectionChanged)
-
- def preWidgetRemove(self, instance):
- instance.setContent(None)
- instance.selectionChanged.get().remove(self.selectionChanged)
-
- def selectionChanged(self):
- for x in self.onSelectionChanged:
- x()
-
- def invalidateEntry(self, index):
- self.l.invalidateEntry(index)
-
- def setIndex(self, index, data):
- self.list[index] = data
- self.invalidateEntry(index)
-
- def setList(self, list):
- self.list = list
- self.l.setList(self.list)
-
- def setSelection(self, index):
- if self.instance is not None:
- self.instance.moveSelectionTo(index)
+ def grabFrame(self):
+ self.close(self.RET_GRABFRAME)
class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, HelpableScreen):
skin = """
@@ -161,7 +124,17 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
</widget>
<eLabel position="62,98" size="179,274" backgroundColor="#505555" />
<eLabel position="64,100" size="175,270" backgroundColor="#000000" />
- <widget name="Cutlist" position="64,100" zPosition="1" size="175,270" scrollbarMode="showOnDemand" transparent="1" />
+ <widget source="cutlist" position="64,100" zPosition="1" size="175,270" scrollbarMode="showOnDemand" transparent="1" render="Listbox" >
+ <convert type="TemplatedMultiContent">
+ {"template": [
+ MultiContentEntryText(size=(125, 20), text = 1, backcolor = MultiContentTemplateColor(3)),
+ MultiContentEntryText(pos=(125,0), size=(50, 20), text = 2, flags = RT_HALIGN_RIGHT, backcolor = MultiContentTemplateColor(3))
+ ],
+ "fonts": [gFont("Regular", 18)],
+ "itemHeight": 20
+ }
+ </convert>
+ </widget>
<widget name="Timeline" position="50,485" size="615,20" backgroundColor="#505555" pointer="skin_default/position_arrow.png:3,5" foregroundColor="black" />
<ePixmap pixmap="skin_default/icons/mp_buttons.png" position="305,515" size="109,13" alphatest="on" />
</screen>"""
@@ -186,8 +159,8 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
self.downloadCuesheet()
self["Timeline"] = ServicePositionGauge(self.session.nav)
- self["Cutlist"] = CutList(self.getCutlist())
- self["Cutlist"].onSelectionChanged.append(self.selectionChanged)
+ self["cutlist"] = List(self.getCutlist())
+ self["cutlist"].onSelectionChanged.append(self.selectionChanged)
self["Video"] = VideoWindow(decoder = 0)
@@ -229,20 +202,20 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
def setType(self, index, type):
if len(self.cut_list):
self.cut_list[index] = (self.cut_list[index][0], type)
- self["Cutlist"].setIndex(index, CutListEntry(*self.cut_list[index]))
+ self["cutlist"].modifyEntry(index, CutListEntry(*self.cut_list[index]))
def setIn(self):
- m = self["Cutlist"].getCurrentIndex()
+ m = self["cutlist"].getIndex()
self.setType(m, 0)
self.uploadCuesheet()
def setOut(self):
- m = self["Cutlist"].getCurrentIndex()
+ m = self["cutlist"].getIndex()
self.setType(m, 1)
self.uploadCuesheet()
def setMark(self):
- m = self["Cutlist"].getCurrentIndex()
+ m = self["cutlist"].getIndex()
self.setType(m, 2)
self.uploadCuesheet()
@@ -250,7 +223,7 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
self.toggleMark(onlyadd=True, tolerance=90000) # do not allow two marks in <1s
def __removeMark(self):
- m = self["Cutlist"].getCurrent()
+ m = self["cutlist"].getCurrent()
m = m and m[0]
if m is not None:
self.removeMark(m)
@@ -265,7 +238,7 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
return r
def selectionChanged(self):
- where = self["Cutlist"].getCurrent()
+ where = self["cutlist"].getCurrent()
if where is None:
print "no selection"
return
@@ -282,11 +255,11 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
# get the first changed entry, and select it
new_list = self.getCutlist()
- self["Cutlist"].setList(new_list)
+ self["cutlist"].list = new_list
for i in range(min(len(new_list), len(self.last_cuts))):
if new_list[i] != self.last_cuts[i]:
- self["Cutlist"].setSelection(i)
+ self["cutlist"].setIndex(i)
break
self.last_cuts = new_list
@@ -390,6 +363,8 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
# add 'out' point
bisect.insort(self.cut_list, (self.context_position, 1))
self.uploadCuesheet()
+ elif result == CutListContextMenu.RET_GRABFRAME:
+ self.grabFrame()
# we modify the "play" behavior a bit:
# if we press pause while being in slowmotion, we will pause (and not play)
@@ -399,6 +374,14 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
else:
self.pauseService()
+ def grabFrame(self):
+ path = self.session.nav.getCurrentlyPlayingServiceReference().getPath()
+ from Components.Console import Console
+ grabConsole = Console()
+ cmd = 'grab -vblpr%d "%s"' % (180, path.rsplit('.',1)[0] + ".png")
+ grabConsole.ePopen(cmd)
+ self.playpauseService()
+
def main(session, service, **kwargs):
session.open(CutListEditor, service)
diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py
index 112a221e..b0b8197a 100644
--- a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py
+++ b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py
@@ -1,18 +1,10 @@
from Tools.Directories import fileExists
-from Components.config import config, ConfigSubsection, ConfigInteger, ConfigText, ConfigSelection, getConfigListEntry, ConfigSequence
+from Components.config import config, ConfigSubsection, ConfigInteger, ConfigText, ConfigSelection, getConfigListEntry, ConfigSequence, ConfigSubList
class ConfigColor(ConfigSequence):
def __init__(self):
ConfigSequence.__init__(self, seperator = "#", limits = [(0,255),(0,255),(0,255)])
-class ConfigPixelvals(ConfigSequence):
- def __init__(self):
- ConfigSequence.__init__(self, seperator = ",", limits = [(0,200),(0,200),(0,200)])
-
-class ConfigPixelvals(ConfigSequence):
- def __init__(self):
- ConfigSequence.__init__(self, seperator = ",", limits = [(0,200),(0,200),(0,200)])
-
class ConfigFilename(ConfigText):
def __init__(self):
ConfigText.__init__(self, default = "", fixed_size = True, visible_width = False)
@@ -35,19 +27,11 @@ class DVDProject:
self.settings.titlesetmode = ConfigSelection(choices = [("single", _("Simple titleset (compatibility for legacy players)")), ("multi", _("Complex (allows mixing audio tracks and aspects)"))], default="multi")
self.settings.output = ConfigSelection(choices = [("iso", _("Create DVD-ISO")), ("dvd", _("Burn DVD"))])
self.settings.isopath = ConfigText(fixed_size = False, visible_width = 40)
- self.settings.dataformat = ConfigSelection(choices = [("iso9660_1", ("ISO9660 Level 1")), ("iso9660_4", ("ISO9660 version 2")), ("udf", ("UDF"))])
- self.settings.menubg = ConfigFilename()
- self.settings.menuaudio = ConfigFilename()
- self.settings.titleformat = ConfigText(fixed_size = False, visible_width = 40)
- self.settings.subtitleformat = ConfigText(fixed_size = False, visible_width = 40)
- self.settings.color_headline = ConfigColor()
- self.settings.color_highlight = ConfigColor()
- self.settings.color_button = ConfigColor()
- self.settings.font_face = ConfigFilename()
- self.settings.font_size = ConfigPixelvals()
- self.settings.space = ConfigPixelvals()
+ self.settings.dataformat = ConfigSelection(choices = [("iso9660_1", ("ISO9660 Level 1")), ("iso9660_4", ("ISO9660 version 2")), ("udf", ("UDF"))])
+ self.settings.menutemplate = ConfigFilename()
self.settings.vmgm = ConfigFilename()
- self.filekeys = ["vmgm", "menubg", "menuaudio", "font_face", "isopath"]
+ self.filekeys = ["vmgm", "isopath", "menutemplate"]
+ self.menutemplate = MenuTemplate()
def addService(self, service):
import DVDTitle
@@ -65,12 +49,30 @@ class DVDProject:
list.append('\t<settings ')
for key, val in self.settings.dict().iteritems():
list.append( key + '="' + str(val.getValue()) + '" ' )
- list.append(' />\n')
+ list.append('/>\n')
list.append('\t<titles>\n')
for title in self.titles:
- list.append('\t\t<path>')
+ list.append('\t\t<title>\n')
+ list.append('\t\t\t<path>')
list.append(stringToXML(title.source.getPath()))
list.append('</path>\n')
+ list.append('\t\t\t<properties ')
+ audiotracks = []
+ for key, val in title.properties.dict().iteritems():
+ if type(val) is ConfigSubList:
+ audiotracks.append('\t\t\t<audiotracks>\n')
+ for audiotrack in val:
+ audiotracks.append('\t\t\t\t<audiotrack ')
+ for subkey, subval in audiotrack.dict().iteritems():
+ audiotracks.append( subkey + '="' + str(subval.getValue()) + '" ' )
+ audiotracks.append(' />\n')
+ audiotracks.append('\t\t\t</audiotracks>\n')
+ else:
+ list.append( key + '="' + str(val.getValue()) + '" ' )
+ list.append('/>\n')
+ for line in audiotracks:
+ list.append(line)
+ list.append('\t\t</title>\n')
list.append('\t</titles>\n')
list.append('</DreamDVDBurnerProject>\n')
@@ -89,6 +91,13 @@ class DVDProject:
return False
return filename
+ def load(self, filename):
+ ret = self.loadProject(filename)
+ if ret:
+ ret = self.menutemplate.loadTemplate(self.settings.menutemplate.getValue())
+ self.error += self.menutemplate.error
+ return ret
+
def loadProject(self, filename):
import xml.dom.minidom
try:
@@ -105,9 +114,9 @@ class DVDProject:
if project.nodeType == xml.dom.minidom.Element.nodeType:
if project.tagName == 'settings':
i = 0
- if project.attributes.length < 11:
+ if project.attributes.length < len(self.settings.dict()):
self.error = "project attributes missing"
- raise AttributeError
+ raise AttributeError
while i < project.attributes.length:
item = project.attributes.item(i)
key = item.name.encode("utf-8")
@@ -131,3 +140,44 @@ class DVDProject:
self.error += (" in project '%s'") % (filename)
return False
return True
+
+class MenuTemplate(DVDProject):
+ def __init__(self):
+ self.settings = ConfigSubsection()
+ self.settings.titleformat = ConfigText(fixed_size = False, visible_width = 40)
+ self.settings.subtitleformat = ConfigText(fixed_size = False, visible_width = 40)
+ self.settings.menubg = ConfigFilename()
+ self.settings.menuaudio = ConfigFilename()
+ self.settings.dimensions = ConfigSequence(seperator = ',', default = [576,720], limits = [(352,720),(480,576)])
+ self.settings.rows = ConfigInteger(default = 4, limits = (1, 10))
+ self.settings.cols = ConfigInteger(default = 1, limits = (1, 4))
+ self.settings.color_headline = ConfigColor()
+ self.settings.color_headline = ConfigColor()
+ self.settings.color_highlight = ConfigColor()
+ self.settings.color_button = ConfigColor()
+ self.settings.fontface_headline = ConfigFilename()
+ self.settings.fontface_title = ConfigFilename()
+ self.settings.fontface_subtitle = ConfigFilename()
+ self.settings.fontsize_headline = ConfigInteger(default = 46, limits = (0, 199))
+ self.settings.fontsize_title = ConfigInteger(default = 24, limits = (0, 199))
+ self.settings.fontsize_subtitle = ConfigInteger(default = 14, limits = (0, 199))
+ self.settings.margin_top = ConfigInteger(default = 120, limits = (0, 500))
+ self.settings.margin_bottom = ConfigInteger(default = 40, limits = (0, 500))
+ self.settings.margin_left = ConfigInteger(default = 56, limits = (0, 500))
+ self.settings.margin_right = ConfigInteger(default = 56, limits = (0, 500))
+ self.settings.space_rows = ConfigInteger(default = 32, limits = (0, 500))
+ self.settings.space_cols = ConfigInteger(default = 24, limits = (0, 500))
+ self.settings.prev_page_text = ConfigText(default = "<<<", fixed_size = False)
+ self.settings.next_page_text = ConfigText(default = ">>>", fixed_size = False)
+ self.settings.offset_headline = ConfigSequence(seperator = ',', default = [0,0], limits = [(-1,500),(-1,500)])
+ self.settings.offset_title = ConfigSequence(seperator = ',', default = [0,0], limits = [(-1,500),(-1,500)])
+ self.settings.offset_subtitle = ConfigSequence(seperator = ',', default = [20,0], limits = [(-1,500),(-1,500)])
+ self.settings.offset_thumb = ConfigSequence(seperator = ',', default = [40,0], limits = [(-1,500),(-1,500)])
+ self.settings.thumb_size = ConfigSequence(seperator = ',', default = [200,158], limits = [(0,576),(-1,720)])
+ self.settings.thumb_border = ConfigInteger(default = 2, limits = (0, 20))
+ self.filekeys = ["menubg", "menuaudio", "fontface_headline", "fontface_title", "fontface_subtitle"]
+
+ def loadTemplate(self, filename):
+ ret = DVDProject.loadProject(self, filename)
+ DVDProject.error = self.error
+ return ret
diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py b/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py
index b1c627aa..660005e6 100644
--- a/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py
+++ b/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py
@@ -51,11 +51,11 @@ class DVDTitle:
self.length = info.getLength(service)
def initDVDmenuText(self, project, track):
- self.properties.menutitle.setValue(self.formatDVDmenuText(project.settings.titleformat.getValue(), track))
- self.properties.menusubtitle.setValue(self.formatDVDmenuText(project.settings.subtitleformat.getValue(), track))
+ s = project.menutemplate.settings
+ self.properties.menutitle.setValue(self.formatDVDmenuText(s.titleformat.getValue(), track))
+ self.properties.menusubtitle.setValue(self.formatDVDmenuText(s.subtitleformat.getValue(), track))
def formatDVDmenuText(self, template, track):
- properties = self.properties
template = template.replace("$i", str(track))
template = template.replace("$t", self.DVBname)
template = template.replace("$d", self.DVBdescr)
@@ -76,7 +76,7 @@ class DVDTitle:
audiolist.append(trackstring)
audiostring = ', '.join(audiolist)
template = template.replace("$A", audiostring)
-
+
if template.find("$l") >= 0:
l = self.length
lengthstring = "%d:%02d:%02d" % (l/3600, l%3600/60, l%60)
@@ -90,7 +90,7 @@ class DVDTitle:
else:
template = template.replace("$Y", "").replace("$M", "").replace("$D", "").replace("$T", "")
return template
-
+
def produceFinalCuesheet(self):
CUT_TYPE_IN = 0
CUT_TYPE_OUT = 1
diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py
index 836c9fbd..ce16259e 100644
--- a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py
+++ b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py
@@ -50,7 +50,7 @@ class DVDToolbox(Screen):
"green": self.update,
"yellow": self.format,
#"blue": self.eject,
- "cancel": self.close,
+ "cancel": self.exit,
"pageUp": self.pageUp,
"pageDown": self.pageDown
})
@@ -63,7 +63,7 @@ class DVDToolbox(Screen):
def pageDown(self):
self["details"].pageDown()
- def update(self, dev="", media_state=""):
+ def update(self, dev="", action=""):
self["space_label"].text = _("Please wait... Loading list...")
self["info"].text = ""
self["details"].setText("")
@@ -89,7 +89,7 @@ class DVDToolbox(Screen):
for line in mediuminfo.splitlines():
if line.find("Mounted Media:") > -1:
mediatype = line.rsplit(',',1)[1][1:]
- if mediatype.find("RW") > 0:
+ if mediatype.find("RW") > 0 or mediatype.find("RAM") > 0:
self.formattable = True
else:
self.formattable = False
@@ -186,7 +186,7 @@ class DVDformatTask(Task):
if line.startswith("- media is already formatted"):
self.error = self.ERROR_ALREADYFORMATTED
self.retryargs = [ "-force" ]
- if line.startswith("- media is not blank"):
+ if line.startswith("- media is not blank") or line.startswith(" -format=full to perform full (lengthy) reformat;"):
self.error = self.ERROR_ALREADYFORMATTED
self.retryargs = [ "-blank" ]
if line.startswith(":-( mounted media doesn't appear to be"):
diff --git a/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVD.ddvdp.xml b/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVD.ddvdp.xml
new file mode 100644
index 00000000..2c35e531
--- /dev/null
+++ b/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVD.ddvdp.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<DreamDVDBurnProject>
+ <settings
+ name="Dreambox DVD record"
+ authormode="menu_linked"
+ menutemplate="/usr/lib/enigma2/python/Plugins/Extensions/DVDBurn/Thumbs menu clouds.ddvdm.xml"
+ titlesetmode="multi"
+ vmgm="/usr/lib/enigma2/python/Plugins/Extensions/DVDBurn/vmgmdream.mpg"
+ output="dvd"
+ isopath="/media/hdd/movie/"
+ dataformat="iso9660_4"
+ />
+ <titles> </titles>
+</DreamDVDBurnProject>
diff --git a/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVDtemplate.ddvdp.xml b/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVDtemplate.ddvdp.xml
deleted file mode 100644
index 7d8de8ce..00000000
--- a/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVDtemplate.ddvdp.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<DreamDVDBurnerProject>
- <settings
- name="Dreambox DVD record"
- authormode="menu_linked"
- titlesetmode="multi"
- titleformat="$i. $t"
- subtitleformat="$D.$M.$Y, $T $C, $d"
- vmgm="/usr/lib/enigma2/python/Plugins/Extensions/DVDBurn/vmgmdream.mpg"
- menubg="/usr/lib/enigma2/python/Plugins/Extensions/DVDBurn/dreamdvd_boat.jpg"
- menuaudio="/usr/lib/enigma2/python/Plugins/Extensions/DVDBurn/silence.mp2"
- color_button="[8, 0, 0]"
- color_highlight="[0, 192, 192]"
- color_headline="[0, 0, 128]"
- font_face="/usr/share/fonts/nmsbd.ttf"
- font_size="[46, 24, 14]"
- space="[120, 32, 56]"
- output="dvd"
- isopath="/media/hdd/movie/"
- dataformat="iso9660_4"
- />
- <titles> </titles>
-</DreamDVDBurnerProject>
diff --git a/lib/python/Plugins/Extensions/DVDBurn/Process.py b/lib/python/Plugins/Extensions/DVDBurn/Process.py
index 89ca90fd..d0c9d3c6 100644
--- a/lib/python/Plugins/Extensions/DVDBurn/Process.py
+++ b/lib/python/Plugins/Extensions/DVDBurn/Process.py
@@ -165,7 +165,7 @@ class DemuxTask(Task):
def cleanup(self, failed):
if failed:
import os
- for file in self.generated_files.itervalues():
+ for file in self.generated_files:
os.remove(file)
class MplexTaskPostcondition(Condition):
@@ -220,7 +220,7 @@ class RemoveESFiles(Task):
def prepare(self):
self.args += ["-f"]
- self.args += self.demux_task.generated_files.values()
+ self.args += self.demux_task.generated_files
self.args += [self.demux_task.cutfile]
class DVDAuthorTask(Task):
@@ -368,6 +368,9 @@ class CheckDiskspaceTask(Task):
self.global_preconditions.append(DiskspacePrecondition(diskSpaceNeeded))
self.weighting = 5
+ def abort(self):
+ self.finish(aborted = True)
+
def run(self, callback):
failed_preconditions = self.checkPreconditions(True) + self.checkPreconditions(False)
if len(failed_preconditions):
@@ -452,13 +455,13 @@ class ImagePrepareTask(Task):
try:
from ImageFont import truetype
from Image import open as Image_open
- s = self.job.project.settings
+ s = self.job.project.menutemplate.settings
+ (width, height) = s.dimensions.getValue()
self.Menus.im_bg_orig = Image_open(s.menubg.getValue())
- if self.Menus.im_bg_orig.size != (self.Menus.imgwidth, self.Menus.imgheight):
- self.Menus.im_bg_orig = self.Menus.im_bg_orig.resize((720, 576))
- self.Menus.fontsizes = s.font_size.getValue()
- fontface = s.font_face.getValue()
- self.Menus.fonts = [truetype(fontface, self.Menus.fontsizes[0]), truetype(fontface, self.Menus.fontsizes[1]), truetype(fontface, self.Menus.fontsizes[2])]
+ if self.Menus.im_bg_orig.size != (width, height):
+ self.Menus.im_bg_orig = self.Menus.im_bg_orig.resize((width, height))
+ self.Menus.fontsizes = [s.fontsize_headline.getValue(), s.fontsize_title.getValue(), s.fontsize_subtitle.getValue()]
+ self.Menus.fonts = [(truetype(s.fontface_headline.getValue(), self.Menus.fontsizes[0])), (truetype(s.fontface_title.getValue(), self.Menus.fontsizes[1])),(truetype(s.fontface_subtitle.getValue(), self.Menus.fontsizes[2]))]
Task.processFinished(self, 0)
except:
Task.processFinished(self, 1)
@@ -477,98 +480,158 @@ class MenuImageTask(Task):
def run(self, callback):
self.callback = callback
- try:
- import ImageDraw, Image, os
- s = self.job.project.settings
- fonts = self.Menus.fonts
- im_bg = self.Menus.im_bg_orig.copy()
- im_high = Image.new("P", (self.Menus.imgwidth, self.Menus.imgheight), 0)
- im_high.putpalette(self.Menus.spu_palette)
- draw_bg = ImageDraw.Draw(im_bg)
- draw_high = ImageDraw.Draw(im_high)
- if self.menu_count == 1:
- headline = s.name.getValue().decode("utf-8")
- textsize = draw_bg.textsize(headline, font=fonts[0])
- if textsize[0] > self.Menus.imgwidth:
- offset = (0 , 20)
- else:
- offset = (((self.Menus.imgwidth-textsize[0]) / 2) , 20)
- draw_bg.text(offset, headline, fill=self.Menus.color_headline, font=fonts[0])
- spuxml = """<?xml version="1.0" encoding="utf-8"?>
- <subpictures>
- <stream>
- <spu
- highlight="%s"
- transparent="%02x%02x%02x"
- start="00:00:00.00"
- force="yes" >""" % (self.highlightpngfilename, self.Menus.spu_palette[0], self.Menus.spu_palette[1], self.Menus.spu_palette[2])
- s_top, s_rows, s_left = s.space.getValue()
- rowheight = (self.Menus.fontsizes[1]+self.Menus.fontsizes[2]+s_rows)
- menu_start_title = (self.menu_count-1)*self.job.titles_per_menu + 1
- menu_end_title = (self.menu_count)*self.job.titles_per_menu + 1
- nr_titles = len(self.job.project.titles)
- if menu_end_title > nr_titles:
- menu_end_title = nr_titles+1
- menu_i = 0
- for title_no in range( menu_start_title , menu_end_title ):
- menu_i += 1
- title = self.job.project.titles[title_no-1]
- top = s_top + ( menu_i * rowheight )
- titleText = title.formatDVDmenuText(s.titleformat.getValue(), title_no).decode("utf-8")
- draw_bg.text((s_left,top), titleText, fill=self.Menus.color_button, font=fonts[1])
- draw_high.text((s_left,top), titleText, fill=1, font=self.Menus.fonts[1])
- subtitleText = title.formatDVDmenuText(s.subtitleformat.getValue(), title_no).decode("utf-8")
- draw_bg.text((s_left,top+36), subtitleText, fill=self.Menus.color_button, font=fonts[2])
- bottom = top+rowheight
- if bottom > self.Menus.imgheight:
- bottom = self.Menus.imgheight
- spuxml += """
- <button name="button%s" x0="%d" x1="%d" y0="%d" y1="%d"/>""" % (str(title_no).zfill(2),s_left,self.Menus.imgwidth,top,bottom )
- if self.menu_count < self.job.nr_menus:
- next_page_text = ">>>"
- textsize = draw_bg.textsize(next_page_text, font=fonts[1])
- offset = ( self.Menus.imgwidth-textsize[0]-2*s_left, s_top + ( self.job.titles_per_menu * rowheight ) )
- draw_bg.text(offset, next_page_text, fill=self.Menus.color_button, font=fonts[1])
- draw_high.text(offset, next_page_text, fill=1, font=fonts[1])
- spuxml += """
- <button name="button_next" x0="%d" x1="%d" y0="%d" y1="%d"/>""" % (offset[0],offset[0]+textsize[0],offset[1],offset[1]+textsize[1])
- if self.menu_count > 1:
- prev_page_text = "<<<"
- textsize = draw_bg.textsize(prev_page_text, font=fonts[1])
- offset = ( 2*s_left, s_top + ( self.job.titles_per_menu * rowheight ) )
- draw_bg.text(offset, prev_page_text, fill=self.Menus.color_button, font=fonts[1])
- draw_high.text(offset, prev_page_text, fill=1, font=fonts[1])
- spuxml += """
- <button name="button_prev" x0="%d" x1="%d" y0="%d" y1="%d"/>""" % (offset[0],offset[0]+textsize[0],offset[1],offset[1]+textsize[1])
- del draw_bg
- del draw_high
- fd=open(self.menubgpngfilename,"w")
- im_bg.save(fd,"PNG")
- fd.close()
- fd=open(self.highlightpngfilename,"w")
- im_high.save(fd,"PNG")
- fd.close()
+ #try:
+ import ImageDraw, Image, os
+ s = self.job.project.menutemplate.settings
+ s_top = s.margin_top.getValue()
+ s_bottom = s.margin_bottom.getValue()
+ s_left = s.margin_left.getValue()
+ s_right = s.margin_right.getValue()
+ s_rows = s.space_rows.getValue()
+ s_cols = s.space_cols.getValue()
+ nr_cols = s.cols.getValue()
+ nr_rows = s.rows.getValue()
+ thumb_size = s.thumb_size.getValue()
+ if thumb_size[0]:
+ from Image import open as Image_open
+ (s_width, s_height) = s.dimensions.getValue()
+ fonts = self.Menus.fonts
+ im_bg = self.Menus.im_bg_orig.copy()
+ im_high = Image.new("P", (s_width, s_height), 0)
+ im_high.putpalette(self.Menus.spu_palette)
+ draw_bg = ImageDraw.Draw(im_bg)
+ draw_high = ImageDraw.Draw(im_high)
+ if self.menu_count == 1:
+ headlineText = self.job.project.settings.name.getValue().decode("utf-8")
+ headlinePos = self.getPosition(s.offset_headline.getValue(), 0, 0, s_width, s_top, draw_bg.textsize(headlineText, font=fonts[0]))
+ draw_bg.text(headlinePos, headlineText, fill=self.Menus.color_headline, font=fonts[0])
+ spuxml = """<?xml version="1.0" encoding="utf-8"?>
+ <subpictures>
+ <stream>
+ <spu
+ highlight="%s"
+ transparent="%02x%02x%02x"
+ start="00:00:00.00"
+ force="yes" >""" % (self.highlightpngfilename, self.Menus.spu_palette[0], self.Menus.spu_palette[1], self.Menus.spu_palette[2])
+ #rowheight = (self.Menus.fontsizes[1]+self.Menus.fontsizes[2]+thumb_size[1]+s_rows)
+ menu_start_title = (self.menu_count-1)*self.job.titles_per_menu + 1
+ menu_end_title = (self.menu_count)*self.job.titles_per_menu + 1
+ nr_titles = len(self.job.project.titles)
+ if menu_end_title > nr_titles:
+ menu_end_title = nr_titles+1
+ col = 1
+ row = 1
+ for title_no in range( menu_start_title , menu_end_title ):
+ title = self.job.project.titles[title_no-1]
+ col_width = ( s_width - s_left - s_right ) / nr_cols
+ row_height = ( s_height - s_top - s_bottom ) / nr_rows
+ left = s_left + ( (col-1) * col_width ) + s_cols/2
+ right = left + col_width - s_cols
+ top = s_top + ( (row-1) * row_height) + s_rows/2
+ bottom = top + row_height - s_rows
+ width = right - left
+ height = bottom - top
+
+ if bottom > s_height:
+ bottom = s_height
+ #draw_bg.rectangle((left, top, right, bottom), outline=(255,0,0))
+ im_cell_bg = Image.new("RGBA", (width, height),(0,0,0,0))
+ draw_cell_bg = ImageDraw.Draw(im_cell_bg)
+ im_cell_high = Image.new("P", (width, height), 0)
+ im_cell_high.putpalette(self.Menus.spu_palette)
+ draw_cell_high = ImageDraw.Draw(im_cell_high)
+
+ if thumb_size[0]:
+ thumbPos = self.getPosition(s.offset_thumb.getValue(), 0, 0, width, height, thumb_size)
+ box = (thumbPos[0], thumbPos[1], thumbPos[0]+thumb_size[0], thumbPos[1]+thumb_size[1])
+ try:
+ thumbIm = Image_open(title.inputfile.rsplit('.',1)[0] + ".png")
+ im_cell_bg.paste(thumbIm,thumbPos)
+ except:
+ draw_cell_bg.rectangle(box, fill=(64,127,127,127))
+ border = s.thumb_border.getValue()
+ if border:
+ draw_cell_high.rectangle(box, fill=1)
+ draw_cell_high.rectangle((box[0]+border, box[1]+border, box[2]-border, box[3]-border), fill=0)
+
+ titleText = title.formatDVDmenuText(s.titleformat.getValue(), title_no).decode("utf-8")
+ titlePos = self.getPosition(s.offset_title.getValue(), 0, 0, width, height, draw_bg.textsize(titleText, font=fonts[1]))
+
+ draw_cell_bg.text(titlePos, titleText, fill=self.Menus.color_button, font=fonts[1])
+ draw_cell_high.text(titlePos, titleText, fill=1, font=self.Menus.fonts[1])
+
+ subtitleText = title.formatDVDmenuText(s.subtitleformat.getValue(), title_no).decode("utf-8")
+ subtitlePos = self.getPosition(s.offset_subtitle.getValue(), 0, 0, width, height, draw_cell_bg.textsize(subtitleText, font=fonts[2]))
+ draw_cell_bg.text(subtitlePos, subtitleText, fill=self.Menus.color_button, font=fonts[2])
+
+ del draw_cell_bg
+ del draw_cell_high
+ im_bg.paste(im_cell_bg,(left, top, right, bottom), mask=im_cell_bg)
+ im_high.paste(im_cell_high,(left, top, right, bottom))
+
spuxml += """
- </spu>
- </stream>
- </subpictures>"""
-
- f = open(self.spuxmlfilename, "w")
- f.write(spuxml)
- f.close()
- Task.processFinished(self, 0)
- except:
- Task.processFinished(self, 1)
+ <button name="button%s" x0="%d" x1="%d" y0="%d" y1="%d"/>""" % (str(title_no).zfill(2),left,right,top,bottom )
+ if col < nr_cols:
+ col += 1
+ else:
+ col = 1
+ row += 1
+
+ top = s_height - s_bottom - s_rows/2
+ if self.menu_count < self.job.nr_menus:
+ next_page_text = s.next_page_text.getValue().decode("utf-8")
+ textsize = draw_bg.textsize(next_page_text, font=fonts[1])
+ pos = ( s_width-textsize[0]-s_right, top )
+ draw_bg.text(pos, next_page_text, fill=self.Menus.color_button, font=fonts[1])
+ draw_high.text(pos, next_page_text, fill=1, font=fonts[1])
+ spuxml += """
+ <button name="button_next" x0="%d" x1="%d" y0="%d" y1="%d"/>""" % (pos[0],pos[0]+textsize[0],pos[1],pos[1]+textsize[1])
+ if self.menu_count > 1:
+ prev_page_text = s.prev_page_text.getValue().decode("utf-8")
+ textsize = draw_bg.textsize(prev_page_text, font=fonts[1])
+ pos = ( (s_left+s_cols/2), top )
+ draw_bg.text(pos, prev_page_text, fill=self.Menus.color_button, font=fonts[1])
+ draw_high.text(pos, prev_page_text, fill=1, font=fonts[1])
+ spuxml += """
+ <button name="button_prev" x0="%d" x1="%d" y0="%d" y1="%d"/>""" % (pos[0],pos[0]+textsize[0],pos[1],pos[1]+textsize[1])
+ del draw_bg
+ del draw_high
+ fd=open(self.menubgpngfilename,"w")
+ im_bg.save(fd,"PNG")
+ fd.close()
+ fd=open(self.highlightpngfilename,"w")
+ im_high.save(fd,"PNG")
+ fd.close()
+ spuxml += """
+ </spu>
+ </stream>
+ </subpictures>"""
+
+ f = open(self.spuxmlfilename, "w")
+ f.write(spuxml)
+ f.close()
+ Task.processFinished(self, 0)
+ #except:
+ #Task.processFinished(self, 1)
+
+ def getPosition(self, offset, left, top, right, bottom, size):
+ pos = [left, top]
+ if offset[0] != -1:
+ pos[0] += offset[0]
+ else:
+ pos[0] += ( (right-left) - size[0] ) / 2
+ if offset[1] != -1:
+ pos[1] += offset[1]
+ else:
+ pos[1] += ( (bottom-top) - size[1] ) / 2
+ return tuple(pos)
class Menus:
def __init__(self, job):
self.job = job
job.Menus = self
-
- s = self.job.project.settings
- self.imgwidth = 720
- self.imgheight = 576
+ s = self.job.project.menutemplate.settings
self.color_headline = tuple(s.color_headline.getValue())
self.color_button = tuple(s.color_button.getValue())
@@ -577,10 +640,9 @@ class Menus:
ImagePrepareTask(job)
nr_titles = len(job.project.titles)
- if nr_titles < 6:
- job.titles_per_menu = 5
- else:
- job.titles_per_menu = 4
+
+ job.titles_per_menu = s.cols.getValue()*s.rows.getValue()
+
job.nr_menus = ((nr_titles+job.titles_per_menu-1)/job.titles_per_menu)
#a new menu_count every 4 titles (1,2,3,4->1 ; 5,6,7,8->2 etc.)
@@ -791,7 +853,7 @@ class DVDJob(Job):
demux = DemuxTask(self, link_name)
self.mplextask = MplexTask(self, outputfile=title_filename, demux_task=demux)
self.mplextask.end = self.estimateddvdsize
- #RemoveESFiles(self, demux)
+ RemoveESFiles(self, demux)
WaitForResidentTasks(self)
PreviewTask(self, self.workspace + "/dvd/VIDEO_TS/")
output = self.project.settings.output.getValue()
diff --git a/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py b/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py
index b77383cf..7407263d 100644
--- a/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py
+++ b/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py
@@ -26,7 +26,10 @@ class FileBrowser(Screen, HelpableScreen):
currDir = "/"
if self.scope == "project":
currDir = self.getDir()
- pattern = "(?i)^.*\.(ddvdp\.xml)"
+ pattern = "(?i)^.*\.(ddvdp\.xml)"
+ elif self.scope == "menutemplate":
+ currDir = self.getDir()
+ pattern = "(?i)^.*\.(ddvdm\.xml)"
if self.scope == "menubg":
currDir = self.getDir(settings.menubg)
pattern = "(?i)^.*\.(jpeg|jpg|jpe|png|bmp)"
@@ -101,7 +104,7 @@ class ProjectSettings(Screen,ConfigListScreen):
self["key_yellow"] = StaticText(_("Load"))
self["key_blue"] = StaticText(_("Save"))
- infotext = _("Available format variables") + ":\n$i=" + _("Track") + ", $t=" + _("Title") + ", $d=" + _("Description") + ", $l=" + _("length") + ", $c=" + _("chapters") + ",\n" + _("Record") + " $T=" + _("Begin time") + ", $Y=" + _("year") + ", $M=" + _("month") + ", $D=" + _("day") + ",\n$A=" + _("audio tracks") + ", $C=" + _("Channel") + ", $f=" + _("filename")
+ infotext = _("Available format variables") + ":\n$i=" + _("Track") + ", $t=" + _("Title") + ", $d=" + _("Description") + ", $l=" + _("length") + ", $c=" + _("chapters") + ",\n" + _("Record") + " $T=" + _("Begin time") + ", $Y=" + _("Year") + ", $M=" + _("month") + ", $D=" + _("day") + ",\n$A=" + _("audio tracks") + ", $C=" + _("Channel") + ", $f=" + _("filename")
self["info"] = StaticText(infotext)
self.settings = project.settings
@@ -137,16 +140,17 @@ class ProjectSettings(Screen,ConfigListScreen):
if output == "iso":
self.list.append(getConfigListEntry(_("ISO path"), self.settings.isopath))
if authormode.startswith("menu"):
- self.list.append(getConfigListEntry(_("Menu")+' '+_("background image"), self.settings.menubg))
- self.list.append(getConfigListEntry(_("Menu")+' '+_("Title"), self.settings.titleformat))
- self.list.append(getConfigListEntry(_("Menu")+' '+_("Subtitles"), self.settings.subtitleformat))
- self.list.append(getConfigListEntry(_("Menu")+' '+_("headline")+' '+_("color"), self.settings.color_headline))
- self.list.append(getConfigListEntry(_("Menu")+' '+_("text")+' '+_("color"), self.settings.color_button))
- self.list.append(getConfigListEntry(_("Menu")+' '+_("highlighted button")+' '+_("color"), self.settings.color_highlight))
- self.list.append(getConfigListEntry(_("Menu")+' '+_("font face"), self.settings.font_face))
- self.list.append(getConfigListEntry(_("Font size")+' ('+_("headline")+', '+_("Title")+', '+_("Subtitles")+')', self.settings.font_size))
- self.list.append(getConfigListEntry(_("Menu")+' '+_("spaces (top, between rows, left)"), self.settings.space))
- self.list.append(getConfigListEntry(_("Menu")+' '+_("Audio"), self.settings.menuaudio))
+ self.list.append(getConfigListEntry(_("Menu")+' '+_("template file"), self.settings.menutemplate))
+ self.list.append(getConfigListEntry(_("Menu")+' '+_("Title"), self.project.menutemplate.settings.titleformat))
+ self.list.append(getConfigListEntry(_("Menu")+' '+_("Subtitles"), self.project.menutemplate.settings.subtitleformat))
+ self.list.append(getConfigListEntry(_("Menu")+' '+_("background image"), self.project.menutemplate.settings.menubg))
+ #self.list.append(getConfigListEntry(_("Menu")+' '+_("headline")+' '+_("color"), self.settings.color_headline))
+ #self.list.append(getConfigListEntry(_("Menu")+' '+_("text")+' '+_("color"), self.settings.color_button))
+ #self.list.append(getConfigListEntry(_("Menu")+' '+_("highlighted button")+' '+_("color"), self.settings.color_highlight))
+ #self.list.append(getConfigListEntry(_("Menu")+' '+_("font face"), self.settings.font_face))
+ #self.list.append(getConfigListEntry(_("Font size")+' ('+_("headline")+', '+_("Title")+', '+_("Subtitles")+')', self.settings.font_size))
+ #self.list.append(getConfigListEntry(_("Menu")+' '+_("spaces (top, between rows, left)"), self.settings.space))
+ #self.list.append(getConfigListEntry(_("Menu")+' '+_("Audio"), self.settings.menuaudio))
if authormode != "data_ts":
self.list.append(getConfigListEntry(_("Titleset mode"), self.settings.titlesetmode))
if self.settings.titlesetmode.getValue() == "single" or authormode == "just_linked":
@@ -198,8 +202,16 @@ class ProjectSettings(Screen,ConfigListScreen):
self.session.open(MessageBox,text,type = MessageBox.TYPE_ERROR)
def FileBrowserClosed(self, path, scope):
+ if scope == "menutemplate":
+ if not self.project.menutemplate.loadTemplate(path):
+ self.session.open(MessageBox,self.project.error,MessageBox.TYPE_ERROR)
+ else:
+ print "[ProjectSettings] menu template loaded"
+
if scope in self.project.filekeys:
self.settings.dict()[scope].setValue(path)
elif scope == "project":
if not self.project.loadProject(path):
self.session.open(MessageBox,self.project.error,MessageBox.TYPE_ERROR)
+ else:
+ self.initConfigList()
diff --git a/lib/python/Plugins/Extensions/DVDBurn/Text menu boat.ddvdm.xml b/lib/python/Plugins/Extensions/DVDBurn/Text menu boat.ddvdm.xml
new file mode 100644
index 00000000..0de7f4b6
--- /dev/null
+++ b/lib/python/Plugins/Extensions/DVDBurn/Text menu boat.ddvdm.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<DreamDVDBurnMenu>
+ <settings
+ titleformat="$i. $t"
+ subtitleformat="$D.$M.$Y, $T $C, $d"
+ menubg="/usr/lib/enigma2/python/Plugins/Extensions/DVDBurn/dreamdvd_boat.jpg"
+ menuaudio="/usr/lib/enigma2/python/Plugins/Extensions/DVDBurn/silence.mp2"
+ dimensions="(720, 576)"
+ rows="5"
+ cols="1"
+ color_button="[8, 0, 0]"
+ color_highlight="[0, 192, 192]"
+ color_headline="[0, 0, 128]"
+ fontface_headline="/usr/share/fonts/nmsbd.ttf"
+ fontface_title="/usr/share/fonts/nmsbd.ttf"
+ fontface_subtitle="/usr/share/fonts/nmsbd.ttf"
+ fontsize_headline="46"
+ fontsize_title="24"
+ fontsize_subtitle="14"
+ margin_left="56"
+ margin_right="56"
+ margin_top="100"
+ margin_bottom="70"
+ space_rows="30"
+ space_cols="40"
+ offset_headline="(-1, 40)"
+ offset_title="(0, 0)"
+ offset_subtitle="(0, 32)"
+ offset_thumb="(0, 0)"
+ thumb_size="(0, 0)"
+ thumb_border="0"
+ prev_page_text="«««"
+ next_page_text="»»»"
+ />
+</DreamDVDBurnMenu>
diff --git a/lib/python/Plugins/Extensions/DVDBurn/Thumbs menu clouds.ddvdm.xml b/lib/python/Plugins/Extensions/DVDBurn/Thumbs menu clouds.ddvdm.xml
new file mode 100644
index 00000000..c00c3fee
--- /dev/null
+++ b/lib/python/Plugins/Extensions/DVDBurn/Thumbs menu clouds.ddvdm.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<DreamDVDBurnMenu>
+ <settings
+ titleformat="$t"
+ subtitleformat="$d"
+ menubg="/usr/lib/enigma2/python/Plugins/Extensions/DVDBurn/dreamdvd_clouds.jpg"
+ menuaudio="/usr/lib/enigma2/python/Plugins/Extensions/DVDBurn/silence.mp2"
+ dimensions="(720, 576)"
+ rows="2"
+ cols="2"
+ color_button="[8, 0, 0]"
+ color_highlight="[128, 0, 0]"
+ color_headline="[128, 0, 0]"
+ fontface_headline="/usr/share/fonts/nmsbd.ttf"
+ fontface_title="/usr/share/fonts/nmsbd.ttf"
+ fontface_subtitle="/usr/share/fonts/nmsbd.ttf"
+ fontsize_headline="46"
+ fontsize_title="18"
+ fontsize_subtitle="12"
+ margin_left="48"
+ margin_right="48"
+ margin_top="100"
+ margin_bottom="48"
+ space_rows="24"
+ space_cols="24"
+ offset_headline="(-1, 40)"
+ offset_title="(-1, 144)"
+ offset_subtitle="(-1, 164)"
+ offset_thumb="(-1, 0)"
+ thumb_size="(180, 144)"
+ thumb_border="2"
+ prev_page_text="«««"
+ next_page_text="»»»"
+ />
+</DreamDVDBurnMenu>
diff --git a/lib/python/Plugins/Extensions/DVDBurn/TitleCutter.py b/lib/python/Plugins/Extensions/DVDBurn/TitleCutter.py
index 210a3d58..61152e8a 100644
--- a/lib/python/Plugins/Extensions/DVDBurn/TitleCutter.py
+++ b/lib/python/Plugins/Extensions/DVDBurn/TitleCutter.py
@@ -1,6 +1,7 @@
from Plugins.Extensions.CutListEditor.plugin import CutListEditor
from Components.ServiceEventTracker import ServiceEventTracker
from enigma import iPlayableService, iServiceInformation
+from Tools.Directories import fileExists
class TitleCutter(CutListEditor):
def __init__(self, session, t):
@@ -46,7 +47,12 @@ class TitleCutter(CutListEditor):
self.t.properties.aspect.setValue(aspect)
self.t.VideoType = service.info().getInfo(iServiceInformation.sVideoType)
+ def checkAndGrabThumb(self):
+ if not fileExists(self.t.inputfile.rsplit('.',1)[0] + ".png"):
+ CutListEditor.grabFrame(self)
+
def exit(self):
+ self.checkAndGrabThumb()
self.session.nav.stopService()
self.close(self.cut_list[:])
@@ -56,4 +62,5 @@ class CutlistReader(TitleCutter):
def getPMTInfo(self):
TitleCutter.getPMTInfo(self)
+ TitleCutter.checkAndGrabThumb(self)
self.close(self.cut_list[:])
diff --git a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py
index 345af877..749f80eb 100644
--- a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py
+++ b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py
@@ -74,9 +74,22 @@ class TitleList(Screen, HelpableScreen):
self["titles"] = List(list = [ ], enableWrapAround = True, item_height=30, fonts = [gFont("Regular", 20)])
self.updateTitleList()
-
+
+ def checkBackgroundJobs(self):
+ for job in job_manager.getPendingJobs():
+ print "type(job):", type(job)
+ print "Process.DVDJob:", Process.DVDJob
+ if type(job) == Process.DVDJob:
+ self.backgroundJob = job
+ return
+ self.backgroundJob = None
+
def showMenu(self):
menu = []
+ self.checkBackgroundJobs()
+ if self.backgroundJob:
+ j = self.backgroundJob
+ menu.append(("%s: %s (%d%%)" % (j.getStatustext(), j.name, int(100*j.progress/float(j.end))), self.showBackgroundJob))
if self.project.settings.output.getValue() == "dvd":
menu.append((_("Burn DVD"), self.burnProject))
elif self.project.settings.output.getValue() == "iso":
@@ -97,6 +110,11 @@ class TitleList(Screen, HelpableScreen):
if choice:
choice[1]()
+ def showBackgroundJob(self):
+ job_manager.in_background = False
+ self.session.openWithCallback(self.JobViewCB, JobView, self.backgroundJob)
+ self.backgroundJob = None
+
def titleProperties(self):
if self.getCurrentTitle():
self.session.openWithCallback(self.updateTitleList, TitleProperties.TitleProperties, self, self.project, self["titles"].getIndex())
@@ -172,8 +190,8 @@ class TitleList(Screen, HelpableScreen):
self["title_label"].text = _("Table of content for collection") + " \"" + self.project.settings.name.getValue() + "\":"
def loadTemplate(self):
- filename = resolveFilename(SCOPE_PLUGINS)+"Extensions/DVDBurn/DreamboxDVDtemplate.ddvdp.xml"
- if self.project.loadProject(filename):
+ filename = resolveFilename(SCOPE_PLUGINS)+"Extensions/DVDBurn/DreamboxDVD.ddvdp.xml"
+ if self.project.load(filename):
self["error_label"].hide()
return True
else:
@@ -212,12 +230,12 @@ class TitleList(Screen, HelpableScreen):
res = [ ]
totalsize = 0
for title in self.project.titles:
- a = [ title, (eListboxPythonMultiContent.TYPE_TEXT, 0, 10, 500, 50, 0, RT_HALIGN_LEFT, title.properties.menutitle.getValue()) ]
+ a = [ title, (eListboxPythonMultiContent.TYPE_TEXT, 0, 5, 500, 25, 0, RT_HALIGN_LEFT, title.properties.menutitle.getValue()) ]
res.append(a)
totalsize += title.estimatedDiskspace
self["titles"].list = res
self.updateSize(totalsize)
-
+
def updateSize(self, totalsize):
size = int((totalsize/1024)/1024)
max_SL = 4370
diff --git a/lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py b/lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py
index d5ba6c16..63ae6c1f 100644
--- a/lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py
+++ b/lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py
@@ -8,10 +8,12 @@ from Components.Sources.List import List
from Components.Sources.StaticText import StaticText
from Components.Sources.Progress import Progress
from Components.FileList import FileList
-from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT
+from Components.Pixmap import Pixmap
+from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT, ePicLoad
from Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_FONTS, SCOPE_HDD
from Components.config import config, getConfigListEntry, ConfigInteger, ConfigSubsection, ConfigSelection
from Components.ConfigList import ConfigListScreen
+from Components.AVSwitch import AVSwitch
import DVDTitle
class TitleProperties(Screen,ConfigListScreen):
@@ -23,9 +25,9 @@ class TitleProperties(Screen,ConfigListScreen):
<widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
<widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
<widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
- <widget name="config" position="10,50" size="540,300" scrollbarMode="showOnDemand" />
- <widget source="serviceinfo_headline" render="Label" position="20,360" size="520,20" font="Regular;20" />
- <widget source="serviceinfo" render="Label" position="20,382" size="520,66" font="Regular;16" />
+ <widget source="serviceinfo" render="Label" position="10,46" size="350,144" font="Regular;18" />
+ <widget name="thumbnail" position="370,46" size="180,144" alphatest="on" />
+ <widget name="config" position="10,206" size="540,228" scrollbarMode="showOnDemand" />
</screen>"""
def __init__(self, session, parent, project, title_idx):
@@ -37,9 +39,12 @@ class TitleProperties(Screen,ConfigListScreen):
self["key_red"] = StaticText(_("Cancel"))
self["key_green"] = StaticText(_("OK"))
self["key_blue"] = StaticText(_("Edit Title"))
- self["serviceinfo_headline"] = StaticText("DVB info:")
self["serviceinfo"] = StaticText()
+ self["thumbnail"] = Pixmap()
+ self.picload = ePicLoad()
+ self.picload.PictureData.get().append(self.paintThumbPixmapCB)
+
self.properties = project.titles[title_idx].properties
ConfigListScreen.__init__(self, [])
self.properties.crop = DVDTitle.ConfigFixedText("crop")
@@ -47,8 +52,6 @@ class TitleProperties(Screen,ConfigListScreen):
self.properties.aspect.addNotifier(self.initConfigList)
for audiotrack in self.properties.audiotracks:
audiotrack.active.addNotifier(self.initConfigList)
-
- self.initConfigList()
self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
{
@@ -58,6 +61,8 @@ class TitleProperties(Screen,ConfigListScreen):
"cancel": self.cancel,
"ok": self.ok,
}, -2)
+
+ self.onShown.append(self.update)
def initConfigList(self, element=None):
try:
@@ -79,18 +84,15 @@ class TitleProperties(Screen,ConfigListScreen):
self.list.append(getConfigListEntry("DVD " + "widescreen", self.properties.widescreen))
else:
self.list.append(getConfigListEntry("DVD " + "widescreen", self.properties.crop))
-
- infotext = _("Available format variables") + ":\n$i=" + _("Track") + ", $t=" + _("Title") + ", $d=" + _("Description") + ", $l=" + _("length") + ", $c=" + _("chapters") + ",\n" + _("Record") + " $T=" + _("Begin time") + ", $Y=" + _("year") + ", $M=" + _("month") + ", $D=" + _("day") + ",\n$A=" + _("audio tracks") + ", $C=" + _("Channel") + ", $f=" + _("filename")
- self["info"] = StaticText(infotext)
-
+
if len(title.chaptermarks) == 0:
self.list.append(getConfigListEntry(_("Auto chapter split every ? minutes (0=never)"), self.properties.autochapter))
- infotext = _("Title") + ': ' + title.DVBname + "\n" + _("Description") + ': ' + title.DVBdescr + "\n" + _("Channel") + ': ' + title.DVBchannel
+ infotext = "DVB " + _("Title") + ': ' + title.DVBname + "\n" + _("Description") + ': ' + title.DVBdescr + "\n" + _("Channel") + ': ' + title.DVBchannel + '\n' + _("Begin time") + title.formatDVDmenuText(": $D.$M.$Y, $T\n", self.title_idx+1)
chaptermarks = title.getChapterMarks(template="$h:$m:$s")
chapters_count = len(chaptermarks)
if chapters_count >= 1:
- infotext += ', ' + str(chapters_count+1) + ' ' + _("chapters") + ' ('
- infotext += ' / '.join(chaptermarks) + ')'
+ infotext += '\n' + str(chapters_count+1) + ' ' + _("chapters") + ': '
+ infotext += ' / '.join(chaptermarks)
self["serviceinfo"].setText(infotext)
self["config"].setList(self.list)
except AttributeError:
@@ -98,7 +100,22 @@ class TitleProperties(Screen,ConfigListScreen):
def editTitle(self):
self.parent.editTitle()
+
+ def update(self):
+ print "[onShown]"
self.initConfigList()
+ self.loadThumb()
+
+ def loadThumb(self):
+ thumbfile = self.project.titles[self.title_idx].inputfile.rsplit('.',1)[0] + ".png"
+ sc = AVSwitch().getFramebufferScale()
+ self.picload.setPara((self["thumbnail"].instance.size().width(), self["thumbnail"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
+ self.picload.startDecode(thumbfile)
+
+ def paintThumbPixmapCB(self, picInfo=None):
+ ptr = self.picload.getData()
+ if ptr != None:
+ self["thumbnail"].instance.setPixmap(ptr.__deref__())
def changedConfigList(self):
self.initConfigList()
diff --git a/lib/python/Plugins/Extensions/DVDBurn/dreamdvd_clouds.jpg b/lib/python/Plugins/Extensions/DVDBurn/dreamdvd_clouds.jpg
new file mode 100644
index 00000000..aacf25d0
--- /dev/null
+++ b/lib/python/Plugins/Extensions/DVDBurn/dreamdvd_clouds.jpg
Binary files differ
diff --git a/lib/python/Plugins/Extensions/DVDBurn/dvdburn.png b/lib/python/Plugins/Extensions/DVDBurn/dvdburn.png
index 7e7adead..7e7adead 100755..100644
--- a/lib/python/Plugins/Extensions/DVDBurn/dvdburn.png
+++ b/lib/python/Plugins/Extensions/DVDBurn/dvdburn.png
Binary files differ
diff --git a/lib/python/Plugins/Extensions/DVDPlayer/keymap.xml b/lib/python/Plugins/Extensions/DVDPlayer/keymap.xml
index 2a872c21..7b7f2054 100644
--- a/lib/python/Plugins/Extensions/DVDPlayer/keymap.xml
+++ b/lib/python/Plugins/Extensions/DVDPlayer/keymap.xml
@@ -11,7 +11,7 @@
<key id="KEY_AUDIO" mapto="dvdAudioMenu" flags="m" />
<key id="KEY_RADIO" mapto="nextAudioTrack" flags="m" />
<key id="KEY_TEXT" mapto="nextSubtitleTrack" flags="m" />
- <key id="KEY_VIDEO" mapto="seekBeginning" flags="l" />
+ <key id="KEY_VIDEO" mapto="nextAngle" flags="m" />
</device>
<device name="dreambox advanced remote control (native)">
<key id="KEY_PREVIOUS" mapto="prevChapter" flags="m" />
@@ -21,6 +21,7 @@
<key id="KEY_RADIO" mapto="dvdAudioMenu" flags="l" />
<key id="KEY_RADIO" mapto="nextAudioTrack" flags="m" />
<key id="KEY_TEXT" mapto="nextSubtitleTrack" flags="m" />
+ <key id="KEY_VIDEO" mapto="nextAngle" flags="m" />
</device>
<!--device name="dreambox ir keyboard">
<key id="KEY_PAUSE" mapto="pause" flags="m" />
diff --git a/lib/python/Plugins/Extensions/DVDPlayer/plugin.py b/lib/python/Plugins/Extensions/DVDPlayer/plugin.py
index cb5f0e0d..421a2b4e 100644
--- a/lib/python/Plugins/Extensions/DVDPlayer/plugin.py
+++ b/lib/python/Plugins/Extensions/DVDPlayer/plugin.py
@@ -1,5 +1,5 @@
from os import path as os_path, remove as os_remove, listdir as os_listdir, system
-from enigma import eTimer, iPlayableService, iServiceInformation, eServiceReference, iServiceKeys
+from enigma import eTimer, iPlayableService, iServiceInformation, eServiceReference, iServiceKeys, getDesktop
from Screens.Screen import Screen
from Screens.MessageBox import MessageBox
from Screens.ChoiceBox import ChoiceBox
@@ -7,6 +7,7 @@ from Screens.HelpMenu import HelpableScreen
from Screens.InfoBarGenerics import InfoBarSeek, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarShowHide, InfoBarNotifications
from Components.ActionMap import ActionMap, NumberActionMap, HelpableActionMap
from Components.Label import Label
+from Components.Pixmap import Pixmap
from Components.FileList import FileList
from Components.MenuList import MenuList
from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
@@ -109,10 +110,11 @@ class DVDSummary(Screen):
self["Title"].setText(title)
class DVDOverlay(Screen):
- skin = """<screen name="DVDOverlay" position="0,0" size="720,576" flags="wfNoBorder" zPosition="-1" backgroundColor="transparent" />"""
def __init__(self, session, args = None):
+ desktop_size = getDesktop(0).size()
+ DVDOverlay.skin = """<screen name="DVDOverlay" position="0,0" size="%d,%d" flags="wfNoBorder" zPosition="-1" backgroundColor="transparent" />""" %(desktop_size.width(), desktop_size.height())
Screen.__init__(self, session)
-
+
class ChapterZap(Screen):
skin = """
<screen name="ChapterZap" position="235,255" size="250,60" title="Chapter" >
@@ -182,14 +184,17 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
<!-- Chapter info -->
<widget name="chapterLabel" position="230,96" size="360,22" font="Regular;20" foregroundColor="#c3c3c9" backgroundColor="#263c59" transparent="1" />
<!-- Audio track info -->
- <ePixmap pixmap="skin_default/icons/icon_dolby.png" position="540,73" zPosition="1" size="26,16" alphatest="on"/>
- <widget name="audioLabel" position="570,73" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
+ <ePixmap pixmap="skin_default/icons/icon_dolby.png" position="540,60" zPosition="1" size="26,16" alphatest="on"/>
+ <widget name="audioLabel" position="570,60" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
<!-- Subtitle track info -->
- <widget source="session.CurrentService" render="Pixmap" pixmap="skin_default/icons/icon_txt.png" position="540,96" zPosition="1" size="26,16" alphatest="on" >
+ <widget source="session.CurrentService" render="Pixmap" pixmap="skin_default/icons/icon_txt.png" position="540,83" zPosition="1" size="26,16" alphatest="on" >
<convert type="ServiceInfo">HasTelext</convert>
<convert type="ConditionalShowHide" />
</widget>
- <widget name="subtitleLabel" position="570,96" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
+ <widget name="subtitleLabel" position="570,83" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
+ <!-- Angle info -->
+ <widget name="anglePix" pixmap="skin_default/icons/icon_view.png" position="540,106" size="26,16" alphatest="on" />
+ <widget name="angleLabel" position="570,106" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
<!-- Elapsed time -->
<widget source="session.CurrentService" render="Label" position="205,129" size="100,20" font="Regular;18" halign="center" valign="center" backgroundColor="#06224f" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" >
<convert type="ServicePosition">Position,ShowHours</convert>
@@ -251,9 +256,13 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
self.session.nav.stopService()
self["audioLabel"] = Label("n/a")
self["subtitleLabel"] = Label("")
+ self["angleLabel"] = Label("")
self["chapterLabel"] = Label("")
+ self["anglePix"] = Pixmap()
+ self["anglePix"].hide()
self.last_audioTuple = None
self.last_subtitleTuple = None
+ self.last_angleTuple = None
self.totalChapters = 0
self.currentChapter = 0
self.totalTitles = 0
@@ -273,7 +282,8 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
iPlayableService.evUser+8: self.__chapterUpdated,
iPlayableService.evUser+9: self.__titleUpdated,
iPlayableService.evUser+11: self.__menuOpened,
- iPlayableService.evUser+12: self.__menuClosed
+ iPlayableService.evUser+12: self.__menuClosed,
+ iPlayableService.evUser+13: self.__osdAngleInfoAvail
})
self["DVDPlayerDirectionActions"] = ActionMap(["DirectionActions"],
@@ -316,6 +326,7 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
"dvdAudioMenu": (self.enterDVDAudioMenu, _("(show optional DVD audio menu)")),
"nextAudioTrack": (self.nextAudioTrack, _("switch to the next audio track")),
"nextSubtitleTrack": (self.nextSubtitleTrack, _("switch to the next subtitle language")),
+ "nextAngle": (self.nextAngle, _("switch to the next angle")),
"seekBeginning": self.seekBeginning,
}, -2)
@@ -352,7 +363,7 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
if file.mimetype == "video/x-dvd":
self.dvd_device = devicepath
print "physical dvd found:", self.dvd_device
- self.physicalDVD = True
+ self.physicalDVD = True
self.dvd_filelist = dvd_filelist
self.onFirstExecBegin.append(self.showFileBrowser)
@@ -387,9 +398,6 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
def serviceStarted(self): #override InfoBarShowHide function
self.dvdScreen.show()
- subs = self.getServiceInterface("subtitle")
- if subs:
- subs.enableSubtitles(self.dvdScreen.instance, None)
def doEofInternal(self, playing):
if self.in_menu:
@@ -469,6 +477,22 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
if subtitleTuple != self.last_subtitleTuple and not self.in_menu:
self.doShow()
self.last_subtitleTuple = subtitleTuple
+
+ def __osdAngleInfoAvail(self):
+ info = self.getServiceInterface("info")
+ angleTuple = info and info.getInfoObject(iServiceInformation.sUser+8)
+ print "AngleInfoAvail ", repr(angleTuple)
+ if angleTuple:
+ angleString = ""
+ if angleTuple[1] > 1:
+ angleString = "%d / %d" % (angleTuple[0],angleTuple[1])
+ self["anglePix"].show()
+ else:
+ self["anglePix"].hide()
+ self["angleLabel"].setText(angleString)
+ if angleTuple != self.last_angleTuple and not self.in_menu:
+ self.doShow()
+ self.last_angleTuple = angleTuple
def __chapterUpdated(self):
info = self.getServiceInterface("info")
@@ -489,9 +513,9 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
self.doShow()
def askLeavePlayer(self):
- choices = [(_("Continue playing"), "play"), (_("Exit"), "exit")]
+ choices = [(_("Exit"), "exit"), (_("Continue playing"), "play")]
if not self.physicalDVD:
- choices.insert(1,(_("Return to file browser"), "browser"))
+ choices.insert(1,(_("Return to file browser"), "browser"))
self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list = choices)
def sendKey(self, key):
@@ -523,6 +547,9 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
def enterDVDMenu(self):
self.sendKey(iServiceKeys.keyUser+7)
+
+ def nextAngle(self):
+ self.sendKey(iServiceKeys.keyUser+8)
def seekBeginning(self):
if self.service:
@@ -588,6 +615,9 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
self.service = self.session.nav.getCurrentService()
print "self.service", self.service
print "cur_dlg", self.session.current_dialog
+ subs = self.getServiceInterface("subtitle")
+ if subs:
+ subs.enableSubtitles(self.dvdScreen.instance, None)
def exitCB(self, answer):
if answer is not None:
diff --git a/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp b/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp
index 1add04ab..c2590af5 100644
--- a/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp
+++ b/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp
@@ -87,30 +87,48 @@ DEFINE_REF(eServiceDVD);
eServiceDVD::eServiceDVD(const char *filename):
m_filename(filename),
m_ddvdconfig(ddvd_create()),
- m_pixmap(new gPixmap(eSize(720, 576), 32)),
m_subtitle_widget(0),
m_state(stIdle),
m_current_trick(0),
m_pump(eApp, 1)
{
+ int aspect = DDVD_16_9;
+ int policy = DDVD_PAN_SCAN;
+
+ char tmp[255];
+ ssize_t rd;
+
m_sn = eSocketNotifier::create(eApp, ddvd_get_messagepipe_fd(m_ddvdconfig), eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Error|eSocketNotifier::Hungup);
- std::string aspect;
eDebug("SERVICEDVD construct!");
// create handle
ddvd_set_dvd_path(m_ddvdconfig, filename);
ddvd_set_ac3thru(m_ddvdconfig, 0);
ddvd_set_language(m_ddvdconfig, "de");
- if (ePythonConfigQuery::getConfigValue("config.av.aspect", aspect) != 0)
- aspect = "16_9";
- if (aspect == "4_3_letterbox")
- ddvd_set_video(m_ddvdconfig, DDVD_4_3_LETTERBOX, DDVD_PAL);
- else if (aspect == "4_3_panscan")
- ddvd_set_video(m_ddvdconfig, DDVD_4_3_PAN_SCAN, DDVD_PAL);
- else
- ddvd_set_video(m_ddvdconfig, DDVD_16_9, DDVD_PAL);
+ int fd = open("/proc/stb/video/aspect", O_RDONLY);
+ if (fd > -1)
+ {
+ rd = read(fd, tmp, 255);
+ if (rd > 2 && !strncmp(tmp, "4:3", 3))
+ aspect = DDVD_4_3;
+ else if (rd > 4 && !strncmp(tmp, "16:10", 5))
+ aspect = DDVD_16_10;
+ close(fd);
+ }
+
+ fd = open("/proc/stb/video/policy", O_RDONLY);
+ if (fd > -1)
+ {
+ rd = read(fd, tmp, 255);
+ if (rd > 6 && !strncmp(tmp, "bestfit", 7))
+ policy = DDVD_JUSTSCALE;
+ else if (rd > 8 && !strncmp(tmp, "letterbox", 9))
+ policy = DDVD_LETTERBOX;
+ close(fd);
+ }
+
+ ddvd_set_video(m_ddvdconfig, aspect, policy, DDVD_PAL /*unused*/);
- ddvd_set_lfb(m_ddvdconfig, (unsigned char *)m_pixmap->surface->data, 720, 576, 4, 720*4);
CONNECT(m_sn->activated, eServiceDVD::gotMessage);
CONNECT(m_pump.recv_msg, eServiceDVD::gotThreadMessage);
strcpy(m_ddvd_titlestring,"");
@@ -158,8 +176,11 @@ void eServiceDVD::gotMessage(int /*what*/)
}
case DDVD_SCREEN_UPDATE:
eDebug("DVD_SCREEN_UPDATE!");
- if (m_subtitle_widget)
- m_subtitle_widget->setPixmap(m_pixmap, eRect(0, 0, 720, 576));
+ if (m_subtitle_widget) {
+ int x1,x2,y1,y2;
+ ddvd_get_last_blit_area(m_ddvdconfig, &x1, &x2, &y1, &y2);
+ m_subtitle_widget->setPixmap(m_pixmap, eRect(x1, y1, (x2-x1)+1, (y2-y1)+1));
+ }
break;
case DDVD_SHOWOSD_STATE_PLAY:
{
@@ -213,6 +234,14 @@ void eServiceDVD::gotMessage(int /*what*/)
eDebug("DVD_SOF_REACHED!");
m_event(this, evSOF);
break;
+ case DDVD_SHOWOSD_ANGLE:
+ {
+ int current, num;
+ ddvd_get_angle_info(m_ddvdconfig, &current, &num);
+ eDebug("DVD_ANGLE_INFO: %d / %d", current, num);
+ m_event(this, evUser+13);
+ break;
+ }
case DDVD_SHOWOSD_TIME:
{
static struct ddvd_time last_info;
@@ -259,6 +288,7 @@ eServiceDVD::~eServiceDVD()
kill();
saveCuesheet();
ddvd_close(m_ddvdconfig);
+ disableSubtitles(0);
}
RESULT eServiceDVD::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
@@ -272,7 +302,6 @@ RESULT eServiceDVD::start()
assert(m_state == stIdle);
m_state = stRunning;
eDebug("eServiceDVD starting");
- run();
// m_event(this, evStart);
return 0;
}
@@ -437,6 +466,7 @@ int eServiceDVD::getInfo(int w)
}
case sUser+6:
case sUser+7:
+ case sUser+8:
return resIsPyObject;
default:
return resNA;
@@ -506,6 +536,16 @@ PyObject *eServiceDVD::getInfoObject(int w)
}
return tuple;
}
+ case sUser+8:
+ {
+ ePyObject tuple = PyTuple_New(2);
+ int current, num;
+ ddvd_get_angle_info(m_ddvdconfig, &current, &num);
+ PyTuple_SetItem(tuple, 0, PyInt_FromLong(current));
+ PyTuple_SetItem(tuple, 1, PyInt_FromLong(num));
+
+ return tuple;
+ }
default:
eDebug("unhandled getInfoObject(%d)", w);
}
@@ -514,13 +554,23 @@ PyObject *eServiceDVD::getInfoObject(int w)
RESULT eServiceDVD::enableSubtitles(eWidget *parent, SWIG_PYOBJECT(ePyObject) /*entry*/)
{
- if (m_subtitle_widget)
- delete m_subtitle_widget;
+ delete m_subtitle_widget;
+
m_subtitle_widget = new eSubtitleWidget(parent);
m_subtitle_widget->resize(parent->size());
- m_subtitle_widget->setPixmap(m_pixmap, eRect(0, 0, 720, 576));
+
+ eSize size = parent->size();
+
+ if (!m_pixmap)
+ {
+ m_pixmap = new gPixmap(size, 32);
+ ddvd_set_lfb(m_ddvdconfig, (unsigned char *)m_pixmap->surface->data, size.width(), size.height(), 4, size.width()*4);
+ run(); // start the thread
+ }
+
m_subtitle_widget->setZPosition(-1);
m_subtitle_widget->show();
+
return 0;
}
@@ -655,6 +705,9 @@ RESULT eServiceDVD::keyPressed(int key)
case iServiceKeys::keyUser+7:
ddvd_send_key(m_ddvdconfig, DDVD_KEY_MENU);
break;
+ case iServiceKeys::keyUser+8:
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_ANGLE);
+ break;
default:
return -1;
}
diff --git a/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py b/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py
index 1af90f13..b22c4b80 100644
--- a/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py
+++ b/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py
@@ -15,8 +15,9 @@ from Screens.TimeDateInput import TimeDateInput
from Screens.TimerEntry import TimerEntry
from Screens.EpgSelection import EPGSelection
from Screens.TimerEdit import TimerSanityConflict
+from Screens.MessageBox import MessageBox
from Tools.Directories import resolveFilename, SCOPE_SKIN_IMAGE
-from RecordTimer import RecordTimerEntry, parseEvent
+from RecordTimer import RecordTimerEntry, parseEvent, AFTEREVENT
from ServiceReference import ServiceReference
from Tools.LoadPixmap import LoadPixmap
from enigma import eEPGCache, eListbox, gFont, eListboxPythonMultiContent, \
@@ -41,6 +42,10 @@ class EPGList(HTMLComponent, GUIComponent):
self.l.setSelectableFunc(self.isSelectable)
self.epgcache = eEPGCache.getInstance()
self.clock_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock.png'))
+ self.clock_add_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_add.png'))
+ self.clock_pre_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_pre.png'))
+ self.clock_post_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_post.png'))
+ self.clock_prepost_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_prepost.png'))
self.time_base = None
self.time_epoch = time_epoch
self.list = None
@@ -81,10 +86,10 @@ class EPGList(HTMLComponent, GUIComponent):
return (event_list and len(event_list) and True) or False
def setEpoch(self, epoch):
- if self.cur_event is not None and self.cur_service is not None:
- self.offs = 0
- self.time_epoch = epoch
- self.fillMultiEPG(None) # refill
+# if self.cur_event is not None and self.cur_service is not None:
+ self.offs = 0
+ self.time_epoch = epoch
+ self.fillMultiEPG(None) # refill
def getEventFromId(self, service, eventid):
event = None
@@ -92,14 +97,31 @@ class EPGList(HTMLComponent, GUIComponent):
event = self.epgcache.lookupEventId(service.ref, eventid)
return event
+ def moveToService(self,serviceref):
+ if serviceref is not None:
+ for x in range(len(self.list)):
+ if self.list[x][0] == serviceref.toString():
+ self.instance.moveSelectionTo(x)
+ break
+
+ def getIndexFromService(self, serviceref):
+ if serviceref is not None:
+ for x in range(len(self.list)):
+ if self.list[x][0] == serviceref.toString():
+ return x
+
+ def setCurrentIndex(self, index):
+ if self.instance is not None:
+ self.instance.moveSelectionTo(index)
+
def getCurrent(self):
- if self.cur_service is None or self.cur_event is None:
+ if self.cur_service is None:
return ( None, None )
old_service = self.cur_service #(service, service_name, events)
events = self.cur_service[2]
refstr = self.cur_service[0]
- if not events or not len(events):
- return ( None, None )
+ if self.cur_event is None or not events or not len(events):
+ return ( None, ServiceReference(refstr) )
event = events[self.cur_event] #(event_id, event_title, begin_time, duration)
eventid = event[0]
service = ServiceReference(refstr)
@@ -155,11 +177,12 @@ class EPGList(HTMLComponent, GUIComponent):
def selectionChanged(self):
for x in self.onSelChanged:
if x is not None:
- try:
- x()
- except: # FIXME!!!
- print "FIXME in EPGList.selectionChanged"
- pass
+ x()
+# try:
+# x()
+# except: # FIXME!!!
+# print "FIXME in EPGList.selectionChanged"
+# pass
GUI_WIDGET = eListbox
@@ -204,7 +227,13 @@ class EPGList(HTMLComponent, GUIComponent):
def buildEntry(self, service, service_name, events):
r1=self.service_rect
r2=self.event_rect
- res = [ None, MultiContentEntryText(pos = (r1.left(),r1.top()), size = (r1.width(), r1.height()), font = 0, flags = RT_HALIGN_LEFT | RT_VALIGN_CENTER, text = service_name, color = self.foreColorService, backcolor = self.backColorService) ]
+ res = [ None, MultiContentEntryText(
+ pos = (r1.left(),r1.top()),
+ size = (r1.width(), r1.height()),
+ font = 0, flags = RT_HALIGN_LEFT | RT_VALIGN_CENTER,
+ text = service_name,
+ color = self.foreColorService,
+ backcolor = self.backColorService) ]
if events:
start = self.time_base+self.offs*self.time_epoch*60
@@ -220,11 +249,19 @@ class EPGList(HTMLComponent, GUIComponent):
borderColor = self.borderColor
for ev in events: #(event_id, event_title, begin_time, duration)
- rec=ev[2] and self.timer.isInTimer(ev[0], ev[2], ev[3], service) > ((ev[3]/10)*8)
+ rec=ev[2] and self.timer.isInTimer(ev[0], ev[2], ev[3], service)
xpos, ewidth = self.calcEntryPosAndWidthHelper(ev[2], ev[3], start, end, width)
- res.append(MultiContentEntryText(pos = (left+xpos, top), size = (ewidth, height), font = 1, flags = RT_HALIGN_CENTER | RT_VALIGN_CENTER | RT_WRAP, text = ev[1], color = foreColor, color_sel = foreColorSelected, backcolor = backColor, backcolor_sel = backColorSelected, border_width = 1, border_color = borderColor))
+ res.append(MultiContentEntryText(
+ pos = (left+xpos, top), size = (ewidth, height),
+ font = 1, flags = RT_HALIGN_CENTER | RT_VALIGN_CENTER | RT_WRAP,
+ text = ev[1], color = foreColor, color_sel = foreColorSelected,
+ backcolor = backColor, backcolor_sel = backColorSelected, border_width = 1, border_color = borderColor))
if rec and ewidth > 23:
- res.append(MultiContentEntryPixmapAlphaTest(pos = (left+xpos+ewidth-22, top+height-22), size = (21, 21), png = self.clock_pixmap, backcolor = backColor, backcolor_sel = backColorSelected))
+ res.append(MultiContentEntryPixmapAlphaTest(
+ pos = (left+xpos+ewidth-22, top+height-22), size = (21, 21),
+ png = self.getClockPixmap(service, ev[2], ev[3], ev[0]),
+ backcolor = backColor,
+ backcolor_sel = backColorSelected))
return res
def selEntry(self, dir, visible=True):
@@ -278,8 +315,13 @@ class EPGList(HTMLComponent, GUIComponent):
self.time_base = int(stime)
test = [ (service.ref.toString(), 0, self.time_base, self.time_epoch) for service in services ]
test.insert(0, 'XRnITBD')
+# print "BEFORE:"
+# for x in test:
+# print x
epg_data = self.queryEPG(test)
-
+# print "EPG:"
+# for x in epg_data:
+# print x
self.list = [ ]
tmp_list = None
service = ""
@@ -310,6 +352,30 @@ class EPGList(HTMLComponent, GUIComponent):
def resetOffset(self):
self.offs = 0
+
+ def getClockPixmap(self, refstr, beginTime, duration, eventId):
+ pre_clock = 1
+ post_clock = 2
+ clock_type = 0
+ endTime = beginTime + duration
+ for x in self.timer.timer_list:
+ if x.service_ref.ref.toString() == refstr:
+ if x.eit == eventId:
+ return self.clock_pixmap
+ beg = x.begin
+ end = x.end
+ if beginTime > beg and beginTime < end and endTime > end:
+ clock_type |= pre_clock
+ elif beginTime < beg and endTime > beg and endTime < end:
+ clock_type |= post_clock
+ if clock_type == 0:
+ return self.clock_add_pixmap
+ elif clock_type == pre_clock:
+ return self.clock_pre_pixmap
+ elif clock_type == post_clock:
+ return self.clock_post_pixmap
+ else:
+ return self.clock_prepost_pixmap
class TimelineText(HTMLComponent, GUIComponent):
def __init__(self):
@@ -337,6 +403,12 @@ config.misc.graph_mepg_prev_time=ConfigClock(default = time())
config.misc.graph_mepg_prev_time_period=ConfigInteger(default=120, limits=(60,300))
class GraphMultiEPG(Screen):
+ EMPTY = 0
+ ADD_TIMER = 1
+ REMOVE_TIMER = 2
+
+ ZAP = 1
+
def __init__(self, session, services, zapFunc=None, bouquetChangeCB=None):
Screen.__init__(self, session)
self.bouquetChangeCB = bouquetChangeCB
@@ -345,7 +417,9 @@ class GraphMultiEPG(Screen):
self.ask_time = now - tmp
self.closeRecursive = False
self["key_red"] = Button("")
- self["key_green"] = Button(_("Add timer"))
+ self["key_green"] = Button("")
+ self.key_green_choice = self.EMPTY
+ self.key_red_choice = self.EMPTY
self["timeline_text"] = TimelineText()
self["Event"] = Event()
self.time_lines = [ ]
@@ -469,6 +543,7 @@ class GraphMultiEPG(Screen):
#just used in multipeg
def onCreate(self):
self["list"].fillMultiEPG(self.services, self.ask_time)
+ self["list"].moveToService(self.session.nav.getCurrentlyPlayingServiceReference())
self.moveTimeLines()
def eventViewCallback(self, setEvent, setService, val):
@@ -486,22 +561,37 @@ class GraphMultiEPG(Screen):
setEvent(cur[0])
def zapTo(self):
- if self.zapFunc and self["key_red"].getText() == "Zap":
+ if self.zapFunc and self.key_red_choice == self.ZAP:
self.closeRecursive = True
ref = self["list"].getCurrent()[1]
- self.zapFunc(ref.ref)
+ if ref:
+ self.zapFunc(ref.ref)
def eventSelected(self):
self.infoKeyPressed()
+ def removeTimer(self, timer):
+ timer.afterEvent = AFTEREVENT.NONE
+ self.session.nav.RecordTimer.removeEntry(timer)
+ self["key_green"].setText(_("Add timer"))
+ self.key_green_choice = self.ADD_TIMER
+
def timerAdd(self):
cur = self["list"].getCurrent()
event = cur[0]
serviceref = cur[1]
if event is None:
return
- newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, *parseEvent(event))
- self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
+ eventid = event.getEventId()
+ refstr = serviceref.ref.toString()
+ for timer in self.session.nav.RecordTimer.timer_list:
+ if timer.eit == eventid and timer.service_ref.ref.toString() == refstr:
+ cb_func = lambda ret : not ret or self.removeTimer(timer)
+ self.session.openWithCallback(cb_func, MessageBox, _("Do you really want to delete %s?") % event.getEventName())
+ break
+ else:
+ newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, *parseEvent(event))
+ self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
def finishedAdd(self, answer):
print "finished add"
@@ -509,32 +599,71 @@ class GraphMultiEPG(Screen):
entry = answer[1]
simulTimerList = self.session.nav.RecordTimer.record(entry)
if simulTimerList is not None:
- if (len(simulTimerList) == 2) and (simulTimerList[1].dontSave) and (simulTimerList[1].autoincrease):
- simulTimerList[1].end = entry.begin - 30
- self.session.nav.RecordTimer.timeChanged(simulTimerList[1])
- self.session.nav.RecordTimer.record(entry)
- else:
+ for x in simulTimerList:
+ if x.setAutoincreaseEnd(entry):
+ self.session.nav.RecordTimer.timeChanged(x)
+ simulTimerList = self.session.nav.RecordTimer.record(entry)
+ if simulTimerList is not None:
self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
+ self["key_green"].setText(_("Remove timer"))
+ self.key_green_choice = self.REMOVE_TIMER
else:
- print "Timeredit aborted"
+ self["key_green"].setText(_("Add timer"))
+ self.key_green_choice = self.ADD_TIMER
+ print "Timeredit aborted"
def finishSanityCorrection(self, answer):
self.finishedAdd(answer)
def onSelectionChanged(self):
- evt = self["list"].getCurrent()
- self["Event"].newEvent(evt and evt[0])
- if evt and evt[0]:
- evt = evt[0]
- now = time()
- start = evt.getBeginTime()
- end = start + evt.getDuration()
- if now >= start and now <= end:
- self["key_red"].setText("Zap")
- else:
+ cur = self["list"].getCurrent()
+ if cur is None:
+ if self.key_green_choice != self.EMPTY:
+ self["key_green"].setText("")
+ self.key_green_choice = self.EMPTY
+ if self.key_red_choice != self.EMPTY:
self["key_red"].setText("")
-
+ self.key_red_choice = self.EMPTY
+ return
+
+ event = cur[0]
+ self["Event"].newEvent(event)
+
+ if cur[1] is None or cur[1].getServiceName() == "":
+ if self.key_green_choice != self.EMPTY:
+ self["key_green"].setText("")
+ self.key_green_choice = self.EMPTY
+ if self.key_red_choice != self.EMPTY:
+ self["key_red"].setText("")
+ self.key_red_choice = self.EMPTY
+ return
+ elif self.key_red_choice != self.ZAP:
+ self["key_red"].setText("Zap")
+ self.key_red_choice = self.ZAP
+
+ if not event:
+ if self.key_green_choice != self.EMPTY:
+ self["key_green"].setText("")
+ self.key_green_choice = self.EMPTY
+ return
+
+ serviceref = cur[1]
+ eventid = event.getEventId()
+ refstr = serviceref.ref.toString()
+ isRecordEvent = False
+ for timer in self.session.nav.RecordTimer.timer_list:
+ if timer.eit == eventid and timer.service_ref.ref.toString() == refstr:
+ isRecordEvent = True
+ break
+ if isRecordEvent and self.key_green_choice != self.REMOVE_TIMER:
+ self["key_green"].setText(_("Remove timer"))
+ self.key_green_choice = self.REMOVE_TIMER
+ elif not isRecordEvent and self.key_green_choice != self.ADD_TIMER:
+ self["key_green"].setText(_("Add timer"))
+ self.key_green_choice = self.ADD_TIMER
+
def moveTimeLines(self, force=False):
+ self.updateTimelineTimer.start((60-(int(time())%60))*1000) #keep syncronised
l = self["list"]
event_rect = l.getEventRect()
time_epoch = l.getTimeEpoch()
@@ -542,6 +671,7 @@ class GraphMultiEPG(Screen):
if event_rect is None or time_epoch is None or time_base is None:
return
time_steps = time_epoch > 180 and 60 or 30
+
num_lines = time_epoch/time_steps
incWidth=event_rect.width()/num_lines
pos=event_rect.left()
@@ -569,8 +699,7 @@ class GraphMultiEPG(Screen):
now=time()
timeline_now = self["timeline_now"]
if now >= time_base and now < (time_base + time_epoch * 60):
- bla = (event_rect.width() * 1000) / time_epoch
- xpos = ((now/60) - (time_base/60)) * bla / 1000
+ xpos = int((((now - time_base) * event_rect.width()) / (time_epoch * 60))-(timeline_now.instance.size().width()/2))
old_pos = timeline_now.position
new_pos = (xpos+event_rect.left(), old_pos[1])
if old_pos != new_pos:
@@ -578,3 +707,6 @@ class GraphMultiEPG(Screen):
timeline_now.visible = True
else:
timeline_now.visible = False
+ # here no l.l.invalidate() is needed when the zPosition in the skin is correct!
+
+
diff --git a/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py b/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py
index 21d1bfe8..adb7015d 100644
--- a/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py
+++ b/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py
@@ -69,6 +69,7 @@ def changeBouquetCB(direction, epg):
bouquet = bouquetSel.getCurrent()
services = getBouquetServices(bouquet)
if len(services):
+ global epg_bouquet
epg_bouquet = bouquet
epg.setServices(services)
@@ -93,4 +94,5 @@ def main(session, servicelist, **kwargs):
def Plugins(**kwargs):
name = _("Graphical Multi EPG")
descr = _("A graphical EPG for all services of an specific bouquet")
- return [ PluginDescriptor(name=name, description=descr, where = PluginDescriptor.WHERE_EVENTINFO, fnc=main) ]
+ return [ PluginDescriptor(name=name, description=descr, where = PluginDescriptor.WHERE_EVENTINFO, fnc=main),
+ PluginDescriptor(name=name, description=descr, where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=main) ]
diff --git a/lib/python/Plugins/Extensions/Makefile.am b/lib/python/Plugins/Extensions/Makefile.am
index 6b5d9735..9f3737aa 100644
--- a/lib/python/Plugins/Extensions/Makefile.am
+++ b/lib/python/Plugins/Extensions/Makefile.am
@@ -1,2 +1 @@
SUBDIRS = TuxboxPlugins FileManager CutListEditor PicturePlayer MediaScanner MediaPlayer IpkgInstaller GraphMultiEPG SocketMMI DVDPlayer DVDBurn
-# SimpleRSS is still not finished
diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py
index 0d5305d7..3e023841 100644
--- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py
+++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py
@@ -1,6 +1,6 @@
from os import path as os_path, remove as os_remove, listdir as os_listdir
from time import strftime
-from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation, loadPic
+from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation, ePicLoad
from ServiceReference import ServiceReference
from Screens.Screen import Screen
from Screens.HelpMenu import HelpableScreen
@@ -35,18 +35,59 @@ class MyPlayList(PlayList):
self.oldCurrPlaying = -1
class MediaPixmap(Pixmap):
+ def __init__(self):
+ Pixmap.__init__(self)
+ self.coverArtFileName = ""
+ self.picload = ePicLoad()
+ self.picload.PictureData.get().append(self.paintCoverArtPixmapCB)
+ self.coverFileNames = ["folder.png", "folder.jpg"]
+
def applySkin(self, desktop, screen):
- self.default_pixmap = None
+ from Tools.LoadPixmap import LoadPixmap
+ noCoverFile = None
if self.skinAttributes is not None:
for (attrib, value) in self.skinAttributes:
if attrib == "pixmap":
- self.default_pixmap = value
+ noCoverFile = value
break
- if self.default_pixmap is None:
- self.default_pixmap = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png")
- self.coverFileNames = ["folder.png", "folder.jpg"]
+ if noCoverFile is None:
+ noCoverFile = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png")
+ self.noCoverPixmap = LoadPixmap(noCoverFile)
return Pixmap.applySkin(self, desktop, screen)
+ def onShow(self):
+ Pixmap.onShow(self)
+ sc = AVSwitch().getFramebufferScale()
+ #0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB)
+ self.picload.setPara((self.instance.size().width(), self.instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
+
+ def paintCoverArtPixmapCB(self, picInfo=None):
+ ptr = self.picload.getData()
+ if ptr != None:
+ self.instance.setPixmap(ptr.__deref__())
+
+ def updateCoverArt(self, path):
+ while not path.endswith("/"):
+ path = path[:-1]
+ new_coverArtFileName = None
+ for filename in self.coverFileNames:
+ if fileExists(path + filename):
+ new_coverArtFileName = path + filename
+ if self.coverArtFileName != new_coverArtFileName:
+ self.coverArtFileName = new_coverArtFileName
+ if new_coverArtFileName:
+ self.picload.startDecode(self.coverArtFileName)
+ else:
+ self.showDefaultCover()
+
+ def showDefaultCover(self):
+ self.instance.setPixmap(self.noCoverPixmap)
+
+ def embeddedCoverArt(self):
+ print "[embeddedCoverArt] found"
+ self.coverArtFileName = "/tmp/.id3coverart"
+ self.picload.startDecode(self.coverArtFileName)
+
class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport, HelpableScreen):
ALLOW_SUSPEND = True
ENABLE_RESUME_SUPPORT = True
@@ -70,11 +111,10 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
# 'None' is magic to start at the list of mountpoints
defaultDir = config.mediaplayer.defaultDir.getValue()
- self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|mkv|mp4|dat|flac)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
+ self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|mkv|mp4|m4a|dat|flac)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
self["filelist"] = self.filelist
self.playlist = MyPlayList()
- #self.playlist = PlayList()
self.is_closing = False
self.delname = ""
self["playlist"] = self.playlist
@@ -83,15 +123,15 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
self["currenttext"] = Label("")
- self["artisttext"] = Label(_("Artist:"))
+ self["artisttext"] = Label(_("Artist")+':')
self["artist"] = Label("")
- self["titletext"] = Label(_("Title:"))
+ self["titletext"] = Label(_("Title")+':')
self["title"] = Label("")
- self["albumtext"] = Label(_("Album:"))
+ self["albumtext"] = Label(_("Album")+':')
self["album"] = Label("")
- self["yeartext"] = Label(_("Year:"))
+ self["yeartext"] = Label(_("Year")+':')
self["year"] = Label("")
- self["genretext"] = Label(_("Genre:"))
+ self["genretext"] = Label(_("Genre")+':')
self["genre"] = Label("")
self["coverArt"] = MediaPixmap()
self["repeat"] = MultiPixmap()
@@ -169,8 +209,6 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
self.leftKeyTimer.callback.append(self.leftTimerFire)
self.currList = "filelist"
-
- self.coverArtFileName = ""
self.isAudioCD = False
self.AudioCD_albuminfo = {}
self.cdAudioTrackFiles = []
@@ -187,7 +225,8 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
{
iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
iPlayableService.evUser+11: self.__evDecodeError,
- iPlayableService.evUser+12: self.__evPluginError
+ iPlayableService.evUser+12: self.__evPluginError,
+ iPlayableService.evUser+13: self["coverArt"].embeddedCoverArt
})
def doNothing(self):
@@ -206,6 +245,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory())
config.mediaplayer.defaultDir.save()
hotplugNotifier.remove(self.hotplugCB)
+ del self["coverArt"].picload
self.close()
def checkSkipShowHideLock(self):
@@ -285,19 +325,6 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
if self[name].getText() != info:
self[name].setText(info)
- def updateCoverArtPixmap(self, path):
- while not path.endswith("/"):
- path = path[:-1]
- new_coverArtFileName = self["coverArt"].default_pixmap
- for filename in self["coverArt"].coverFileNames:
- if fileExists(path + filename):
- new_coverArtFileName = path + filename
- if self.coverArtFileName != new_coverArtFileName:
- self.coverArtFileName = new_coverArtFileName
- pixmap = loadPic(self.coverArtFileName, 116, 116, AVSwitch().getAspectRatioSetting()/2,1,0,0)
- if pixmap is not None:
- self["coverArt"].instance.setPixmap(pixmap.__deref__())
-
def leftDown(self):
self.lefttimer = True
self.leftKeyTimer.start(1000)
@@ -456,17 +483,20 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
else:
menu.append((_("add files to playlist"), "copyfiles"))
menu.append((_("switch to playlist"), "playlist"))
- menu.append((_("delete file"), "deletefile"))
+ if config.usage.setup_level.index >= 1: # intermediate+
+ menu.append((_("delete file"), "deletefile"))
else:
menu.append((_("switch to filelist"), "filelist"))
- menu.append((_("shuffle playlist"), "shuffle"))
- menu.append((_("Delete entry"), "deleteentry"))
menu.append((_("clear playlist"), "clear"))
+ menu.append((_("Delete entry"), "deleteentry"))
+ if config.usage.setup_level.index >= 1: # intermediate+
+ menu.append((_("shuffle playlist"), "shuffle"))
menu.append((_("hide player"), "hide"));
- menu.append((_("save playlist"), "saveplaylist"));
menu.append((_("load playlist"), "loadplaylist"));
- menu.append((_("delete saved playlist"), "deleteplaylist"));
- menu.append((_("Edit settings"), "settings"))
+ if config.usage.setup_level.index >= 1: # intermediate+
+ menu.append((_("save playlist"), "saveplaylist"));
+ menu.append((_("delete saved playlist"), "deleteplaylist"));
+ menu.append((_("Edit settings"), "settings"))
self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
def menuCallback(self, choice):
@@ -629,12 +659,16 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
def copyDirectory(self, directory, recursive = True):
print "copyDirectory", directory
- filelist = FileList(directory, useServiceRef = True, isTop = True)
+ if directory == '/':
+ print "refusing to operate on /"
+ return
+ filelist = FileList(directory, useServiceRef = True, showMountpoints = False, isTop = True)
for x in filelist.getFileList():
if x[0][1] == True: #isDir
if recursive:
- self.copyDirectory(x[0][0])
+ if x[0][0] != directory:
+ self.copyDirectory(x[0][0])
elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097:
self.playlist.addFile(x[0][0])
self.playlist.updateList()
@@ -775,6 +809,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
def playEntry(self):
if len(self.playlist.getServiceRefList()):
+ audio_extensions = (".mp2", ".mp3", ".wav", ".ogg", "flac", "m4a")
needsInfoUpdate = False
currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
@@ -790,7 +825,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
ext = text[-4:].lower()
# FIXME: the information if the service contains video (and we should hide our window) should com from the service instead
- if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
+ if ext not in audio_extensions and not self.isAudioCD:
self.hide()
else:
needsInfoUpdate = True
@@ -817,7 +852,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
currref = self.playlist.getServiceRefList()[idx]
text = currref.getPath()
ext = text[-4:].lower()
- if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
+ if ext not in audio_extensions and not self.isAudioCD:
self.hide()
else:
needsInfoUpdate = True
@@ -825,11 +860,9 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
self.unPauseService()
if needsInfoUpdate == True:
path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath()
- self.updateCoverArtPixmap(path)
+ self["coverArt"].updateCoverArt(path)
else:
- pngname = self["coverArt"].default_pixmap
- self.coverArtFileName = pngname
- self["coverArt"].instance.setPixmapFromFile(self.coverArtFileName)
+ self["coverArt"].showDefaultCover()
self.readTitleInformation()
def updatedSeekState(self):
@@ -863,17 +896,22 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
self.session.open(Subtitles)
def hotplugCB(self, dev, media_state):
- if dev == harddiskmanager.getCD():
- from Components.Scanner import scanDevice
- devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
- self.cdAudioTrackFiles = []
- res = scanDevice(devpath)
- list = [ (r.description, r, res[r], self.session) for r in res ]
- if list:
- (desc, scanner, files, session) = list[0]
- for file in files:
- if file.mimetype == "audio/x-cda":
- self.cdAudioTrackFiles.append(file.path)
+ if dev == harddiskmanager.getCD():
+ if media_state == "1":
+ from Components.Scanner import scanDevice
+ devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
+ self.cdAudioTrackFiles = []
+ res = scanDevice(devpath)
+ list = [ (r.description, r, res[r], self.session) for r in res ]
+ if list:
+ (desc, scanner, files, session) = list[0]
+ for file in files:
+ if file.mimetype == "audio/x-cda":
+ self.cdAudioTrackFiles.append(file.path)
+ else:
+ self.cdAudioTrackFiles = []
+ if self.isAudioCD:
+ self.clear_playlist()
class MediaPlayerLCDScreen(Screen):
skin = """
diff --git a/lib/python/Plugins/Extensions/MediaPlayer/settings.py b/lib/python/Plugins/Extensions/MediaPlayer/settings.py
index c6d274bd..416ab2ee 100644
--- a/lib/python/Plugins/Extensions/MediaPlayer/settings.py
+++ b/lib/python/Plugins/Extensions/MediaPlayer/settings.py
@@ -3,30 +3,10 @@ from Screens.HelpMenu import HelpableScreen
from Components.Label import Label
from Components.FileList import FileList
from Components.MediaPlayer import PlayList
-from Components.config import config, getConfigListEntry, ConfigSubsection, configfile, ConfigText, ConfigYesNo
+from Components.config import config, getConfigListEntry, ConfigSubsection, configfile, ConfigText, ConfigYesNo, ConfigDirectory
from Components.ConfigList import ConfigListScreen
from Components.ActionMap import ActionMap
-class ConfigDirectory(ConfigText):
- def __init__(self, default="", visible_width=60):
- ConfigText.__init__(self, default, fixed_size = True, visible_width = visible_width)
- def handleKey(self, key):
- pass
- def getValue(self):
- if self.text == "":
- return None
- else:
- return ConfigText.getValue(self)
- def setValue(self, val):
- if val == None:
- val = ""
- ConfigText.setValue(self, val)
- def getMulti(self, selected):
- if self.text == "":
- return ("mtext"[1-selected:], _("List of Storage Devices"), range(0))
- else:
- return ConfigText.getMulti(self, selected)
-
config.mediaplayer = ConfigSubsection()
config.mediaplayer.repeat = ConfigYesNo(default=False)
config.mediaplayer.savePlaylistOnExit = ConfigYesNo(default=True)
diff --git a/lib/python/Plugins/Extensions/MediaScanner/plugin.py b/lib/python/Plugins/Extensions/MediaScanner/plugin.py
index 7d57ce0b..88b917ee 100644
--- a/lib/python/Plugins/Extensions/MediaScanner/plugin.py
+++ b/lib/python/Plugins/Extensions/MediaScanner/plugin.py
@@ -17,6 +17,7 @@ def mountpoint_choosen(option):
from Screens.ChoiceBox import ChoiceBox
+ print "scanning", option
(description, mountpoint, session) = option
res = scanDevice(mountpoint)
diff --git a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py
index ea906f0d..05adb633 100644
--- a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py
+++ b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py
@@ -1,384 +1,151 @@
-from enigma import eTimer, loadPic, getExif
+from enigma import ePicLoad, eTimer, getDesktop
+
from Screens.Screen import Screen
-from Screens.ServiceInfo import ServiceInfoList, ServiceInfoListEntry
-from Components.ActionMap import ActionMap, NumberActionMap
+from Tools.Directories import resolveFilename, pathExists, fileExists, SCOPE_MEDIA
+from Plugins.Plugin import PluginDescriptor
+
from Components.Pixmap import Pixmap, MovingPixmap
+from Components.ActionMap import ActionMap, NumberActionMap
from Components.Label import Label
-
-from Components.ConfigList import ConfigList
-from Components.config import *
-
-from Tools.Directories import resolveFilename, fileExists, pathExists, createDir, SCOPE_MEDIA
+from Components.Button import Button
from Components.FileList import FileList
from Components.AVSwitch import AVSwitch
+from Components.Sources.List import List
+from Components.ConfigList import ConfigList
-from Plugins.Plugin import PluginDescriptor
+from Components.config import config, ConfigSubsection, ConfigInteger, ConfigSelection, ConfigText, ConfigEnableDisable, KEY_LEFT, KEY_RIGHT, KEY_0, getConfigListEntry
+
+def getScale():
+ return AVSwitch().getFramebufferScale()
config.pic = ConfigSubsection()
-config.pic.slidetime = ConfigInteger(default=10, limits=(5, 60))
-config.pic.resize = ConfigSelection(default="0", choices = [("0", _("simple")), ("1", _("better"))])
+config.pic.framesize = ConfigInteger(default=30, limits=(5, 99))
+config.pic.slidetime = ConfigInteger(default=10, limits=(10, 60))
+config.pic.resize = ConfigSelection(default="1", choices = [("0", _("simple")), ("1", _("better"))])
config.pic.cache = ConfigEnableDisable(default=True)
config.pic.lastDir = ConfigText(default=resolveFilename(SCOPE_MEDIA))
-config.pic.rotate = ConfigSelection(default="0", choices = [("0", _("none")), ("1", _("manual")), ("2", _("by Exif"))])
-
-def getAspect():
- val = AVSwitch().getAspectRatioSetting()
- return val/2
+config.pic.infoline = ConfigEnableDisable(default=True)
+config.pic.loop = ConfigEnableDisable(default=True)
+config.pic.bgcolor = ConfigSelection(default="#00000000", choices = [("#00000000", _("black")),("#009eb9ff", _("blue")),("#00ff5a51", _("red")), ("#00ffe875", _("yellow")), ("#0038FF48", _("green"))])
+config.pic.textcolor = ConfigSelection(default="#0038FF48", choices = [("#00000000", _("black")),("#009eb9ff", _("blue")),("#00ff5a51", _("red")), ("#00ffe875", _("yellow")), ("#0038FF48", _("green"))])
-#------------------------------------------------------------------------------------------
+class picshow(Screen):
+ def __init__(self, session):
+ self.skin = """<screen position="80,80" size="560,440" title="PicturePlayer" >
+ <ePixmap position="0,0" size="140,40" pixmap="skin_default/buttons/red.png" alphatest="on" />
+ <ePixmap position="140,0" size="140,40" pixmap="skin_default/buttons/green.png" alphatest="on" />
+ <ePixmap position="280,0" size="140,40" pixmap="skin_default/buttons/yellow.png" alphatest="on" />
+ <ePixmap position="420,0" size="140,40" pixmap="skin_default/buttons/blue.png" alphatest="on" />
+ <widget name="key_red" position="0,0" size="140,40" font="Regular;20" backgroundColor="#9f1313" zPosition="2" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
+ <widget name="key_green" position="140,0" size="140,40" font="Regular;20" backgroundColor="#1f771f" zPosition="2" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
+ <widget name="key_yellow" position="280,0" size="140,40" font="Regular;20" backgroundColor="#a08500" zPosition="2" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
+ <widget name="key_blue" position="420,0" size="140,40" font="Regular;20" backgroundColor="#18188b" zPosition="2" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
+ <widget name="label" position="5,55" size="350,140" font="Regular;19" />
+ <widget name="thn" position="360,40" size="180,160" alphatest="on" />
+ <widget name="filelist" position="5,205" zPosition="2" size="550,230" scrollbarMode="showOnDemand" />
+ </screen>"""
-class ThumbView(Screen):
- skin = """
- <screen position="0,0" size="720,576" flags="wfNoBorder" title="ThumbView" >
- <eLabel position="0,0" zPosition="0" size="720,576" backgroundColor="black" />
- <widget name="frame" position="50,63" size="190,200" pixmap="pic_frame.png" zPosition="1" alphatest="on" />
- <widget name="label0" position="55,240" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
- <widget name="label1" position="270,240" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
- <widget name="label2" position="485,240" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
- <widget name="label3" position="55,465" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
- <widget name="label4" position="270,465" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
- <widget name="label5" position="485,465" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
- <widget name="thumb0" position="55,68" size="180,160" zPosition="2" transparent="1" />
- <widget name="thumb1" position="270,68" size="180,160" zPosition="2" transparent="1" />
- <widget name="thumb2" position="485,68" size="180,160" zPosition="2" transparent="1" />
- <widget name="thumb3" position="55,293" size="180,160" zPosition="2" transparent="1" />
- <widget name="thumb4" position="270,293" size="180,160" zPosition="2" transparent="1" />
- <widget name="thumb5" position="485,293" size="180,160" zPosition="2" transparent="1" />
- </screen>"""
-
- def __init__(self, session, filelist, name, path):
- self.skin = ThumbView.skin
Screen.__init__(self, session)
- self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "MovieSelectionActions"],
+ self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions"],
{
- "cancel": self.Exit,
- "ok": self.KeyOk,
- "showEventInfo": self.StartExif,
- "right": self.key_right,
- "left": self.key_left,
- "up": self.key_up,
- "down": self.key_down
+ "cancel": self.KeyExit,
+ "red": self.KeyRed,
+ "yellow": self.KeyYellow,
+ "blue": self.KeyBlue,
+ "ok": self.KeyOk
}, -1)
-
- for x in range(6):
- self["label"+str(x)] = Label()
- self["thumb"+str(x)] = Pixmap()
- self["frame"] = MovingPixmap()
-
- self.aspect = getAspect()
- self.path = path
- self.filelist = filelist
- self.currPage = -1
- self.index = 0
- self.old_index = 0
- self.thumblist = []
- self.thumbindex = 0
- self.list = []
- self.poslist = [[50,63],[265,63],[480,63],[50,288],[265,288],[480,288]]
-
- count=0
- pos=0
- for x in self.filelist:
- if x[0][1] == False:
- self.list.append((x[0][0], self.path + x[0][0], count/6, pos, "(" + str(count+1) + ") "))
- pos += 1
- if pos == 6:
- pos = 0
- if x[0][0] == name:
- self.index = count
- count += 1
- self.maxentry = len(self.list)-1
-
- if self.maxentry < 0:
- self["label0"].setText(_("no Picture found"))
-
- self.ThumbTimer = eTimer()
- self.ThumbTimer.callback.append(self.showThumb)
- self.fillPage()
-
- def key_left(self):
- self.index -= 1
- if self.index < 0:
- self.index = self.maxentry
- self.fillPage()
-
- def key_right(self):
- self.index += 1
- if self.index > self.maxentry:
- self.index = 0
- self.fillPage()
-
- def key_up(self):
- self.index -= 3
- if self.index < 0:
- self.index = 0
- self.fillPage()
-
- def key_down(self):
- self.index += 3
- if self.index > self.maxentry:
- self.index = self.maxentry
- self.fillPage()
-
- def fillPage(self):
- if self.maxentry < 0:
- return
+ self["key_red"] = Button(_("Thumbnails"))
+ self["key_green"] = Button()
+ self["key_yellow"] = Button(_("Exif"))
+ self["key_blue"] = Button(_("Setup"))
+ self["label"] = Label()
+ self["thn"] = Pixmap()
- self["frame"].moveTo(self.poslist[self.list[self.index][3]][0], self.poslist[self.list[self.index][3]][1], 1)
- self["frame"].startMoving()
-
- if self.list[self.index][2] != self.currPage:
- self.currPage = self.list[self.index][2]
- textlist = ["","","","","",""]
- self.thumblist = ["","","","","",""]
-
- for x in self.list:
- if x[2] == self.currPage:
- textlist[x[3]] = x[4] + x[0]
- self.thumblist[x[3]] = x[0]
-
- for x in range(6):
- self["label"+str(x)].setText(textlist[x])
- self["thumb"+str(x)].hide()
-
- self.ThumbTimer.start(500, True)
-
- def showThumb(self):
- if self.thumblist[self.thumbindex] != "":
- cachefile = ""
- if config.pic.cache.value:
- cachedir = self.path + ".Thumbnails/"
- cachefile = cachedir + self.thumblist[self.thumbindex] + str(180) + str(160) + str(self.aspect)
- if not pathExists(cachedir):
- if not createDir(cachedir):
- cachefile = ""
-
- ptr = loadPic(self.path + self.thumblist[self.thumbindex], 180, 160, self.aspect, int(config.pic.resize.value), int(config.pic.rotate.value), 1, cachefile, 1)
- if ptr != None:
- self["thumb"+str(self.thumbindex)].show()
- self["thumb"+str(self.thumbindex)].instance.setPixmap(ptr)
-
- self.thumbindex += 1
- if self.thumbindex < 6:
- self.ThumbTimer.start(500, True)
- else:
- self.thumbindex = 0
- else:
- self.thumbindex = 0
-
- def StartExif(self):
- if self.maxentry < 0:
- return
-
- self.session.open(ExifView, self.list[self.index][1], self.list[self.index][0])
-
- def KeyOk(self):
- if self.maxentry < 0:
- return
-
- self.old_index = self.index
- self.session.openWithCallback(self.returnView ,PicView, self.filelist, self.list[self.index][0], self.path)
-
- def returnView(self, val=0):
- self.index = val
- if self.old_index != self.index:
- self.fillPage()
-
- def Exit(self):
- self.close(self.index)
-
-#------------------------------------------------------------------------------------------
-
-class PicView(Screen):
- skin = """
- <screen position="0,0" size="720,576" flags="wfNoBorder" title="PicturePlayer" >
- <eLabel position="0,0" zPosition="0" size="720,576" backgroundColor="black" />
- <widget name="picture" position="80,50" size="560,450" zPosition="1" transparent="1" />
- <widget name="point" position="80,515" size="14,14" zPosition="1" pixmap="skin_default/icons/record.png" alphatest="on" />
- <widget name="file" position="150,510" size="350,30" font="Regular;20" halign="center" zPosition="1" transparent="1" />
- <ePixmap position="500,515" size="36,20" pixmap="skin_default/buttons/key_info.png" zPosition="1" alphatest="on" />
- <ePixmap position="550,515" size="20,20" pixmap="skin_default/icons/ico_mp_rewind.png" zPosition="1" alphatest="on" />
- <widget name="play" position="575,515" size="20,20" pixmap="skin_default/icons/ico_mp_play.png" zPosition="1" alphatest="on" />
- <widget name="pause" position="600,515" size="20,20" pixmap="skin_default/icons/ico_mp_pause.png" zPosition="1" alphatest="on" />
- <ePixmap position="625,515" size="20,20" pixmap="skin_default/icons/ico_mp_forward.png" zPosition="1" alphatest="on" />
- </screen>"""
-
- def __init__(self, session, filelist, name, path):
- self.skin = PicView.skin
- Screen.__init__(self, session)
-
- self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "MovieSelectionActions"],
- {
- "cancel": self.Exit,
- "showEventInfo": self.StartExif,
- "green": self.Play,
- "yellow": self.Pause,
- "blue": self.nextPic,
- "red": self.prevPic
- }, -1)
-
- self.aspect = getAspect()
- self.blinking = False
- self.autoShow = True
- self.slideOn = False
- self.pauseOn = False
- self.index = 0
- self.old = 0
- self.list = []
-
- count=0
- for x in filelist:
- if x[0][1] == False:
- self.list.append((x[0][0], path + x[0][0], 0))
- if x[0][0] == name:
- self.index = count
- count += 1
- self.maxentry = len(self.list)-1
+ currDir = config.pic.lastDir.value
+ if not pathExists(currDir):
+ currDir = "/"
- self["file"] = Label(_("please wait, loading picture..."))
- self["picture"] = Pixmap()
- self["point"] = Pixmap()
- self["play"] = Pixmap()
- self["pause"] = Pixmap()
+ self.filelist = FileList(currDir, matchingPattern = "(?i)^.*\.(jpeg|jpg|jpe|png|bmp|gif)")
+ self["filelist"] = self.filelist
+ self["filelist"].onSelectionChanged.append(self.selectionChanged)
- self.decodeTimer = eTimer()
- self.decodeTimer.callback.append(self.decodePic)
- self.decodeTimer.start(300, True)
+ self.ThumbTimer = eTimer()
+ self.ThumbTimer.callback.append(self.showThumb)
- self.slideTimer = eTimer()
- self.slideTimer.callback.append(self.slidePic)
-
-
- def Pause(self):
- if self.slideOn:
- if self.pauseOn:
- self.pauseOn=False
- self["pause"].show()
- else:
- self.pauseOn=True
- self["play"].show()
- self.slideValue = 0
-
- def Play(self):
- if self.pauseOn == False:
- if self.slideOn:
- self.slideOn=False
- self["play"].show()
- else:
- self.slideOn=True
- self.slideTimer.start(1000, True)
-
- self.slideValue = int(config.pic.slidetime.value)
+ self.picload = ePicLoad()
+ self.picload.PictureData.get().append(self.showPic)
- def slidePic(self):
- if self.slideOn == True and self.pauseOn == False:
- self.blinkingWidget("play")
- self.slideValue -= 1
- if self.slideValue <= 0:
- self.slideValue = int(config.pic.slidetime.value)
- self.nextPic()
-
- self.slideTimer.start(1000, True)
+ self.onLayoutFinish.append(self.setConf)
- if self.pauseOn:
- self.blinkingWidget("pause")
- self.slideTimer.start(1000, True)
+ def showPic(self, picInfo=""):
+ ptr = self.picload.getData()
+ if ptr != None:
+ self["thn"].instance.setPixmap(ptr.__deref__())
+ self["thn"].show()
- def decodePic(self):
- self.currPic = loadPic(self.list[self.index][1], 560, 450, self.aspect, int(config.pic.resize.value), int(config.pic.rotate.value),1)
- self["point"].hide()
- if self.autoShow:
- self.showPic()
- self.autoShow = False
+ text = picInfo.split('\n',1)
+ self["label"].setText(text[1])
+ self["label"].show()
- def showPic(self):
- if self.currPic != None:
- self.old = self.index
- self["file"].setText(self.list[self.old][0] + " (" + str(self.old+1) + "/" + str(self.maxentry+1) + ")")
- self["picture"].instance.setPixmap(self.currPic)
+ def showThumb(self):
+ if not self.filelist.canDescent():
+ if self.filelist.getCurrentDirectory() and self.filelist.getFilename():
+ if self.picload.getThumbnail(self.filelist.getCurrentDirectory() + self.filelist.getFilename()) == 1:
+ self.ThumbTimer.start(500, True)
- self.next()
- self["point"].show()
- self.decodeTimer.start(300, True)
-
- def nextPic(self):
- self.showPic()
-
- def prevPic(self):
- self.index = self.old
- self.prev()
- self.autoShow = True
- self["point"].show()
- self.decodeTimer.start(300, True)
+ def selectionChanged(self):
+ if not self.filelist.canDescent():
+ self.ThumbTimer.start(500, True)
+ else:
+ self["label"].hide()
+ self["thn"].hide()
- def next(self):
- self.index += 1
- if self.index > self.maxentry:
- self.index = 0
+ def KeyRed(self):
+ #if not self.filelist.canDescent():
+ self.session.openWithCallback(self.callbackView, Pic_Thumb, self.filelist.getFileList(), self.filelist.getSelectionIndex(), self.filelist.getCurrentDirectory())
+
+ def KeyYellow(self):
+ if not self.filelist.canDescent():
+ self.session.open(Pic_Exif, self.picload.getInfo(self.filelist.getCurrentDirectory() + self.filelist.getFilename()))
+
+ def KeyBlue(self):
+ self.session.openWithCallback(self.setConf ,Pic_Setup)
- def prev(self):
- self.index -= 1
- if self.index < 0:
- self.index = self.maxentry
-
- def blinkingWidget(self, name):
- if self.blinking:
- self.blinking=False
- self[name].show()
+ def KeyOk(self):
+ if self.filelist.canDescent():
+ self.filelist.descent()
else:
- self.blinking=True
- self[name].hide()
+ self.session.openWithCallback(self.callbackView, Pic_Full_View, self.filelist.getFileList(), self.filelist.getSelectionIndex(), self.filelist.getCurrentDirectory())
- def StartExif(self):
- if self.pauseOn == False:
- self.Pause()
- self.session.openWithCallback(self.StopExif ,ExifView, self.list[self.old][1], self.list[self.old][0])
+ def setConf(self):
+ sc = getScale()
+ #0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB)
+ self.picload.setPara((self["thn"].instance.size().width(), self["thn"].instance.size().height(), sc[0], sc[1], config.pic.cache.value, int(config.pic.resize.value), "#00000000"))
- def StopExif(self):
- if self.pauseOn:
- self.Pause()
-
- def Exit(self):
- self.close(self.old)
+ def callbackView(self, val=0):
+ if val > 0:
+ self.filelist.moveToIndex(val)
-#------------------------------------------------------------------------------------------
+ def KeyExit(self):
+ del self.picload
-class ExifView(Screen):
- skin = """
- <screen position="80,130" size="560,320" title="Exif-Data" >
- <widget name="exiflist" position="5,5" size="550,310" selectionDisabled="1" />
- </screen>"""
-
- def __init__(self, session, fullname, name):
- self.skin = ExifView.skin
- Screen.__init__(self, session)
+ if self.filelist.getCurrentDirectory() is None:
+ config.pic.lastDir.value = "/"
+ else:
+ config.pic.lastDir.value = self.filelist.getCurrentDirectory()
- self["actions"] = ActionMap(["OkCancelActions"],
- {
- "cancel": self.close
- }, -1)
-
- dlist = ["Name:", "EXIF-Version:", "Camera-Make:", "Camera-Model:", "Date/Time:", "User Comments:", "Width / Height:", "Orientation:", "Metering Mode:", "Exposure Program:", "Light Source:", "Flash used:", "CompressedBitsPerPixel:", "ISO Speed Rating:", "X-Resolution:", "Y-Resolution:", "Resolution Unit:", "Brightness:", "Exposure Time:", "Exposure Bias:", "Distance:", "CCD-Width:", "ApertureFNumber:"]
- tlist = [ ]
- self["exiflist"] = ServiceInfoList(tlist)
- tlist.append(ServiceInfoListEntry(dlist[0], name))
- count=1
- for x in getExif(fullname):
- tlist.append(ServiceInfoListEntry(dlist[count], x))
- count += 1
+ config.pic.save()
+ self.close()
#------------------------------------------------------------------------------------------
-class PicSetup(Screen):
- skin = """
- <screen position="160,220" size="400,120" title="Settings" >
- <widget name="liste" position="10,10" size="380,100" />
- </screen>"""
-
+class Pic_Setup(Screen):
def __init__(self, session):
- self.skin = PicSetup.skin
+ self.skin = """<screen position="120,180" size="480,210" title="Settings" >
+ <widget name="liste" position="5,5" size="470,200" />
+ </screen>"""
Screen.__init__(self, session)
self["actions"] = NumberActionMap(["SetupActions"],
@@ -398,12 +165,16 @@ class PicSetup(Screen):
"9": self.keyNumber
}, -1)
- self.list = []
- self["liste"] = ConfigList(self.list)
- self.list.append(getConfigListEntry(_("Slideshow Interval (sec.)"), config.pic.slidetime))
- self.list.append(getConfigListEntry(_("Scaling Mode"), config.pic.resize))
- self.list.append(getConfigListEntry(_("Cache Thumbnails"), config.pic.cache))
- #self.list.append(getConfigListEntry(_("Rotate Picture"), config.pic.rotate))
+ list = []
+ self["liste"] = ConfigList(list)
+ list.append(getConfigListEntry(_("Slideshow Interval (sec.)"), config.pic.slidetime))
+ list.append(getConfigListEntry(_("Scaling Mode"), config.pic.resize))
+ list.append(getConfigListEntry(_("Cache Thumbnails"), config.pic.cache))
+ list.append(getConfigListEntry(_("show Infoline"), config.pic.infoline))
+ list.append(getConfigListEntry(_("Frame size in full view"), config.pic.framesize))
+ list.append(getConfigListEntry(_("slide picture in loop"), config.pic.loop))
+ list.append(getConfigListEntry(_("backgroundcolor"), config.pic.bgcolor))
+ list.append(getConfigListEntry(_("textcolor"), config.pic.textcolor))
def keyLeft(self):
self["liste"].handleKey(KEY_LEFT)
@@ -414,126 +185,390 @@ class PicSetup(Screen):
def keyNumber(self, number):
self["liste"].handleKey(KEY_0 + number)
+#---------------------------------------------------------------------------
+
+class Pic_Exif(Screen):
+ def __init__(self, session, exiflist):
+ self.skin = """<screen position="80,120" size="560,360" title="Info" >
+ <widget source="menu" render="Listbox" position="0,0" size="560,360" scrollbarMode="showOnDemand" selectionDisabled="1" >
+ <convert type="TemplatedMultiContent">
+ {"template": [ MultiContentEntryText(pos = (5, 5), size = (250, 30), flags = RT_HALIGN_LEFT, text = 0), MultiContentEntryText(pos = (260, 5), size = (290, 30), flags = RT_HALIGN_LEFT, text = 1)], "fonts": [gFont("Regular", 20)], "itemHeight": 30 }
+ </convert>
+ </widget>
+ </screen>"""
+ Screen.__init__(self, session)
-#------------------------------------------------------------------------------------------
+ self["actions"] = ActionMap(["OkCancelActions"],
+ {
+ "cancel": self.close
+ }, -1)
+
+ exifdesc = [_("filename")+':', "EXIF-Version:", "Make:", "Camera:", "Date/Time:", "Width / Height:", "Flash used:", "Orientation:", "User Comments:", "Metering Mode:", "Exposure Program:", "Light Source:", "CompressedBitsPerPixel:", "ISO Speed Rating:", "X-Resolution:", "Y-Resolution:", "Resolution Unit:", "Brightness:", "Exposure Time:", "Exposure Bias:", "Distance:", "CCD-Width:", "ApertureFNumber:"]
+ list = []
-class picmain(Screen):
- skin = """
- <screen position="160,90" size="400,390" title="PicturePlayer" >
- <ePixmap position="10,40" size="36,20" pixmap="skin_default/buttons/key_menu.png" transparent="1" alphatest="on" />
- <ePixmap position="10,70" size="36,20" pixmap="skin_default/buttons/key_info.png" transparent="1" alphatest="on" />
- <ePixmap position="12,100" size="36,20" pixmap="skin_default/buttons/key_red.png" transparent="1" alphatest="on" />
- <eLabel text="Settings" position="60,40" size="120,25" font="Regular;20" transparent="1" />
- <eLabel text="Exif-Data" position="60,70" size="120,25" font="Regular;20" transparent="1" />
- <eLabel text="Thumbnails" position="60,100" size="120,25" font="Regular;20" transparent="1" />
- <widget name="thumbnail" position="200,5" size="180,160" alphatest="on" />
- <widget name="filelist" position="5,170" zPosition="2" size="390,210" scrollbarMode="showOnDemand" />
- </screen>"""
-
- def __init__(self, session):
- self.skin = picmain.skin
+ for x in range(len(exiflist)):
+ if x>0:
+ list.append((exifdesc[x], exiflist[x]))
+ else:
+ name = exiflist[x].split('/')[-1]
+ list.append((exifdesc[x], name))
+ self["menu"] = List(list)
+
+#----------------------------------------------------------------------------------------
+
+T_INDEX = 0
+T_FRAME_POS = 1
+T_PAGE = 2
+T_NAME = 3
+T_FULL = 4
+
+class Pic_Thumb(Screen):
+ def __init__(self, session, piclist, lastindex, path):
+
+ self.textcolor = config.pic.textcolor.value
+ self.color = config.pic.bgcolor.value
+ textsize = 20
+ self.spaceX = 35
+ self.picX = 190
+ self.spaceY = 30
+ self.picY = 200
+
+ size_w = getDesktop(0).size().width()
+ size_h = getDesktop(0).size().height()
+ self.thumbsX = size_w / (self.spaceX + self.picX) # thumbnails in X
+ self.thumbsY = size_h / (self.spaceY + self.picY) # thumbnails in Y
+ self.thumbsC = self.thumbsX * self.thumbsY # all thumbnails
+
+ self.positionlist = []
+ skincontent = ""
+
+ posX = -1
+ for x in range(self.thumbsC):
+ posY = x / self.thumbsX
+ posX += 1
+ if posX >= self.thumbsX:
+ posX = 0
+
+ absX = self.spaceX + (posX*(self.spaceX + self.picX))
+ absY = self.spaceY + (posY*(self.spaceY + self.picY))
+ self.positionlist.append((absX, absY))
+ skincontent += "<widget name=\"label" + str(x) + "\" position=\"" + str(absX+5) + "," + str(absY+self.picY-textsize) + "\" size=\"" + str(self.picX - 10) + "," + str(textsize) + "\" font=\"Regular;14\" zPosition=\"2\" transparent=\"1\" noWrap=\"1\" foregroundColor=\"" + self.textcolor + "\" />"
+
+ skincontent += "<widget name=\"thumb" + str(x) + "\" position=\"" + str(absX+5)+ "," + str(absY+5) + "\" size=\"" + str(self.picX -10) + "," + str(self.picY - (textsize*2)) + "\" zPosition=\"2\" transparent=\"1\" alphatest=\"on\" />"
+
+
+ # Screen, backgroundlabel and MovingPixmap
+ self.skin = "<screen position=\"0,0\" size=\"" + str(size_w) + "," + str(size_h) + "\" flags=\"wfNoBorder\" > \
+ <eLabel position=\"0,0\" zPosition=\"0\" size=\""+ str(size_w) + "," + str(size_h) + "\" backgroundColor=\"" + self.color + "\" /><widget name=\"frame\" position=\"35,30\" size=\"190,200\" pixmap=\"pic_frame.png\" zPosition=\"1\" alphatest=\"on\" />" + skincontent + "</screen>"
+
Screen.__init__(self, session)
-
- self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "ColorActions", "MovieSelectionActions"],
+
+ self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "MovieSelectionActions"],
{
- "ok": self.KeyOk,
"cancel": self.Exit,
- "right": self.rightDown,
- "left": self.leftUp,
- "up": self.up,
- "down": self.down,
+ "ok": self.KeyOk,
+ "left": self.key_left,
+ "right": self.key_right,
+ "up": self.key_up,
+ "down": self.key_down,
"showEventInfo": self.StartExif,
- "contextMenu": self.Settings,
- "red": self.StartThumb
}, -1)
- self.aspect = getAspect()
- currDir = config.pic.lastDir.value
- if not pathExists(currDir):
- currDir = "/"
+ self["frame"] = MovingPixmap()
+ for x in range(self.thumbsC):
+ self["label"+str(x)] = Label()
+ self["thumb"+str(x)] = Pixmap()
+
+ self.Thumbnaillist = []
+ self.filelist = []
+ self.currPage = -1
+ self.dirlistcount = 0
+ self.path = path
- self.filelist = FileList(currDir, matchingPattern = "(?i)^.*\.(jpeg|jpg|jpe|png|bmp|gif)")
- self["filelist"] = self.filelist
- self["thumbnail"] = Pixmap()
+ index = 0
+ framePos = 0
+ Page = 0
+ for x in piclist:
+ if x[0][1] == False:
+ self.filelist.append((index, framePos, Page, x[0][0], path + x[0][0]))
+ index += 1
+ framePos += 1
+ if framePos > (self.thumbsC -1):
+ framePos = 0
+ Page += 1
+ else:
+ self.dirlistcount += 1
+
+ self.maxentry = len(self.filelist)-1
+ self.index = lastindex - self.dirlistcount
+ if self.index < 0:
+ self.index = 0
+
+ self.picload = ePicLoad()
+ self.picload.PictureData.get().append(self.showPic)
+
+ self.onLayoutFinish.append(self.setPicloadConf)
self.ThumbTimer = eTimer()
- self.ThumbTimer.callback.append(self.showThumb)
- self.ThumbTimer.start(500, True)
+ self.ThumbTimer.callback.append(self.showPic)
+
+ def setPicloadConf(self):
+ sc = getScale()
+ self.picload.setPara([self["thumb0"].instance.size().width(), self["thumb0"].instance.size().height(), sc[0], sc[1], config.pic.cache.value, int(config.pic.resize.value), self.color])
+ self.paintFrame()
+
+ def paintFrame(self):
+ #print "index=" + str(self.index)
+ if self.maxentry < self.index or self.index < 0:
+ return
+
+ pos = self.positionlist[self.filelist[self.index][T_FRAME_POS]]
+ self["frame"].moveTo( pos[0], pos[1], 1)
+ self["frame"].startMoving()
- def up(self):
- self["filelist"].up()
- self.ThumbTimer.start(1500, True)
+ if self.currPage != self.filelist[self.index][T_PAGE]:
+ self.currPage = self.filelist[self.index][T_PAGE]
+ self.newPage()
+
+ def newPage(self):
+ self.Thumbnaillist = []
+ #clear Labels and Thumbnail
+ for x in range(self.thumbsC):
+ self["label"+str(x)].setText("")
+ self["thumb"+str(x)].hide()
+ #paint Labels and fill Thumbnail-List
+ for x in self.filelist:
+ if x[T_PAGE] == self.currPage:
+ self["label"+str(x[T_FRAME_POS])].setText("(" + str(x[T_INDEX]+1) + ") " + x[T_NAME])
+ self.Thumbnaillist.append([0, x[T_FRAME_POS], x[T_FULL]])
+
+ #paint Thumbnail start
+ self.showPic()
- def down(self):
- self["filelist"].down()
- self.ThumbTimer.start(1500, True)
+ def showPic(self, picInfo=""):
+ for x in range(len(self.Thumbnaillist)):
+ if self.Thumbnaillist[x][0] == 0:
+ if self.picload.getThumbnail(self.Thumbnaillist[x][2]) == 1: #zu tun probier noch mal
+ self.ThumbTimer.start(500, True)
+ else:
+ self.Thumbnaillist[x][0] = 1
+ break
+ elif self.Thumbnaillist[x][0] == 1:
+ self.Thumbnaillist[x][0] = 2
+ ptr = self.picload.getData()
+ if ptr != None:
+ self["thumb" + str(self.Thumbnaillist[x][1])].instance.setPixmap(ptr.__deref__())
+ self["thumb" + str(self.Thumbnaillist[x][1])].show()
+
+ def key_left(self):
+ self.index -= 1
+ if self.index < 0:
+ self.index = self.maxentry
+ self.paintFrame()
- def leftUp(self):
- self["filelist"].pageUp()
- self.ThumbTimer.start(1500, True)
+ def key_right(self):
+ self.index += 1
+ if self.index > self.maxentry:
+ self.index = 0
+ self.paintFrame()
- def rightDown(self):
- self["filelist"].pageDown()
- self.ThumbTimer.start(1500, True)
+ def key_up(self):
+ self.index -= self.thumbsX
+ if self.index < 0:
+ self.index =self.maxentry
+ self.paintFrame()
+
+ def key_down(self):
+ self.index += self.thumbsX
+ if self.index > self.maxentry:
+ self.index = 0
+ self.paintFrame()
- def showThumb(self):
- if not self.filelist.canDescent():
- cachefile = ""
- if config.pic.cache.value:
- cachedir = self.filelist.getCurrentDirectory() + ".Thumbnails/"
- cachefile = cachedir + self.filelist.getFilename() + str(180) + str(160) + str(self.aspect)
- if not pathExists(cachedir):
- if not createDir(cachedir):
- cachefile = ""
-
- ptr = loadPic(self.filelist.getCurrentDirectory() + self.filelist.getFilename(), 180, 160, self.aspect, int(config.pic.resize.value), 0, 0, cachefile, 1)
- if ptr != None:
- self["thumbnail"].show()
- self["thumbnail"].instance.setPixmap(ptr)
- else:
- self["thumbnail"].hide()
+ def StartExif(self):
+ if self.maxentry < 0:
+ return
+ self.session.open(Pic_Exif, self.picload.getInfo(self.filelist[self.index][T_FULL]))
def KeyOk(self):
- if self.filelist.canDescent():
- self.filelist.descent()
- else:
- self.session.openWithCallback(self.returnVal, PicView, self.filelist.getFileList(), self.filelist.getFilename(), self.filelist.getCurrentDirectory())
-
- def StartThumb(self):
- self.session.openWithCallback(self.returnVal, ThumbView, self.filelist.getFileList(), self.filelist.getFilename(), self.filelist.getCurrentDirectory())
+ if self.maxentry < 0:
+ return
+ self.old_index = self.index
+ self.session.openWithCallback(self.callbackView, Pic_Full_View, self.filelist, self.index, self.path)
- def returnVal(self, val=0):
- if val > 0:
- for x in self.filelist.getFileList():
- if x[0][1] == True:
- val += 1
- self.filelist.moveToIndex(val)
+ def callbackView(self, val=0):
+ self.index = val
+ if self.old_index != self.index:
+ self.paintFrame()
+ def Exit(self):
+ del self.picload
+ self.close(self.index + self.dirlistcount)
- def StartExif(self):
- if not self.filelist.canDescent():
- self.session.open(ExifView, self.filelist.getCurrentDirectory() + self.filelist.getFilename(), self.filelist.getFilename())
+#---------------------------------------------------------------------------
+
+class Pic_Full_View(Screen):
+ def __init__(self, session, filelist, index, path):
+
+ self.textcolor = config.pic.textcolor.value
+ self.bgcolor = config.pic.bgcolor.value
+ space = config.pic.framesize.value
+ size_w = getDesktop(0).size().width()
+ size_h = getDesktop(0).size().height()
+
+ self.skin = "<screen position=\"0,0\" size=\"" + str(size_w) + "," + str(size_h) + "\" flags=\"wfNoBorder\" > \
+ <eLabel position=\"0,0\" zPosition=\"0\" size=\""+ str(size_w) + "," + str(size_h) + "\" backgroundColor=\""+ self.bgcolor +"\" /><widget name=\"pic\" position=\"" + str(space) + "," + str(space) + "\" size=\"" + str(size_w-(space*2)) + "," + str(size_h-(space*2)) + "\" zPosition=\"1\" alphatest=\"on\" /> \
+ <widget name=\"point\" position=\""+ str(space+5) + "," + str(space+2) + "\" size=\"20,20\" zPosition=\"2\" pixmap=\"skin_default/icons/record.png\" alphatest=\"on\" /> \
+ <widget name=\"play_icon\" position=\""+ str(space+25) + "," + str(space+2) + "\" size=\"20,20\" zPosition=\"2\" pixmap=\"skin_default/icons/ico_mp_play.png\" alphatest=\"on\" /> \
+ <widget name=\"file\" position=\""+ str(space+45) + "," + str(space) + "\" size=\""+ str(size_w-(space*2)-50) + ",25\" font=\"Regular;20\" halign=\"left\" foregroundColor=\"" + self.textcolor + "\" zPosition=\"2\" noWrap=\"1\" transparent=\"1\" /></screen>"
+
+ Screen.__init__(self, session)
+
+ self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "MovieSelectionActions"],
+ {
+ "cancel": self.Exit,
+ "green": self.PlayPause,
+ "yellow": self.PlayPause,
+ "blue": self.nextPic,
+ "red": self.prevPic,
+ "left": self.prevPic,
+ "right": self.nextPic,
+ "showEventInfo": self.StartExif,
+ }, -1)
+
+ self["point"] = Pixmap()
+ self["pic"] = Pixmap()
+ self["play_icon"] = Pixmap()
+ self["file"] = Label(_("please wait, loading picture..."))
+
+ self.old_index = 0
+ self.filelist = []
+ self.lastindex = index
+ self.currPic = []
+ self.shownow = True
+ self.dirlistcount = 0
+
+ for x in filelist:
+ if len(filelist[0]) == 3: #orig. filelist
+ if x[0][1] == False:
+ self.filelist.append(path + x[0][0])
+ else:
+ self.dirlistcount += 1
+ elif len(filelist[0]) == 2: #scanlist
+ if x[0][1] == False:
+ self.filelist.append(x[0][0])
+ else:
+ self.dirlistcount += 1
+ else: # thumbnaillist
+ self.filelist.append(x[T_FULL])
+
+ self.maxentry = len(self.filelist)-1
+ self.index = index - self.dirlistcount
+ if self.index < 0:
+ self.index = 0
+
+ self.picload = ePicLoad()
+ self.picload.PictureData.get().append(self.finish_decode)
+
+ self.slideTimer = eTimer()
+ self.slideTimer.callback.append(self.slidePic)
- def Settings(self):
- self.session.open(PicSetup)
+ if self.maxentry >= 0:
+ self.onLayoutFinish.append(self.setPicloadConf)
+
+ def setPicloadConf(self):
+ sc = getScale()
+ self.picload.setPara([self["pic"].instance.size().width(), self["pic"].instance.size().height(), sc[0], sc[1], 0, int(config.pic.resize.value), self.bgcolor])
+
+ self["play_icon"].hide()
+ if config.pic.infoline.value == False:
+ self["file"].hide()
+ self.start_decode()
+
+ def ShowPicture(self):
+ if self.shownow and len(self.currPic):
+ self.shownow = False
+ self["file"].setText(self.currPic[0])
+ self.lastindex = self.currPic[1]
+ self["pic"].instance.setPixmap(self.currPic[2].__deref__())
+ self.currPic = []
+
+ self.next()
+ self.start_decode()
- def Exit(self):
- if self.filelist.getCurrentDirectory() is None:
- config.pic.lastDir.value = "/"
+ def finish_decode(self, picInfo=""):
+ self["point"].hide()
+ ptr = self.picload.getData()
+ if ptr != None:
+ text = ""
+ try:
+ text = picInfo.split('\n',1)
+ text = "(" + str(self.index+1) + "/" + str(self.maxentry+1) + ") " + text[0].split('/')[-1]
+ except:
+ pass
+ self.currPic = []
+ self.currPic.append(text)
+ self.currPic.append(self.index)
+ self.currPic.append(ptr)
+ self.ShowPicture()
+
+ def start_decode(self):
+ self.picload.startDecode(self.filelist[self.index])
+ self["point"].show()
+
+ def next(self):
+ self.index += 1
+ if self.index > self.maxentry:
+ self.index = 0
+
+ def prev(self):
+ self.index -= 1
+ if self.index < 0:
+ self.index = self.maxentry
+
+ def slidePic(self):
+ print "slide to next Picture index=" + str(self.lastindex)
+ if config.pic.loop.value==False and self.lastindex == self.maxentry:
+ self.PlayPause()
+ self.shownow = True
+ self.ShowPicture()
+
+ def PlayPause(self):
+ if self.slideTimer.isActive():
+ self.slideTimer.stop()
+ self["play_icon"].hide()
else:
- config.pic.lastDir.value = self.filelist.getCurrentDirectory()
+ self.slideTimer.start(config.pic.slidetime.value*1000)
+ self["play_icon"].show()
+ self.nextPic()
- config.pic.save()
- self.close()
+ def prevPic(self):
+ self.currPic = []
+ self.index = self.lastindex
+ self.prev()
+ self.start_decode()
+ self.shownow = True
+
+ def nextPic(self):
+ self.shownow = True
+ self.ShowPicture()
+
+ def StartExif(self):
+ if self.maxentry < 0:
+ return
+ self.session.open(Pic_Exif, self.picload.getInfo(self.filelist[self.lastindex]))
+
+ def Exit(self):
+ del self.picload
+ self.close(self.lastindex + self.dirlistcount)
#------------------------------------------------------------------------------------------
def main(session, **kwargs):
- session.open(picmain)
+ session.open(picshow)
def filescan_open(list, session, **kwargs):
# Recreate List as expected by PicView
filelist = [((file.path, False), None) for file in list]
- session.open(PicView, filelist, "", "")
+ session.open(Pic_Full_View, filelist, 0, file.path)
def filescan(**kwargs):
from Components.Scanner import Scanner, ScanPath
@@ -557,5 +592,5 @@ def filescan(**kwargs):
def Plugins(**kwargs):
return \
- [PluginDescriptor(name="PicturePlayer", description="Picture Viewer (BMP, PNG, JPG, GIF)", icon="pictureplayer.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main),
- PluginDescriptor(name="PicturePlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)]
+ [PluginDescriptor(name=_("PicturePlayer"), description=_("fileformats (BMP, PNG, JPG, GIF)"), icon="pictureplayer.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main),
+ PluginDescriptor(name=_("PicturePlayer"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)]
diff --git a/lib/python/Plugins/SystemPlugins/DiseqcTester/Makefile.am b/lib/python/Plugins/SystemPlugins/DiseqcTester/Makefile.am
new file mode 100644
index 00000000..cd72696a
--- /dev/null
+++ b/lib/python/Plugins/SystemPlugins/DiseqcTester/Makefile.am
@@ -0,0 +1,5 @@
+installdir = $(LIBDIR)/enigma2/python/Plugins/SystemPlugins/DiseqcTester
+
+install_PYTHON = \
+ __init__.py \
+ plugin.py \ No newline at end of file
diff --git a/lib/python/Plugins/SystemPlugins/DiseqcTester/__init__.py b/lib/python/Plugins/SystemPlugins/DiseqcTester/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/lib/python/Plugins/SystemPlugins/DiseqcTester/__init__.py
diff --git a/lib/python/Plugins/SystemPlugins/DiseqcTester/plugin.py b/lib/python/Plugins/SystemPlugins/DiseqcTester/plugin.py
new file mode 100644
index 00000000..07861954
--- /dev/null
+++ b/lib/python/Plugins/SystemPlugins/DiseqcTester/plugin.py
@@ -0,0 +1,642 @@
+from Screens.Satconfig import NimSelection
+from Screens.Screen import Screen
+from Screens.TextBox import TextBox
+from Screens.MessageBox import MessageBox
+
+from Plugins.Plugin import PluginDescriptor
+
+from Components.ActionMap import ActionMap, NumberActionMap
+from Components.NimManager import nimmanager
+from Components.ResourceManager import resourcemanager
+from Components.Sources.FrontendStatus import FrontendStatus
+from Components.TuneTest import TuneTest
+from Components.Sources.List import List
+from Components.Sources.Progress import Progress
+from Components.Sources.StaticText import StaticText
+from Components.ConfigList import ConfigListScreen
+from Components.config import getConfigListEntry, ConfigSelection, ConfigYesNo
+from Components.Harddisk import harddiskmanager
+
+import random
+
+# always use:
+# setResultType(type)
+# setResultParameter(parameter)
+# getTextualResult()
+class ResultParser:
+ def __init__(self):
+ pass
+
+ TYPE_BYORBPOS = 0
+ TYPE_BYINDEX = 1
+ TYPE_ALL = 2
+ def setResultType(self, type):
+ self.type = type
+
+ def setResultParameter(self, parameter):
+ if self.type == self.TYPE_BYORBPOS:
+ self.orbpos = parameter
+ elif self.type == self.TYPE_BYINDEX:
+ self.index = parameter
+
+ def getTextualResultForIndex(self, index, logfulltransponders = False):
+ text = ""
+ text += "%s:\n" % self.getTextualIndexRepresentation(index)
+
+ failed, successful = self.results[index]["failed"], self.results[index]["successful"]
+ countfailed = len(failed)
+ countsuccessful = len(successful)
+ countall = countfailed + countsuccessful
+ percentfailed = round(countfailed / float(countall + 0.0001) * 100)
+ percentsuccessful = round(countsuccessful / float(countall + 0.0001) * 100)
+ text += "Tested %d transponders\n%d (%d %%) transponders succeeded\n%d (%d %%) transponders failed\n" % (countall, countsuccessful, percentsuccessful, countfailed, percentfailed)
+ reasons = {}
+ if countfailed > 0:
+ for transponder in failed:
+ reasons[transponder[2]] = reasons.get(transponder[2], [])
+ reasons[transponder[2]].append(transponder)
+ if transponder[2] == "pids_failed":
+ print transponder[2], "-", transponder[3]
+
+ text += "The %d unsuccessful tuning attempts failed for the following reasons:\n" % countfailed
+
+ for reason in reasons.keys():
+ text += "%s: %d transponders failed\n" % (reason, len(reasons[reason]))
+
+ for reason in reasons.keys():
+ text += "\n"
+ text += "%s previous planes:\n" % reason
+ for transponder in reasons[reason]:
+ if transponder[1] is not None:
+ text += self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[1]))
+ else:
+ text += "No transponder tuned"
+ text += " ==> " + self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[0]))
+ text += "\n"
+ if logfulltransponders:
+ text += str(transponder[1])
+ text += " ==> "
+ text += str(transponder[0])
+ text += "\n"
+ if countsuccessful > 0:
+ text += "\n"
+ text += "Successfully tuned transponders' previous planes:\n"
+ for transponder in successful:
+ if transponder[1] is not None:
+ text += self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[1]))
+ else:
+ text += "No transponder tuned"
+ text += " ==> " + self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[0]))
+ text += "\n"
+ return text
+
+ def getTextualResult(self):
+ text = ""
+ if self.type == self.TYPE_BYINDEX:
+ text += self.getTextualResultForIndex(self.index)
+ elif self.type == self.TYPE_BYORBPOS:
+ for index in self.results.keys():
+ if index[2] == self.orbpos:
+ text += self.getTextualResultForIndex(index)
+ text += "\n-----------------------------------------------------\n"
+ elif self.type == self.TYPE_ALL:
+ orderedResults = {}
+ for index in self.results.keys():
+ orbpos = index[2]
+ orderedResults[orbpos] = orderedResults.get(orbpos, [])
+ orderedResults[orbpos].append(index)
+ ordered_orbpos = orderedResults.keys()
+ ordered_orbpos.sort()
+ for orbpos in ordered_orbpos:
+ text += "\n*****************************************\n"
+ text += "Orbital position %s:" % str(orbpos)
+ text += "\n*****************************************\n"
+ for index in orderedResults[orbpos]:
+ text += self.getTextualResultForIndex(index, logfulltransponders = True)
+ text += "\n-----------------------------------------------------\n"
+
+
+ return text
+
+class DiseqcTester(Screen, TuneTest, ResultParser):
+ skin = """
+ <screen position="90,100" size="520,400" title="DiSEqC Tester" >
+ <!--ePixmap pixmap="skin_default/icons/dish_scan.png" position="5,25" zPosition="0" size="119,110" transparent="1" alphatest="on" />
+ <widget source="Frontend" render="Label" position="190,10" zPosition="2" size="260,20" font="Regular;19" halign="center" valign="center" transparent="1">
+ <convert type="FrontendInfo">SNRdB</convert>
+ </widget>
+ <eLabel name="snr" text="SNR:" position="120,35" size="60,22" font="Regular;21" halign="right" transparent="1" />
+ <widget source="Frontend" render="Progress" position="190,35" size="260,20" pixmap="skin_default/bar_snr.png" borderWidth="2" borderColor="#cccccc">
+ <convert type="FrontendInfo">SNR</convert>
+ </widget>
+ <widget source="Frontend" render="Label" position="460,35" size="60,22" font="Regular;21">
+ <convert type="FrontendInfo">SNR</convert>
+ </widget>
+ <eLabel name="agc" text="AGC:" position="120,60" size="60,22" font="Regular;21" halign="right" transparent="1" />
+ <widget source="Frontend" render="Progress" position="190,60" size="260,20" pixmap="skin_default/bar_snr.png" borderWidth="2" borderColor="#cccccc">
+ <convert type="FrontendInfo">AGC</convert>
+ </widget>
+ <widget source="Frontend" render="Label" position="460,60" size="60,22" font="Regular;21">
+ <convert type="FrontendInfo">AGC</convert>
+ </widget>
+ <eLabel name="ber" text="BER:" position="120,85" size="60,22" font="Regular;21" halign="right" transparent="1" />
+ <widget source="Frontend" render="Progress" position="190,85" size="260,20" pixmap="skin_default/bar_ber.png" borderWidth="2" borderColor="#cccccc">
+ <convert type="FrontendInfo">BER</convert>
+ </widget>
+ <widget source="Frontend" render="Label" position="460,85" size="60,22" font="Regular;21">
+ <convert type="FrontendInfo">BER</convert>
+ </widget>
+ <eLabel name="lock" text="Lock:" position="120,115" size="60,22" font="Regular;21" halign="right" />
+ <widget source="Frontend" render="Pixmap" pixmap="skin_default/icons/lock_on.png" position="190,110" zPosition="1" size="38,31" alphatest="on">
+ <convert type="FrontendInfo">LOCK</convert>
+ <convert type="ConditionalShowHide" />
+ </widget>
+ <widget source="Frontend" render="Pixmap" pixmap="skin_default/icons/lock_off.png" position="190,110" zPosition="1" size="38,31" alphatest="on">
+ <convert type="FrontendInfo">LOCK</convert>
+ <convert type="ConditionalShowHide">Invert</convert>
+ </widget-->
+ <widget source="progress_list" render="Listbox" position="0,0" size="510,150" scrollbarMode="showOnDemand">
+ <convert type="TemplatedMultiContent">
+ {"template": [
+ MultiContentEntryText(pos = (10, 0), size = (330, 25), flags = RT_HALIGN_LEFT, text = 1), # index 1 is the index name,
+ MultiContentEntryText(pos = (330, 0), size = (150, 25), flags = RT_HALIGN_RIGHT, text = 2) # index 2 is the status,
+ ],
+ "fonts": [gFont("Regular", 20)],
+ "itemHeight": 25
+ }
+ </convert>
+ </widget>
+ <eLabel name="overall_progress" text="Overall progress:" position="20,162" size="480,22" font="Regular;21" halign="center" transparent="1" />
+ <widget source="overall_progress" render="Progress" position="20,192" size="480,20" borderWidth="2" backgroundColor="#254f7497" />
+ <eLabel name="overall_progress" text="Progress:" position="20,222" size="480,22" font="Regular;21" halign="center" transparent="1" />
+ <widget source="sub_progress" render="Progress" position="20,252" size="480,20" borderWidth="2" backgroundColor="#254f7497" />
+
+ <eLabel name="" text="Failed:" position="20,282" size="140,22" font="Regular;21" halign="left" transparent="1" />
+ <widget source="failed_counter" render="Label" position="160,282" size="100,20" font="Regular;21" />
+
+ <eLabel name="" text="Succeeded:" position="20,312" size="140,22" font="Regular;21" halign="left" transparent="1" />
+ <widget source="succeeded_counter" render="Label" position="160,312" size="100,20" font="Regular;21" />
+
+ <eLabel name="" text="With errors:" position="20,342" size="140,22" font="Regular;21" halign="left" transparent="1" />
+ <widget source="witherrors_counter" render="Label" position="160,342" size="100,20" font="Regular;21" />
+
+ <eLabel name="" text="Not tested:" position="20,372" size="140,22" font="Regular;21" halign="left" transparent="1" />
+ <widget source="untestable_counter" render="Label" position="160,372" size="100,20" font="Regular;21" />
+
+ <widget source="CmdText" render="Label" position="300,282" size="180,200" font="Regular;21" />
+ </screen>"""
+
+ TEST_TYPE_QUICK = 0
+ TEST_TYPE_RANDOM = 1
+ TEST_TYPE_COMPLETE = 2
+ def __init__(self, session, feid, test_type = TEST_TYPE_QUICK, loopsfailed = 3, loopssuccessful = 1, log = False):
+ Screen.__init__(self, session)
+ self.feid = feid
+ self.test_type = test_type
+ self.loopsfailed = loopsfailed
+ self.loopssuccessful = loopssuccessful
+ self.log = log
+
+ self["actions"] = NumberActionMap(["SetupActions"],
+ {
+ "ok": self.select,
+ "cancel": self.keyCancel,
+ }, -2)
+
+ TuneTest.__init__(self, feid, stopOnSuccess = self.loopssuccessful, stopOnError = self.loopsfailed)
+ #self["Frontend"] = FrontendStatus(frontend_source = lambda : self.frontend, update_interval = 100)
+ self["overall_progress"] = Progress()
+ self["sub_progress"] = Progress()
+
+ self["failed_counter"] = StaticText("0")
+ self["succeeded_counter"] = StaticText("0")
+ self["witherrors_counter"] = StaticText("0")
+ self["untestable_counter"] = StaticText("0")
+
+ self.list = []
+ self["progress_list"] = List(self.list)
+ self["progress_list"].onSelectionChanged.append(self.selectionChanged)
+
+ self["CmdText"] = StaticText(_("Please wait while scanning is in progress..."))
+
+ self.indexlist = {}
+ self.readTransponderList()
+
+ self.running = False
+
+ self.results = {}
+ self.resultsstatus = {}
+
+ self.onLayoutFinish.append(self.go)
+
+ def getProgressListComponent(self, index, status):
+ return (index, self.getTextualIndexRepresentation(index), status)
+
+ def clearProgressList(self):
+ self.list = []
+ self["progress_list"].list = self.list
+
+ def addProgressListItem(self, index):
+ if index in self.indexlist:
+ for entry in self.list:
+ if entry[0] == index:
+ self.changeProgressListStatus(index, "working")
+ return
+ self.list.append(self.getProgressListComponent(index, _("working")))
+ self["progress_list"].list = self.list
+ self["progress_list"].setIndex(len(self.list) - 1)
+
+ def changeProgressListStatus(self, index, status):
+ self.newlist = []
+ count = 0
+ indexpos = 0
+ for entry in self.list:
+ if entry[0] == index:
+ self.newlist.append(self.getProgressListComponent(index, status))
+ indexpos = count
+ else:
+ self.newlist.append(entry)
+ count += 1
+ self.list = self.newlist
+ self["progress_list"].list = self.list
+ self["progress_list"].setIndex(indexpos)
+
+ def readTransponderList(self):
+ for sat in nimmanager.getSatListForNim(self.feid):
+ for transponder in nimmanager.getTransponders(sat[0]):
+ #print transponder
+ mytransponder = (transponder[1] / 1000, transponder[2] / 1000, transponder[3], transponder[4], transponder[5], sat[0], None, None, transponder[10], transponder[11])
+ self.analyseTransponder(mytransponder)
+
+ def getIndexForTransponder(self, transponder):
+
+ if transponder[0] < 11700:
+ band = 1 # low
+ else:
+ band = 0 # high
+
+ polarisation = transponder[2]
+
+ sat = transponder[5]
+
+ index = (band, polarisation, sat)
+ return index
+
+ # sort the transponder into self.transponderlist
+ def analyseTransponder(self, transponder):
+ index = self.getIndexForTransponder(transponder)
+ if index not in self.indexlist:
+ self.indexlist[index] = []
+ self.indexlist[index].append(transponder)
+ #print "self.indexlist:", self.indexlist
+
+ # returns a string for the user representing a human readable output for index
+ def getTextualIndexRepresentation(self, index):
+ print "getTextualIndexRepresentation:", index
+ text = ""
+
+ text += nimmanager.getSatDescription(index[2]) + ", "
+
+ if index[0] == 1:
+ text += "Low Band, "
+ else:
+ text += "High Band, "
+
+ if index[1] == 0:
+ text += "H"
+ else:
+ text += "V"
+ return text
+
+ def fillTransponderList(self):
+ self.clearTransponder()
+ print "----------- fillTransponderList"
+ print "index:", self.currentlyTestedIndex
+ keys = self.indexlist.keys()
+ if self.getContinueScanning():
+ print "index:", self.getTextualIndexRepresentation(self.currentlyTestedIndex)
+ for transponder in self.indexlist[self.currentlyTestedIndex]:
+ self.addTransponder(transponder)
+ print "transponderList:", self.transponderlist
+ return True
+ else:
+ return False
+
+ def progressCallback(self, progress):
+ if progress[0] != self["sub_progress"].getRange():
+ self["sub_progress"].setRange(progress[0])
+ self["sub_progress"].setValue(progress[1])
+
+ # logic for scanning order of transponders
+ # on go getFirstIndex is called
+ def getFirstIndex(self):
+ # TODO use other function to scan more randomly
+ if self.test_type == self.TEST_TYPE_QUICK:
+ self.myindex = 0
+ keys = self.indexlist.keys()
+ keys.sort(key = lambda a: a[2]) # sort by orbpos
+ self["overall_progress"].setRange(len(keys))
+ self["overall_progress"].setValue(self.myindex)
+ return keys[0]
+ elif self.test_type == self.TEST_TYPE_RANDOM:
+ self.randomkeys = self.indexlist.keys()
+ random.shuffle(self.randomkeys)
+ self.myindex = 0
+ self["overall_progress"].setRange(len(self.randomkeys))
+ self["overall_progress"].setValue(self.myindex)
+ return self.randomkeys[0]
+ elif self.test_type == self.TEST_TYPE_COMPLETE:
+ keys = self.indexlist.keys()
+ print "keys:", keys
+ successorindex = {}
+ for index in keys:
+ successorindex[index] = []
+ for otherindex in keys:
+ if otherindex != index:
+ successorindex[index].append(otherindex)
+ random.shuffle(successorindex[index])
+ self.keylist = []
+ stop = False
+ currindex = None
+ while not stop:
+ if currindex is None or len(successorindex[currindex]) == 0:
+ oldindex = currindex
+ for index in successorindex.keys():
+ if len(successorindex[index]) > 0:
+ currindex = index
+ self.keylist.append(currindex)
+ break
+ if currindex == oldindex:
+ stop = True
+ else:
+ currindex = successorindex[currindex].pop()
+ self.keylist.append(currindex)
+ print "self.keylist:", self.keylist
+ self.myindex = 0
+ self["overall_progress"].setRange(len(self.keylist))
+ self["overall_progress"].setValue(self.myindex)
+ return self.keylist[0]
+
+
+ # after each index is finished, getNextIndex is called to get the next index to scan
+ def getNextIndex(self):
+ # TODO use other function to scan more randomly
+ if self.test_type == self.TEST_TYPE_QUICK:
+ self.myindex += 1
+ keys = self.indexlist.keys()
+ keys.sort(key = lambda a: a[2]) # sort by orbpos
+
+ self["overall_progress"].setValue(self.myindex)
+ if self.myindex < len(keys):
+ return keys[self.myindex]
+ else:
+ return None
+ elif self.test_type == self.TEST_TYPE_RANDOM:
+ self.myindex += 1
+ keys = self.randomkeys
+
+ self["overall_progress"].setValue(self.myindex)
+ if self.myindex < len(keys):
+ return keys[self.myindex]
+ else:
+ return None
+ elif self.test_type == self.TEST_TYPE_COMPLETE:
+ self.myindex += 1
+ keys = self.keylist
+
+ self["overall_progress"].setValue(self.myindex)
+ if self.myindex < len(keys):
+ return keys[self.myindex]
+ else:
+ return None
+
+ # after each index is finished and the next index is returned by getNextIndex
+ # the algorithm checks, if we should continue scanning
+ def getContinueScanning(self):
+ if self.test_type == self.TEST_TYPE_QUICK or self.test_type == self.TEST_TYPE_RANDOM:
+ return (self.myindex < len(self.indexlist.keys()))
+ elif self.test_type == self.TEST_TYPE_COMPLETE:
+ return (self.myindex < len(self.keylist))
+
+ def addResult(self, index, status, failedTune, successfullyTune):
+ self.results[index] = self.results.get(index, {"failed": [], "successful": [], "status": None, "internalstatus": None})
+ self.resultsstatus[status] = self.resultsstatus.get(status, [])
+
+ oldstatus = self.results[index]["internalstatus"]
+ if oldstatus is None:
+ self.results[index]["status"] = status
+ elif oldstatus == "successful":
+ if status == "failed":
+ self.results[index]["status"] = "with_errors"
+ elif status == "successful":
+ self.results[index]["status"] = oldstatus
+ elif status == "with_errors":
+ self.results[index]["status"] = "with_errors"
+ elif status == "not_tested":
+ self.results[index]["status"] = oldstatus
+ elif oldstatus == "failed":
+ if status == "failed":
+ self.results[index]["status"] = oldstatus
+ elif status == "successful":
+ self.results[index]["status"] = "with_errors"
+ elif status == "with_errors":
+ self.results[index]["status"] = "with_errors"
+ elif status == "not_tested":
+ self.results[index]["status"] = oldstatus
+ elif oldstatus == "with_errors":
+ if status == "failed":
+ self.results[index]["status"] = oldstatus
+ elif status == "successful":
+ self.results[index]["status"] = oldstatus
+ elif status == "with_errors":
+ self.results[index]["status"] = oldstatus
+ elif status == "not_tested":
+ self.results[index]["status"] = oldstatus
+ elif oldstatus == "not_tested":
+ self.results[index]["status"] = status
+
+ if self.results[index]["status"] != "working":
+ self.results[index]["internalstatus"] = self.results[index]["status"]
+ self.results[index]["failed"] = failedTune + self.results[index]["failed"]
+ self.results[index]["successful"] = successfullyTune + self.results[index]["successful"]
+
+ self.resultsstatus[status].append(index)
+
+ def finishedChecking(self):
+ print "finishedChecking"
+ TuneTest.finishedChecking(self)
+
+ if not self.results.has_key(self.currentlyTestedIndex):
+ self.results[self.currentlyTestedIndex] = {"failed": [], "successful": [], "status": None, "internalstatus": None}
+
+ if len(self.failedTune) > 0 and len(self.successfullyTune) > 0:
+ self.changeProgressListStatus(self.currentlyTestedIndex, "with errors")
+ self["witherrors_counter"].setText(str(int(self["witherrors_counter"].getText()) + 1))
+ self.addResult(self.currentlyTestedIndex, "with_errors", self.failedTune, self.successfullyTune)
+ elif len(self.failedTune) == 0 and len(self.successfullyTune) == 0:
+ self.changeProgressListStatus(self.currentlyTestedIndex, "not tested")
+ self["untestable_counter"].setText(str(int(self["untestable_counter"].getText()) + 1))
+ self.addResult(self.currentlyTestedIndex, "untestable", self.failedTune, self.successfullyTune)
+ elif len(self.failedTune) > 0:
+ self.changeProgressListStatus(self.currentlyTestedIndex, "failed")
+ #self["failed_counter"].setText(str(int(self["failed_counter"].getText()) + len(self.failedTune)))
+ self["failed_counter"].setText(str(int(self["failed_counter"].getText()) + 1))
+ self.addResult(self.currentlyTestedIndex, "failed", self.failedTune, self.successfullyTune)
+ else:
+ self.changeProgressListStatus(self.currentlyTestedIndex, "successful")
+ #self["succeeded_counter"].setText(str(int(self["succeeded_counter"].getText()) + len(self.successfullyTune)))
+ self["succeeded_counter"].setText(str(int(self["succeeded_counter"].getText()) + 1))
+ self.addResult(self.currentlyTestedIndex, "successful", self.failedTune, self.successfullyTune)
+
+
+ #self["failed_counter"].setText(str(int(self["failed_counter"].getText()) + len(self.failedTune)))
+ #self["succeeded_counter"].setText(str(int(self["succeeded_counter"].getText()) + len(self.successfullyTune)))
+ #if len(self.failedTune) == 0 and len(self.successfullyTune) == 0:
+ #self["untestable_counter"].setText(str(int(self["untestable_counter"].getText()) + 1))
+
+ self.currentlyTestedIndex = self.getNextIndex()
+ self.addProgressListItem(self.currentlyTestedIndex)
+
+ if self.fillTransponderList():
+ self.run(checkPIDs = True)
+ else:
+ self.running = False
+ self["progress_list"].setIndex(0)
+ print "results:", self.results
+ print "resultsstatus:", self.resultsstatus
+ if self.log:
+ file = open("/media/hdd/diseqctester.log", "w")
+ self.setResultType(ResultParser.TYPE_ALL)
+ file.write(self.getTextualResult())
+ file.close()
+ self.session.open(MessageBox, text=_("The results have been written to %s.") % "/media/hdd/diseqctester.log", type = MessageBox.TYPE_INFO)
+
+ def go(self):
+ self.running = True
+ self["failed_counter"].setText("0")
+ self["succeeded_counter"].setText("0")
+ self["untestable_counter"].setText("0")
+ self.currentlyTestedIndex = self.getFirstIndex()
+
+ self.clearProgressList()
+ self.addProgressListItem(self.currentlyTestedIndex)
+
+ if self.fillTransponderList():
+ self.run(True)
+
+ def keyCancel(self):
+ self.close()
+
+ def select(self):
+ print "selectedIndex:", self["progress_list"].getCurrent()[0]
+ if not self.running:
+ index = self["progress_list"].getCurrent()[0]
+ #self.setResultType(ResultParser.TYPE_BYORBPOS)
+ #self.setResultParameter(index[2])
+ self.setResultType(ResultParser.TYPE_BYINDEX)
+ self.setResultParameter(index)
+ #self.setResultType(ResultParser.TYPE_ALL)
+ self.session.open(TextBox, self.getTextualResult())
+
+ def selectionChanged(self):
+ print "selection changed"
+ if len(self.list) > 0 and not self.running:
+ self["CmdText"].setText(_("Press OK to get further details for %s") % str(self["progress_list"].getCurrent()[1]))
+
+class DiseqcTesterTestTypeSelection(Screen, ConfigListScreen):
+ skin = """<screen position="80,95" size="560,412" title="DiSEqC Tester Test Settings">
+ <widget name="config" position="10,10" size="540,402" scrollbarMode="showOnDemand" />
+ </screen>
+ """
+ def __init__(self, session, feid):
+ Screen.__init__(self, session)
+ self.feid = feid
+
+ self.list = []
+ ConfigListScreen.__init__(self, self.list)
+
+ self["actions"] = ActionMap(["SetupActions"],
+ {
+ "cancel": self.keyCancel
+ }, -2)
+
+ self.createSetup()
+
+ def createSetup(self):
+ self.testtype = ConfigSelection(choices={"quick": _("Quick"), "random": _("Random"), "complete": _("Complete")}, default = "quick")
+ self.testtypeEntry = getConfigListEntry(_("Test Type"), self.testtype)
+ self.list.append(self.testtypeEntry)
+
+ self.loopsfailed = ConfigSelection(choices={"-1": "Every known", "1": "1", "2": "2", "3": "3", "4": "4", "5": "5", "6": "6", "7": "7", "8": "8"}, default = "3")
+ self.loopsfailedEntry = getConfigListEntry(_("Stop testing plane after # failed transponders"), self.loopsfailed)
+ self.list.append(self.loopsfailedEntry)
+
+ self.loopssuccessful = ConfigSelection(choices={"-1": "Every known", "1": "1", "2": "2", "3": "3", "4": "4", "5": "5", "6": "6", "7": "7", "8": "8"}, default = "1")
+ self.loopssuccessfulEntry = getConfigListEntry(_("Stop testing plane after # successful transponders"), self.loopssuccessful)
+ self.list.append(self.loopssuccessfulEntry)
+
+ self.log = ConfigYesNo(False)
+ if harddiskmanager.HDDCount() > 0:
+ self.logEntry = getConfigListEntry(_("Log results to harddisk"), self.log)
+ self.list.append(self.logEntry)
+
+ self["config"].list = self.list
+ self["config"].l.setList(self.list)
+
+ def keyOK(self):
+ print self.testtype.getValue()
+ testtype = DiseqcTester.TEST_TYPE_QUICK
+ if self.testtype.getValue() == "quick":
+ testtype = DiseqcTester.TEST_TYPE_QUICK
+ elif self.testtype.getValue() == "random":
+ testtype = DiseqcTester.TEST_TYPE_RANDOM
+ elif self.testtype.getValue() == "complete":
+ testtype = DiseqcTester.TEST_TYPE_COMPLETE
+ self.session.open(DiseqcTester, feid = self.feid, test_type = testtype, loopsfailed = int(self.loopsfailed.value), loopssuccessful = int(self.loopssuccessful.value), log = self.log.value)
+
+ def keyCancel(self):
+ self.close()
+
+class DiseqcTesterNimSelection(NimSelection):
+ skin = """
+ <screen position="160,123" size="400,330" title="Choose Tuner">
+ <widget source="nimlist" render="Listbox" position="0,0" size="380,300" scrollbarMode="showOnDemand">
+ <convert type="TemplatedMultiContent">
+ {"template": [
+ MultiContentEntryText(pos = (10, 5), size = (360, 30), flags = RT_HALIGN_LEFT, text = 1), # index 1 is the nim name,
+ MultiContentEntryText(pos = (50, 30), size = (320, 30), font = 1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is a description of the nim settings,
+ ],
+ "fonts": [gFont("Regular", 20), gFont("Regular", 15)],
+ "itemHeight": 70
+ }
+ </convert>
+ </widget>
+ </screen>"""
+
+ def __init__(self, session, args = None):
+ NimSelection.__init__(self, session)
+
+ def setResultClass(self):
+ #self.resultclass = DiseqcTester
+ self.resultclass = DiseqcTesterTestTypeSelection
+
+ def showNim(self, nim):
+ nimConfig = nimmanager.getNimConfig(nim.slot)
+ if nim.isCompatible("DVB-S"):
+ if nimConfig.configMode.value in ["loopthrough", "equal", "satposdepends", "nothing"]:
+ return False
+ if nimConfig.configMode.value == "simple":
+ if nimConfig.diseqcMode.value == "positioner":
+ return True
+ return True
+ return False
+
+def DiseqcTesterMain(session, **kwargs):
+ session.open(DiseqcTesterNimSelection)
+
+def autostart(reason, **kwargs):
+ resourcemanager.addResource("DiseqcTester", DiseqcTesterMain)
+
+def Plugins(**kwargs):
+ return [ PluginDescriptor(name="DiSEqC Tester", description=_("Test DiSEqC settings"), where = PluginDescriptor.WHERE_PLUGINMENU, fnc=DiseqcTesterMain),
+ PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, fnc = autostart)]
diff --git a/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py b/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py
index 97ddf4a1..b19007c9 100644
--- a/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py
+++ b/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py
@@ -3,17 +3,9 @@ from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor
from Components.Harddisk import harddiskmanager
-DEVICEDB = \
- { "/devices/pci0000:00/0000:00:14.2/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0": "CF Slot",
- "/devices/pci0000:00/0000:00:14.2/usb1/1-1/1-1:1.0/host0/target1:0:0/0:0:0:0": "SD Slot"
- }
-
hotplugNotifier = [ ]
class Hotplug(Protocol):
- def getUserfriendlyDeviceName(self, phys):
- return DEVICEDB.get(phys, "USB Storage")
-
def connectionMade(self):
self.received = ""
@@ -40,20 +32,19 @@ class Hotplug(Protocol):
dev = device.split('/')[-1]
if action is not None and action == "add":
- print "Medium found in", self.getUserfriendlyDeviceName(dev)
- harddiskmanager.addHotplugPartition(dev, self.getUserfriendlyDeviceName(physdevpath))
+ harddiskmanager.addHotplugPartition(dev, physdevpath)
elif action is not None and action == "remove":
harddiskmanager.removeHotplugPartition(dev)
elif media_state is not None:
if media_state == '1':
harddiskmanager.removeHotplugPartition(dev)
- harddiskmanager.addHotplugPartition(dev, self.getUserfriendlyDeviceName(physdevpath))
+ harddiskmanager.addHotplugPartition(dev, physdevpath)
elif media_state == '0':
harddiskmanager.removeHotplugPartition(dev)
for callback in hotplugNotifier:
try:
- callback(dev, media_state)
+ callback(dev, action or media_state)
except AttributeError:
hotplugNotifier.remove(callback)
diff --git a/lib/python/Plugins/SystemPlugins/Makefile.am b/lib/python/Plugins/SystemPlugins/Makefile.am
index 36b4bde5..4491eafc 100644
--- a/lib/python/Plugins/SystemPlugins/Makefile.am
+++ b/lib/python/Plugins/SystemPlugins/Makefile.am
@@ -1 +1 @@
-SUBDIRS = SoftwareUpdate FrontprocessorUpgrade PositionerSetup ConfigurationBackup Satfinder SkinSelector SatelliteEquipmentControl Videomode VideoTune Hotplug DefaultServicesScanner NFIFlash
+SUBDIRS = SoftwareUpdate FrontprocessorUpgrade PositionerSetup ConfigurationBackup Satfinder SkinSelector SatelliteEquipmentControl Videomode VideoTune Hotplug DefaultServicesScanner NFIFlash DiseqcTester
diff --git a/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py b/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py
index c2046af7..c91c8588 100644
--- a/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py
+++ b/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
from Components.MenuList import MenuList
from Screens.Screen import Screen
from Screens.MessageBox import MessageBox
@@ -18,6 +19,7 @@ import urllib
from twisted.web import client
from twisted.internet import reactor, defer
from twisted.python import failure
+from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
class UserRequestedCancel(Exception):
pass
@@ -119,10 +121,10 @@ class NFIDownload(Screen):
<ePixmap pixmap="skin_default/buttons/green.png" position="140,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
<ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
<ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
- <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#9f1313" transparent="1" />
- <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
- <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#a08500" transparent="1" />
- <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#18188b" transparent="1" />
+ <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;19" valign="center" halign="center" backgroundColor="#9f1313" transparent="1" />
+ <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;19" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
+ <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;19" valign="center" halign="center" backgroundColor="#a08500" transparent="1" />
+ <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;19" valign="center" halign="center" backgroundColor="#18188b" transparent="1" />
<widget source="label_top" render="Label" position="10,44" size="240,20" font="Regular;16" />
<widget name="feedlist" position="10,66" size="250,222" scrollbarMode="showOnDemand" />
@@ -169,6 +171,7 @@ class NFIDownload(Screen):
self.box = HardwareInfo().get_device_name()
self.feed_base = "http://www.dreamboxupdate.com/opendreambox/1.5/%s/images/" % self.box
self.nfi_filter = "" # "release" # only show NFIs containing this string, or all if ""
+ self.wizard_mode = False
self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "EPGSelectActions"],
{
@@ -205,7 +208,7 @@ class NFIDownload(Screen):
self["key_yellow"].text = (_("Change dir."))
else:
self["key_yellow"].text = (_("Select image"))
- self["key_blue"].text = (_("Fix USB stick"))
+ self["key_blue"].text = (_("USB stick wizard"))
def switchList(self,to_where=None):
if self.download or not self["feedlist"].isValid():
@@ -335,7 +338,7 @@ class NFIDownload(Screen):
self.download = self.nfo_download
self.downloading(True)
client.getPage(nfourl).addCallback(self.nfo_finished).addErrback(self.nfo_failed)
- self["statusbar"].text = _("Downloading image description...")
+ self["statusbar"].text = ("Downloading image description...")
def nfo_failed(self, failure_instance):
print "[nfo_failed] " + str(failure_instance)
@@ -399,8 +402,8 @@ class NFIDownload(Screen):
print "couldn't save nfo file " + self.nfofilename
pos = self.nfo.find("MD5:")
- if pos > 0 and len(self.nfo) >= pos+5+32:
- self["statusbar"].text = _("Please wait for md5 signature verification...")
+ if pos > 0 and len(self.nfo) >= pos+5+32:
+ self["statusbar"].text = ("Please wait for md5 signature verification...")
cmd = "md5sum -c -"
md5 = self.nfo[pos+5:pos+5+32] + " " + self.nfilocal
print cmd, md5
@@ -415,6 +418,8 @@ class NFIDownload(Screen):
else:
self["statusbar"].text = "Download completed."
self.downloading(False)
+ if self.wizard_mode:
+ self.configBackup()
def md5ready(self, retval):
self.download_container.sendEOF()
@@ -423,9 +428,12 @@ class NFIDownload(Screen):
print "[md5finished]: " + str(retval)
self.download_container.appClosed.remove(self.md5finished)
if retval==0:
- self["statusbar"].text = _(".NFI file passed md5sum signature check. You can safely flash this image!")
- self.switchList(self.LIST_SOURCE)
self.downloading(False)
+ if self.wizard_mode:
+ self.configBackup()
+ else:
+ self["statusbar"].text = _(".NFI file passed md5sum signature check. You can safely flash this image!")
+ self.switchList(self.LIST_SOURCE)
else:
self.session.openWithCallback(self.nfi_remove, MessageBox, (_("The md5sum validation failed, the file may be downloaded incompletely or be corrupted!") + "\n" + _("Remove the broken .NFI file?")), MessageBox.TYPE_YESNO)
@@ -489,33 +497,22 @@ class NFIDownload(Screen):
def umount_finished(self, retval):
self.container.appClosed.remove(self.umount_finished)
- self.session.openWithCallback(self.dmesg_clear, MessageBox, _("To make sure you intend to do this, please remove the target USB stick now and stick it back in upon prompt. Press OK when you have taken the stick out."), MessageBox.TYPE_INFO)
-
- def dmesg_clear(self, answer):
self.container.appClosed.append(self.dmesg_cleared)
self.taskstring = ""
self.cmd = "dmesg -c"
print "executing " + self.cmd
self.container.execute(self.cmd)
- def dmesg_cleared(self, retval):
+ def dmesg_cleared(self, answer):
self.container.appClosed.remove(self.dmesg_cleared)
- self.session.openWithCallback(self.stick_back_in, MessageBox, (_("Now please insert the USB stick (minimum size is 64 MB) that you want to format and use as .NFI image flasher. Press OK after you've put the stick back in.")), MessageBox.TYPE_INFO)
-
- def stick_back_in(self, answer):
- self["statusbar"].text = _("Waiting for USB stick to settle...")
- self.delayTimer = eTimer()
- self.delayTimer.callback.append(self.waiting_for_stick)
- self.delayCount = -1
- self.delayTimer.start(1000)
-
- def waiting_for_stick(self):
- self.delayCount += 1
- self["job_progressbar"].range = 6
- self["job_progressbar"].value = self.delayCount
- self["job_progresslabel"].text = "-%d s" % (6-self.delayCount)
- if self.delayCount > 5:
- self.delayTimer.stop()
+ self.msgbox = self.session.open(MessageBox, _("Please disconnect all USB devices from your Dreambox and (re-)attach the target USB stick (minimum size is 64 MB) now!"), MessageBox.TYPE_INFO)
+ hotplugNotifier.append(self.hotplugCB)
+
+ def hotplugCB(self, dev, action):
+ print "[hotplugCB]", dev, action
+ if dev.startswith("sd") and action == "add":
+ self.msgbox.close()
+ hotplugNotifier.remove(self.hotplugCB)
self.container.appClosed.append(self.dmesg_scanned)
self.taskstring = ""
self.cmd = "dmesg"
@@ -539,8 +536,8 @@ class NFIDownload(Screen):
self.session.openWithCallback(self.fdisk_query, MessageBox, (_("The following device was found:\n\n%s\n\nDo you want to write the USB flasher to this stick?") % self.devicetext), MessageBox.TYPE_YESNO)
def fdisk_query(self, answer):
- if answer == True:
- self["statusbar"].text = _("Partitioning USB stick...")
+ if answer == True and self.stickdevice:
+ self["statusbar"].text = ("Partitioning USB stick...")
self["job_progressbar"].range = 1000
self["job_progressbar"].value = 100
self["job_progresslabel"].text = "5.00%"
@@ -562,7 +559,7 @@ class NFIDownload(Screen):
self.tar_finished(0)
self["job_progressbar"].value = 700
else:
- self["statusbar"].text = _("Decompressing USB stick flasher boot image...")
+ self["statusbar"].text = ("Decompressing USB stick flasher boot image...")
self.taskstring = ""
self.container.appClosed.append(self.tar_finished)
self.container.setCWD("/tmp")
@@ -588,7 +585,7 @@ class NFIDownload(Screen):
self.container.appClosed.remove(self.tar_finished)
if retval == 0:
self.imagefilename = "/tmp/nfiflash_" + self.box + ".img"
- self["statusbar"].text = _("Copying USB flasher boot image to stick...")
+ self["statusbar"].text = ("Copying USB flasher boot image to stick...")
self.taskstring = ""
self.container.appClosed.append(self.dd_finished)
self.cmd = "dd if=%s of=%s" % (self.imagefilename,self.stickdevice+"/part1")
@@ -607,7 +604,7 @@ class NFIDownload(Screen):
if retval == 0:
self["job_progressbar"].value = 950
self["job_progresslabel"].text = "95.00%"
- self["statusbar"].text = _("Remounting stick partition...")
+ self["statusbar"].text = ("Remounting stick partition...")
self.taskstring = ""
self.container.appClosed.append(self.mount_finished)
self.cmd = "mount %s /mnt/usb -o rw,sync" % (self.stickdevice+"/part1")
@@ -622,11 +619,12 @@ class NFIDownload(Screen):
if retval == 0:
self["job_progressbar"].value = 1000
self["job_progresslabel"].text = "100.00%"
- self["statusbar"].text = _(".NFI Flasher bootable USB stick successfully created.")
- self.session.openWithCallback(self.remove_img, MessageBox, _("The .NFI Image flasher USB stick is now ready to use. Please download an .NFI image file from the feed server and save it on the stick. Then reboot and hold the 'Down' key on the front panel to boot the .NFI flasher from the stick!"), MessageBox.TYPE_INFO)
+ self["statusbar"].text = (".NFI Flasher bootable USB stick successfully created.")
+ self.session.openWithCallback(self.flasherFinishedCB, MessageBox, _("The USB stick is now bootable. Do you want to download the latest image from the feed server and save it on the stick?"), type = MessageBox.TYPE_YESNO)
self["destlist"].changeDir("/mnt/usb")
else:
- self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
+ self.session.openWithCallback(self.flasherFinishedCB, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR)
+ self.remove_img(True)
def remove_img(self, answer):
if fileExists("/tmp/nfiflasher_image.tar.bz2"):
@@ -636,6 +634,43 @@ class NFIDownload(Screen):
self.downloading(False)
self.switchList(self.LIST_SOURCE)
+ def flasherFinishedCB(self, answer):
+ if answer == True:
+ self.wizard_mode = True
+ self["feedlist"].moveSelection(0)
+ self["path_bottom"].text = str(self["destlist"].getCurrentDirectory())
+ self.nfo_download()
+ self.nfi_download()
+
+ def configBackup(self):
+ self.session.openWithCallback(self.runBackup, MessageBox, _("The wizard can backup your current settings. Do you want to do a backup now?"))
+
+ def runBackup(self, result=None):
+ from Tools.Directories import createDir, isMount, pathExists
+ from time import localtime
+ from datetime import date
+ from Screens.Console import Console
+ if result:
+ if isMount("/mnt/usb/"):
+ if (pathExists("/mnt/usb/backup") == False):
+ createDir("/mnt/usb/backup", True)
+ d = localtime()
+ dt = date(d.tm_year, d.tm_mon, d.tm_mday)
+ self.backup_file = "backup/" + str(dt) + "_settings_backup.tar.gz"
+ self.session.open(Console, title = "Backup running", cmdlist = ["tar -czvf " + "/mnt/usb/" + self.backup_file + " /etc/enigma2/ /etc/network/interfaces /etc/wpa_supplicant.conf"], finishedCallback = self.backup_finished, closeOnSuccess = True)
+ else:
+ self.backup_file = None
+ self.backup_finished(skipped=True)
+
+ def backup_finished(self, skipped=False):
+ if not skipped:
+ wizardfd = open("/mnt/usb/wizard.nfo", "w")
+ if wizardfd:
+ wizardfd.write("image: "+self["feedlist"].getNFIname()+'\n')
+ wizardfd.write("configuration: "+self.backup_file+'\n')
+ wizardfd.close()
+ self.session.open(MessageBox, _("To update your Dreambox firmware, please follow these steps:\n1) Turn off your box with the rear power switch and plug in the bootable USB stick.\n2) Turn mains back on and hold the DOWN button on the front panel pressed for 10 seconds.\n3) Wait for bootup and follow instructions of the wizard."), type = MessageBox.TYPE_INFO)
+
def closeCB(self):
if self.download:
self.download.stop()
@@ -659,8 +694,8 @@ def filescan(**kwargs):
Scanner(mimetypes = ["application/x-dream-image"],
paths_to_scan =
[
- ScanPath(path = "", with_subdirs = False),
+ ScanPath(path = "", with_subdirs = False),
],
name = "NFI",
- description = (_("Download .NFI-Files for USB-Flasher")+"..."),
+ description = (_("Download .NFI-Files for USB-Flasher")+"..."),
openfnc = filescan_open, )
diff --git a/lib/python/Plugins/SystemPlugins/NFIFlash/flasher.py b/lib/python/Plugins/SystemPlugins/NFIFlash/flasher.py
index 6a982c58..860efc02 100644
--- a/lib/python/Plugins/SystemPlugins/NFIFlash/flasher.py
+++ b/lib/python/Plugins/SystemPlugins/NFIFlash/flasher.py
@@ -17,7 +17,7 @@ import re
class writeNAND(Task):
def __init__(self,job,param,box):
- Task.__init__(self,job, _("Writing image file to NAND Flash"))
+ Task.__init__(self,job, ("Writing image file to NAND Flash"))
self.setTool("/usr/lib/enigma2/python/Plugins/SystemPlugins/NFIFlash/mywritenand")
if box == "dm7025":
self.end = 256
@@ -26,7 +26,7 @@ class writeNAND(Task):
if box == "dm8000":
self.setTool("/usr/lib/enigma2/python/Plugins/SystemPlugins/NFIFlash/dm8000_writenand")
self.args += param
- self.weighting = 1
+ self.weighting = 1
def processOutput(self, data):
print "[writeNand] " + data
@@ -174,8 +174,8 @@ class NFIFlash(Screen):
print sign
if sign.find("NFI1" + self.box + "\0") == 0:
if self.md5sum != "":
- self["statusbar"].text = _("Please wait for md5 signature verification...")
- self.session.summary.setText(_("Please wait for md5 signature verification..."))
+ self["statusbar"].text = ("Please wait for md5 signature verification...")
+ self.session.summary.setText(("Please wait for md5 signature verification..."))
self.container = eConsoleAppContainer()
self.container.setCWD(self["filelist"].getCurrentDirectory())
self.container.appClosed.append(self.md5finished)
@@ -252,7 +252,7 @@ class NFIFlash(Screen):
def reboot(self):
if self.job.status == self.job.FINISHED:
- self["statusbar"].text = _("rebooting...")
+ self["statusbar"].text = ("rebooting...")
TryQuitMainloop(self.session,2)
def createSummary(self):
diff --git a/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py b/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py
index d67a97cb..6d2ddce3 100644
--- a/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py
+++ b/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py
@@ -14,6 +14,8 @@ from Components.ActionMap import ActionMap
from Components.NimManager import nimmanager
from Components.MenuList import MenuList
from Components.config import ConfigSatlist, ConfigNothing, ConfigSelection, ConfigSubsection, KEY_LEFT, KEY_RIGHT, getConfigListEntry
+from Components.TuneTest import Tuner
+from Tools.Transponder import ConvertToHumanReadable
from time import sleep
@@ -26,22 +28,20 @@ class PositionerSetup(Screen):
<widget name="green" position="140,155" size="140,80" backgroundColor="green" halign="center" valign="center" font="Regular;21" />
<widget name="yellow" position="280,155" size="140,80" backgroundColor="yellow" halign="center" valign="center" font="Regular;21" />
<widget name="blue" position="420,155" size="140,80" backgroundColor="blue" halign="center" valign="center" font="Regular;21" />
-
- <widget name="snr" text="SNR:" position="0,245" size="60,22" font="Regular;21" />
- <widget name="agc" text="AGC:" position="0,270" size="60,22" font="Regular;21" />
- <widget name="ber" text="BER:" position="0,295" size="60,22" font="Regular;21" />
- <widget name="lock" text="Lock:" position="0,320" size="60,22" font="Regular;21" />
- <widget name="snr_percentage" position="220,245" size="60,22" font="Regular;21" />
- <widget name="agc_percentage" position="220,270" size="60,22" font="Regular;21" />
+
+ <widget name="snr_db" position="60,245" size="150,22" halign="center" valign="center" font="Regular;21" />
+ <eLabel text="SNR:" position="0,270" size="60,22" font="Regular;21" />
+ <eLabel text="BER:" position="0,295" size="60,22" font="Regular;21" />
+ <eLabel text="Lock:" position="0,320" size="60,22" font="Regular;21" />
+ <widget name="snr_percentage" position="220,270" size="60,22" font="Regular;21" />
<widget name="ber_value" position="220,295" size="60,22" font="Regular;21" />
<widget name="lock_state" position="60,320" size="150,22" font="Regular;21" />
- <widget name="snr_bar" position="60,245" size="150,22" />
- <widget name="agc_bar" position="60,270" size="150,22" />
+ <widget name="snr_bar" position="60,270" size="150,22" />
<widget name="ber_bar" position="60,295" size="150,22" />
- <widget name="frequency" text="Frequency:" position="300,245" size="120,22" font="Regular;21" />
- <widget name="symbolrate" text="Symbolrate:" position="300,270" size="120,22" font="Regular;21" />
- <widget name="fec" text="FEC:" position="300,295" size="120,22" font="Regular;21" />
+ <eLabel text="Frequency:" position="300,245" size="120,22" font="Regular;21" />
+ <eLabel text="Symbolrate:" position="300,270" size="120,22" font="Regular;21" />
+ <eLabel text="FEC:" position="300,295" size="120,22" font="Regular;21" />
<widget name="frequency_value" position="420,245" size="120,22" font="Regular;21" />
<widget name="symbolrate_value" position="420,270" size="120,22" font="Regular;21" />
<widget name="fec_value" position="420,295" size="120,22" font="Regular;21" />
@@ -51,23 +51,46 @@ class PositionerSetup(Screen):
Screen.__init__(self, session)
self.feid = feid
self.oldref = None
-
+
+ cur = { }
if not self.openFrontend():
self.oldref = session.nav.getCurrentlyPlayingServiceReference()
+ service = session.nav.getCurrentService()
+ feInfo = service and service.frontendInfo()
+ if feInfo:
+ cur = feInfo.getTransponderData(True)
+ del feInfo
+ del service
session.nav.stopService() # try to disable foreground service
if not self.openFrontend():
if session.pipshown: # try to disable pip
+ service = self.session.pip.pipservice
+ feInfo = service and service.frontendInfo()
+ if feInfo:
+ cur = feInfo.getTransponderData()
+ del feInfo
+ del service
session.pipshown = False
del session.pip
if not self.openFrontend():
self.frontend = None # in normal case this should not happen
-
+
self.frontendStatus = { }
-
self.diseqc = Diseqc(self.frontend)
self.tuner = Tuner(self.frontend)
- self.tuner.tune((0,0,0,0,0,0))
-
+
+ tp = ( cur.get("frequency", 0) / 1000,
+ cur.get("symbol_rate", 0) / 1000,
+ cur.get("polarization", eDVBFrontendParametersSatellite.Polarisation_Horizontal),
+ cur.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto),
+ cur.get("inversion", eDVBFrontendParametersSatellite.Inversion_Unknown),
+ cur.get("orbital_position", 0),
+ cur.get("system", eDVBFrontendParametersSatellite.System_DVB_S),
+ cur.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK),
+ cur.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35),
+ cur.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown))
+
+ self.tuner.tune(tp)
self.createConfig()
self.isMoving = False
@@ -81,27 +104,18 @@ class PositionerSetup(Screen):
self["yellow"] = self.yellow
self.blue = Label("")
self["blue"] = self.blue
-
+
self.list = []
self["list"] = ConfigList(self.list)
self.createSetup()
-
- self["snr"] = Label()
- self["agc"] = Label()
- self["ber"] = Label()
- self["lock"] = Label()
+
+ self["snr_db"] = TunerInfo(TunerInfo.SNR_DB, statusDict = self.frontendStatus)
self["snr_percentage"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, statusDict = self.frontendStatus)
- self["agc_percentage"] = TunerInfo(TunerInfo.AGC_PERCENTAGE, statusDict = self.frontendStatus)
self["ber_value"] = TunerInfo(TunerInfo.BER_VALUE, statusDict = self.frontendStatus)
self["snr_bar"] = TunerInfo(TunerInfo.SNR_BAR, statusDict = self.frontendStatus)
- self["agc_bar"] = TunerInfo(TunerInfo.AGC_BAR, statusDict = self.frontendStatus)
self["ber_bar"] = TunerInfo(TunerInfo.BER_BAR, statusDict = self.frontendStatus)
self["lock_state"] = TunerInfo(TunerInfo.LOCK_STATE, statusDict = self.frontendStatus)
- self["frequency"] = Label()
- self["symbolrate"] = Label()
- self["fec"] = Label()
-
self["frequency_value"] = Label("")
self["symbolrate_value"] = Label("")
self["fec_value"] = Label("")
@@ -260,7 +274,12 @@ class PositionerSetup(Screen):
elif entry == "limits":
self.diseqccommand("limitOff")
elif entry == "tune":
- self.session.openWithCallback(self.tune, TunerScreen, self.feid)
+ fe_data = { }
+ self.frontend.getFrontendData(fe_data)
+ self.frontend.getTransponderData(fe_data, True)
+ feparm = self.tuner.lastparm.getDVBS()
+ fe_data["orbital_position"] = feparm.orbital_position
+ self.session.openWithCallback(self.tune, TunerScreen, self.feid, fe_data)
elif entry == "goto0":
print "move to position 0"
self.diseqccommand("moveTo", 0)
@@ -283,6 +302,7 @@ class PositionerSetup(Screen):
elif entry == "storage":
print "store at position", int(self.positioner_storage.value)
self.diseqccommand("store", int(self.positioner_storage.value))
+
elif entry == "limits":
self.diseqccommand("limitWest")
@@ -329,14 +349,13 @@ class PositionerSetup(Screen):
def updateStatus(self):
if self.frontend:
self.frontend.getFrontendStatus(self.frontendStatus)
+ self["snr_db"].update()
self["snr_percentage"].update()
- self["agc_percentage"].update()
self["ber_value"].update()
self["snr_bar"].update()
- self["agc_bar"].update()
self["ber_bar"].update()
self["lock_state"].update()
- transponderdata = self.tuner.getTransponderData()
+ transponderdata = ConvertToHumanReadable(self.tuner.getTransponderData())
self["frequency_value"].setText(str(transponderdata.get("frequency")))
self["symbolrate_value"].setText(str(transponderdata.get("symbol_rate")))
self["fec_value"].setText(str(transponderdata.get("fec_inner")))
@@ -387,37 +406,6 @@ class Diseqc:
sleep(0.05)
self.frontend.sendDiseqc(cmd) # send 2nd time
-class Tuner:
- def __init__(self, frontend):
- self.frontend = frontend
-
- def tune(self, transponder):
- print "tuning to transponder with data", transponder
- parm = eDVBFrontendParametersSatellite()
- parm.frequency = transponder[0] * 1000
- parm.symbol_rate = transponder[1] * 1000
- parm.polarisation = transponder[2]
- parm.fec = transponder[3]
- parm.inversion = transponder[4]
- parm.orbital_position = transponder[5]
- parm.system = 0 # FIXMEE !! HARDCODED DVB-S (add support for DVB-S2)
- parm.modulation = 1 # FIXMEE !! HARDCODED QPSK
- feparm = eDVBFrontendParameters()
- feparm.setDVBS(parm, True)
- self.lastparm = feparm
- if self.frontend:
- self.frontend.tune(feparm)
-
- def retune(self):
- if self.frontend:
- self.frontend.tune(self.lastparm)
-
- def getTransponderData(self):
- ret = { }
- if self.frontend:
- self.frontend.getTransponderData(ret, True)
- return ret
-
tuning = None
class TunerScreen(ScanSetup):
@@ -427,8 +415,9 @@ class TunerScreen(ScanSetup):
<widget name="introduction" position="20,360" size="350,30" font="Regular;23" />
</screen>"""
- def __init__(self, session, feid):
+ def __init__(self, session, feid, fe_data):
self.feid = feid
+ self.fe_data = fe_data
ScanSetup.__init__(self, session)
self["introduction"].setText("")
@@ -440,21 +429,35 @@ class TunerScreen(ScanSetup):
self.list.append(self.typeOfTuningEntry)
self.satEntry = getConfigListEntry(_('Satellite'), tuning.sat)
self.list.append(self.satEntry)
+ nim = nimmanager.nim_slots[self.feid]
+ self.systemEntry = None
+
if tuning.type.value == "manual_transponder":
+ if nim.isCompatible("DVB-S2"):
+ self.systemEntry = getConfigListEntry(_('System'), self.scan_sat.system)
+ self.list.append(self.systemEntry)
+ else:
+ # downgrade to dvb-s, in case a -s2 config was active
+ self.scan_sat.system.value = eDVBFrontendParametersSatellite.System_DVB_S
self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
- self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
+ if self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S:
+ self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
+ elif self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S2:
+ self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2))
+ self.modulationEntry = getConfigListEntry(_('Modulation'), self.scan_sat.modulation)
+ self.list.append(self.modulationEntry)
+ self.list.append(getConfigListEntry(_('Rolloff'), self.scan_sat.rolloff))
+ self.list.append(getConfigListEntry(_('Pilot'), self.scan_sat.pilot))
elif tuning.type.value == "predefined_transponder":
self.list.append(getConfigListEntry(_("Transponder"), tuning.transponder))
self["config"].list = self.list
self["config"].l.setList(self.list)
def newConfig(self):
- if self["config"].getCurrent() == self.typeOfTuningEntry:
- self.createSetup()
- elif self["config"].getCurrent() == self.satEntry:
+ if self["config"].getCurrent() in (self.typeOfTuningEntry, self.satEntry, self.systemEntry):
self.createSetup()
def createConfig(self, foo):
@@ -468,8 +471,14 @@ class TunerScreen(ScanSetup):
tuning.sat = ConfigSatlist(list=nimmanager.getRotorSatListForNim(self.feid))
tuning.sat.addNotifier(self.tuningSatChanged)
self.updateTransponders()
- TunerScreenConfigCreated = True
- ScanSetup.createConfig(self, None)
+ orb_pos = self.fe_data.get("orbital_position", None)
+ if orb_pos is not None:
+ for x in nimmanager.getRotorSatListForNim(self.feid):
+ opos = str(orb_pos)
+ if x[0] == orb_pos and tuning.sat.value != opos:
+ tuning.sat.value = opos
+ del self.fe_data["orbital_position"]
+ ScanSetup.createConfig(self, self.fe_data)
def tuningSatChanged(self, *parm):
self.updateTransponders()
@@ -491,46 +500,55 @@ class TunerScreen(ScanSetup):
else:
pol = "??"
if x[4] == 0:
- fec = "FEC_AUTO"
+ fec = "FEC Auto"
elif x[4] == 1:
- fec = "FEC_1_2"
+ fec = "FEC 1/2"
elif x[4] == 2:
- fec = "FEC_2_3"
+ fec = "FEC 2/3"
elif x[4] == 3:
- fec = "FEC_3_4"
+ fec = "FEC 3/4"
elif x[4] == 4:
- fec = "FEC_5_6"
+ fec = "FEC 5/6"
elif x[4] == 5:
- fec = "FEC_7_8"
+ fec = "FEC 7/8"
elif x[4] == 6:
- fec = "FEC_8_9"
+ fec = "FEC 8/9"
elif x[4] == 7:
- fec = "FEC_3_5"
+ fec = "FEC 3/5"
elif x[4] == 8:
- fec = "FEC_4_5"
+ fec = "FEC 4/5"
elif x[4] == 9:
- fec = "FEC_9_10"
+ fec = "FEC 9/10"
elif x[4] == 15:
- fec = "FEC_None"
+ fec = "FEC None"
else:
- fec = "FEC_Unknown"
+ fec = "FEC Unknown"
tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
tuning.transponder = ConfigSelection(choices=tps)
def keyGo(self):
- returnvalue = (0, 0, 0, 0, 0, 0)
+ returnvalue = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
satpos = int(tuning.sat.value)
if tuning.type.value == "manual_transponder":
+ if self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S2:
+ fec = self.scan_sat.fec_s2.value
+ else:
+ fec = self.scan_sat.fec.value
returnvalue = (
self.scan_sat.frequency.value,
self.scan_sat.symbolrate.value,
- self.scan_sat.polarization.index,
- self.scan_sat.fec.index,
- self.scan_sat.inversion.index,
- satpos)
+ self.scan_sat.polarization.value,
+ fec,
+ self.scan_sat.inversion.value,
+ satpos,
+ self.scan_sat.system.value,
+ self.scan_sat.modulation.value,
+ self.scan_sat.rolloff.value,
+ self.scan_sat.pilot.value)
elif tuning.type.value == "predefined_transponder":
transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
- returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000), transponder[3], transponder[4], 2, satpos)
+ returnvalue = (transponder[1] / 1000, transponder[2] / 1000,
+ transponder[3], transponder[4], 2, satpos, transponder[5], transponder[6], transponder[8], transponder[9])
self.close(returnvalue)
def keyCancel(self):
@@ -538,8 +556,8 @@ class TunerScreen(ScanSetup):
class RotorNimSelection(Screen):
skin = """
- <screen position="140,165" size="400,100" title="select Slot">
- <widget name="nimlist" position="20,10" size="360,75" />
+ <screen position="140,165" size="400,130" title="select Slot">
+ <widget name="nimlist" position="20,10" size="360,100" />
</screen>"""
def __init__(self, session):
diff --git a/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py b/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py
index 74568855..8e148812 100644
--- a/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py
+++ b/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py
@@ -12,73 +12,9 @@ from Components.ActionMap import ActionMap
from Components.NimManager import nimmanager, getConfigSatlist
from Components.MenuList import MenuList
from Components.config import ConfigSelection, getConfigListEntry
-
-class Tuner:
- def __init__(self, frontend):
- self.frontend = frontend
-
- def tune(self, transponder):
- if self.frontend:
- print "tuning to transponder with data", transponder
- parm = eDVBFrontendParametersSatellite()
- parm.frequency = transponder[0] * 1000
- parm.symbol_rate = transponder[1] * 1000
- parm.polarisation = transponder[2]
- parm.fec = transponder[3]
- parm.inversion = transponder[4]
- parm.orbital_position = transponder[5]
- parm.system = 0 # FIXMEE !! HARDCODED DVB-S (add support for DVB-S2)
- parm.modulation = 1 # FIXMEE !! HARDCODED QPSK
- feparm = eDVBFrontendParameters()
- feparm.setDVBS(parm)
- self.lastparm = feparm
- self.frontend.tune(feparm)
-
- def retune(self):
- if self.frontend:
- self.frontend.tune(self.lastparm)
+from Components.TuneTest import Tuner
class Satfinder(ScanSetup):
- skin = """
- <screen position="90,100" size="520,400" title="Tune">
- <widget name="config" position="20,10" size="460,210" scrollbarMode="showOnDemand" />
- <widget name="introduction" position="20,360" zPosition="-10" size="350,30" font="Regular;23" />
- <eLabel text="dB:" position="23,230" size="60,22" font="Regular;21" />
- <eLabel text="SNR:" position="23,255" size="60,22" font="Regular;21" />
- <eLabel text="AGC:" position="23,280" size="60,22" font="Regular;21" />
- <eLabel text="BER:" position="23,305" size="60,22" font="Regular;21" />
- <eLabel text="Lock:" position="23,330" size="60,22" font="Regular;21" />
- <widget source="Frontend" render="Label" position="295,230" size="60,22" font="Regular;21" >
- <convert type="FrontendInfo">SNRdB</convert>
- </widget>
- <widget source="Frontend" render="Label" position="295,255" size="60,22" font="Regular;21" >
- <convert type="FrontendInfo">SNR</convert>
- </widget>
- <widget source="Frontend" render="Label" position="295,280" size="60,22" font="Regular;21" >
- <convert type="FrontendInfo">AGC</convert>
- </widget>
- <widget source="Frontend" render="Label" position="295,305" size="60,22" font="Regular;21" >
- <convert type="FrontendInfo">BER</convert>
- </widget>
- <widget source="Frontend" render="Progress" position="85,257" size="200,22" >
- <convert type="FrontendInfo">SNR</convert>
- </widget>
- <widget source="Frontend" render="Progress" position="85,282" size="200,22" >
- <convert type="FrontendInfo">AGC</convert>
- </widget>
- <widget source="Frontend" render="Progress" position="85,307" size="200,22" >
- <convert type="FrontendInfo">BER</convert>
- </widget>
- <widget source="Frontend" render="Pixmap" pixmap="skin_default/buttons/key_green.png" position="295,330" zPosition="4" size="28,20" alphatest="on" >
- <convert type="FrontendInfo">LOCK</convert>
- <convert type="ConditionalShowHide" />
- </widget>
- <widget source="Frontend" render="Pixmap" pixmap="skin_default/buttons/key_red.png" position="295,330" zPosition="4" size="28,20" alphatest="on" >
- <convert type="FrontendInfo">LOCK</convert>
- <convert type="ConditionalShowHide">Invert</convert>
- </widget>
- </screen>"""
-
def openFrontend(self):
res_mgr = eDVBResourceManager.getInstance()
if res_mgr:
@@ -125,25 +61,44 @@ class Satfinder(ScanSetup):
self.satEntry = None
self.list = []
+
self.typeOfTuningEntry = getConfigListEntry(_('Tune'), self.tuning_type)
self.list.append(self.typeOfTuningEntry)
self.satEntry = getConfigListEntry(_('Satellite'), self.tuning_sat)
self.list.append(self.satEntry)
+
+ nim = nimmanager.nim_slots[self.feid]
+
+ self.systemEntry = None
if self.tuning_type.value == "manual_transponder":
+ if nim.isCompatible("DVB-S2"):
+ self.systemEntry = getConfigListEntry(_('System'), self.scan_sat.system)
+ self.list.append(self.systemEntry)
+ else:
+ # downgrade to dvb-s, in case a -s2 config was active
+ self.scan_sat.system.value = eDVBFrontendParametersSatellite.System_DVB_S
self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
- self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
+ if self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S:
+ self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
+ elif self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S2:
+ self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2))
+ self.modulationEntry = getConfigListEntry(_('Modulation'), self.scan_sat.modulation)
+ self.list.append(self.modulationEntry)
+ self.list.append(getConfigListEntry(_('Rolloff'), self.scan_sat.rolloff))
+ self.list.append(getConfigListEntry(_('Pilot'), self.scan_sat.pilot))
elif self.tuning_transponder and self.tuning_type.value == "predefined_transponder":
self.list.append(getConfigListEntry(_("Transponder"), self.tuning_transponder))
self["config"].list = self.list
self["config"].l.setList(self.list)
def newConfig(self):
- if self["config"].getCurrent() == self.typeOfTuningEntry:
+ cur = self["config"].getCurrent()
+ if cur in (self.typeOfTuningEntry, self.systemEntry):
self.createSetup()
- elif self["config"].getCurrent() == self.satEntry:
+ elif cur == self.satEntry:
self.updateSats()
self.createSetup()
@@ -152,20 +107,33 @@ class Satfinder(ScanSetup):
self.retune(config_element)
def retune(self, configElement):
- returnvalue = (0, 0, 0, 0, 0, 0, 0)
- satpos = self.tuning_sat.orbital_position
-
- if satpos is not None:
- if self.tuning_type.value == "manual_transponder":
- returnvalue = (self.scan_sat.frequency.value, self.scan_sat.symbolrate.value, self.scan_sat.polarization.index, self.scan_sat.fec.index, self.scan_sat.inversion.index, satpos)
+ returnvalue = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+ satpos = int(self.tuning_sat.value)
+ if self.tuning_type.value == "manual_transponder":
+ if self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S2:
+ fec = self.scan_sat.fec_s2.value
+ else:
+ fec = self.scan_sat.fec.value
+ returnvalue = (
+ self.scan_sat.frequency.value,
+ self.scan_sat.symbolrate.value,
+ self.scan_sat.polarization.value,
+ fec,
+ self.scan_sat.inversion.value,
+ satpos,
+ self.scan_sat.system.value,
+ self.scan_sat.modulation.value,
+ self.scan_sat.rolloff.value,
+ self.scan_sat.pilot.value)
+ self.tune(returnvalue)
+ elif self.tuning_type.value == "predefined_transponder":
+ tps = nimmanager.getTransponders(satpos)
+ l = len(tps)
+ if l > self.tuning_transponder.index:
+ transponder = tps[self.tuning_transponder.index]
+ returnvalue = (transponder[1] / 1000, transponder[2] / 1000,
+ transponder[3], transponder[4], 2, satpos, transponder[5], transponder[6], transponder[8], transponder[9])
self.tune(returnvalue)
- elif self.tuning_type.value == "predefined_transponder":
- tps = nimmanager.getTransponders(satpos)
- l = len(tps)
- if l > self.tuning_transponder.index:
- transponder = nimmanager.getTransponders(satpos)[self.tuning_transponder.index]
- returnvalue = (int(transponder[1] / 1000), int(transponder[2] / 1000), transponder[3], transponder[4], 2, satpos)
- self.tune(returnvalue)
def createConfig(self, foo):
self.tuning_transponder = None
@@ -174,14 +142,13 @@ class Satfinder(ScanSetup):
ScanSetup.createConfig(self, None)
self.updateSats()
-
- self.tuning_type.addNotifier(self.retune, initial_call = False)
- self.tuning_sat.addNotifier(self.sat_changed, initial_call = False)
- self.scan_sat.frequency.addNotifier(self.retune, initial_call = False)
- self.scan_sat.inversion.addNotifier(self.retune, initial_call = False)
- self.scan_sat.symbolrate.addNotifier(self.retune, initial_call = False)
- self.scan_sat.polarization.addNotifier(self.retune, initial_call = False)
- self.scan_sat.fec.addNotifier(self.retune, initial_call = False)
+
+ for x in (self.tuning_type, self.tuning_sat, self.scan_sat.frequency,
+ self.scan_sat.inversion, self.scan_sat.symbolrate,
+ self.scan_sat.polarization, self.scan_sat.fec, self.scan_sat.pilot,
+ self.scan_sat.fec_s2, self.scan_sat.fec, self.scan_sat.modulation,
+ self.scan_sat.rolloff, self.scan_sat.system):
+ x.addNotifier(self.retune, initial_call = False)
def updateSats(self):
orb_pos = self.tuning_sat.orbital_position
@@ -201,29 +168,29 @@ class Satfinder(ScanSetup):
else:
pol = "??"
if x[4] == 0:
- fec = "FEC_AUTO"
+ fec = "FEC Auto"
elif x[4] == 1:
- fec = "FEC_1_2"
+ fec = "FEC 1/2"
elif x[4] == 2:
- fec = "FEC_2_3"
+ fec = "FEC 2/3"
elif x[4] == 3:
- fec = "FEC_3_4"
+ fec = "FEC 3/4"
elif x[4] == 4:
- fec = "FEC_5_6"
+ fec = "FEC 5/6"
elif x[4] == 5:
- fec = "FEC_7_8"
+ fec = "FEC 7/8"
elif x[4] == 6:
- fec = "FEC_8_9"
+ fec = "FEC 8/9"
elif x[4] == 7:
- fec = "FEC_3_5"
+ fec = "FEC 3/5"
elif x[4] == 8:
- fec = "FEC_4_5"
+ fec = "FEC 4/5"
elif x[4] == 9:
- fec = "FEC_9_10"
+ fec = "FEC 9/10"
elif x[4] == 15:
- fec = "FEC_None"
+ fec = "FEC None"
else:
- fec = "FEC_Unknown"
+ fec = "FEC Unknown"
e = str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec
if default is None:
default = e
@@ -256,8 +223,8 @@ class Satfinder(ScanSetup):
class SatNimSelection(Screen):
skin = """
- <screen position="140,165" size="400,100" title="select Slot">
- <widget name="nimlist" position="20,10" size="360,75" />
+ <screen position="140,165" size="400,130" title="select Slot">
+ <widget name="nimlist" position="20,10" size="360,100" />
</screen>"""
def __init__(self, session):
@@ -281,7 +248,13 @@ class SatNimSelection(Screen):
self.session.open(Satfinder, selection)
def SatfinderMain(session, **kwargs):
- nimList = nimmanager.getNimListOfType("DVB-S")
+ nims = nimmanager.getNimListOfType("DVB-S")
+
+ nimList = []
+ for x in nims:
+ if not nimmanager.getNimConfig(x).configMode.value in ("loopthrough", "satposdepends", "nothing"):
+ nimList.append(x)
+
if len(nimList) == 0:
session.open(MessageBox, _("No satellite frontend found!!"), MessageBox.TYPE_ERROR)
else:
diff --git a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py
index 2422475e..6a85c4da 100644
--- a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py
+++ b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py
@@ -59,10 +59,37 @@ class VideoHardware:
widescreen_modes = set(["720p", "1080i"])
+ def getOutputAspect(self):
+ ret = (16,9)
+ port = config.av.videoport.value
+ if port not in config.av.videomode:
+ print "current port not available in getOutputAspect!!! force 16:9"
+ else:
+ mode = config.av.videomode[port].value
+ force_widescreen = self.isWidescreenMode(port, mode)
+ is_widescreen = force_widescreen or config.av.aspect.value in ["16_9", "16_10"]
+ is_auto = config.av.aspect.value == "auto"
+ if is_widescreen:
+ if force_widescreen:
+ pass
+ else:
+ aspect = {"16_9": "16:9", "16_10": "16:10"}[config.av.aspect.value]
+ if aspect == "16:10":
+ ret = (16,10)
+ elif is_auto:
+ try:
+ aspect_str = open("/proc/stb/vmpeg/0/aspect", "r").read()
+ if aspect_str == "1": # 4:3
+ ret = (4,3)
+ except IOError:
+ pass
+ else: # 4:3
+ ret = (4,3)
+ return ret
+
def __init__(self):
self.last_modes_preferred = [ ]
self.on_hotplug = CList()
- self.standby = False
self.current_mode = None
self.current_port = None
@@ -79,7 +106,7 @@ class VideoHardware:
config.av.aspectratio.notifiers = [ ]
config.av.tvsystem.notifiers = [ ]
config.av.wss.notifiers = [ ]
- AVSwitch.setInput = self.AVSwitchSetInput
+ AVSwitch.getOutputAspect = self.getOutputAspect
config.av.aspect.addNotifier(self.updateAspect)
config.av.wss.addNotifier(self.updateAspect)
@@ -91,12 +118,6 @@ class VideoHardware:
# self.timer.callback.append(self.readPreferredModes)
# self.timer.start(1000)
- config.av.colorformat.addNotifier(self.updateFastblank)
-
- def AVSwitchSetInput(self, mode):
- self.standby = mode == "SCART"
- self.updateStandby()
-
def readAvailableModes(self):
try:
modes = open("/proc/stb/video/videomode_choices").read()[:-1]
@@ -264,6 +285,7 @@ class VideoHardware:
is_widescreen = force_widescreen or config.av.aspect.value in ["16_9", "16_10"]
is_auto = config.av.aspect.value == "auto"
+ policy2 = "policy" # use main policy
if is_widescreen:
if force_widescreen:
@@ -271,6 +293,7 @@ class VideoHardware:
else:
aspect = {"16_9": "16:9", "16_10": "16:10"}[config.av.aspect.value]
policy = {"pillarbox": "panscan", "panscan": "letterbox", "nonlinear": "nonlinear", "scale": "bestfit"}[config.av.policy_43.value]
+ policy2 = {"letterbox": "letterbox", "panscan": "panscan", "scale": "bestfit"}[config.av.policy_169.value]
elif is_auto:
aspect = "any"
policy = "bestfit"
@@ -283,46 +306,14 @@ class VideoHardware:
else:
wss = "auto"
- print "-> setting aspect, policy, wss", aspect, policy, wss
+ print "-> setting aspect, policy, policy2, wss", aspect, policy, policy2, wss
open("/proc/stb/video/aspect", "w").write(aspect)
open("/proc/stb/video/policy", "w").write(policy)
open("/proc/stb/denc/0/wss", "w").write(wss)
- self.updateSlowblank()
- self.updateFastblank()
-
- def updateSlowblank(self):
- if self.standby:
- from Components.SystemInfo import SystemInfo
- if SystemInfo["ScartSwitch"]:
- input = "scart"
- sb = "vcr"
- else:
- input = "off"
- sb = "0"
- else:
- input = "encoder"
- sb = "auto"
-
- open("/proc/stb/avs/0/sb", "w").write(sb)
- open("/proc/stb/avs/0/input", "w").write(input)
-
- def updateStandby(self):
- self.updateSlowblank()
- self.updateFastblank()
-
- def updateFastblank(self, *args):
- if self.standby:
- from Components.SystemInfo import SystemInfo
- if SystemInfo["ScartSwitch"]:
- fb = "vcr"
- else:
- fb = "low"
- else:
- if self.current_port == "Scart" and config.av.colorformat.value == "rgb":
- fb = "high"
- else:
- fb = "low"
- open("/proc/stb/avs/0/fb", "w").write(fb)
+ try:
+ open("/proc/stb/video/policy2", "w").write(policy2)
+ except IOError:
+ pass
config.av.edid_override = ConfigYesNo(default = False)
video_hw = VideoHardware()
diff --git a/lib/python/Plugins/SystemPlugins/Videomode/plugin.py b/lib/python/Plugins/SystemPlugins/Videomode/plugin.py
index ab7aad72..30bdf796 100644
--- a/lib/python/Plugins/SystemPlugins/Videomode/plugin.py
+++ b/lib/python/Plugins/SystemPlugins/Videomode/plugin.py
@@ -78,6 +78,7 @@ class VideoSetup(Screen, ConfigListScreen):
if force_wide or config.av.aspect.value in ["16_9", "16_10"]:
self.list.append(getConfigListEntry(_("Display 4:3 content as"), config.av.policy_43))
+ self.list.append(getConfigListEntry(_("Display >16:9 content as"), config.av.policy_169))
elif config.av.aspect.value == "4_3":
self.list.append(getConfigListEntry(_("Display 16:9 content as"), config.av.policy_169))
diff --git a/lib/python/Plugins/newplugin.py b/lib/python/Plugins/newplugin.py
new file mode 100644
index 00000000..48bb28ea
--- /dev/null
+++ b/lib/python/Plugins/newplugin.py
@@ -0,0 +1,146 @@
+#!/usr/bin/python
+
+import os
+
+os.system("clear")
+internalname = raw_input("Internal plugin name (no whitespaces, plugin directory): ")
+name = raw_input("Visible plugin name: ")
+print
+
+os.system("clear")
+dirlist = []
+count = 0
+print "Plugin categories:"
+for dir in os.listdir("."):
+ if os.path.isdir(dir):
+ count += 1
+ dirlist.append(dir)
+ print count, dir
+
+category = raw_input("Select plugin category: ")
+category = dirlist[int(category) - 1]
+
+def add_where_extensionsmenu(name, fnc):
+ description = raw_input("Plugin description: ")
+ return 'PluginDescriptor(name = "%s", description = _("%s"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc = %s)' % (name, description, fnc)
+
+def add_where_pluginmenu(name, fnc):
+ description = raw_input("Plugin description: ")
+ icon = raw_input("Icon (default: 'plugin.png': ")
+ if icon == "":
+ icon = "plugin.png"
+ return 'PluginDescriptor(name = "%s", description = _("%s"), icon = "%s", where = PluginDescriptor.WHERE_PLUGINMENU, fnc = %s)' % (name, description, icon, fnc)
+
+wherelist = []
+wherelist.append(("WHERE_EXTENSIONSMENU", add_where_extensionsmenu))
+wherelist.append(("WHERE_PLUGINMENU", add_where_pluginmenu))
+
+targetlist = []
+
+stop = False
+
+while not stop:
+ os.system("clear")
+ print "selected targets:"
+ for where in targetlist:
+ print where[0]
+
+ print
+ print "available targets:"
+ count = 0
+ for where in wherelist:
+ count += 1
+ print count, where[0]
+ print "x break"
+
+ target = raw_input("Select WHERE-target: ")
+ if target == "x":
+ stop = True
+ else:
+ if wherelist[int(target) - 1] not in targetlist:
+ targetlist.append(wherelist[int(target) - 1])
+ else:
+ targetlist.remove(wherelist[int(target) - 1])
+
+
+pluginpath = category + "/" + internalname
+os.mkdir(pluginpath)
+
+makefile = open(category + "/Makefile.am", "r")
+lines = makefile.readlines()
+lines = ''.join(lines)
+lines = lines.strip()
+lines += " " + internalname
+makefile.close()
+
+makefile = open(category + "/Makefile.am", "w")
+makefile.write(lines)
+makefile.close()
+
+lines = []
+print "open"
+configure = open("../../../configure.ac", "r")
+while True:
+ line = configure.readline()
+ if not line:
+ break
+ lines.append(line)
+ if line.strip() == "lib/python/Plugins/" + category + "/Makefile":
+ lines.append("lib/python/Plugins/" + pluginpath + "/Makefile\n")
+configure.close()
+print "close"
+
+configure = open("../../../configure.ac", "w")
+configure.writelines(lines)
+configure.close()
+
+file = open(pluginpath + "/plugin.py", "w")
+
+importlist = []
+for where in targetlist:
+ importlist.append(where[0])
+
+file.write("""from Screens.Screen import Screen
+from Plugins.Plugin import PluginDescriptor, %s
+""" % ', '.join(importlist))
+
+mainlist = []
+for count in range(len(targetlist)):
+ if count == 0:
+ mainlist.append("main")
+ else:
+ mainlist.append("main" + str(count))
+
+for main in mainlist:
+ file.write("""
+def %s(session, **kwargs):
+ pass
+""" % main)
+
+descriptorlist = []
+for count in range(len(targetlist)):
+ os.system("clear")
+ where = targetlist[count]
+ print "Options for target %s" % where[0]
+ descriptorlist.append(where[1](name, mainlist[count]))
+
+if len(descriptorlist) == 1:
+ descriptorlist = descriptorlist[0]
+else:
+ descriptorlist = "[" + ', '.join(descriptorlist) + "]"
+
+file.write("""
+def Plugins(**kwargs):
+ return %s
+ """ % descriptorlist)
+
+file.close()
+
+makefile = open(pluginpath + "/Makefile.am", "w")
+makefile.write("""installdir = $(LIBDIR)/enigma2/python/Plugins/%s/%s
+
+install_PYTHON = \\
+ __init__.py \\
+ plugin.py
+""" % (category, internalname))
+makefile.close()
diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py
index b203b24e..ebfbe812 100644
--- a/lib/python/Screens/ChannelSelection.py
+++ b/lib/python/Screens/ChannelSelection.py
@@ -76,7 +76,7 @@ def append_when_current_valid(current, menu, args, level = 0):
class ChannelContextMenu(Screen):
def __init__(self, session, csel):
Screen.__init__(self, session)
- #raise "we need a better summary screen here"
+ #raise Exception("we need a better summary screen here")
self.csel = csel
self.bsel = None
diff --git a/lib/python/Screens/Console.py b/lib/python/Screens/Console.py
index b57f2400..c6b156cf 100644
--- a/lib/python/Screens/Console.py
+++ b/lib/python/Screens/Console.py
@@ -55,6 +55,7 @@ class Console(Screen):
str = self["text"].getText()
str += _("Execution finished!!");
self["text"].setText(str)
+ self["text"].lastPage()
if self.finishedCallback is not None:
self.finishedCallback()
if not retval and self.closeOnSuccess:
@@ -67,4 +68,4 @@ class Console(Screen):
self.container.dataAvail.remove(self.dataAvail)
def dataAvail(self, str):
- self["text"].setText(self["text"].getText() + str)
+ self["text"].setText(self["text"].getText() + str) \ No newline at end of file
diff --git a/lib/python/Screens/EpgSelection.py b/lib/python/Screens/EpgSelection.py
index 6740bfb6..e7388fc2 100644
--- a/lib/python/Screens/EpgSelection.py
+++ b/lib/python/Screens/EpgSelection.py
@@ -5,11 +5,13 @@ from Components.Pixmap import Pixmap
from Components.Label import Label
from Components.EpgList import EPGList, EPG_TYPE_SINGLE, EPG_TYPE_SIMILAR, EPG_TYPE_MULTI
from Components.ActionMap import ActionMap
+from Components.TimerSanityCheck import TimerSanityCheck
from Screens.TimerEdit import TimerSanityConflict
from Screens.EventView import EventViewSimple
+from Screens.MessageBox import MessageBox
from TimeDateInput import TimeDateInput
from enigma import eServiceReference
-from RecordTimer import RecordTimerEntry, parseEvent
+from RecordTimer import RecordTimerEntry, parseEvent, AFTEREVENT
from TimerEntry import TimerEntry
from ServiceReference import ServiceReference
from time import localtime, time
@@ -17,6 +19,12 @@ from time import localtime, time
mepg_config_initialized = False
class EPGSelection(Screen):
+ EMPTY = 0
+ ADD_TIMER = 1
+ REMOVE_TIMER = 2
+
+ ZAP = 1
+
def __init__(self, session, service, zapFunc=None, eventid=None, bouquetChangeCB=None):
Screen.__init__(self, session)
self.bouquetChangeCB = bouquetChangeCB
@@ -58,6 +66,8 @@ class EPGSelection(Screen):
self.zapFunc = zapFunc
self["key_green"] = Button(_("Add timer"))
+ self.key_green_choice = self.ADD_TIMER
+ self.key_red_choice = self.EMPTY
self["list"] = EPGList(type = self.type, selChangedCB = self.onSelectionChanged, timer = self.session.nav.RecordTimer)
self["actions"] = ActionMap(["EPGSelectActions", "OkCancelActions"],
@@ -125,6 +135,7 @@ class EPGSelection(Screen):
l.recalcEntrySize()
if self.type == EPG_TYPE_MULTI:
l.fillMultiEPG(self.services, self.ask_time)
+ l.moveToService(self.session.nav.getCurrentlyPlayingServiceReference())
elif self.type == EPG_TYPE_SINGLE:
l.fillSingleEPG(self.currentService)
else:
@@ -145,7 +156,7 @@ class EPGSelection(Screen):
setEvent(cur[0])
def zapTo(self): # just used in multiepg
- if self.zapFunc and self["key_red"].getText() == "Zap":
+ if self.zapFunc and self.key_red_choice == self.ZAP:
lst = self["list"]
count = lst.getCurrentChangeCount()
if count == 0:
@@ -179,14 +190,28 @@ class EPGSelection(Screen):
if self.type == EPG_TYPE_MULTI:
self["list"].updateMultiEPG(1)
+ def removeTimer(self, timer):
+ timer.afterEvent = AFTEREVENT.NONE
+ self.session.nav.RecordTimer.removeEntry(timer)
+ self["key_green"].setText(_("Add timer"))
+ self.key_green_choice = self.ADD_TIMER
+
def timerAdd(self):
cur = self["list"].getCurrent()
event = cur[0]
serviceref = cur[1]
if event is None:
return
- newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, *parseEvent(event))
- self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
+ eventid = event.getEventId()
+ refstr = serviceref.ref.toString()
+ for timer in self.session.nav.RecordTimer.timer_list:
+ if timer.eit == eventid and timer.service_ref.ref.toString() == refstr:
+ cb_func = lambda ret : not ret or self.removeTimer(timer)
+ self.session.openWithCallback(cb_func, MessageBox, _("Do you really want to delete %s?") % event.getEventName())
+ break
+ else:
+ newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, *parseEvent(event))
+ self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
def finishedAdd(self, answer):
print "finished add"
@@ -194,14 +219,18 @@ class EPGSelection(Screen):
entry = answer[1]
simulTimerList = self.session.nav.RecordTimer.record(entry)
if simulTimerList is not None:
- if (len(simulTimerList) == 2) and (simulTimerList[1].dontSave) and (simulTimerList[1].autoincrease):
- simulTimerList[1].end = entry.begin - 30
- self.session.nav.RecordTimer.timeChanged(simulTimerList[1])
- self.session.nav.RecordTimer.record(entry)
- else:
+ for x in simulTimerList:
+ if x.setAutoincreaseEnd(entry):
+ self.session.nav.RecordTimer.timeChanged(x)
+ simulTimerList = self.session.nav.RecordTimer.record(entry)
+ if simulTimerList is not None:
self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
+ self["key_green"].setText(_("Remove timer"))
+ self.key_green_choice = self.REMOVE_TIMER
else:
- print "Timeredit aborted"
+ self["key_green"].setText(_("Add timer"))
+ self.key_green_choice = self.ADD_TIMER
+ print "Timeredit aborted"
def finishSanityCorrection(self, answer):
self.finishedAdd(answer)
@@ -211,7 +240,7 @@ class EPGSelection(Screen):
def moveDown(self):
self["list"].moveDown()
-
+
def applyButtonState(self, state):
if state == 0:
self["now_button"].hide()
@@ -226,13 +255,11 @@ class EPGSelection(Screen):
self["key_red"].setText("")
else:
if state == 1:
- self["key_red"].setText("Zap")
self["now_button_sel"].show()
self["now_button"].hide()
else:
self["now_button"].show()
self["now_button_sel"].hide()
- self["key_red"].setText("")
if state == 2:
self["next_button_sel"].show()
@@ -249,6 +276,16 @@ class EPGSelection(Screen):
self["more_button_sel"].hide()
def onSelectionChanged(self):
+ cur = self["list"].getCurrent()
+ if cur is None:
+ if self.key_green_choice != self.EMPTY:
+ self["key_green"].setText("")
+ self.key_green_choice = self.EMPTY
+ if self.key_red_choice != self.EMPTY:
+ self["key_red"].setText("")
+ self.key_red_choice = self.EMPTY
+ return
+ event = cur[0]
if self.type == EPG_TYPE_MULTI:
count = self["list"].getCurrentChangeCount()
if self.ask_time != -1:
@@ -260,8 +297,7 @@ class EPGSelection(Screen):
else:
self.applyButtonState(1)
days = [ _("Mon"), _("Tue"), _("Wed"), _("Thu"), _("Fri"), _("Sat"), _("Sun") ]
- datastr = ""
- event = self["list"].getCurrent()[0]
+ datestr = ""
if event is not None:
now = time()
beg = event.getBeginTime()
@@ -272,3 +308,36 @@ class EPGSelection(Screen):
else:
datestr = '%s %d.%d.'%(_("Today"), begTime[2], begTime[1])
self["date"].setText(datestr)
+
+ if cur[1] is None or cur[1].getServiceName() == "":
+ if self.key_green_choice != self.EMPTY:
+ self["key_green"].setText("")
+ self.key_green_choice = self.EMPTY
+ if self.key_red_choice != self.EMPTY:
+ self["key_red"].setText("")
+ self.key_red_choice = self.EMPTY
+ return
+ elif self.key_red_choice != self.ZAP and self.type == EPG_TYPE_MULTI:
+ self["key_red"].setText("Zap")
+ self.key_red_choice = self.ZAP
+
+ if event is None:
+ if self.key_green_choice != self.EMPTY:
+ self["key_green"].setText("")
+ self.key_green_choice = self.EMPTY
+ return
+
+ serviceref = cur[1]
+ eventid = event.getEventId()
+ refstr = serviceref.ref.toString()
+ isRecordEvent = False
+ for timer in self.session.nav.RecordTimer.timer_list:
+ if timer.eit == eventid and timer.service_ref.ref.toString() == refstr:
+ isRecordEvent = True
+ break
+ if isRecordEvent and self.key_green_choice != self.REMOVE_TIMER:
+ self["key_green"].setText(_("Remove timer"))
+ self.key_green_choice = self.REMOVE_TIMER
+ elif not isRecordEvent and self.key_green_choice != self.ADD_TIMER:
+ self["key_green"].setText(_("Add timer"))
+ self.key_green_choice = self.ADD_TIMER
diff --git a/lib/python/Screens/EventView.py b/lib/python/Screens/EventView.py
index 5d50d9bc..6aed1e11 100644
--- a/lib/python/Screens/EventView.py
+++ b/lib/python/Screens/EventView.py
@@ -1,17 +1,21 @@
from Screen import Screen
from Screens.TimerEdit import TimerSanityConflict
+from Screens.MessageBox import MessageBox
from Components.ActionMap import ActionMap
from Components.Button import Button
from Components.Label import Label
from Components.ScrollLabel import ScrollLabel
from Components.TimerList import TimerList
from enigma import eEPGCache, eTimer, eServiceReference
-from RecordTimer import RecordTimerEntry, parseEvent
+from RecordTimer import RecordTimerEntry, parseEvent, AFTEREVENT
from TimerEntry import TimerEntry
from time import localtime
from Components.config import config
class EventViewBase:
+ ADD_TIMER = 0
+ REMOVE_TIMER = 1
+
def __init__(self, Event, Ref, callback=None, similarEPGCB=None):
self.similarEPGCB = similarEPGCB
self.cbFunc = callback
@@ -28,6 +32,7 @@ class EventViewBase:
self.SimilarBroadcastTimer.callback.append(self.getSimilarEvents)
else:
self.SimilarBroadcastTimer = None
+ self.key_green_choice = self.ADD_TIMER
if self.isRecording:
self["key_green"] = Button("")
else:
@@ -59,8 +64,25 @@ class EventViewBase:
if self.cbFunc is not None:
self.cbFunc(self.setEvent, self.setService, +1)
+ def removeTimer(self, timer):
+ timer.afterEvent = AFTEREVENT.NONE
+ self.session.nav.RecordTimer.removeEntry(timer)
+ self["key_green"].setText(_("Add timer"))
+ self.key_green_choice = self.ADD_TIMER
+
def timerAdd(self):
- if not self.isRecording:
+ event = self.event
+ serviceref = self.currentService
+ if event is None:
+ return
+ eventid = event.getEventId()
+ refstr = serviceref.ref.toString()
+ for timer in self.session.nav.RecordTimer.timer_list:
+ if timer.eit == eventid and timer.service_ref.ref.toString() == refstr:
+ cb_func = lambda ret : not ret or self.removeTimer(timer)
+ self.session.openWithCallback(cb_func, MessageBox, _("Do you really want to delete %s?") % event.getEventName())
+ break
+ else:
newEntry = RecordTimerEntry(self.currentService, checkOldTimers = True, *parseEvent(self.event))
self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
@@ -70,13 +92,17 @@ class EventViewBase:
entry = answer[1]
simulTimerList = self.session.nav.RecordTimer.record(entry)
if simulTimerList is not None:
- if (len(simulTimerList) == 2) and (simulTimerList[1].dontSave) and (simulTimerList[1].autoincrease):
- simulTimerList[1].end = entry.begin - 30
- self.session.nav.RecordTimer.timeChanged(simulTimerList[1])
- self.session.nav.RecordTimer.record(entry)
- else:
+ for x in simulTimerList:
+ if x.setAutoincreaseEnd(entry):
+ self.session.nav.RecordTimer.timeChanged(x)
+ simulTimerList = self.session.nav.RecordTimer.record(entry)
+ if simulTimerList is not None:
self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
+ self["key_green"].setText(_("Remove timer"))
+ self.key_green_choice = self.REMOVE_TIMER
else:
+ self["key_green"].setText(_("Add timer"))
+ self.key_green_choice = self.ADD_TIMER
print "Timeredit aborted"
def finishSanityCorrection(self, answer):
@@ -123,6 +149,22 @@ class EventViewBase:
if self.SimilarBroadcastTimer is not None:
self.SimilarBroadcastTimer.start(400,True)
+ serviceref = self.currentService
+ eventid = self.event.getEventId()
+ refstr = serviceref.ref.toString()
+ isRecordEvent = False
+ for timer in self.session.nav.RecordTimer.timer_list:
+ if timer.eit == eventid and timer.service_ref.ref.toString() == refstr:
+ isRecordEvent = True
+ break
+ if isRecordEvent and self.key_green_choice != self.REMOVE_TIMER:
+ self["key_green"].setText(_("Remove timer"))
+ self.key_green_choice = self.REMOVE_TIMER
+ elif not isRecordEvent and self.key_green_choice != self.ADD_TIMER:
+ self["key_green"].setText(_("Add timer"))
+ self.key_green_choice = self.ADD_TIMER
+
+
def pageUp(self):
self["epg_description"].pageUp()
diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py
index 409018de..89a6b8e3 100644
--- a/lib/python/Screens/InfoBarGenerics.py
+++ b/lib/python/Screens/InfoBarGenerics.py
@@ -29,7 +29,7 @@ from Screens.TimeDateInput import TimeDateInput
from ServiceReference import ServiceReference
from Tools import Notifications
-from Tools.Directories import SCOPE_HDD, resolveFilename, pathExists
+from Tools.Directories import SCOPE_HDD, resolveFilename, fileExists
from enigma import eTimer, eServiceCenter, eDVBServicePMTHandler, iServiceInformation, \
iPlayableService, eServiceReference, eEPGCache
@@ -348,14 +348,14 @@ class InfoBarMenu:
def mainMenu(self):
print "loading mainmenu XML..."
- menu = mdom.childNodes[0]
- assert menu.tagName == "menu", "root element in menu must be 'menu'!"
+ menu = mdom.getroot()
+ assert menu.tag == "menu", "root element in menu must be 'menu'!"
self.session.infobar = self
# so we can access the currently active infobar from screens opened from within the mainmenu
# at the moment used from the SubserviceSelection
- self.session.openWithCallback(self.mainMenuClosed, MainMenu, menu, menu.childNodes)
+ self.session.openWithCallback(self.mainMenuClosed, MainMenu, menu)
def mainMenuClosed(self, *val):
self.session.infobar = None
@@ -403,7 +403,7 @@ class InfoBarEPG:
self.eventView = None
self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
{
- "showEventView": (self.openEventView, _("show EPG...")),
+ "showEventInfo": (self.openEventView, _("show EPG...")),
"showEventInfoPlugin": (self.showEventInfoPlugins, _("show single service EPG...")),
"showInfobarOrEpgWhenInfobarAlreadyVisible": self.showEventInfoWhenNotVisible,
})
@@ -1033,7 +1033,13 @@ class InfoBarPVRState:
def __playStateChanged(self, state):
playstateString = state[3]
self.pvrStateDialog["state"].setText(playstateString)
- self._mayShow()
+
+ # if we return into "PLAY" state, ensure that the dialog gets hidden if there will be no infobar displayed
+ if not config.usage.show_infobar_on_skip.value and self.seekstate == self.SEEK_STATE_PLAY:
+ self.pvrStateDialog.hide()
+ else:
+ self._mayShow()
+
class InfoBarTimeshiftState(InfoBarPVRState):
def __init__(self):
@@ -1321,7 +1327,6 @@ class InfoBarJobman:
self.session.openWithCallback(self.JobViewCB, JobView, job)
def JobViewCB(self, in_background):
- from Screens.TaskView import JobView
job_manager.in_background = in_background
# depends on InfoBarExtensions
@@ -1437,8 +1442,8 @@ class InfoBarInstantRecord:
except:
pass
- begin = time()
- end = time() + 3600 * 24 * 365 * 1 # 1 year
+ begin = int(time())
+ end = begin + 3600 # dummy
name = "instant record"
description = ""
eventid = None
@@ -1459,19 +1464,28 @@ class InfoBarInstantRecord:
recording = RecordTimerEntry(serviceref, begin, end, name, description, eventid, dirname = config.movielist.last_videodir.value)
recording.dontSave = True
- recording.autoincrease = True
-
- simulTimerList = self.session.nav.RecordTimer.record(recording)
- if simulTimerList is not None:
- print "timer conflict detected!"
- if (len(simulTimerList) > 1):
- print "tsc_list > 1"
- recording.end = simulTimerList[1].begin - 30
+
+ if event is None or limitEvent == False:
+ recording.autoincrease = True
+ if recording.setAutoincreaseEnd():
self.session.nav.RecordTimer.record(recording)
- print "new endtime applied"
- else:
- print "conflict with only one timer? ! ?"
- self.recording.append(recording)
+ self.recording.append(recording)
+ else:
+ simulTimerList = self.session.nav.RecordTimer.record(recording)
+ if simulTimerList is not None: # conflict with other recording
+ name = simulTimerList[1].name
+ name_date = name + strftime(" %c", localtime(simulTimerList[1].begin))
+ print "[TIMER] conflicts with", name_date
+ recording.autoincrease = True # start with max available length, then increment
+ if recording.setAutoincreaseEnd():
+ self.session.nav.RecordTimer.record(recording)
+ self.recording.append(recording)
+ self.session.open(MessageBox, _("Record time limited due to conflicting timer %s") % name_date, MessageBox.TYPE_INFO)
+ else:
+ self.session.open(MessageBox, _("Couldn't record due to conflicting timer %s") % name, MessageBox.TYPE_INFO)
+ recording.autoincrease = False
+ else:
+ self.recording.append(recording)
def isInstantRecordRunning(self):
print "self.recording:", self.recording
@@ -1544,12 +1558,12 @@ class InfoBarInstantRecord:
print "stopping recording after", int(value), "minutes."
if int(value) != 0:
self.recording[self.selectedEntry].autoincrease = False
- self.recording[self.selectedEntry].end = time() + 60 * int(value)
+ self.recording[self.selectedEntry].end = int(time()) + 60 * int(value)
self.session.nav.RecordTimer.timeChanged(self.recording[self.selectedEntry])
def instantRecord(self):
dir = config.movielist.last_videodir.value
- if not pathExists(dir):
+ if not fileExists(dir, 'w'):
dir = resolveFilename(SCOPE_HDD)
try:
stat = os_stat(dir)
@@ -1561,21 +1575,21 @@ class InfoBarInstantRecord:
if self.isInstantRecordRunning():
self.session.openWithCallback(self.recordQuestionCallback, ChoiceBox, \
title=_("A recording is currently running.\nWhat do you want to do?"), \
- list=[(_("stop recording"), "stop"), \
- (_("change recording (duration)"), "changeduration"), \
- (_("change recording (endtime)"), "changeendtime"), \
- (_("add recording (indefinitely)"), "indefinitely"), \
- (_("add recording (stop after current event)"), "event"), \
+ list=[(_("add recording (stop after current event)"), "event"), \
(_("add recording (enter recording duration)"), "manualduration"), \
(_("add recording (enter recording endtime)"), "manualendtime"), \
+ (_("add recording (indefinitely)"), "indefinitely"), \
+ (_("change recording (duration)"), "changeduration"), \
+ (_("change recording (endtime)"), "changeendtime"), \
+ (_("stop recording"), "stop"), \
(_("do nothing"), "no")])
else:
self.session.openWithCallback(self.recordQuestionCallback, ChoiceBox, \
title=_("Start recording?"), \
- list=[(_("add recording (indefinitely)"), "indefinitely"), \
- (_("add recording (stop after current event)"), "event"), \
+ list=[(_("add recording (stop after current event)"), "event"), \
(_("add recording (enter recording duration)"), "manualduration"), \
(_("add recording (enter recording endtime)"), "manualendtime"), \
+ (_("add recording (indefinitely)"), "indefinitely"), \
(_("don't record"), "no")])
from Tools.ISO639 import LanguageCodes
diff --git a/lib/python/Screens/Makefile.am b/lib/python/Screens/Makefile.am
index a3cf70bb..cde2d6c3 100755
--- a/lib/python/Screens/Makefile.am
+++ b/lib/python/Screens/Makefile.am
@@ -13,5 +13,6 @@ install_PYTHON = \
TimerSelection.py PictureInPicture.py TimeDateInput.py \
SubtitleDisplay.py SubservicesQuickzap.py ParentalControlSetup.py NumericalTextInputHelpDialog.py \
SleepTimerEdit.py Ipkg.py RdsDisplay.py Globals.py DefaultWizard.py \
- SessionGlobals.py LocationBox.py WizardLanguage.py TaskView.py Rc.py VirtualKeyBoard.py
+ SessionGlobals.py LocationBox.py WizardLanguage.py TaskView.py Rc.py VirtualKeyBoard.py \
+ TextBox.py
diff --git a/lib/python/Screens/Menu.py b/lib/python/Screens/Menu.py
index 92039b42..93f23dfb 100644
--- a/lib/python/Screens/Menu.py
+++ b/lib/python/Screens/Menu.py
@@ -9,12 +9,10 @@ from Components.SystemInfo import SystemInfo
from Tools.Directories import resolveFilename, SCOPE_SKIN
-import xml.dom.minidom
+import xml.etree.cElementTree
from Screens.Setup import Setup, getSetupTitle
-from Tools import XMLTools
-
# <item text="TV-Mode">self.setModeTV()</item>
# <item text="Radio-Mode">self.setModeRadio()</item>
# <item text="File-Mode">self.setModeFile()</item>
@@ -22,9 +20,7 @@ from Tools import XMLTools
# read the menu
-menufile = file(resolveFilename(SCOPE_SKIN, 'menu.xml'), 'r')
-mdom = xml.dom.minidom.parseString(menufile.read())
-menufile.close()
+mdom = xml.etree.cElementTree.parse(resolveFilename(SCOPE_SKIN, 'menu.xml'))
class boundFunction:
def __init__(self, fnc, *args):
@@ -103,17 +99,17 @@ class Menu(Screen):
self.session.openWithCallback(self.menuClosed, Setup, dialog)
def addMenu(self, destList, node):
- requires = node.getAttribute("requires")
+ requires = node.get("requires")
if requires and not SystemInfo.get(requires, False):
return
- MenuTitle = _(node.getAttribute("text").encode("UTF-8") or "??")
- entryID = node.getAttribute("entryID") or "undefined"
- weight = node.getAttribute("weight") or 50
- x = node.getAttribute("flushConfigOnClose")
+ MenuTitle = _(node.get("text", "??").encode("UTF-8"))
+ entryID = node.get("entryID", "undefined")
+ weight = node.get("weight", 50)
+ x = node.get("flushConfigOnClose")
if x:
- a = boundFunction(self.session.openWithCallback, self.menuClosedWithConfigFlush, Menu, node, node.childNodes)
+ a = boundFunction(self.session.openWithCallback, self.menuClosedWithConfigFlush, Menu, node)
else:
- a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node, node.childNodes)
+ a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node)
#TODO add check if !empty(node.childNodes)
destList.append((MenuTitle, a, entryID, weight))
@@ -126,18 +122,16 @@ class Menu(Screen):
self.close(True)
def addItem(self, destList, node):
- requires = node.getAttribute("requires")
+ requires = node.get("requires")
if requires and not SystemInfo.get(requires, False):
return
- item_text = node.getAttribute("text").encode("UTF-8")
- entryID = node.getAttribute("entryID") or "undefined"
- weight = node.getAttribute("weight") or 50
- for x in node.childNodes:
- if x.nodeType != xml.dom.minidom.Element.nodeType:
- continue
- elif x.tagName == 'screen':
- module = x.getAttribute("module") or None
- screen = x.getAttribute("screen") or None
+ item_text = node.get("text", "").encode("UTF-8")
+ entryID = node.get("entryID", "undefined")
+ weight = node.get("weight", 50)
+ for x in node:
+ if x.tag == 'screen':
+ module = x.get("module")
+ screen = x.get("screen")
if screen is None:
screen = module
@@ -150,16 +144,16 @@ class Menu(Screen):
# check for arguments. they will be appended to the
# openDialog call
- args = XMLTools.mergeText(x.childNodes)
+ args = x.text or ""
screen += ", " + args
destList.append((_(item_text or "??"), boundFunction(self.runScreen, (module, screen)), entryID, weight))
return
- elif x.tagName == 'code':
- destList.append((_(item_text or "??"), boundFunction(self.execText, XMLTools.mergeText(x.childNodes)), entryID, weight))
+ elif x.tag == 'code':
+ destList.append((_(item_text or "??"), boundFunction(self.execText, x.text), entryID, weight))
return
- elif x.tagName == 'setup':
- id = x.getAttribute("id")
+ elif x.tag == 'setup':
+ id = x.get("id")
if item_text == "":
item_text = _(getSetupTitle(id)) + "..."
else:
@@ -169,26 +163,23 @@ class Menu(Screen):
destList.append((item_text, self.nothing, entryID, weight))
- def __init__(self, session, parent, childNode):
+ def __init__(self, session, parent):
Screen.__init__(self, session)
list = []
menuID = None
- for x in childNode: #walk through the actual nodelist
- if x.nodeType != xml.dom.minidom.Element.nodeType:
- continue
- elif x.tagName == 'item':
- item_level = int(x.getAttribute("level") or "0")
-
+ for x in parent: #walk through the actual nodelist
+ if x.tag == 'item':
+ item_level = int(x.get("level", 0))
if item_level <= config.usage.setup_level.index:
self.addItem(list, x)
count += 1
- elif x.tagName == 'menu':
+ elif x.tag == 'menu':
self.addMenu(list, x)
count += 1
- elif x.tagName == "id":
- menuID = x.getAttribute("val")
+ elif x.tag == "id":
+ menuID = x.get("val")
count = 0
if menuID is not None:
@@ -237,10 +228,10 @@ class Menu(Screen):
"9": self.keyNumberGlobal
})
- a = parent.getAttribute("title").encode("UTF-8") or None
+ a = parent.get("title", "").encode("UTF-8") or None
a = a and _(a)
if a is None:
- a = _(parent.getAttribute("text").encode("UTF-8"))
+ a = _(parent.get("text", "").encode("UTF-8"))
self["title"] = StaticText(a)
self.menu_title = a
diff --git a/lib/python/Screens/Satconfig.py b/lib/python/Screens/Satconfig.py
index 6489f28f..da6fcc12 100644
--- a/lib/python/Screens/Satconfig.py
+++ b/lib/python/Screens/Satconfig.py
@@ -87,6 +87,10 @@ class NimSetup(Screen, ConfigListScreen):
self.uncommittedDiseqcCommand = None
self.cableScanType = None
self.have_advanced = False
+ self.advancedUnicable = None
+ self.advancedType = None
+ self.advancedManufacturer = None
+ self.advancedSCR = None
if self.nim.isCompatible("DVB-S"):
self.configMode = getConfigListEntry(_("Configuration Mode"), self.nimConfig.configMode)
@@ -190,6 +194,7 @@ class NimSetup(Screen, ConfigListScreen):
checkList = (self.configMode, self.diseqcModeEntry, self.advancedSatsEntry, \
self.advancedLnbsEntry, self.advancedDiseqcMode, self.advancedUsalsEntry, \
self.advancedLof, self.advancedPowerMeasurement, self.turningSpeed, \
+ self.advancedType, self.advancedSCR, self.advancedManufacturer, self.advancedUnicable, \
self.uncommittedDiseqcCommand, self.cableScanType)
for x in checkList:
if self["config"].getCurrent() == x:
@@ -216,19 +221,57 @@ class NimSetup(Screen, ConfigListScreen):
if isinstance(currLnb, ConfigNothing):
currLnb = None
- self.list.append(getConfigListEntry(_("Voltage mode"), Sat.voltage))
- self.list.append(getConfigListEntry(_("Tone mode"), Sat.tonemode))
- if currLnb and currLnb.diseqcMode.value == "1_2":
- if lnbnum < 33:
- self.advancedUsalsEntry = getConfigListEntry(_("Use usals for this sat"), Sat.usals)
- self.list.append(self.advancedUsalsEntry)
- if not Sat.usals.value:
- self.list.append(getConfigListEntry(_("Stored position"), Sat.rotorposition))
-
# LNBs
self.advancedLnbsEntry = getConfigListEntry(_("LNB"), Sat.lnb)
self.list.append(self.advancedLnbsEntry)
+
if currLnb:
+ self.list.append(getConfigListEntry(_("Priority"), currLnb.prio))
+ self.advancedLof = getConfigListEntry(_("LOF"), currLnb.lof)
+ self.list.append(self.advancedLof)
+ if currLnb.lof.value == "user_defined":
+ self.list.append(getConfigListEntry(_("LOF/L"), currLnb.lofl))
+ self.list.append(getConfigListEntry(_("LOF/H"), currLnb.lofh))
+ self.list.append(getConfigListEntry(_("Threshold"), currLnb.threshold))
+# self.list.append(getConfigListEntry(_("12V Output"), currLnb.output_12v))
+
+ if currLnb.lof.value == "unicable":
+ self.advancedUnicable = getConfigListEntry("Unicable "+_("Configuration Mode"), currLnb.unicable)
+ self.list.append(self.advancedUnicable)
+ if currLnb.unicable.value == "unicable_user":
+ self.advancedSCR = getConfigListEntry(_("Channel"), currLnb.satcruser)
+ self.list.append(self.advancedSCR)
+ self.list.append(getConfigListEntry(_("Frequency"), currLnb.satcrvcouser[currLnb.satcruser.index]))
+ self.list.append(getConfigListEntry(_("LOF/L"), currLnb.lofl))
+ self.list.append(getConfigListEntry(_("LOF/H"), currLnb.lofh))
+ self.list.append(getConfigListEntry(_("Threshold"), currLnb.threshold))
+ elif currLnb.unicable.value == "unicable_matrix":
+ manufacturer_name = currLnb.unicableMatrixManufacturer.value
+ manufacturer = currLnb.unicableMatrix[manufacturer_name]
+ product_name = manufacturer.product.value
+ self.advancedManufacturer = getConfigListEntry(_("Manufacturer"), currLnb.unicableMatrixManufacturer)
+ self.advancedType = getConfigListEntry(_("Type"), manufacturer.product)
+ self.advancedSCR = getConfigListEntry(_("Channel"), manufacturer.scr[product_name])
+ self.list.append(self.advancedManufacturer)
+ self.list.append(self.advancedType)
+ self.list.append(self.advancedSCR)
+ self.list.append(getConfigListEntry(_("Frequency"), manufacturer.vco[product_name][manufacturer.scr[product_name].index]))
+ elif currLnb.unicable.value == "unicable_lnb":
+ manufacturer_name = currLnb.unicableLnbManufacturer.value
+ manufacturer = currLnb.unicableLnb[manufacturer_name]
+ product_name = manufacturer.product.value
+ self.advancedManufacturer = getConfigListEntry(_("Manufacturer"), currLnb.unicableLnbManufacturer)
+ self.advancedType = getConfigListEntry(_("Type"), manufacturer.product)
+ self.advancedSCR = getConfigListEntry(_("Channel"), manufacturer.scr[product_name])
+ self.list.append(self.advancedManufacturer)
+ self.list.append(self.advancedType)
+ self.list.append(self.advancedSCR)
+ self.list.append(getConfigListEntry(_("Frequency"), manufacturer.vco[product_name][manufacturer.scr[product_name].index]))
+ else: #kein Unicable
+ self.list.append(getConfigListEntry(_("Voltage mode"), Sat.voltage))
+ self.list.append(getConfigListEntry(_("Increased voltage"), currLnb.increased_voltage))
+ self.list.append(getConfigListEntry(_("Tone mode"), Sat.tonemode))
+
if lnbnum < 33:
self.advancedDiseqcMode = getConfigListEntry(_("DiSEqC mode"), currLnb.diseqcMode)
self.list.append(self.advancedDiseqcMode)
@@ -275,14 +318,12 @@ class NimSetup(Screen, ConfigListScreen):
if currLnb.powerMeasurement.value:
currLnb.powerMeasurement.value = False
currLnb.powerMeasurement.save()
- self.advancedLof = getConfigListEntry(_("LOF"), currLnb.lof)
- self.list.append(self.advancedLof)
- if currLnb.lof.value == "user_defined":
- self.list.append(getConfigListEntry(_("LOF/L"), currLnb.lofl))
- self.list.append(getConfigListEntry(_("LOF/H"), currLnb.lofh))
- self.list.append(getConfigListEntry(_("Threshold"), currLnb.threshold))
-# self.list.append(getConfigListEntry(_("12V Output"), currLnb.output_12v))
- self.list.append(getConfigListEntry(_("Increased voltage"), currLnb.increased_voltage))
+ self.advancedUsalsEntry = getConfigListEntry(_("Use usals for this sat"), Sat.usals)
+ self.list.append(self.advancedUsalsEntry)
+ if not Sat.usals.value:
+ self.list.append(getConfigListEntry(_("Stored position"), Sat.rotorposition))
+
+
def fillAdvancedList(self):
self.list = [ ]
@@ -383,18 +424,26 @@ class NimSelection(Screen):
self.list = [None] * nimmanager.getSlotCount()
self["nimlist"] = List(self.list)
self.updateList()
+
+ self.setResultClass()
self["actions"] = ActionMap(["OkCancelActions"],
{
"ok": self.okbuttonClick ,
"cancel": self.close
}, -2)
+
+ def setResultClass(self):
+ self.resultclass = NimSetup
def okbuttonClick(self):
nim = self["nimlist"].getCurrent()
nim = nim and nim[3]
if nim is not None and not nim.empty:
- self.session.openWithCallback(self.updateList, NimSetup, nim.slot)
+ self.session.openWithCallback(self.updateList, self.resultclass, nim.slot)
+
+ def showNim(self, nim):
+ return True
def updateList(self):
self.list = [ ]
@@ -402,42 +451,44 @@ class NimSelection(Screen):
slotid = x.slot
nimConfig = nimmanager.getNimConfig(x.slot)
text = nimConfig.configMode.value
- if x.isCompatible("DVB-S"):
- if nimConfig.configMode.value in ["loopthrough", "equal", "satposdepends"]:
- text = { "loopthrough": _("loopthrough to"),
- "equal": _("equal to"),
- "satposdepends": _("second cable of motorized LNB") } [nimConfig.configMode.value]
- text += " " + _("Tuner") + " " + ["A", "B", "C", "D"][int(nimConfig.connectedTo.value)]
- elif nimConfig.configMode.value == "nothing":
- text = _("nothing connected")
- elif nimConfig.configMode.value == "simple":
- if nimConfig.diseqcMode.value in ["single", "toneburst_a_b", "diseqc_a_b", "diseqc_a_b_c_d"]:
- text = _("Sats") + ": "
- if nimConfig.diseqcA.orbital_position != 3601:
- text += nimmanager.getSatName(int(nimConfig.diseqcA.value))
- if nimConfig.diseqcMode.value in ["toneburst_a_b", "diseqc_a_b", "diseqc_a_b_c_d"]:
- if nimConfig.diseqcB.orbital_position != 3601:
- text += "," + nimmanager.getSatName(int(nimConfig.diseqcB.value))
- if nimConfig.diseqcMode.value == "diseqc_a_b_c_d":
- if nimConfig.diseqcC.orbital_position != 3601:
- text += "," + nimmanager.getSatName(int(nimConfig.diseqcC.value))
- if nimConfig.diseqcD.orbital_position != 3601:
- text += "," + nimmanager.getSatName(int(nimConfig.diseqcD.value))
- elif nimConfig.diseqcMode.value == "positioner":
- text = _("Positioner") + ":"
- if nimConfig.positionerMode.value == "usals":
- text += _("USALS")
- elif nimConfig.positionerMode.value == "manual":
- text += _("manual")
- else:
- text = _("simple")
- elif nimConfig.configMode.value == "advanced":
- text = _("advanced")
- elif x.isCompatible("DVB-T") or x.isCompatible("DVB-C"):
- if nimConfig.configMode.value == "nothing":
- text = _("nothing connected")
- elif nimConfig.configMode.value == "enabled":
- text = _("enabled")
-
- self.list.append((slotid, x.friendly_full_description, text, x))
+ if self.showNim(x):
+ if x.isCompatible("DVB-S"):
+ if nimConfig.configMode.value in ["loopthrough", "equal", "satposdepends"]:
+ text = { "loopthrough": _("loopthrough to"),
+ "equal": _("equal to"),
+ "satposdepends": _("second cable of motorized LNB") } [nimConfig.configMode.value]
+ text += " " + _("Tuner") + " " + ["A", "B", "C", "D"][int(nimConfig.connectedTo.value)]
+ elif nimConfig.configMode.value == "nothing":
+ text = _("nothing connected")
+ elif nimConfig.configMode.value == "simple":
+ if nimConfig.diseqcMode.value in ["single", "toneburst_a_b", "diseqc_a_b", "diseqc_a_b_c_d"]:
+ text = _("Sats") + ": "
+ if nimConfig.diseqcA.orbital_position != 3601:
+ text += nimmanager.getSatName(int(nimConfig.diseqcA.value))
+ if nimConfig.diseqcMode.value in ["toneburst_a_b", "diseqc_a_b", "diseqc_a_b_c_d"]:
+ if nimConfig.diseqcB.orbital_position != 3601:
+ text += "," + nimmanager.getSatName(int(nimConfig.diseqcB.value))
+ if nimConfig.diseqcMode.value == "diseqc_a_b_c_d":
+ if nimConfig.diseqcC.orbital_position != 3601:
+ text += "," + nimmanager.getSatName(int(nimConfig.diseqcC.value))
+ if nimConfig.diseqcD.orbital_position != 3601:
+ text += "," + nimmanager.getSatName(int(nimConfig.diseqcD.value))
+ elif nimConfig.diseqcMode.value == "positioner":
+ text = _("Positioner") + ":"
+ if nimConfig.positionerMode.value == "usals":
+ text += _("USALS")
+ elif nimConfig.positionerMode.value == "manual":
+ text += _("manual")
+ else:
+ text = _("simple")
+ elif nimConfig.configMode.value == "advanced":
+ text = _("advanced")
+ elif x.isCompatible("DVB-T") or x.isCompatible("DVB-C"):
+ if nimConfig.configMode.value == "nothing":
+ text = _("nothing connected")
+ elif nimConfig.configMode.value == "enabled":
+ text = _("enabled")
+
+ self.list.append((slotid, x.friendly_full_description, text, x))
+ self["nimlist"].setList(self.list)
self["nimlist"].updateList(self.list) \ No newline at end of file
diff --git a/lib/python/Screens/ScanSetup.py b/lib/python/Screens/ScanSetup.py
index 608dcb2d..7089074a 100644
--- a/lib/python/Screens/ScanSetup.py
+++ b/lib/python/Screens/ScanSetup.py
@@ -17,64 +17,17 @@ def buildTerTransponder(frequency,
inversion=2, bandwidth = 3, fechigh = 6, feclow = 6,
modulation = 2, transmission = 2, guard = 4,
hierarchy = 4):
-
# print "freq", frequency, "inv", inversion, "bw", bandwidth, "fech", fechigh, "fecl", feclow, "mod", modulation, "tm", transmission, "guard", guard, "hierarchy", hierarchy
-
- # WARNING: normally, enums are working directly.
- # Don't copy this (very bad)!! Instead either fix swig (good) or
- # move this into a central place.
- Bw8MHz = 0
- Bw7MHz = 1
- Bw6MHz = 2
- #Bw5MHz = 3 #not implemented for e1 compatibilty
- BwAuto = 3
-
- f1_2 = 0
- f2_3 = 1
- f3_4 = 2
- f5_6 = 3
- f7_8 = 4
- fAuto = 5
-
- TM2k = 0
- TM8k = 1
- #TM4k = 2 #not implemented for e1 compatibilty
- TMAuto = 2
-
- GI_1_32 = 0
- GI_1_16 = 1
- GI_1_8 = 2
- GI_1_4 = 3
- GI_Auto = 4
-
- HNone = 0
- H1 = 1
- H2 = 2
- H4 = 3
- HAuto = 4
-
- QPSK = 0
- QAM16 = 1
- QAM64 = 2
- Auto = 3
-
- Off = 0
- On = 1
- Unknown = 2
-
parm = eDVBFrontendParametersTerrestrial()
-
parm.frequency = frequency
-
- parm.inversion = [Off, On, Unknown][inversion]
- parm.bandwidth = [Bw8MHz, Bw7MHz, Bw6MHz, BwAuto][bandwidth] # Bw5MHz unsupported
- parm.code_rate_HP = [f1_2, f2_3, f3_4, f5_6, f7_8, fAuto][fechigh]
- parm.code_rate_LP = [f1_2, f2_3, f3_4, f5_6, f7_8, fAuto][feclow]
- parm.modulation = [QPSK, QAM16, QAM64, Auto][modulation]
- parm.transmission_mode = [TM2k, TM8k, TMAuto][transmission] # TM4k unsupported
- parm.guard_interval = [GI_1_32, GI_1_16, GI_1_8, GI_1_4, GI_Auto][guard]
- parm.hierarchy = [HNone, H1, H2, H4, HAuto][hierarchy]
-
+ parm.inversion = inversion
+ parm.bandwidth = bandwidth
+ parm.code_rate_HP = fechigh
+ parm.code_rate_LP = feclow
+ parm.modulation = modulation
+ parm.transmission_mode = transmission
+ parm.guard_interval = guard
+ parm.hierarchy = hierarchy
return parm
def getInitialTransponderList(tlist, pos):
@@ -103,7 +56,7 @@ def getInitialCableTransponderList(tlist, nim):
parm.symbol_rate = x[2]
parm.modulation = x[3]
parm.fec_inner = x[4]
- parm.inversion = 2 # AUTO
+ parm.inversion = parm.Inversion_Unknown
#print "frequency:", x[1]
#print "symbol_rate:", x[2]
#print "modulation:", x[3]
@@ -178,10 +131,22 @@ class CableTransponderSearchSupport:
if len(data):
if data[0] == 'OK':
print str
- qam = { "QAM16" : 1, "QAM32" : 2, "QAM64" : 3, "QAM128" : 4, "QAM256" : 5 }
- inv = { "INVERSION_OFF" : 0, "INVERSION_ON" : 1 }
- fec = { "FEC_AUTO" : 0, "FEC_1_2" : 1, "FEC_2_3" : 2, "FEC_3_4" : 3, "FEC_5_6": 4, "FEC_7_8" : 5, "FEC_8_9" : 6, "FEC_NONE" : 15 }
parm = eDVBFrontendParametersCable()
+ qam = { "QAM16" : parm.Modulation_QAM16,
+ "QAM32" : parm.Modulation_QAM32,
+ "QAM64" : parm.Modulation_QAM64,
+ "QAM128" : parm.Modulation_QAM128,
+ "QAM256" : parm.Modulation_QAM256 }
+ inv = { "INVERSION_OFF" : parm.Inversion_Off,
+ "INVERSION_ON" : parm.Inversion_On }
+ fec = { "FEC_AUTO" : parm.FEC_Auto,
+ "FEC_1_2" : parm.FEC_1_2,
+ "FEC_2_3" : parm.FEC_2_3,
+ "FEC_3_4" : parm.FEC_3_4,
+ "FEC_5_6": parm.FEC_5_6,
+ "FEC_7_8" : parm.FEC_7_8,
+ "FEC_8_9" : parm.FEC_8_9,
+ "FEC_NONE" : parm.FEC_None }
parm.frequency = int(data[1])
parm.symbol_rate = int(data[2])
parm.fec_inner = fec[data[3]]
@@ -381,15 +346,15 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport):
self.list.append(self.systemEntry)
else:
# downgrade to dvb-s, in case a -s2 config was active
- self.scan_sat.system.value = "dvb-s"
+ self.scan_sat.system.value = eDVBFrontendParametersSatellite.System_DVB_S
self.list.append(getConfigListEntry(_('Satellite'), self.scan_satselection[index_to_scan]))
self.list.append(getConfigListEntry(_('Frequency'), self.scan_sat.frequency))
self.list.append(getConfigListEntry(_('Inversion'), self.scan_sat.inversion))
self.list.append(getConfigListEntry(_('Symbol Rate'), self.scan_sat.symbolrate))
self.list.append(getConfigListEntry(_("Polarity"), self.scan_sat.polarization))
- if self.scan_sat.system.value == "dvb-s":
+ if self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S:
self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec))
- elif self.scan_sat.system.value == "dvb-s2":
+ elif self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S2:
self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2))
self.modulationEntry = getConfigListEntry(_('Modulation'), self.scan_sat.modulation)
self.list.append(self.modulationEntry)
@@ -447,7 +412,7 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport):
if cur == self.typeOfScanEntry or \
cur == self.tunerEntry or \
cur == self.systemEntry or \
- (self.modulationEntry and self.systemEntry[1].value == "dvb-s2" and cur == self.modulationEntry):
+ (self.modulationEntry and self.systemEntry[1].value == eDVBFrontendParametersSatellite.System_DVB_S2 and cur == self.modulationEntry):
self.createSetup()
def createConfig(self, frontendData):
@@ -481,34 +446,65 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport):
#("Transmission Mode", frontendData["transmission_mode"], TYPE_TEXT),
#("Guard Interval", frontendData["guard_interval"], TYPE_TEXT),
#("Hierarchy Inform.", frontendData["hierarchy_information"], TYPE_TEXT),
- defaultSat = { "orbpos": 192, "system": "dvb-s", "frequency": 11836, "inversion": "auto", "symbolrate": 27500, "polarization": "horizontal", "fec": "auto", "fec_s2": "9_10", "modulation": "qpsk" }
- defaultCab = {"frequency": 466, "inversion": "auto", "modulation": "64qam", "fec": "auto", "symbolrate": 6900}
+ defaultSat = {
+ "orbpos": 192,
+ "system": eDVBFrontendParametersSatellite.System_DVB_S,
+ "frequency": 11836,
+ "inversion": eDVBFrontendParametersSatellite.Inversion_Unknown,
+ "symbolrate": 27500,
+ "polarization": eDVBFrontendParametersSatellite.Polarisation_Horizontal,
+ "fec": eDVBFrontendParametersSatellite.FEC_Auto,
+ "fec_s2": eDVBFrontendParametersSatellite.FEC_9_10,
+ "modulation": eDVBFrontendParametersSatellite.Modulation_QPSK }
+ defaultCab = {
+ "frequency": 466,
+ "inversion": eDVBFrontendParametersCable.Inversion_Unknown,
+ "modulation": eDVBFrontendParametersCable.Modulation_QAM64,
+ "fec": eDVBFrontendParametersCable.FEC_Auto,
+ "symbolrate": 6900 }
+ defaultTer = {
+ "frequency" : 466000,
+ "inversion" : eDVBFrontendParametersTerrestrial.Inversion_Unknown,
+ "bandwidth" : eDVBFrontendParametersTerrestrial.Bandwidth_7MHz,
+ "fechigh" : eDVBFrontendParametersTerrestrial.FEC_Auto,
+ "feclow" : eDVBFrontendParametersTerrestrial.FEC_Auto,
+ "modulation" : eDVBFrontendParametersTerrestrial.Modulation_Auto,
+ "transmission_mode" : eDVBFrontendParametersTerrestrial.TransmissionMode_Auto,
+ "guard_interval" : eDVBFrontendParametersTerrestrial.GuardInterval_Auto,
+ "hierarchy": eDVBFrontendParametersTerrestrial.Hierarchy_Auto }
+
if frontendData is not None:
ttype = frontendData.get("tuner_type", "UNKNOWN")
if ttype == "DVB-S":
- defaultSat["system"] = {"DVB-S": "dvb-s", "DVB-S2": "dvb-s2"}[frontendData.get("system", "DVB-S")]
- defaultSat["frequency"] = int(frontendData.get("frequency", 0) / 1000)
- defaultSat["inversion"] = {"INVERSION_OFF": "off", "INVERSION_ON": "on", "INVERSION_AUTO": "auto"}[frontendData.get("inversion", "INVERSION_AUTO")]
- defaultSat["symbolrate"] = int(frontendData.get("symbol_rate", 0) / 1000)
- defaultSat["polarization"] = {"HORIZONTAL": "horizontal", "VERTICAL": "vertical", "CIRCULAR_LEFT": "circular_left", "CIRCULAR_RIGHT": "circular_right", "UNKNOWN": None}[frontendData.get("polarization", "HORIZONTAL")]
-
- if frontendData.get("system", "DVB-S") == "DVB-S2":
- defaultSat["fec_s2"] = {"FEC_1_2": "1_2", "FEC_2_3": "2_3", "FEC_3_4": "3_4", "FEC_4_5": "4_5", "FEC_5_6": "5_6", "FEC_7_8": "7_8", "FEC_8_9": "8_9", "FEC_9_10": "9_10"} \
- [frontendData.get("fec_inner", "FEC_AUTO")]
- defaultSat["rolloff"] = {"ROLLOFF_0_35" : "0_35", "ROLLOFF_0_25" : "0_25", "ROLLOFF_0_20" : "0_20"}[frontendData.get("rolloff", "ROLLOFF_0_35")]
- defaultSat["pilot"] = {"PILOT_ON" : "on", "PILOT_OFF" : "off", "PILOT_AUTO" : "auto"}[frontendData.get("pilot", "PILOT_AUTO")]
+ defaultSat["system"] = frontendData.get("system", eDVBFrontendParametersSatellite.System_DVB_S)
+ defaultSat["frequency"] = frontendData.get("frequency", 0) / 1000
+ defaultSat["inversion"] = frontendData.get("inversion", eDVBFrontendParametersSatellite.Inversion_Unknown)
+ defaultSat["symbolrate"] = frontendData.get("symbol_rate", 0) / 1000
+ defaultSat["polarization"] = frontendData.get("polarization", eDVBFrontendParametersSatellite.Polarisation_Horizontal)
+ if defaultSat["system"] == eDVBFrontendParametersSatellite.System_DVB_S2:
+ defaultSat["fec_s2"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto)
+ defaultSat["rolloff"] = frontendData.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35)
+ defaultSat["pilot"] = frontendData.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown)
else:
- defaultSat["fec"] = {"FEC_AUTO": "auto", "FEC_1_2": "1_2", "FEC_2_3": "2_3", "FEC_3_4": "3_4", "FEC_5_6": "5_6", "FEC_7_8": "7_8", "FEC_NONE": "none"} \
- [frontendData.get("fec_inner", "FEC_AUTO")]
-
- defaultSat["modulation"] = {"QPSK": "qpsk", "8PSK": "8psk"}[frontendData.get("modulation", "QPSK")]
+ defaultSat["fec"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto)
+ defaultSat["modulation"] = frontendData.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK)
defaultSat["orbpos"] = frontendData.get("orbital_position", 0)
elif ttype == "DVB-C":
- defaultCab["frequency"] = int(frontendData.get("frequency", 0) / 1000)
- defaultCab["symbolrate"] = int(frontendData.get("symbol_rate", 0) / 1000)
- defaultCab["inversion"] = {"INVERSION_OFF": "off", "INVERSION_ON": "on", "INVERSION_AUTO": "auto"}[frontendData.get("inversion", "INVERSION_AUTO")]
- defaultCab["fec"] = {"FEC_AUTO": "auto", "FEC_1_2": "1_2", "FEC_2_3": "2_3", "FEC_3_4": "3_4", "FEC_5_6": "5_6", "FEC_7_8": "7_8", "FEC_8_9": "8_9", "FEC_NONE": "none"}[frontendData.get("fec_inner", "FEC_AUTO")]
- defaultCab["modulation"] = {"QAM_AUTO": "auto", "QAM_16": "16qam", "QAM_32": "32qam", "QAM_64": "64qam", "QAM_128": "128qam", "QAM_256": "256qam"}[frontendData.get("modulation", "QAM_16")]
+ defaultCab["frequency"] = frontendData.get("frequency", 0) / 1000
+ defaultCab["symbolrate"] = frontendData.get("symbol_rate", 0) / 1000
+ defaultCab["inversion"] = frontendData.get("inversion", eDVBFrontendParametersCable.Inversion_Unknown)
+ defaultCab["fec"] = frontendData.get("fec_inner", eDVBFrontendParametersCable.FEC_Auto)
+ defaultCab["modulation"] = frontendData.get("modulation", eDVBFrontendParametersCable.Modulation_QAM16)
+ elif ttype == "DVB-T":
+ defaultTer["frequency"] = frontendData.get("frequency", 0)
+ defaultTer["inversion"] = frontendData.get("inversion", eDVBFrontendParametersTerrestrial.Inversion_Unknown)
+ defaultTer["bandwidth"] = frontendData.get("bandwidth", eDVBFrontendParametersTerrestrial.Bandwidth_7MHz)
+ defaultTer["fechigh"] = frontendData.get("code_rate_hp", eDVBFrontendParametersTerrestrial.FEC_Auto)
+ defaultTer["feclow"] = frontendData.get("code_rate_lp", eDVBFrontendParametersTerrestrial.FEC_Auto)
+ defaultTer["modulation"] = frontendData.get("constellation", eDVBFrontendParametersTerrestrial.Modulation_Auto)
+ defaultTer["transmission_mode"] = frontendData.get("transmission_mode", eDVBFrontendParametersTerrestrial.TransmissionMode_Auto)
+ defaultTer["guard_interval"] = frontendData.get("guard_interval", eDVBFrontendParametersTerrestrial.GuardInterval_Auto)
+ defaultTer["hierarchy"] = frontendData.get("hierarchy_information", eDVBFrontendParametersTerrestrial.Hierarchy_Auto)
self.scan_sat = ConfigSubsection()
self.scan_cab = ConfigSubsection()
@@ -524,7 +520,7 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport):
nim_list = []
# collect all nims which are *not* set to "nothing"
for n in nimmanager.nim_slots:
- if n.config_mode != "nothing":
+ if not n.config_mode in ("loopthrough", "satposdepends", "nothing"):
nim_list.append((str(n.slot), n.friendly_full_description))
self.scan_nims = ConfigSelection(choices = nim_list)
@@ -538,36 +534,120 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport):
self.scan_ber.enabled = False
# sat
- self.scan_sat.system = ConfigSelection(default = defaultSat["system"], choices = [("dvb-s", _("DVB-S")), ("dvb-s2", _("DVB-S2"))])
+ self.scan_sat.system = ConfigSelection(default = defaultSat["system"], choices = [
+ (eDVBFrontendParametersSatellite.System_DVB_S, _("DVB-S")),
+ (eDVBFrontendParametersSatellite.System_DVB_S2, _("DVB-S2"))])
self.scan_sat.frequency = ConfigInteger(default = defaultSat["frequency"], limits = (1, 99999))
- self.scan_sat.inversion = ConfigSelection(default = defaultSat["inversion"], choices = [("off", _("off")), ("on", _("on")), ("auto", _("Auto"))])
+ self.scan_sat.inversion = ConfigSelection(default = defaultSat["inversion"], choices = [
+ (eDVBFrontendParametersSatellite.Inversion_Off, _("off")),
+ (eDVBFrontendParametersSatellite.Inversion_On, _("on")),
+ (eDVBFrontendParametersSatellite.Inversion_Unknown, _("Auto"))])
self.scan_sat.symbolrate = ConfigInteger(default = defaultSat["symbolrate"], limits = (1, 99999))
- self.scan_sat.polarization = ConfigSelection(default = defaultSat["polarization"], choices = [("horizontal", _("horizontal")), ("vertical", _("vertical")), ("circular_left", _("circular left")), ("circular_right", _("circular right"))])
- self.scan_sat.fec = ConfigSelection(default = defaultSat["fec"], choices = [("auto", _("Auto")), ("1_2", "1/2"), ("2_3", "2/3"), ("3_4", "3/4"), ("5_6", "5/6"), ("7_8", "7/8"), ("none", _("None"))])
- self.scan_sat.fec_s2 = ConfigSelection(default = defaultSat["fec_s2"], choices = [("1_2", "1/2"), ("2_3", "2/3"), ("3_4", "3/4"), ("3_5", "3/5"), ("4_5", "4/5"), ("5_6", "5/6"), ("7_8", "7/8"), ("8_9", "8/9"), ("9_10", "9/10")])
- self.scan_sat.modulation = ConfigSelection(default = defaultSat["modulation"], choices = [("qpsk", "QPSK"), ("8psk", "8PSK")])
- self.scan_sat.rolloff = ConfigSelection(default = defaultSat.get("rolloff", "0_35"), choices = [("0_35", "0.35"), ("0_25", "0.25"), ("0_20", "0.20")])
- self.scan_sat.pilot = ConfigSelection(default = defaultSat.get("pilot", "auto"), choices = [("off", _("off")), ("on", _("on")), ("auto", _("Auto"))])
+ self.scan_sat.polarization = ConfigSelection(default = defaultSat["polarization"], choices = [
+ (eDVBFrontendParametersSatellite.Polarisation_Horizontal, _("horizontal")),
+ (eDVBFrontendParametersSatellite.Polarisation_Vertical, _("vertical")),
+ (eDVBFrontendParametersSatellite.Polarisation_CircularLeft, _("circular left")),
+ (eDVBFrontendParametersSatellite.Polarisation_CircularRight, _("circular right"))])
+ self.scan_sat.fec = ConfigSelection(default = defaultSat["fec"], choices = [
+ (eDVBFrontendParametersSatellite.FEC_Auto, _("Auto")),
+ (eDVBFrontendParametersSatellite.FEC_1_2, "1/2"),
+ (eDVBFrontendParametersSatellite.FEC_2_3, "2/3"),
+ (eDVBFrontendParametersSatellite.FEC_3_4, "3/4"),
+ (eDVBFrontendParametersSatellite.FEC_5_6, "5/6"),
+ (eDVBFrontendParametersSatellite.FEC_7_8, "7/8"),
+ (eDVBFrontendParametersSatellite.FEC_None, _("None"))])
+ self.scan_sat.fec_s2 = ConfigSelection(default = defaultSat["fec_s2"], choices = [
+ (eDVBFrontendParametersSatellite.FEC_1_2, "1/2"),
+ (eDVBFrontendParametersSatellite.FEC_2_3, "2/3"),
+ (eDVBFrontendParametersSatellite.FEC_3_4, "3/4"),
+ (eDVBFrontendParametersSatellite.FEC_3_5, "3/5"),
+ (eDVBFrontendParametersSatellite.FEC_4_5, "4/5"),
+ (eDVBFrontendParametersSatellite.FEC_5_6, "5/6"),
+ (eDVBFrontendParametersSatellite.FEC_7_8, "7/8"),
+ (eDVBFrontendParametersSatellite.FEC_8_9, "8/9"),
+ (eDVBFrontendParametersSatellite.FEC_9_10, "9/10")])
+ self.scan_sat.modulation = ConfigSelection(default = defaultSat["modulation"], choices = [
+ (eDVBFrontendParametersSatellite.Modulation_QPSK, "QPSK"),
+ (eDVBFrontendParametersSatellite.Modulation_8PSK, "8PSK")])
+ self.scan_sat.rolloff = ConfigSelection(default = defaultSat.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35), choices = [
+ (eDVBFrontendParametersSatellite.RollOff_alpha_0_35, "0.35"),
+ (eDVBFrontendParametersSatellite.RollOff_alpha_0_25, "0.25"),
+ (eDVBFrontendParametersSatellite.RollOff_alpha_0_20, "0.20")])
+ self.scan_sat.pilot = ConfigSelection(default = defaultSat.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown), choices = [
+ (eDVBFrontendParametersSatellite.Pilot_Off, _("off")),
+ (eDVBFrontendParametersSatellite.Pilot_On, _("on")),
+ (eDVBFrontendParametersSatellite.Pilot_Unknown, _("Auto"))])
# cable
self.scan_cab.frequency = ConfigInteger(default = defaultCab["frequency"], limits = (50, 999))
- self.scan_cab.inversion = ConfigSelection(default = defaultCab["inversion"], choices = [("off", _("off")), ("on", _("on")), ("auto", _("Auto"))])
- self.scan_cab.modulation = ConfigSelection(default = defaultCab["modulation"], choices = [("16qam", "16-QAM"), ("32qam", "32-QAM"), ("64qam", "64-QAM"), ("128qam", "128-QAM"), ("256qam", "256-QAM")])
- self.scan_cab.fec = ConfigSelection(default = defaultCab["fec"], choices = [("auto", _("Auto")), ("1_2", "1/2"), ("2_3", "2/3"), ("3_4", "3/4"), ("5_6", "5/6"), ("7_8", "7/8"), ("8_9", "8/9"), ("none", _("None"))])
+ self.scan_cab.inversion = ConfigSelection(default = defaultCab["inversion"], choices = [
+ (eDVBFrontendParametersCable.Inversion_Off, _("off")),
+ (eDVBFrontendParametersCable.Inversion_On, _("on")),
+ (eDVBFrontendParametersCable.Inversion_Unknown, _("Auto"))])
+ self.scan_cab.modulation = ConfigSelection(default = defaultCab["modulation"], choices = [
+ (eDVBFrontendParametersCable.Modulation_QAM16, "16-QAM"),
+ (eDVBFrontendParametersCable.Modulation_QAM32, "32-QAM"),
+ (eDVBFrontendParametersCable.Modulation_QAM64, "64-QAM"),
+ (eDVBFrontendParametersCable.Modulation_QAM128, "128-QAM"),
+ (eDVBFrontendParametersCable.Modulation_QAM256, "256-QAM")])
+ self.scan_cab.fec = ConfigSelection(default = defaultCab["fec"], choices = [
+ (eDVBFrontendParametersCable.FEC_Auto, _("Auto")),
+ (eDVBFrontendParametersCable.FEC_1_2, "1/2"),
+ (eDVBFrontendParametersCable.FEC_2_3, "2/3"),
+ (eDVBFrontendParametersCable.FEC_3_4, "3/4"),
+ (eDVBFrontendParametersCable.FEC_5_6, "5/6"),
+ (eDVBFrontendParametersCable.FEC_7_8, "7/8"),
+ (eDVBFrontendParametersCable.FEC_8_9, "8/9"),
+ (eDVBFrontendParametersCable.FEC_None, _("None"))])
self.scan_cab.symbolrate = ConfigInteger(default = defaultCab["symbolrate"], limits = (1, 99999))
# terrestial
self.scan_ter.frequency = ConfigInteger(default = 466000, limits = (50000, 999000))
- self.scan_ter.inversion = ConfigSelection(default = "auto", choices = [("off", _("off")), ("on", _("on")), ("auto", _("Auto"))])
+ self.scan_ter.inversion = ConfigSelection(default = defaultTer["inversion"], choices = [
+ (eDVBFrontendParametersTerrestrial.Inversion_Off, _("off")),
+ (eDVBFrontendParametersTerrestrial.Inversion_On, _("on")),
+ (eDVBFrontendParametersTerrestrial.Inversion_Unknown, _("Auto"))])
# WORKAROUND: we can't use BW-auto
- self.scan_ter.bandwidth = ConfigSelection(default = "8MHz", choices = [("8MHz", "8MHz"), ("7MHz", "7MHz"), ("6MHz", "6MHz")])
- #, ("auto", _("Auto"))))
- self.scan_ter.fechigh = ConfigSelection(default = "auto", choices = [("1_2", "1/2"), ("2_3", "2/3"), ("3_4", "3/4"), ("5_6", "5/6"), ("7_8", "7/8"), ("auto", _("Auto"))])
- self.scan_ter.feclow = ConfigSelection(default = "auto", choices = [("1_2", "1/2"), ("2_3", "2/3"), ("3_4", "3/4"), ("5_6", "5/6"), ("7_8", "7/8"), ("auto", _("Auto"))])
- self.scan_ter.modulation = ConfigSelection(default = "auto", choices = [("qpsk", "QPSK"), ("qam16", "QAM16"), ("qam64", "QAM64"), ("auto", _("Auto"))])
- self.scan_ter.transmission = ConfigSelection(default = "auto", choices = [("2k", "2K"), ("8k", "8K"), ("auto", _("Auto"))])
- self.scan_ter.guard = ConfigSelection(default = "auto", choices = [("1_32", "1/32"), ("1_16", "1/16"), ("1_8", "1/8"), ("1_4", "1/4"), ("auto", _("Auto"))])
- self.scan_ter.hierarchy = ConfigSelection(default = "auto", choices = [("none", _("None")), ("1", "1"), ("2", "2"), ("4", "4"), ("auto", _("Auto"))])
+ self.scan_ter.bandwidth = ConfigSelection(default = defaultTer["bandwidth"], choices = [
+ (eDVBFrontendParametersTerrestrial.Bandwidth_8MHz, "8MHz"),
+ (eDVBFrontendParametersTerrestrial.Bandwidth_7MHz, "7MHz"),
+ (eDVBFrontendParametersTerrestrial.Bandwidth_6MHz, "6MHz")])
+ #, (eDVBFrontendParametersTerrestrial.Bandwidth_Auto, _("Auto"))))
+ self.scan_ter.fechigh = ConfigSelection(default = defaultTer["fechigh"], choices = [
+ (eDVBFrontendParametersTerrestrial.FEC_1_2, "1/2"),
+ (eDVBFrontendParametersTerrestrial.FEC_2_3, "2/3"),
+ (eDVBFrontendParametersTerrestrial.FEC_3_4, "3/4"),
+ (eDVBFrontendParametersTerrestrial.FEC_5_6, "5/6"),
+ (eDVBFrontendParametersTerrestrial.FEC_7_8, "7/8"),
+ (eDVBFrontendParametersTerrestrial.FEC_Auto, _("Auto"))])
+ self.scan_ter.feclow = ConfigSelection(default = defaultTer["feclow"], choices = [
+ (eDVBFrontendParametersTerrestrial.FEC_1_2, "1/2"),
+ (eDVBFrontendParametersTerrestrial.FEC_2_3, "2/3"),
+ (eDVBFrontendParametersTerrestrial.FEC_3_4, "3/4"),
+ (eDVBFrontendParametersTerrestrial.FEC_5_6, "5/6"),
+ (eDVBFrontendParametersTerrestrial.FEC_7_8, "7/8"),
+ (eDVBFrontendParametersTerrestrial.FEC_Auto, _("Auto"))])
+ self.scan_ter.modulation = ConfigSelection(default = defaultTer["modulation"], choices = [
+ (eDVBFrontendParametersTerrestrial.Modulation_QPSK, "QPSK"),
+ (eDVBFrontendParametersTerrestrial.Modulation_QAM16, "QAM16"),
+ (eDVBFrontendParametersTerrestrial.Modulation_QAM64, "QAM64"),
+ (eDVBFrontendParametersTerrestrial.Modulation_Auto, _("Auto"))])
+ self.scan_ter.transmission = ConfigSelection(default = defaultTer["transmission_mode"], choices = [
+ (eDVBFrontendParametersTerrestrial.TransmissionMode_2k, "2K"),
+ (eDVBFrontendParametersTerrestrial.TransmissionMode_8k, "8K"),
+ (eDVBFrontendParametersTerrestrial.TransmissionMode_Auto, _("Auto"))])
+ self.scan_ter.guard = ConfigSelection(default = defaultTer["guard_interval"], choices = [
+ (eDVBFrontendParametersTerrestrial.GuardInterval_1_32, "1/32"),
+ (eDVBFrontendParametersTerrestrial.GuardInterval_1_16, "1/16"),
+ (eDVBFrontendParametersTerrestrial.GuardInterval_1_8, "1/8"),
+ (eDVBFrontendParametersTerrestrial.GuardInterval_1_4, "1/4"),
+ (eDVBFrontendParametersTerrestrial.GuardInterval_Auto, _("Auto"))])
+ self.scan_ter.hierarchy = ConfigSelection(default = defaultTer["hierarchy"], choices = [
+ (eDVBFrontendParametersTerrestrial.Hierarchy_None, _("None")),
+ (eDVBFrontendParametersTerrestrial.Hierarchy_1, "1"),
+ (eDVBFrontendParametersTerrestrial.Hierarchy_2, "2"),
+ (eDVBFrontendParametersTerrestrial.Hierarchy_4, "4"),
+ (eDVBFrontendParametersTerrestrial.Hierarchy_Auto, _("Auto"))])
self.scan_scansat = {}
for sat in nimmanager.satList:
@@ -577,7 +657,7 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport):
self.scan_satselection = []
for slot in nimmanager.nim_slots:
if slot.isCompatible("DVB-S"):
- self.scan_satselection.append(getConfigSatlist(int(defaultSat["orbpos"]), self.satList[slot.slot]))
+ self.scan_satselection.append(getConfigSatlist(defaultSat["orbpos"], self.satList[slot.slot]))
else:
self.scan_satselection.append(None)
@@ -594,36 +674,20 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport):
def updateStatus(self):
print "updatestatus"
- fecmap = { "auto": 0,
- "1_2": 1,
- "2_3": 2,
- "3_4": 3,
- "5_6": 4,
- "7_8": 5,
- "8_9": 6,
- "3_5": 7,
- "4_5": 8,
- "9_10": 9,
- "none": 15
- }
-
def addSatTransponder(self, tlist, frequency, symbol_rate, polarisation, fec, inversion, orbital_position, system, modulation, rolloff, pilot):
- print "Add Sat: frequ: " + str(frequency) + " symbol: " + str(symbol_rate) + " pol: " + str(polarisation) + " fec: " + str(self.fecmap[fec]) + " inversion: " + str(inversion) + " modulation: " + str(modulation) + " system: " + str(system) + " rolloff" + str(rolloff) + " pilot" + str(pilot)
+ print "Add Sat: frequ: " + str(frequency) + " symbol: " + str(symbol_rate) + " pol: " + str(polarisation) + " fec: " + str(fec) + " inversion: " + str(inversion) + " modulation: " + str(modulation) + " system: " + str(system) + " rolloff" + str(rolloff) + " pilot" + str(pilot)
print "orbpos: " + str(orbital_position)
parm = eDVBFrontendParametersSatellite()
- if modulation == 1:
- parm.modulation = 2 # eDVBFrontendParametersSatellite.Modulation.8PSK
- else:
- parm.modulation = 1 # eDVBFrontendParametersSatellite.Modulation.QPSK
+ parm.modulation = modulation
parm.system = system
parm.frequency = frequency * 1000
parm.symbol_rate = symbol_rate * 1000
parm.polarisation = polarisation
- parm.fec = self.fecmap[fec]
+ parm.fec = fec
parm.inversion = inversion
- parm.orbital_position = int(orbital_position)
- parm.rolloff = int(rolloff)
- parm.pilot = int(pilot)
+ parm.orbital_position = orbital_position
+ parm.rolloff = rolloff
+ parm.pilot = pilot
tlist.append(parm)
def addCabTransponder(self, tlist, frequency, symbol_rate, modulation, fec, inversion):
@@ -632,7 +696,7 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport):
parm.frequency = frequency * 1000
parm.symbol_rate = symbol_rate * 1000
parm.modulation = modulation
- parm.fec = self.fecmap[fec]
+ parm.fec = fec
parm.inversion = inversion
tlist.append(parm)
@@ -665,21 +729,21 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport):
# however, the satList itself could be empty. in that case, "index" is 0 (for "None").
if len(nimsats):
orbpos = nimsats[selsatidx][0]
- if self.scan_sat.system.value == "dvb-s":
+ if self.scan_sat.system.value == eDVBFrontendParametersSatellite.System_DVB_S:
fec = self.scan_sat.fec.value
else:
fec = self.scan_sat.fec_s2.value
print "add sat transponder"
self.addSatTransponder(tlist, self.scan_sat.frequency.value,
self.scan_sat.symbolrate.value,
- self.scan_sat.polarization.index,
+ self.scan_sat.polarization.value,
fec,
- self.scan_sat.inversion.index,
+ self.scan_sat.inversion.value,
orbpos,
- self.scan_sat.system.index,
- self.scan_sat.modulation.index,
- self.scan_sat.rolloff.index,
- self.scan_sat.pilot.index)
+ self.scan_sat.system.value,
+ self.scan_sat.modulation.value,
+ self.scan_sat.rolloff.value,
+ self.scan_sat.pilot.value)
removeAll = False
elif self.scan_type.value == "single_satellite":
sat = self.satList[index_to_scan][self.scan_satselection[index_to_scan].index]
@@ -693,12 +757,11 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport):
elif nim.isCompatible("DVB-C"):
if self.scan_typecable.value == "single_transponder":
- fec = self.scan_cab.fec.value
self.addCabTransponder(tlist, self.scan_cab.frequency.value,
self.scan_cab.symbolrate.value,
- self.scan_cab.modulation.index + 1,
- fec,
- self.scan_cab.inversion.index)
+ self.scan_cab.modulation.value,
+ self.scan_cab.fec.value,
+ self.scan_cab.inversion.value)
removeAll = False
elif self.scan_typecable.value == "complete":
if config.Nims[index_to_scan].cable.scan_type.value == "provider":
@@ -710,14 +773,14 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport):
if self.scan_typeterrestrial.value == "single_transponder":
self.addTerTransponder(tlist,
self.scan_ter.frequency.value * 1000,
- inversion = self.scan_ter.inversion.index,
- bandwidth = self.scan_ter.bandwidth.index,
- fechigh = self.scan_ter.fechigh.index,
- feclow = self.scan_ter.feclow.index,
- modulation = self.scan_ter.modulation.index,
- transmission = self.scan_ter.transmission.index,
- guard = self.scan_ter.guard.index,
- hierarchy = self.scan_ter.hierarchy.index)
+ inversion = self.scan_ter.inversion.value,
+ bandwidth = self.scan_ter.bandwidth.value,
+ fechigh = self.scan_ter.fechigh.value,
+ feclow = self.scan_ter.feclow.value,
+ modulation = self.scan_ter.modulation.value,
+ transmission = self.scan_ter.transmission.value,
+ guard = self.scan_ter.guard.value,
+ hierarchy = self.scan_ter.hierarchy.value)
removeAll = False
elif self.scan_typeterrestrial.value == "complete":
getInitialTerrestrialTransponderList(tlist, nimmanager.getTerrestrialDescription(index_to_scan))
diff --git a/lib/python/Screens/ServiceInfo.py b/lib/python/Screens/ServiceInfo.py
index 4606f883..e07b3208 100644
--- a/lib/python/Screens/ServiceInfo.py
+++ b/lib/python/Screens/ServiceInfo.py
@@ -5,6 +5,7 @@ from Components.ActionMap import ActionMap
from Components.Label import Label
from ServiceReference import ServiceReference
from enigma import eListboxPythonMultiContent, eListbox, gFont, iServiceInformation, eServiceCenter
+from Tools.Transponder import ConvertToHumanReadable
RT_HALIGN_LEFT = 0
@@ -131,27 +132,28 @@ class ServiceInfo(Screen):
self.fillList(Labels)
else:
if self.transponder_info:
- conv = { "type" : _("Transponder Type"),
+ tp_info = ConvertToHumanReadable(self.transponder_info)
+ conv = { "tuner_type" : _("Transponder Type"),
"system" : _("System"),
"modulation" : _("Modulation"),
- "orbital position" : _("Orbital Position"),
+ "orbital_position" : _("Orbital Position"),
"frequency" : _("Frequency"),
- "symbolrate" : _("Symbolrate"),
+ "symbol_rate" : _("Symbolrate"),
"bandwidth" : _("Bandwidth"),
"polarization" : _("Polarization"),
"inversion" : _("Inversion"),
"pilot" : _("Pilot"),
- "roll off" : _("Rolloff"),
- "fec inner" : _("FEC"),
- "code rate lp" : _("Coderate LP"),
- "code rate hp" : _("Coderate HP"),
+ "rolloff" : _("Rolloff"),
+ "fec_inner" : _("FEC"),
+ "code_rate_lp" : _("Coderate LP"),
+ "code_rate_hp" : _("Coderate HP"),
"constellation" : _("Constellation"),
- "transmission mode": _("Transmission Mode"),
- "guard interval" : _("Guard Interval"),
- "hierarchy" : _("Hierarchy Information") }
+ "transmission_mode": _("Transmission Mode"),
+ "guard_interval" : _("Guard Interval"),
+ "hierarchy_information": _("Hierarchy Information") }
Labels = [ ]
- for i in self.transponder_info.keys():
- Labels.append( (conv[i], self.transponder_info[i], TYPE_TEXT) )
+ for i in tp_info.keys():
+ Labels.append( (conv[i], tp_info[i], TYPE_VALUE_DEC) )
self.fillList(Labels)
def pids(self):
@@ -180,9 +182,10 @@ class ServiceInfo(Screen):
if self.type == TYPE_SERVICE_INFO:
self.showFrontendData(False)
- def getFEData(self, frontendData):
- if frontendData and len(frontendData):
- if frontendData["tuner_type"] == "DVB-S":
+ def getFEData(self, frontendDataOrg):
+ if frontendDataOrg and len(frontendDataOrg):
+ frontendData = ConvertToHumanReadable(frontendDataOrg)
+ if frontendDataOrg["tuner_type"] == "DVB-S":
return (("NIM", ['A', 'B', 'C', 'D'][frontendData["tuner_number"]], TYPE_TEXT),
("Type", frontendData["system"], TYPE_TEXT),
("Modulation", frontendData["modulation"], TYPE_TEXT),
@@ -194,7 +197,7 @@ class ServiceInfo(Screen):
("FEC inner", frontendData["fec_inner"], TYPE_TEXT),
("Pilot", frontendData.get("pilot", None), TYPE_TEXT),
("Rolloff", frontendData.get("rolloff", None), TYPE_TEXT))
- elif frontendData["tuner_type"] == "DVB-C":
+ elif frontendDataOrg["tuner_type"] == "DVB-C":
return (("NIM", ['A', 'B', 'C', 'D'][frontendData["tuner_number"]], TYPE_TEXT),
("Type", frontendData["tuner_type"], TYPE_TEXT),
("Frequency", frontendData["frequency"], TYPE_VALUE_DEC),
@@ -202,7 +205,7 @@ class ServiceInfo(Screen):
("Modulation", frontendData["modulation"], TYPE_TEXT),
("Inversion", frontendData["inversion"], TYPE_TEXT),
("FEC inner", frontendData["fec_inner"], TYPE_TEXT))
- elif frontendData["tuner_type"] == "DVB-T":
+ elif frontendDataOrg["tuner_type"] == "DVB-T":
return (("NIM", ['A', 'B', 'C', 'D'][frontendData["tuner_number"]], TYPE_TEXT),
("Type", frontendData["tuner_type"], TYPE_TEXT),
("Frequency", frontendData["frequency"], TYPE_VALUE_DEC),
diff --git a/lib/python/Screens/Setup.py b/lib/python/Screens/Setup.py
index 3ff0b76e..1d035b8a 100644
--- a/lib/python/Screens/Setup.py
+++ b/lib/python/Screens/Setup.py
@@ -6,8 +6,7 @@ from Components.ConfigList import ConfigListScreen
from Components.Label import Label
from Components.Pixmap import Pixmap
-import xml.dom.minidom
-from Tools import XMLTools
+import xml.etree.cElementTree
# FIXME: use resolveFile!
# read the setupmenu
@@ -17,9 +16,16 @@ try:
except:
# if not found in the current path, we use the global datadir-path
setupfile = file('/usr/share/enigma2/setup.xml', 'r')
-setupdom = xml.dom.minidom.parseString(setupfile.read())
+setupdom = xml.etree.cElementTree.parse(setupfile)
setupfile.close()
+class SetupError(Exception):
+ def __init__(self, message):
+ self.message = message
+
+ def __str__(self):
+ return self.message
+
class SetupSummary(Screen):
skin = """
<screen position="6,0" size="120,64">
@@ -63,16 +69,12 @@ class Setup(ConfigListScreen, Screen):
self["config"].setList(list)
def refill(self, list):
- xmldata = setupdom.childNodes[0]
- entries = xmldata.childNodes
- for x in entries: #walk through the actual nodelist
- if x.nodeType != xml.dom.minidom.Element.nodeType:
+ xmldata = setupdom.getroot()
+ for x in xmldata.findall("setup"):
+ if x.get("key") != self.setup:
continue
- elif x.tagName == 'setup':
- if x.getAttribute("key") != self.setup:
- continue
- self.addItems(list, x.childNodes);
- self.setup_title = x.getAttribute("title").encode("UTF-8")
+ self.addItems(list, x);
+ self.setup_title = x.get("title", "").encode("UTF-8")
def __init__(self, session, setup):
Screen.__init__(self, session)
@@ -118,12 +120,10 @@ class Setup(ConfigListScreen, Screen):
def createSummary(self):
return SetupSummary
- def addItems(self, list, childNode):
- for x in childNode:
- if x.nodeType != xml.dom.minidom.Element.nodeType:
- continue
- elif x.tagName == 'item':
- item_level = int(x.getAttribute("level") or "0")
+ def addItems(self, list, parentNode):
+ for x in parentNode:
+ if x.tag == 'item':
+ item_level = int(x.get("level", 0))
if not self.levelChanged in config.usage.setup_level.notifiers:
config.usage.setup_level.notifiers.append(self.levelChanged)
@@ -132,12 +132,12 @@ class Setup(ConfigListScreen, Screen):
if item_level > config.usage.setup_level.index:
continue
- requires = x.getAttribute("requires")
+ requires = x.get("requires")
if requires and not SystemInfo.get(requires, False):
continue;
- item_text = _(x.getAttribute("text").encode("UTF-8") or "??")
- b = eval(XMLTools.mergeText(x.childNodes));
+ item_text = _(x.get("text", "??").encode("UTF-8"))
+ b = eval(x.text or "");
if b == "":
continue
#add to configlist
@@ -148,8 +148,8 @@ class Setup(ConfigListScreen, Screen):
list.append( (item_text, item) )
def getSetupTitle(id):
- xmldata = setupdom.childNodes[0].childNodes
- for x in XMLTools.elementsWithTag(xmldata, "setup"):
- if x.getAttribute("key") == id:
- return x.getAttribute("title").encode("UTF-8")
- raise "unknown setup id '%s'!" % repr(id)
+ xmldata = setupdom.getroot()
+ for x in xmldata.findall("setup"):
+ if x.get("key") == id:
+ return x.get("title", "").encode("UTF-8")
+ raise SetupError("unknown setup id '%s'!" % repr(id))
diff --git a/lib/python/Screens/Standby.py b/lib/python/Screens/Standby.py
index 4c3a1720..d09f28af 100644
--- a/lib/python/Screens/Standby.py
+++ b/lib/python/Screens/Standby.py
@@ -2,6 +2,7 @@ from Screen import Screen
from Components.ActionMap import ActionMap
from Components.config import config
from Components.AVSwitch import AVSwitch
+from Components.SystemInfo import SystemInfo
from enigma import eDVBVolumecontrol
inStandby = None
@@ -49,7 +50,10 @@ class Standby(Screen):
#stop actual played dvb-service
self.session.nav.stopService()
#set input to vcr scart
- self.avswitch.setInput("SCART")
+ if SystemInfo["ScartSwitch"]:
+ self.avswitch.setInput("SCART")
+ else:
+ self.avswitch.setInput("AUX")
#set lcd brightness to standby value
config.lcd.standby.apply()
self.onShow.append(self.__onShow)
diff --git a/lib/python/Screens/TextBox.py b/lib/python/Screens/TextBox.py
new file mode 100644
index 00000000..44b8a3cf
--- /dev/null
+++ b/lib/python/Screens/TextBox.py
@@ -0,0 +1,26 @@
+from Screens.Screen import Screen
+
+from Components.ActionMap import ActionMap
+from Components.Sources.StaticText import StaticText
+from Components.ScrollLabel import ScrollLabel
+
+class TextBox(Screen):
+ def __init__(self, session, text = ""):
+ Screen.__init__(self, session)
+
+ self.text = text
+ self["text"] = ScrollLabel(self.text)
+
+ self["actions"] = ActionMap(["OkCancelActions", "DirectionActions"],
+ {
+ "cancel": self.cancel,
+ "ok": self.ok,
+ "up": self["text"].pageUp,
+ "down": self["text"].pageDown,
+ }, -1)
+
+ def ok(self):
+ self.close()
+
+ def cancel(self):
+ self.close()
diff --git a/lib/python/Screens/TimerEdit.py b/lib/python/Screens/TimerEdit.py
index aae345db..bb2d3c76 100644
--- a/lib/python/Screens/TimerEdit.py
+++ b/lib/python/Screens/TimerEdit.py
@@ -199,9 +199,11 @@ class TimerEditList(Screen):
self.updateState()
def removeTimerQuestion(self):
- if not self["timerlist"].getCurrent():
+ cur = self["timerlist"].getCurrent()
+ if not cur:
return
- self.session.openWithCallback(self.removeTimer, MessageBox, _("Really delete this timer?"))
+
+ self.session.openWithCallback(self.removeTimer, MessageBox, _("Do you really want to delete %s?") % (cur.name))
def removeTimer(self, result):
if not result:
@@ -212,18 +214,6 @@ class TimerEditList(Screen):
timer = cur
timer.afterEvent = AFTEREVENT.NONE
self.session.nav.RecordTimer.removeEntry(timer)
- if not timer.dontSave:
- for timer in self.session.nav.RecordTimer.timer_list:
- if timer.dontSave and timer.autoincrease:
- timer.end = timer.begin + (3600 * 24 * 356 * 1)
- self.session.nav.RecordTimer.timeChanged(timer)
- timersanitycheck = TimerSanityCheck(self.session.nav.RecordTimer.timer_list,timer)
- if not timersanitycheck.check():
- tsc_list = timersanitycheck.getSimulTimerList()
- if len(tsc_list) > 1:
- timer.end = tsc_list[1].begin - 30
- self.session.nav.RecordTimer.timeChanged(timer)
-
self.refill()
self.updateState()
@@ -259,6 +249,7 @@ class TimerEditList(Screen):
def addTimer(self, timer):
self.session.openWithCallback(self.finishedAdd, TimerEntry, timer)
+
def finishedEdit(self, answer):
print "finished edit"
@@ -267,19 +258,25 @@ class TimerEditList(Screen):
print "Edited timer"
entry = answer[1]
timersanitycheck = TimerSanityCheck(self.session.nav.RecordTimer.timer_list, entry)
+ success = False
if not timersanitycheck.check():
simulTimerList = timersanitycheck.getSimulTimerList()
- if (len(simulTimerList) == 2) and (simulTimerList[1].dontSave) and (simulTimerList[1].autoincrease):
- simulTimerList[1].end = entry.begin - 30
- self.session.nav.RecordTimer.timeChanged(simulTimerList[1])
- self.session.nav.RecordTimer.timeChanged(entry)
- else:
- print "Sanity check failed"
- self.session.openWithCallback(self.finishedEdit, TimerSanityConflict, timersanitycheck.getSimulTimerList())
+ if simulTimerList is not None:
+ for x in simulTimerList:
+ if x.setAutoincreaseEnd(entry):
+ self.session.nav.RecordTimer.timeChanged(x)
+ if not timersanitycheck.check():
+ simulTimerList = timersanitycheck.getSimulTimerList()
+ if simulTimerList is not None:
+ self.session.openWithCallback(self.finishedEdit, TimerSanityConflict, timersanitycheck.getSimulTimerList())
+ else:
+ success = True
else:
+ succsess = True
+ if success:
print "Sanity check passed"
- if not timersanitycheck.doubleCheck():
- self.session.nav.RecordTimer.timeChanged(entry)
+ self.session.nav.RecordTimer.timeChanged(entry)
+
self.fillTimerList()
self.updateState()
else:
@@ -291,11 +288,11 @@ class TimerEditList(Screen):
entry = answer[1]
simulTimerList = self.session.nav.RecordTimer.record(entry)
if simulTimerList is not None:
- if (len(simulTimerList) == 2) and (simulTimerList[1].dontSave) and (simulTimerList[1].autoincrease):
- simulTimerList[1].end = entry.begin - 30
- self.session.nav.RecordTimer.timeChanged(simulTimerList[1])
- self.session.nav.RecordTimer.record(entry)
- else:
+ for x in simulTimerList:
+ if x.setAutoincreaseEnd(entry):
+ self.session.nav.RecordTimer.timeChanged(x)
+ simulTimerList = self.session.nav.RecordTimer.record(entry)
+ if simulTimerList is not None:
self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
self.fillTimerList()
self.updateState()
@@ -333,6 +330,8 @@ class TimerSanityConflict(Screen):
self.list.append((_("Conflicting timer") + " " + str(count), x))
self.list2.append((timer[count], False))
count += 1
+ if count == 1:
+ self.list.append((_("Channel not in services list")))
self["list"] = MenuList(self.list)
self["timer2"] = TimerList(self.list2)
@@ -409,7 +408,7 @@ class TimerSanityConflict(Screen):
self["actions"].actions.update({"green":self.toggleTimer1})
self["key_green"].setText(_("Enable"))
self.key_green_choice = self.ENABLE
- elif self.timer[0].isRunning() and not timer[0].repeated and self.key_green_choice != self.EMPTY:
+ elif self.timer[0].isRunning() and not self.timer[0].repeated and self.key_green_choice != self.EMPTY:
self.removeAction("green")
self["key_green"].setText(" ")
self.key_green_choice = self.EMPTY
@@ -429,7 +428,7 @@ class TimerSanityConflict(Screen):
self["actions"].actions.update({"blue":self.toggleTimer2})
self["key_blue"].setText(_("Enable"))
self.key_blue_choice = self.ENABLE
- elif self.timer[x].isRunning() and not timer[x].repeated and self.key_blue_choice != self.EMPTY:
+ elif self.timer[x].isRunning() and not self.timer[x].repeated and self.key_blue_choice != self.EMPTY:
self.removeAction("blue")
self["key_blue"].setText(" ")
self.key_blue_choice = self.EMPTY
diff --git a/lib/python/Screens/TimerEntry.py b/lib/python/Screens/TimerEntry.py
index 1774061d..0544eff1 100644
--- a/lib/python/Screens/TimerEntry.py
+++ b/lib/python/Screens/TimerEntry.py
@@ -32,11 +32,15 @@ class TimerEntry(Screen, ConfigListScreen):
self.createConfig()
- self["actions"] = NumberActionMap(["SetupActions"],
+ self["actions"] = NumberActionMap(["SetupActions", "GlobalActions", "PiPSetupActions"],
{
"ok": self.keySelect,
"save": self.keyGo,
"cancel": self.keyCancel,
+ "volumeUp": self.incrementStart,
+ "volumeDown": self.decrementStart,
+ "size+": self.incrementEnd,
+ "size-": self.decrementEnd
}, -2)
self.list = []
@@ -46,7 +50,12 @@ class TimerEntry(Screen, ConfigListScreen):
def createConfig(self):
justplay = self.timer.justplay
- afterevent = { AFTEREVENT.NONE: "nothing", AFTEREVENT.DEEPSTANDBY: "deepstandby", AFTEREVENT.STANDBY: "standby"}[self.timer.afterEvent]
+ afterevent = {
+ AFTEREVENT.NONE: "nothing",
+ AFTEREVENT.DEEPSTANDBY: "deepstandby",
+ AFTEREVENT.STANDBY: "standby",
+ AFTEREVENT.AUTO: "auto"
+ }[self.timer.afterEvent]
weekday_table = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
@@ -84,7 +93,7 @@ class TimerEntry(Screen, ConfigListScreen):
day[weekday] = 1
self.timerentry_justplay = ConfigSelection(choices = [("zap", _("zap")), ("record", _("record"))], default = {0: "record", 1: "zap"}[justplay])
- self.timerentry_afterevent = ConfigSelection(choices = [("nothing", _("do nothing")), ("standby", _("go to standby")), ("deepstandby", _("go to deep standby"))], default = afterevent)
+ self.timerentry_afterevent = ConfigSelection(choices = [("nothing", _("do nothing")), ("standby", _("go to standby")), ("deepstandby", _("go to deep standby")), ("auto", _("auto"))], default = afterevent)
self.timerentry_type = ConfigSelection(choices = [("once",_("once")), ("repeated", _("repeated"))], default = type)
self.timerentry_name = ConfigText(default = self.timer.name, visible_width = 50, fixed_size = False)
self.timerentry_description = ConfigText(default = self.timer.description, visible_width = 50, fixed_size = False)
@@ -155,9 +164,14 @@ class TimerEntry(Screen, ConfigListScreen):
self.entryDate = getConfigListEntry(_("Date"), self.timerentry_date)
if self.timerentry_type.value == "once":
self.list.append(self.entryDate)
- self.list.append(getConfigListEntry(_("StartTime"), self.timerentry_starttime))
+
+ self.entryStartTime = getConfigListEntry(_("StartTime"), self.timerentry_starttime)
+ self.list.append(self.entryStartTime)
if self.timerentry_justplay.value != "zap":
- self.list.append(getConfigListEntry(_("EndTime"), self.timerentry_endtime))
+ self.entryEndTime = getConfigListEntry(_("EndTime"), self.timerentry_endtime)
+ self.list.append(self.entryEndTime)
+ else:
+ self.entryEndTime = None
self.channelEntry = getConfigListEntry(_("Channel"), self.timerentry_service)
self.list.append(self.channelEntry)
@@ -250,7 +264,12 @@ class TimerEntry(Screen, ConfigListScreen):
self.timer.description = self.timerentry_description.value
self.timer.justplay = self.timerentry_justplay.value == "zap"
self.timer.resetRepeated()
- self.timer.afterEvent = {"nothing": AFTEREVENT.NONE, "deepstandby": AFTEREVENT.DEEPSTANDBY, "standby": AFTEREVENT.STANDBY}[self.timerentry_afterevent.value]
+ self.timer.afterEvent = {
+ "nothing": AFTEREVENT.NONE,
+ "deepstandby": AFTEREVENT.DEEPSTANDBY,
+ "standby": AFTEREVENT.STANDBY,
+ "auto": AFTEREVENT.AUTO
+ }[self.timerentry_afterevent.value]
self.timer.service_ref = self.timerentry_service_ref
self.timer.tags = self.timerentry_tags
@@ -309,6 +328,24 @@ class TimerEntry(Screen, ConfigListScreen):
self.saveTimer()
self.close((True, self.timer))
+ def incrementStart(self):
+ self.timerentry_starttime.increment()
+ self["config"].invalidate(self.entryStartTime)
+
+ def decrementStart(self):
+ self.timerentry_starttime.decrement()
+ self["config"].invalidate(self.entryStartTime)
+
+ def incrementEnd(self):
+ if self.entryEndTime is not None:
+ self.timerentry_endtime.increment()
+ self["config"].invalidate(self.entryEndTime)
+
+ def decrementEnd(self):
+ if self.entryEndTime is not None:
+ self.timerentry_endtime.decrement()
+ self["config"].invalidate(self.entryEndTime)
+
def subserviceSelected(self, service):
if not service is None:
self.timer.service_ref = ServiceReference(service[1])
diff --git a/lib/python/Screens/Wizard.py b/lib/python/Screens/Wizard.py
index 23d6253a..feba8ac2 100644..100755
--- a/lib/python/Screens/Wizard.py
+++ b/lib/python/Screens/Wizard.py
@@ -3,7 +3,8 @@ from Screen import Screen
import string
from Screens.HelpMenu import HelpableScreen
-from Components.config import config, KEY_LEFT, KEY_RIGHT, KEY_DELETE, KEY_BACKSPACE
+from Components.config import config, KEY_LEFT, KEY_RIGHT, KEY_HOME, KEY_END, KEY_0, KEY_DELETE, KEY_BACKSPACE, KEY_OK, KEY_TOGGLEOW, KEY_ASCII, KEY_TIMEOUT, KEY_NUMBERS
+
from Components.Label import Label
from Components.Slider import Slider
from Components.ActionMap import NumberActionMap
@@ -215,8 +216,9 @@ class Wizard(Screen):
self.disableKeys = False
- self["actions"] = NumberActionMap(["WizardActions", "NumberActions", "ColorActions", "SetupActions"],
+ self["actions"] = NumberActionMap(["WizardActions", "NumberActions", "ColorActions", "SetupActions", "InputAsciiActions"],
{
+ "gotAsciiCode": self.keyGotAscii,
"ok": self.ok,
"back": self.back,
"left": self.left,
@@ -368,6 +370,10 @@ class Wizard(Screen):
def keyNumberGlobal(self, number):
if (self.wizard[self.currStep]["config"]["screen"] != None):
self.configInstance.keyNumberGlobal(number)
+
+ def keyGotAscii(self):
+ if (self.wizard[self.currStep]["config"]["screen"] != None):
+ self["config"].handleKey(KEY_ASCII)
def left(self):
self.resetCounter()
diff --git a/lib/python/Tools/Directories.py b/lib/python/Tools/Directories.py
index 2b60924c..0d238b30 100644
--- a/lib/python/Tools/Directories.py
+++ b/lib/python/Tools/Directories.py
@@ -126,6 +126,9 @@ def resolveFilename(scope, base = "", path_prefix = None):
def pathExists(path):
return os_path.exists(path)
+def isMount(path):
+ return os_path.ismount(path)
+
def createDir(path, makeParents = False):
try:
if makeParents:
diff --git a/lib/python/Tools/LoadPixmap.py b/lib/python/Tools/LoadPixmap.py
index 53e04e54..fff414ad 100644
--- a/lib/python/Tools/LoadPixmap.py
+++ b/lib/python/Tools/LoadPixmap.py
@@ -14,7 +14,7 @@ def LoadPixmap(path, desktop = None, cached = False):
alpha = loadPNG(path + "a.png")
ptr = loadJPG(path + "rgb.jpg", alpha)
else:
- raise "neither .png nor .jpg, please fix file extension"
+ raise Exception("neither .png nor .jpg, please fix file extension")
if ptr and desktop:
desktop.makeCompatiblePixmap(ptr)
diff --git a/lib/python/Tools/Makefile.am b/lib/python/Tools/Makefile.am
index 609f3bab..5617cb66 100644
--- a/lib/python/Tools/Makefile.am
+++ b/lib/python/Tools/Makefile.am
@@ -4,4 +4,4 @@ install_PYTHON = \
FuzzyDate.py XMLTools.py Directories.py NumericalTextInput.py \
KeyBindings.py BoundFunction.py ISO639.py Notifications.py __init__.py \
RedirectOutput.py DreamboxHardware.py Import.py Event.py CList.py \
- LoadPixmap.py Profile.py HardwareInfo.py
+ LoadPixmap.py Profile.py HardwareInfo.py Transponder.py
diff --git a/lib/python/Tools/NumericalTextInput.py b/lib/python/Tools/NumericalTextInput.py
index 5954c9c3..c5576405 100644
--- a/lib/python/Tools/NumericalTextInput.py
+++ b/lib/python/Tools/NumericalTextInput.py
@@ -1,44 +1,65 @@
-# -*- coding: iso-8859-1 -*-
+# -*- coding: utf-8 -*-
from enigma import eTimer
from Components.Language import language
class NumericalTextInput:
- def __init__(self, nextFunc=None, handleTimeout = True):
+ def __init__(self, nextFunc=None, handleTimeout = True, search = False):
self.mapping = []
self.lang = language.getLanguage()
self.useableChars=None
self.nextFunction=nextFunc
-
+
+ if handleTimeout:
+ self.timer = eTimer()
+ self.timer.callback.append(self.timeout)
+ else:
+ self.timer = None
+ self.lastKey = -1
+ self.pos = -1
+
+ if search:
+ self.mapping.append (u"%_0") # 0
+ self.mapping.append (u" 1") # 1
+ self.mapping.append (u"abc2") # 2
+ self.mapping.append (u"def3") # 3
+ self.mapping.append (u"ghi4") # 4
+ self.mapping.append (u"jkl5") # 5
+ self.mapping.append (u"mno6") # 6
+ self.mapping.append (u"pqrs7") # 7
+ self.mapping.append (u"tuv8") # 8
+ self.mapping.append (u"wxyz9") # 9
+ return
+
if self.lang == 'de_DE':
self.mapping.append (u".,?'+\"0-()@/:_$!") # 0
self.mapping.append (u" 1") # 1
- self.mapping.append (u"aäbc2AÄBC") # 2
+ self.mapping.append (u"aäbc2AÄBC") # 2
self.mapping.append (u"def3DEF") # 3
self.mapping.append (u"ghi4GHI") # 4
self.mapping.append (u"jkl5JKL") # 5
- self.mapping.append (u"mnoö6MNOÖ") # 6
- self.mapping.append (u"pqrsß7PQRSß") # 7
- self.mapping.append (u"tuüv8TUÜV") # 8
+ self.mapping.append (u"mnoö6MNOÖ") # 6
+ self.mapping.append (u"pqrsß7PQRSß") # 7
+ self.mapping.append (u"tuüv8TUÜV") # 8
self.mapping.append (u"wxyz9WXYZ") # 9
elif self.lang == 'es_ES':
self.mapping.append (u".,?'+\"0-()@/:_$!") # 0
self.mapping.append (u" 1") # 1
- self.mapping.append (u"abcáà2ABCÁÀ") # 2
- self.mapping.append (u"deéèf3DEFÉÈ") # 3
- self.mapping.append (u"ghiíì4GHIÍÌ") # 4
+ self.mapping.append (u"abcáà2ABCÃÀ") # 2
+ self.mapping.append (u"deéèf3DEFÉÈ") # 3
+ self.mapping.append (u"ghiíì4GHIÃÃŒ") # 4
self.mapping.append (u"jkl5JKL") # 5
- self.mapping.append (u"mnñoóò6MNÑOÓÒ") # 6
+ self.mapping.append (u"mnñoóò6MNÑOÓÒ") # 6
self.mapping.append (u"pqrs7PQRS") # 7
- self.mapping.append (u"tuvúù8TUVÚÙ") # 8
+ self.mapping.append (u"tuvúù8TUVÚÙ") # 8
self.mapping.append (u"wxyz9WXYZ") # 9
if self.lang in ['sv_SE', 'fi_FI']:
self.mapping.append (u".,?'+\"0-()@/:_$!") # 0
self.mapping.append (u" 1") # 1
- self.mapping.append (u"abcåä2ABCÅÄ") # 2
- self.mapping.append (u"defé3DEFÉ") # 3
+ self.mapping.append (u"abcåä2ABCÅÄ") # 2
+ self.mapping.append (u"defé3DEFÉ") # 3
self.mapping.append (u"ghi4GHI") # 4
self.mapping.append (u"jkl5JKL") # 5
- self.mapping.append (u"mnoö6MNOÖ") # 6
+ self.mapping.append (u"mnoö6MNOÖ") # 6
self.mapping.append (u"pqrs7PQRS") # 7
self.mapping.append (u"tuv8TUV") # 8
self.mapping.append (u"wxyz9WXYZ") # 9
@@ -54,14 +75,6 @@ class NumericalTextInput:
self.mapping.append (u"tuv8TUV") # 8
self.mapping.append (u"wxyz9WXYZ") # 9
- if handleTimeout:
- self.timer = eTimer()
- self.timer.callback.append(self.timeout)
- else:
- self.timer = None
- self.lastKey = -1
- self.pos = -1
-
def setUseableChars(self, useable):
self.useableChars = useable
diff --git a/lib/python/Tools/Transponder.py b/lib/python/Tools/Transponder.py
new file mode 100644
index 00000000..f37603c5
--- /dev/null
+++ b/lib/python/Tools/Transponder.py
@@ -0,0 +1,117 @@
+from enigma import eDVBFrontendParametersSatellite, eDVBFrontendParametersCable, eDVBFrontendParametersTerrestrial
+
+def ConvertToHumanReadable(tp):
+ ret = { }
+ type = tp.get("tuner_type", "None")
+ if type == "DVB-S":
+ ret["tuner_type"] = _("Satellite")
+ ret["inversion"] = {
+ eDVBFrontendParametersSatellite.Inversion_Unknown : _("Auto"),
+ eDVBFrontendParametersSatellite.Inversion_On : _("On"),
+ eDVBFrontendParametersSatellite.Inversion_Off : _("Off")}[tp["inversion"]]
+ ret["fec_inner"] = {
+ eDVBFrontendParametersSatellite.FEC_None : _("None"),
+ eDVBFrontendParametersSatellite.FEC_Auto : _("Auto"),
+ eDVBFrontendParametersSatellite.FEC_1_2 : "1/2",
+ eDVBFrontendParametersSatellite.FEC_2_3 : "2/3",
+ eDVBFrontendParametersSatellite.FEC_3_4 : "3/4",
+ eDVBFrontendParametersSatellite.FEC_5_6 : "5/6",
+ eDVBFrontendParametersSatellite.FEC_7_8 : "7/8",
+ eDVBFrontendParametersSatellite.FEC_3_5 : "3/5",
+ eDVBFrontendParametersSatellite.FEC_4_5 : "4/5",
+ eDVBFrontendParametersSatellite.FEC_8_9 : "8/9",
+ eDVBFrontendParametersSatellite.FEC_9_10 : "9/10"}[tp["fec_inner"]]
+ ret["modulation"] = {
+ eDVBFrontendParametersSatellite.Modulation_Auto : _("Auto"),
+ eDVBFrontendParametersSatellite.Modulation_QPSK : "QPSK",
+ eDVBFrontendParametersSatellite.Modulation_QAM16 : "QAM16",
+ eDVBFrontendParametersSatellite.Modulation_8PSK : "8PSK"}[tp["modulation"]]
+ ret["polarization"] = {
+ eDVBFrontendParametersSatellite.Polarisation_Horizontal : _("Horizontal"),
+ eDVBFrontendParametersSatellite.Polarisation_Vertical : _("Vertical"),
+ eDVBFrontendParametersSatellite.Polarisation_CircularLeft : _("Circular left"),
+ eDVBFrontendParametersSatellite.Polarisation_CircularRight : _("Circular right")}[tp["polarization"]]
+ ret["system"] = {
+ eDVBFrontendParametersSatellite.System_DVB_S : "DVB-S",
+ eDVBFrontendParametersSatellite.System_DVB_S2 : "DVB-S2"}[tp["system"]]
+ if ret["system"] == "DVB-S2":
+ ret["rolloff"] = {
+ eDVBFrontendParametersSatellite.RollOff_alpha_0_35 : "0.35",
+ eDVBFrontendParametersSatellite.RollOff_alpha_0_25 : "0.25",
+ eDVBFrontendParametersSatellite.RollOff_alpha_0_20 : "0.20"}[tp["rolloff"]]
+ ret["pilot"] = {
+ eDVBFrontendParametersSatellite.Pilot_Unknown : _("Auto"),
+ eDVBFrontendParametersSatellite.Pilot_On : _("On"),
+ eDVBFrontendParametersSatellite.Pilot_Off : _("Off")}[tp["pilot"]]
+ elif type == "DVB-C":
+ ret["tuner_type"] = _("Cable")
+ ret["modulation"] = {
+ eDVBFrontendParametersCable.Modulation_Auto: _("Auto"),
+ eDVBFrontendParametersCable.Modulation_QAM16 : "QAM16",
+ eDVBFrontendParametersCable.Modulation_QAM32 : "QAM32",
+ eDVBFrontendParametersCable.Modulation_QAM64 : "QAM64",
+ eDVBFrontendParametersCable.Modulation_QAM128 : "QAM128",
+ eDVBFrontendParametersCable.Modulation_QAM256 : "QAM256"}[tp["modulation"]]
+ ret["inversion"] = {
+ eDVBFrontendParametersCable.Inversion_Unknown : _("Auto"),
+ eDVBFrontendParametersCable.Inversion_On : _("On"),
+ eDVBFrontendParametersCable.Inversion_Off : _("Off")}[tp["inversion"]]
+ ret["fec_inner"] = {
+ eDVBFrontendParametersCable.FEC_None : _("None"),
+ eDVBFrontendParametersCable.FEC_Auto : _("Auto"),
+ eDVBFrontendParametersCable.FEC_1_2 : "1/2",
+ eDVBFrontendParametersCable.FEC_2_3 : "2/3",
+ eDVBFrontendParametersCable.FEC_3_4 : "3/4",
+ eDVBFrontendParametersCable.FEC_5_6 : "5/6",
+ eDVBFrontendParametersCable.FEC_7_8 : "7/8",
+ eDVBFrontendParametersCable.FEC_8_9 : "8/9"}[tp["fec_inner"]]
+ elif type == "DVB-T":
+ ret["tuner_type"] = _("Terrestrial")
+ ret["bandwidth"] = {
+ eDVBFrontendParametersTerrestrial.Bandwidth_Auto : _("Auto"),
+ eDVBFrontendParametersTerrestrial.Bandwidth_8MHz : "8 MHz",
+ eDVBFrontendParametersTerrestrial.Bandwidth_7MHz : "7 MHz",
+ eDVBFrontendParametersTerrestrial.Bandwidth_6MHz : "6 MHz"}[tp["bandwidth"]]
+ ret["code_rate_lp"] = {
+ eDVBFrontendParametersTerrestrial.FEC_Auto : _("Auto"),
+ eDVBFrontendParametersTerrestrial.FEC_1_2 : "1/2",
+ eDVBFrontendParametersTerrestrial.FEC_2_3 : "2/3",
+ eDVBFrontendParametersTerrestrial.FEC_3_4 : "3/4",
+ eDVBFrontendParametersTerrestrial.FEC_5_6 : "5/6",
+ eDVBFrontendParametersTerrestrial.FEC_7_8 : "7/8"}[tp["code_rate_lp"]]
+ ret["code_rate_hp"] = {
+ eDVBFrontendParametersTerrestrial.FEC_Auto : _("Auto"),
+ eDVBFrontendParametersTerrestrial.FEC_1_2 : "1/2",
+ eDVBFrontendParametersTerrestrial.FEC_2_3 : "2/3",
+ eDVBFrontendParametersTerrestrial.FEC_3_4 : "3/4",
+ eDVBFrontendParametersTerrestrial.FEC_5_6 : "5/6",
+ eDVBFrontendParametersTerrestrial.FEC_7_8 : "7/8"}[tp["code_rate_hp"]]
+ ret["constellation"] = {
+ eDVBFrontendParametersTerrestrial.Modulation_Auto : _("Auto"),
+ eDVBFrontendParametersTerrestrial.Modulation_QPSK : "QPSK",
+ eDVBFrontendParametersTerrestrial.Modulation_QAM16 : "QAM16",
+ eDVBFrontendParametersTerrestrial.Modulation_QAM64 : "QAM64"}[tp["constellation"]]
+ ret["transmission_mode"] = {
+ eDVBFrontendParametersTerrestrial.TransmissionMode_Auto : _("Auto"),
+ eDVBFrontendParametersTerrestrial.TransmissionMode_2k : "2k",
+ eDVBFrontendParametersTerrestrial.TransmissionMode_8k : "8k"}[tp["transmission_mode"]]
+ ret["guard_interval"] = {
+ eDVBFrontendParametersTerrestrial.GuardInterval_Auto : _("Auto"),
+ eDVBFrontendParametersTerrestrial.GuardInterval_1_32 : "1/32",
+ eDVBFrontendParametersTerrestrial.GuardInterval_1_16 : "1/16",
+ eDVBFrontendParametersTerrestrial.GuardInterval_1_8 : "1/8",
+ eDVBFrontendParametersTerrestrial.GuardInterval_1_4 : "1/4"}[tp["guard_interval"]]
+ ret["hierarchy_information"] = {
+ eDVBFrontendParametersTerrestrial.Hierarchy_Auto : _("Auto"),
+ eDVBFrontendParametersTerrestrial.Hierarchy_None : _("None"),
+ eDVBFrontendParametersTerrestrial.Hierarchy_1 : "1",
+ eDVBFrontendParametersTerrestrial.Hierarchy_2 : "2",
+ eDVBFrontendParametersTerrestrial.Hierarchy_4 : "4"}[tp["hierarchy_information"]]
+ ret["inversion"] = {
+ eDVBFrontendParametersTerrestrial.Inversion_Unknown : _("Auto"),
+ eDVBFrontendParametersTerrestrial.Inversion_On : _("On"),
+ eDVBFrontendParametersTerrestrial.Inversion_Off : _("Off")}[tp["inversion"]]
+ for x in tp.keys():
+ if not ret.has_key(x):
+ ret[x] = tp[x]
+ return ret
diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i
index 7de05d2b..bdf1b144 100644
--- a/lib/python/enigma_python.i
+++ b/lib/python/enigma_python.i
@@ -141,6 +141,7 @@ typedef long time_t;
%include <lib/service/service.h>
// TODO: embed these...
+%immutable ePicLoad::PictureData;
%immutable eButton::selected;
%immutable eInput::changed;
%immutable eComponentScan::statusChanged;
@@ -287,7 +288,7 @@ PyObject *getBestPlayableServiceReference(const eServiceReference &bouquet_ref,
PyObject *getBestPlayableServiceReference(const eServiceReference &bouquet_ref, const eServiceReference &ignore, bool simulate=false)
{
eStaticServiceDVBBouquetInformation info;
- if (info.isPlayable(bouquet_ref, ignore))
+ if (info.isPlayable(bouquet_ref, ignore, simulate))
return New_eServiceReference(info.getPlayableService());
Py_INCREF(Py_None);
return Py_None;
diff --git a/lib/python/python.cpp b/lib/python/python.cpp
index 50b66103..c5faeed4 100644
--- a/lib/python/python.cpp
+++ b/lib/python/python.cpp
@@ -5,7 +5,7 @@
extern "C" void init_enigma();
extern "C" void eBaseInit(void);
extern "C" void eConsoleInit(void);
-extern void bsodFatal();
+extern void bsodFatal(const char *component);
#define SKIP_PART2
#include <lib/python/python.h>
@@ -44,7 +44,7 @@ ePyObject::operator PyObject*()
if (m_file)
eDebug("last modified in file %s line %d from %d to %d",
m_file, m_line, m_from, m_to);
- bsodFatal();
+ bsodFatal("enigma2, refcnt");
}
return 0;
}
@@ -57,7 +57,7 @@ void ePyObject::incref(const char *file, int line)
if (m_file)
eDebug("last modified in file %s line %d from %d to %d",
m_file, m_line, m_from, m_to);
- bsodFatal();
+ bsodFatal("enigma2, refcnt");
}
if (m_erased || m_ob->ob_refcnt <= 0)
{
@@ -66,7 +66,7 @@ void ePyObject::incref(const char *file, int line)
if (m_file)
eDebug("last modified in file %s line %d from %d to %d",
m_file, m_line, m_from, m_to);
- bsodFatal();
+ bsodFatal("enigma2, refcnt");
}
if (m_ob->ob_refcnt == 0x7FFFFFFF)
{
@@ -75,7 +75,7 @@ void ePyObject::incref(const char *file, int line)
if (m_file)
eDebug("last modified in file %s line %d from %d to %d",
m_file, m_line, m_from, m_to);
- bsodFatal();
+ bsodFatal("enigma2, refcnt");
}
m_file = file;
m_line = line;
@@ -92,7 +92,7 @@ void ePyObject::decref(const char *file, int line)
if (m_file)
eDebug("last modified in file %s line %d from %d to %d",
m_file, m_line, m_from, m_to);
- bsodFatal();
+ bsodFatal("enigma2, refcnt");
}
if (m_erased || m_ob->ob_refcnt <= 0)
{
@@ -101,7 +101,7 @@ void ePyObject::decref(const char *file, int line)
if (m_file)
eDebug("last modified in file %s line %d from %d to %d",
m_file, m_line, m_from, m_to);
- bsodFatal();
+ bsodFatal("enigma2, refcnt");
}
m_file = file;
m_line = line;
@@ -207,7 +207,7 @@ int ePython::call(ePyObject pFunc, ePyObject pArgs)
eDebug("(PyObject_CallObject(%s,%s) failed)", PyString_AS_STRING(FuncStr), PyString_AS_STRING(ArgStr));
Py_DECREF(FuncStr);
Py_DECREF(ArgStr);
- bsodFatal();
+ bsodFatal(0);
}
}
return res;
diff --git a/lib/python/python.h b/lib/python/python.h
index f56d49bb..52ec6c1e 100644
--- a/lib/python/python.h
+++ b/lib/python/python.h
@@ -24,6 +24,7 @@ public:
#ifdef PYTHON_REFCOUNT_DEBUG
inline ePyObject(PyObject *ob, const char *file, int line);
#endif
+ inline ePyObject(PyVarObject *ob);
inline ePyObject(PyDictObject *ob);
inline ePyObject(PyTupleObject *ob);
inline ePyObject(PyListObject *ob);
@@ -32,11 +33,13 @@ public:
operator bool() { return !!m_ob; }
ePyObject &operator=(const ePyObject &);
ePyObject &operator=(PyObject *);
+ ePyObject &operator=(PyVarObject *ob) { return operator=((PyObject*)ob); }
ePyObject &operator=(PyDictObject *ob) { return operator=((PyObject*)ob); }
ePyObject &operator=(PyTupleObject *ob) { return operator=((PyObject*)ob); }
ePyObject &operator=(PyListObject *ob) { return operator=((PyObject*)ob); }
ePyObject &operator=(PyStringObject *ob) { return operator=((PyObject*)ob); }
operator PyObject*();
+ operator PyVarObject*() { return (PyVarObject*)operator PyVarObject*(); }
operator PyTupleObject*() { return (PyTupleObject*)operator PyObject*(); }
operator PyListObject*() { return (PyListObject*)operator PyObject*(); }
operator PyStringObject*() { return (PyStringObject*)operator PyObject*(); }
@@ -84,6 +87,14 @@ inline ePyObject::ePyObject(PyObject *ob, const char* file, int line)
}
#endif
+inline ePyObject::ePyObject(PyVarObject *ob)
+ :m_ob((PyObject*)ob)
+#ifdef PYTHON_REFCOUNT_DEBUG
+ ,m_file(0), m_line(0), m_from(0), m_to(0), m_erased(false)
+#endif
+{
+}
+
inline ePyObject::ePyObject(PyDictObject *ob)
:m_ob((PyObject*)ob)
#ifdef PYTHON_REFCOUNT_DEBUG
diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp
index bee0e322..6cd7c625 100644
--- a/lib/service/listboxservice.cpp
+++ b/lib/service/listboxservice.cpp
@@ -584,7 +584,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const
case celServiceInfo:
{
ePtr<eServiceEvent> evt;
- if ( service_info && !service_info->getEvent(*m_cursor, evt) )
+ if ( isPlayable && service_info && !service_info->getEvent(*m_cursor, evt) )
{
std::string name = evt->getEventName();
if (!name.length())
diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp
index af3ab206..33cd865e 100644
--- a/lib/service/servicedvb.cpp
+++ b/lib/service/servicedvb.cpp
@@ -96,217 +96,50 @@ int eStaticServiceDVBInformation::isPlayable(const eServiceReference &ref, const
return false;
}
-static void PutToDict(ePyObject &dict, const char*key, long value)
-{
- ePyObject item = PyString_FromFormat("%d", value);
- if (item)
- {
- if (PyDict_SetItemString(dict, key, item))
- eDebug("put %s to dict failed", key);
- Py_DECREF(item);
- }
- else
- eDebug("could not create PyObject for %s", key);
-}
-
-extern void PutToDict(ePyObject &dict, const char*key, const char *value);
+extern void PutToDict(ePyObject &dict, const char*key, long value); // defined in dvb/frontend.cpp
+extern void PutToDict(ePyObject &dict, const char*key, ePyObject item); // defined in dvb/frontend.cpp
+extern void PutToDict(ePyObject &dict, const char*key, const char *value); // defined in dvb/frontend.cpp
void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
{
- const char *tmp=0;
- PutToDict(dict, "type", "Satellite");
+ PutToDict(dict, "tuner_type", "DVB-S");
PutToDict(dict, "frequency", feparm.frequency);
- PutToDict(dict, "symbolrate", feparm.symbol_rate);
- PutToDict(dict, "orbital position", feparm.orbital_position);
- switch (feparm.inversion)
- {
- case eDVBFrontendParametersSatellite::Inversion::On: tmp="ON"; break;
- case eDVBFrontendParametersSatellite::Inversion::Off: tmp="OFF"; break;
- default:
- case eDVBFrontendParametersSatellite::Inversion::Unknown: tmp="AUTO"; break;
- }
- PutToDict(dict, "inversion", tmp);
- switch (feparm.fec)
- {
- case eDVBFrontendParametersSatellite::FEC::fNone: tmp="NONE"; break;
- case eDVBFrontendParametersSatellite::FEC::f1_2: tmp="1/2"; break;
- case eDVBFrontendParametersSatellite::FEC::f2_3: tmp="2/3"; break;
- case eDVBFrontendParametersSatellite::FEC::f3_4: tmp="3/4"; break;
- case eDVBFrontendParametersSatellite::FEC::f5_6: tmp="5/6"; break;
- case eDVBFrontendParametersSatellite::FEC::f7_8: tmp="7/8"; break;
- case eDVBFrontendParametersSatellite::FEC::f3_5: tmp="3/5"; break;
- case eDVBFrontendParametersSatellite::FEC::f4_5: tmp="4/5"; break;
- case eDVBFrontendParametersSatellite::FEC::f8_9: tmp="8/9"; break;
- case eDVBFrontendParametersSatellite::FEC::f9_10: tmp="9/10"; break;
- default:
- case eDVBFrontendParametersSatellite::FEC::fAuto: tmp="AUTO"; break;
- }
- PutToDict(dict, "fec inner", tmp);
- switch (feparm.modulation)
- {
- case eDVBFrontendParametersSatellite::Modulation::Auto: tmp="AUTO"; break;
- case eDVBFrontendParametersSatellite::Modulation::QPSK: tmp="QPSK"; break;
- case eDVBFrontendParametersSatellite::Modulation::M8PSK: tmp="8PSK"; break;
- case eDVBFrontendParametersSatellite::Modulation::QAM_16: tmp="QAM16"; break;
- }
- PutToDict(dict, "modulation", tmp);
- switch(feparm.polarisation)
+ PutToDict(dict, "symbol_rate", feparm.symbol_rate);
+ PutToDict(dict, "orbital_position", feparm.orbital_position);
+ PutToDict(dict, "inversion", feparm.inversion);
+ PutToDict(dict, "fec_inner", feparm.fec);
+ PutToDict(dict, "modulation", feparm.modulation);
+ PutToDict(dict, "polarization", feparm.polarisation);
+ if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
{
- case eDVBFrontendParametersSatellite::Polarisation::Horizontal: tmp="HORIZONTAL"; break;
- case eDVBFrontendParametersSatellite::Polarisation::Vertical: tmp="VERTICAL"; break;
- case eDVBFrontendParametersSatellite::Polarisation::CircularLeft: tmp="CIRCULAR LEFT"; break;
- default:
- case eDVBFrontendParametersSatellite::Polarisation::CircularRight: tmp="CIRCULAR RIGHT"; break;
- }
- PutToDict(dict, "polarization", tmp);
- switch(feparm.system)
- {
- default:
- case eDVBFrontendParametersSatellite::System::DVB_S: tmp="DVB-S"; break;
- case eDVBFrontendParametersSatellite::System::DVB_S2:
- switch(feparm.rolloff)
- {
- default:
- case eDVBFrontendParametersSatellite::RollOff::alpha_0_35: tmp="0.35"; break;
- case eDVBFrontendParametersSatellite::RollOff::alpha_0_25: tmp="0.25"; break;
- case eDVBFrontendParametersSatellite::RollOff::alpha_0_20: tmp="0.20"; break;
- }
- PutToDict(dict, "roll off", tmp);
- switch(feparm.pilot)
- {
- case eDVBFrontendParametersSatellite::Pilot::On: tmp="ON"; break;
- case eDVBFrontendParametersSatellite::Pilot::Off: tmp="OFF"; break;
- default:
- case eDVBFrontendParametersSatellite::Pilot::Unknown: tmp="AUTO"; break;
- }
- PutToDict(dict, "pilot", tmp);
- tmp="DVB-S2";
- break;
+ PutToDict(dict, "rolloff", feparm.rolloff);
+ PutToDict(dict, "pilot", feparm.pilot);
}
- PutToDict(dict, "system", tmp);
+ PutToDict(dict, "system", feparm.system);
}
void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
{
- PutToDict(dict, "type", "Terrestrial");
+ PutToDict(dict, "tuner_type", "DVB-T");
PutToDict(dict, "frequency", feparm.frequency);
- const char *tmp=0;
- switch (feparm.bandwidth)
- {
- case eDVBFrontendParametersTerrestrial::Bandwidth::Bw8MHz: tmp="8 MHz"; break;
- case eDVBFrontendParametersTerrestrial::Bandwidth::Bw7MHz: tmp="7 MHz"; break;
- case eDVBFrontendParametersTerrestrial::Bandwidth::Bw6MHz: tmp="6 MHz"; break;
- default:
- case eDVBFrontendParametersTerrestrial::Bandwidth::BwAuto: tmp="AUTO"; break;
- }
- PutToDict(dict, "bandwidth", tmp);
- switch (feparm.code_rate_LP)
- {
- case eDVBFrontendParametersTerrestrial::FEC::f1_2: tmp="1/2"; break;
- case eDVBFrontendParametersTerrestrial::FEC::f2_3: tmp="2/3"; break;
- case eDVBFrontendParametersTerrestrial::FEC::f3_4: tmp="3/4"; break;
- case eDVBFrontendParametersTerrestrial::FEC::f5_6: tmp="5/6"; break;
- case eDVBFrontendParametersTerrestrial::FEC::f7_8: tmp="7/8"; break;
- default:
- case eDVBFrontendParametersTerrestrial::FEC::fAuto: tmp="AUTO"; break;
- }
- PutToDict(dict, "code rate lp", tmp);
- switch (feparm.code_rate_HP)
- {
- case eDVBFrontendParametersTerrestrial::FEC::f1_2: tmp="1/2"; break;
- case eDVBFrontendParametersTerrestrial::FEC::f2_3: tmp="2/3"; break;
- case eDVBFrontendParametersTerrestrial::FEC::f3_4: tmp="3/4"; break;
- case eDVBFrontendParametersTerrestrial::FEC::f5_6: tmp="5/6"; break;
- case eDVBFrontendParametersTerrestrial::FEC::f7_8: tmp="7/8"; break;
- default:
- case eDVBFrontendParametersTerrestrial::FEC::fAuto: tmp="AUTO"; break;
- }
- PutToDict(dict, "code rate hp", tmp);
- switch (feparm.modulation)
- {
- case eDVBFrontendParametersTerrestrial::Modulation::QPSK: tmp="QPSK"; break;
- case eDVBFrontendParametersTerrestrial::Modulation::QAM16: tmp="QAM16"; break;
- case eDVBFrontendParametersTerrestrial::Modulation::QAM64: tmp="QAM64"; break;
- default:
- case eDVBFrontendParametersTerrestrial::Modulation::Auto: tmp="AUTO"; break;
- }
- PutToDict(dict, "constellation", tmp);
- switch (feparm.transmission_mode)
- {
- case eDVBFrontendParametersTerrestrial::TransmissionMode::TM2k: tmp="2k"; break;
- case eDVBFrontendParametersTerrestrial::TransmissionMode::TM8k: tmp="8k"; break;
- default:
- case eDVBFrontendParametersTerrestrial::TransmissionMode::TMAuto: tmp="AUTO"; break;
- }
- PutToDict(dict, "transmission mode", tmp);
- switch (feparm.guard_interval)
- {
- case eDVBFrontendParametersTerrestrial::GuardInterval::GI_1_32: tmp="1/32"; break;
- case eDVBFrontendParametersTerrestrial::GuardInterval::GI_1_16: tmp="1/16"; break;
- case eDVBFrontendParametersTerrestrial::GuardInterval::GI_1_8: tmp="1/8"; break;
- case eDVBFrontendParametersTerrestrial::GuardInterval::GI_1_4: tmp="1/4"; break;
- default:
- case eDVBFrontendParametersTerrestrial::GuardInterval::GI_Auto: tmp="AUTO"; break;
- }
- PutToDict(dict, "guard interval", tmp);
- switch (feparm.hierarchy)
- {
- case eDVBFrontendParametersTerrestrial::Hierarchy::HNone: tmp="NONE"; break;
- case eDVBFrontendParametersTerrestrial::Hierarchy::H1: tmp="1"; break;
- case eDVBFrontendParametersTerrestrial::Hierarchy::H2: tmp="2"; break;
- case eDVBFrontendParametersTerrestrial::Hierarchy::H4: tmp="4"; break;
- default:
- case eDVBFrontendParametersTerrestrial::Hierarchy::HAuto: tmp="AUTO"; break;
- }
- PutToDict(dict, "hierarchy", tmp);
- switch (feparm.inversion)
- {
- case eDVBFrontendParametersSatellite::Inversion::On: tmp="ON"; break;
- case eDVBFrontendParametersSatellite::Inversion::Off: tmp="OFF"; break;
- default:
- case eDVBFrontendParametersSatellite::Inversion::Unknown: tmp="AUTO"; break;
- }
- PutToDict(dict, "inversion", tmp);
+ PutToDict(dict, "bandwidth", feparm.bandwidth);
+ PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
+ PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
+ PutToDict(dict, "constellation", feparm.modulation);
+ PutToDict(dict, "transmission_mode", feparm.transmission_mode);
+ PutToDict(dict, "guard_interval", feparm.guard_interval);
+ PutToDict(dict, "hierarchy_information", feparm.hierarchy);
+ PutToDict(dict, "inversion", feparm.inversion);
}
void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
{
- const char *tmp=0;
- PutToDict(dict, "type", "Cable");
+ PutToDict(dict, "tuner_type", "DVB-C");
PutToDict(dict, "frequency", feparm.frequency);
- PutToDict(dict, "symbolrate", feparm.symbol_rate);
- switch (feparm.modulation)
- {
- case eDVBFrontendParametersCable::Modulation::QAM16: tmp="QAM16"; break;
- case eDVBFrontendParametersCable::Modulation::QAM32: tmp="QAM32"; break;
- case eDVBFrontendParametersCable::Modulation::QAM64: tmp="QAM64"; break;
- case eDVBFrontendParametersCable::Modulation::QAM128: tmp="QAM128"; break;
- case eDVBFrontendParametersCable::Modulation::QAM256: tmp="QAM256"; break;
- default:
- case eDVBFrontendParametersCable::Modulation::Auto: tmp="AUTO"; break;
- }
- PutToDict(dict, "modulation", tmp);
- switch (feparm.inversion)
- {
- case eDVBFrontendParametersCable::Inversion::On: tmp="ON"; break;
- case eDVBFrontendParametersCable::Inversion::Off: tmp="OFF"; break;
- default:
- case eDVBFrontendParametersCable::Inversion::Unknown: tmp="AUTO"; break;
- }
- PutToDict(dict, "inversion", tmp);
- switch (feparm.fec_inner)
- {
- case eDVBFrontendParametersCable::FEC::fNone: tmp="NONE"; break;
- case eDVBFrontendParametersCable::FEC::f1_2: tmp="1/2"; break;
- case eDVBFrontendParametersCable::FEC::f2_3: tmp="2/3"; break;
- case eDVBFrontendParametersCable::FEC::f3_4: tmp="3/4"; break;
- case eDVBFrontendParametersCable::FEC::f5_6: tmp="5/6"; break;
- case eDVBFrontendParametersCable::FEC::f7_8: tmp="7/8"; break;
- case eDVBFrontendParametersCable::FEC::f8_9: tmp="8/9"; break;
- default:
- case eDVBFrontendParametersCable::FEC::fAuto: tmp="AUTO"; break;
- }
- PutToDict(dict, "fec inner", tmp);
+ PutToDict(dict, "symbol_rate", feparm.symbol_rate);
+ PutToDict(dict, "modulation", feparm.modulation);
+ PutToDict(dict, "inversion", feparm.inversion);
+ PutToDict(dict, "fec_inner", feparm.fec_inner);
}
PyObject *eStaticServiceDVBInformation::getInfoObject(const eServiceReference &r, int what)
@@ -534,14 +367,25 @@ int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref)
eDVBTSTools tstools;
+ struct stat s;
+ stat(ref.path.c_str(), &s);
+
if (tstools.openFile(ref.path.c_str()))
return 0;
+ /* check if cached data is still valid */
+ if (m_parser.m_data_ok && (s.st_size == m_parser.m_filesize) && (m_parser.m_length))
+ return m_parser.m_length / 90000;
+
+ /* otherwise, re-calc length and update meta file */
pts_t len;
if (tstools.calcLen(len))
return 0;
- return len / 90000;
+ m_parser.m_length = len;
+ m_parser.m_filesize = s.st_size;
+ m_parser.updateMeta(ref.path);
+ return m_parser.m_length / 90000;
}
int eStaticServiceDVBPVRInformation::getInfo(const eServiceReference &ref, int w)
@@ -1042,7 +886,6 @@ RESULT eServiceFactoryDVB::lookupService(ePtr<eDVBService> &service, const eServ
eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service):
m_reference(ref), m_dvb_service(service), m_have_video_pid(0), m_is_paused(0)
{
- memset(&m_videoEventData, 0, sizeof(struct iTSMPEGDecoder::videoEvent));
m_is_primary = 1;
m_is_pvr = !m_reference.path.empty();
@@ -1589,20 +1432,6 @@ RESULT eDVBServicePlay::getEvent(ePtr<eServiceEvent> &evt, int nownext)
return m_event_handler.getEvent(evt, nownext);
}
-static int readMpegProc(char *str, int decoder)
-{
- int val = -1;
- char tmp[64];
- sprintf(tmp, "/proc/stb/vmpeg/%d/%s", decoder, str);
- FILE *f = fopen(tmp, "r");
- if (f)
- {
- fscanf(f, "%x", &val);
- fclose(f);
- }
- return val;
-}
-
int eDVBServicePlay::getInfo(int w)
{
eDVBServicePMTHandler::program program;
@@ -1619,44 +1448,30 @@ int eDVBServicePlay::getInfo(int w)
switch (w)
{
-#if HAVE_DVB_API_VERSION >= 3
case sVideoHeight:
- if (m_videoEventData.type == iTSMPEGDecoder::videoEvent::eventSizeChanged)
- return m_videoEventData.height;
- else
- return readMpegProc("yres", !m_is_primary);
+ if (m_decoder)
+ return m_decoder->getVideoHeight();
+ break;
case sVideoWidth:
- if (m_videoEventData.type == iTSMPEGDecoder::videoEvent::eventSizeChanged)
- return m_videoEventData.width;
- else
- return readMpegProc("xres", !m_is_primary);
+ if (m_decoder)
+ return m_decoder->getVideoWidth();
+ break;
case sFrameRate:
- if (m_videoEventData.type == iTSMPEGDecoder::videoEvent::eventFrameRateChanged)
- return m_videoEventData.framerate;
- else
- return readMpegProc("framerate", !m_is_primary);
+ if (m_decoder)
+ return m_decoder->getVideoFrameRate();
+ break;
case sProgressive:
- if (m_videoEventData.type == iTSMPEGDecoder::videoEvent::eventProgressiveChanged)
- return m_videoEventData.progressive;
- return readMpegProc("progressive", !m_is_primary);
-#else
-#warning "FIXMEE implement sFrameRate, sProgressive, sVideoHeight, sVideoWidth for old DVB API"
-#endif
+ if (m_decoder)
+ return m_decoder->getVideoProgressive();
+ break;
case sAspect:
{
- int val;
-#if HAVE_DVB_API_VERSION >= 3
- if (m_videoEventData.type == iTSMPEGDecoder::videoEvent::eventSizeChanged)
- return m_videoEventData.aspect == VIDEO_FORMAT_4_3 ? 1 : 3;
- else if ((val=readMpegProc("aspect", !m_is_primary)) != -1)
- return val;
- else
-#else
-#warning "FIXMEE implement sAspect for old DVB API"
-#endif
+ int aspect = -1;
+ if (m_decoder)
+ aspect = m_decoder->getVideoAspect();
if (no_program_info)
- return -1;
- else if (!program.videoStreams.empty() && program.videoStreams[0].component_tag != -1)
+ break;
+ else if (aspect == -1 && !program.videoStreams.empty() && program.videoStreams[0].component_tag != -1)
{
ePtr<eServiceEvent> evt;
if (!m_event_handler.getEvent(evt, 0))
@@ -1693,7 +1508,9 @@ int eDVBServicePlay::getInfo(int w)
}
}
}
- return -1;
+ else
+ return aspect;
+ break;
}
case sIsCrypted: if (no_program_info) return -1; return program.isCrypted();
case sVideoPID: if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
@@ -1710,8 +1527,9 @@ int eDVBServicePlay::getInfo(int w)
case sServiceref: return resIsString;
case sDVBState: return m_tune_state;
default:
- return -1;
+ break;
}
+ return -1;
}
std::string eDVBServicePlay::getInfoString(int w)
@@ -1798,6 +1616,8 @@ RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int
info.m_description = "AC3";
else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAAC)
info.m_description = "AAC";
+ else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAACHE)
+ info.m_description = "AAC-HE";
else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS)
info.m_description = "DTS";
else
@@ -2056,19 +1876,8 @@ PyObject *eDVBServiceBase::getTransponderData(bool original)
eDVBFrontendParametersSatellite osat;
if (!feparm->getDVBS(osat))
{
- void PutToDict(ePyObject &, const char*, long);
- void PutToDict(ePyObject &, const char*, const char*);
PutToDict(ret, "orbital_position", osat.orbital_position);
- const char *tmp = "UNKNOWN";
- switch(osat.polarisation)
- {
- case eDVBFrontendParametersSatellite::Polarisation::Horizontal: tmp="HORIZONTAL"; break;
- case eDVBFrontendParametersSatellite::Polarisation::Vertical: tmp="VERTICAL"; break;
- case eDVBFrontendParametersSatellite::Polarisation::CircularLeft: tmp="CIRCULAR_LEFT"; break;
- case eDVBFrontendParametersSatellite::Polarisation::CircularRight: tmp="CIRCULAR_RIGHT"; break;
- default:break;
- }
- PutToDict(ret, "polarization", tmp);
+ PutToDict(ret, "polarization", osat.polarisation);
}
}
}
@@ -2213,8 +2022,8 @@ PyObject *eDVBServicePlay::getCutList()
for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
{
ePyObject tuple = PyTuple_New(2);
- PyTuple_SetItem(tuple, 0, PyLong_FromLongLong(i->where));
- PyTuple_SetItem(tuple, 1, PyInt_FromLong(i->what));
+ PyTuple_SET_ITEM(tuple, 0, PyLong_FromLongLong(i->where));
+ PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(i->what));
PyList_Append(list, tuple);
Py_DECREF(tuple);
}
@@ -3014,7 +2823,6 @@ void eDVBServicePlay::setPCMDelay(int delay)
void eDVBServicePlay::video_event(struct iTSMPEGDecoder::videoEvent event)
{
- memcpy(&m_videoEventData, &event, sizeof(event));
switch(event.type) {
case iTSMPEGDecoder::videoEvent::eventSizeChanged:
m_event((iPlayableService*)this, evVideoSizeChanged);
@@ -3041,18 +2849,16 @@ PyObject *eDVBServicePlay::getStreamingData()
eDVBServicePMTHandler::program program;
if (m_service_handler.getProgramInfo(program))
{
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
- PyObject *r = program.createPythonObject();
+ ePyObject r = program.createPythonObject();
ePtr<iDVBDemux> demux;
if (!m_service_handler.getDataDemux(demux))
{
uint8_t demux_id;
- demux->getCADemuxID(demux_id);
-
- PyDict_SetItemString(r, "demux", PyInt_FromLong(demux_id));
+ if (!demux->getCADemuxID(demux_id))
+ PutToDict(r, "demux", demux_id);
}
return r;
diff --git a/lib/service/servicedvb.h b/lib/service/servicedvb.h
index c19e1ed5..43e4690f 100644
--- a/lib/service/servicedvb.h
+++ b/lib/service/servicedvb.h
@@ -283,7 +283,6 @@ private:
ePtr<eConnection> m_video_event_connection;
void video_event(struct iTSMPEGDecoder::videoEvent);
- struct iTSMPEGDecoder::videoEvent m_videoEventData;
};
class eStaticServiceDVBBouquetInformation: public iStaticServiceInformation
diff --git a/lib/service/servicedvbrecord.cpp b/lib/service/servicedvbrecord.cpp
index 89d022cc..c2767e8d 100644
--- a/lib/service/servicedvbrecord.cpp
+++ b/lib/service/servicedvbrecord.cpp
@@ -3,11 +3,20 @@
#include <lib/dvb/epgcache.h>
#include <fcntl.h>
+ /* for cutlist */
+#include <byteswap.h>
+#include <netinet/in.h>
+
+#ifndef BYTE_ORDER
+#error no byte order defined!
+#endif
+
DEFINE_REF(eDVBServiceRecord);
eDVBServiceRecord::eDVBServiceRecord(const eServiceReferenceDVB &ref): m_ref(ref)
{
CONNECT(m_service_handler.serviceEvent, eDVBServiceRecord::serviceEvent);
+ CONNECT(m_event_handler.m_eit_changed, eDVBServiceRecord::gotNewEvent);
m_state = stateIdle;
m_want_record = 0;
m_tuned = 0;
@@ -15,6 +24,7 @@ eDVBServiceRecord::eDVBServiceRecord(const eServiceReferenceDVB &ref): m_ref(ref
m_error = 0;
m_streaming = 0;
m_simulate = false;
+ m_last_event_id = -1;
}
void eDVBServiceRecord::serviceEvent(int event)
@@ -26,6 +36,22 @@ void eDVBServiceRecord::serviceEvent(int event)
{
eDebug("tuned..");
m_tuned = 1;
+
+ /* start feeding EIT updates */
+ ePtr<iDVBDemux> m_demux;
+ if (!m_service_handler.getDataDemux(m_demux))
+ {
+ eServiceReferenceDVB &ref = (eServiceReferenceDVB&) m_ref;
+ int sid = ref.getParentServiceID().get();
+ if (!sid)
+ sid = ref.getServiceID().get();
+ if ( ref.getParentTransportStreamID().get() &&
+ ref.getParentTransportStreamID() != ref.getTransportStreamID() )
+ m_event_handler.startOther(m_demux, sid);
+ else
+ m_event_handler.start(m_demux, sid);
+ }
+
if (m_state == stateRecording && m_want_record)
doRecord();
m_event((iRecordableService*)this, evTunedIn);
@@ -145,6 +171,9 @@ RESULT eDVBServiceRecord::stop()
::close(m_target_fd);
m_target_fd = -1;
}
+
+ saveCutlist();
+
m_state = statePrepared;
} else if (!m_simulate)
eDebug("(was not recording)");
@@ -363,23 +392,23 @@ RESULT eDVBServiceRecord::stream(ePtr<iStreamableService> &ptr)
return 0;
}
+extern void PutToDict(ePyObject &dict, const char*key, long val); // defined in dvb/frontend.cpp
+
PyObject *eDVBServiceRecord::getStreamingData()
{
eDVBServicePMTHandler::program program;
if (!m_tuned || m_service_handler.getProgramInfo(program))
{
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
- PyObject *r = program.createPythonObject();
+ ePyObject r = program.createPythonObject();
ePtr<iDVBDemux> demux;
if (!m_service_handler.getDataDemux(demux))
{
uint8_t demux_id;
- demux->getCADemuxID(demux_id);
-
- PyDict_SetItemString(r, "demux", PyInt_FromLong(demux_id));
+ if (!demux->getCADemuxID(demux_id))
+ PutToDict(r, "demux", demux_id);
}
return r;
@@ -398,3 +427,77 @@ void eDVBServiceRecord::recordEvent(int event)
eDebug("unhandled record event %d", event);
}
}
+
+void eDVBServiceRecord::gotNewEvent()
+{
+ ePtr<eServiceEvent> event_now;
+ m_event_handler.getEvent(event_now, 0);
+
+ if (!event_now)
+ return;
+
+ int event_id = event_now->getEventId();
+
+ pts_t p;
+
+ if (m_record)
+ {
+ if (m_record->getCurrentPCR(p))
+ eDebug("getting PCR failed!");
+ else
+ {
+ static int i;
+ m_event_timestamps[/* event_id*/ ++i] = p;
+ eDebug("pcr of eit change: %llx", p);
+ }
+ }
+
+ if (event_id != m_last_event_id)
+ eDebug("[eDVBServiceRecord] now running: %s (%d seconds)", event_now->getEventName().c_str(), event_now->getDuration());
+
+ m_last_event_id = event_id;
+}
+
+void eDVBServiceRecord::saveCutlist()
+{
+ /* XXX: dupe of eDVBServicePlay::saveCuesheet, refactor plz */
+ std::string filename = m_filename + ".cuts";
+
+ eDVBTSTools tstools;
+
+ if (tstools.openFile(m_filename.c_str()))
+ {
+ eDebug("[eDVBServiceRecord] saving cutlist failed because tstools failed");
+ return;
+ }
+
+ FILE *f = fopen(filename.c_str(), "wb");
+
+ if (f)
+ {
+ unsigned long long where;
+ int what;
+
+ for (std::map<int,pts_t>::iterator i(m_event_timestamps.begin()); i != m_event_timestamps.end(); ++i)
+ {
+ pts_t p = i->second;
+ off_t offset = 0; // fixme, we need to note down both
+ if (tstools.fixupPTS(offset, p))
+ {
+ eDebug("[eDVBServiceRecord] fixing up PTS failed, not saving");
+ continue;
+ }
+ eDebug("fixed up %llx to %llx (offset %llx)", i->second, p, offset);
+#if BYTE_ORDER == BIG_ENDIAN
+ where = p;
+#else
+ where = bswap_64(p);
+#endif
+ what = htonl(2); /* mark */
+ fwrite(&where, sizeof(where), 1, f);
+ fwrite(&what, sizeof(what), 1, f);
+ }
+ fclose(f);
+ }
+
+}
diff --git a/lib/service/servicedvbrecord.h b/lib/service/servicedvbrecord.h
index 17de033e..856f92b3 100644
--- a/lib/service/servicedvbrecord.h
+++ b/lib/service/servicedvbrecord.h
@@ -36,6 +36,8 @@ private:
friend class eServiceFactoryDVB;
eDVBServiceRecord(const eServiceReferenceDVB &ref);
+ eDVBServiceEITHandler m_event_handler;
+
eServiceReferenceDVB m_ref;
ePtr<iDVBTSRecorder> m_record;
@@ -44,8 +46,11 @@ private:
int m_recording, m_tuned, m_error;
std::set<int> m_pids_active;
std::string m_filename;
+
+ std::map<int,pts_t> m_event_timestamps;
int m_target_fd;
int m_streaming;
+ int m_last_event_id;
int doPrepare();
int doRecord();
@@ -56,6 +61,10 @@ private:
/* recorder events */
void recordEvent(int event);
+
+ /* eit updates */
+ void gotNewEvent();
+ void saveCutlist();
};
#endif
diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp
index 19b7735b..bbcb3b5c 100644
--- a/lib/service/servicemp3.cpp
+++ b/lib/service/servicemp3.cpp
@@ -36,9 +36,11 @@ eServiceFactoryMP3::eServiceFactoryMP3()
extensions.push_back("wave");
extensions.push_back("mkv");
extensions.push_back("avi");
+ extensions.push_back("divx");
extensions.push_back("dat");
extensions.push_back("flac");
extensions.push_back("mp4");
+ extensions.push_back("m4a");
sc->addServiceFactory(eServiceFactoryMP3::id, this, extensions);
}
@@ -184,11 +186,10 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp
CONNECT(m_seekTimeout->timeout, eServiceMP3::seekTimeoutCB);
CONNECT(m_pump.recv_msg, eServiceMP3::gstPoll);
GstElement *source = 0;
-
- GstElement *decoder = 0, *conv = 0, *flt = 0, *sink = 0; /* for audio */
-
- GstElement *audio = 0, *switch_audio = 0, *queue_audio = 0, *video = 0, *queue_video = 0, *videodemux = 0;
-
+ GstElement *decoder = 0, *conv = 0, *flt = 0, *parser = 0, *sink = 0; /* for audio */
+ GstElement *audio = 0, *switch_audio = 0, *queue_audio = 0, *video = 0, *queue_video = 0, *videodemux = 0, *audiodemux = 0, *id3demux;
+ m_aspect = m_width = m_height = m_framerate = m_progressive = -1;
+
m_state = stIdle;
eDebug("SERVICEMP3 construct!");
@@ -200,25 +201,50 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp
ext = filename;
sourceStream sourceinfo;
+ sourceinfo.is_video = FALSE;
+ sourceinfo.audiotype = atUnknown;
if ( (strcasecmp(ext, ".mpeg") && strcasecmp(ext, ".mpg") && strcasecmp(ext, ".vob") && strcasecmp(ext, ".bin") && strcasecmp(ext, ".dat") ) == 0 )
+ {
sourceinfo.containertype = ctMPEGPS;
+ sourceinfo.is_video = TRUE;
+ }
else if ( strcasecmp(ext, ".ts") == 0 )
+ {
sourceinfo.containertype = ctMPEGTS;
+ sourceinfo.is_video = TRUE;
+ }
else if ( strcasecmp(ext, ".mkv") == 0 )
+ {
sourceinfo.containertype = ctMKV;
- else if ( strcasecmp(ext, ".avi") == 0 )
+ sourceinfo.is_video = TRUE;
+ }
+ else if ( strcasecmp(ext, ".avi") == 0 || strcasecmp(ext, ".divx") == 0)
+ {
sourceinfo.containertype = ctAVI;
+ sourceinfo.is_video = TRUE;
+ }
else if ( strcasecmp(ext, ".mp4") == 0 )
+ {
+ sourceinfo.containertype = ctMP4;
+ sourceinfo.is_video = TRUE;
+ }
+ else if ( strcasecmp(ext, ".m4a") == 0 )
+ {
sourceinfo.containertype = ctMP4;
+ sourceinfo.audiotype = atAAC;
+ }
+ else if ( strcasecmp(ext, ".mp3") == 0 )
+ sourceinfo.audiotype = atMP3;
else if ( (strncmp(filename, "/autofs/", 8) || strncmp(filename+strlen(filename)-13, "/track-", 7) || strcasecmp(ext, ".wav")) == 0 )
sourceinfo.containertype = ctCDA;
if ( strcasecmp(ext, ".dat") == 0 )
+ {
sourceinfo.containertype = ctVCD;
+ sourceinfo.is_video = TRUE;
+ }
if ( (strncmp(filename, "http://", 7)) == 0 )
sourceinfo.is_streaming = TRUE;
- sourceinfo.is_video = ( sourceinfo.containertype && sourceinfo.containertype != ctCDA );
-
eDebug("filename=%s, containertype=%d, is_video=%d, is_streaming=%d", filename, sourceinfo.containertype, sourceinfo.is_video, sourceinfo.is_streaming);
int all_ok = 0;
@@ -250,10 +276,24 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp
if (track > 0)
g_object_set (G_OBJECT (source), "track", track, NULL);
}
- else
- sourceinfo.containertype = ctNone;
}
- if ( !sourceinfo.is_streaming && sourceinfo.containertype != ctCDA )
+ else if ( sourceinfo.containertype == ctVCD )
+ {
+ int fd = open(filename,O_RDONLY);
+ char tmp[128*1024];
+ int ret = read(fd, tmp, 128*1024);
+ close(fd);
+ if ( ret == -1 ) // this is a "REAL" VCD
+ {
+ source = gst_element_factory_make ("vcdsrc", "vcd-source");
+ if (source)
+ {
+ g_object_set (G_OBJECT (source), "device", "/dev/cdroms/cdrom0", NULL);
+ eDebug("servicemp3: this is a 'REAL' video cd... we use vcdsrc !");
+ }
+ }
+ }
+ if ( !source && !sourceinfo.is_streaming )
{
source = gst_element_factory_make ("filesrc", "file-source");
if (source)
@@ -269,7 +309,7 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp
audio = gst_element_factory_make("dvbaudiosink", "audiosink");
if (!audio)
m_error_message += "failed to create Gstreamer element dvbaudiosink\n";
-
+
video = gst_element_factory_make("dvbvideosink", "videosink");
if (!video)
m_error_message += "failed to create Gstreamer element dvbvideosink\n";
@@ -320,35 +360,105 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp
}
} else /* is audio */
{
-
- /* filesrc -> decodebin -> audioconvert -> capsfilter -> alsasink */
- decoder = gst_element_factory_make ("decodebin", "decoder");
- if (!decoder)
- m_error_message += "failed to create Gstreamer element decodebin\n";
-
- conv = gst_element_factory_make ("audioconvert", "converter");
- if (!conv)
- m_error_message += "failed to create Gstreamer element audioconvert\n";
-
- flt = gst_element_factory_make ("capsfilter", "flt");
- if (!flt)
- m_error_message += "failed to create Gstreamer element capsfilter\n";
-
- /* for some reasons, we need to set the sample format to depth/width=16, because auto negotiation doesn't work. */
- /* endianness, however, is not required to be set anymore. */
- if (flt)
+ std::string demux_type;
+ switch ( sourceinfo.containertype )
{
- GstCaps *caps = gst_caps_new_simple("audio/x-raw-int", /* "endianness", G_TYPE_INT, 4321, */ "depth", G_TYPE_INT, 16, "width", G_TYPE_INT, 16, /*"channels", G_TYPE_INT, 2, */NULL);
- g_object_set (G_OBJECT (flt), "caps", caps, NULL);
- gst_caps_unref(caps);
+ case ctMP4:
+ demux_type = "qtdemux";
+ break;
+ default:
+ break;
+ }
+ if ( demux_type.length() )
+ {
+ audiodemux = gst_element_factory_make(demux_type.c_str(), "audiodemux");
+ if (!audiodemux)
+ m_error_message = "GStreamer plugin " + demux_type + " not available!\n";
+ }
+ switch ( sourceinfo.audiotype )
+ {
+ case atMP3:
+ {
+ id3demux = gst_element_factory_make("id3demux", "id3demux");
+ if ( !id3demux )
+ {
+ m_error_message += "failed to create Gstreamer element id3demux\n";
+ break;
+ }
+ parser = gst_element_factory_make("mp3parse", "audiosink");
+ if ( !parser )
+ {
+ m_error_message += "failed to create Gstreamer element mp3parse\n";
+ break;
+ }
+ sink = gst_element_factory_make("dvbaudiosink", "audiosink2");
+ if ( !sink )
+ m_error_message += "failed to create Gstreamer element dvbaudiosink\n";
+ else
+ all_ok = 1;
+ break;
+ }
+ case atAAC:
+ {
+ if ( !audiodemux )
+ {
+ m_error_message += "cannot parse raw AAC audio\n";
+ break;
+ }
+ sink = gst_element_factory_make("dvbaudiosink", "audiosink");
+ if (!sink)
+ m_error_message += "failed to create Gstreamer element dvbaudiosink\n";
+ else
+ all_ok = 1;
+ break;
+ }
+ case atAC3:
+ {
+ if ( !audiodemux )
+ {
+ m_error_message += "cannot parse raw AC3 audio\n";
+ break;
+ }
+ sink = gst_element_factory_make("dvbaudiosink", "audiosink");
+ if ( !sink )
+ m_error_message += "failed to create Gstreamer element dvbaudiosink\n";
+ else
+ all_ok = 1;
+ break;
+ }
+ default:
+ { /* filesrc -> decodebin -> audioconvert -> capsfilter -> alsasink */
+ decoder = gst_element_factory_make ("decodebin", "decoder");
+ if (!decoder)
+ m_error_message += "failed to create Gstreamer element decodebin\n";
+
+ conv = gst_element_factory_make ("audioconvert", "converter");
+ if (!conv)
+ m_error_message += "failed to create Gstreamer element audioconvert\n";
+
+ flt = gst_element_factory_make ("capsfilter", "flt");
+ if (!flt)
+ m_error_message += "failed to create Gstreamer element capsfilter\n";
+
+ /* for some reasons, we need to set the sample format to depth/width=16, because auto negotiation doesn't work. */
+ /* endianness, however, is not required to be set anymore. */
+ if (flt)
+ {
+ GstCaps *caps = gst_caps_new_simple("audio/x-raw-int", /* "endianness", G_TYPE_INT, 4321, */ "depth", G_TYPE_INT, 16, "width", G_TYPE_INT, 16, /*"channels", G_TYPE_INT, 2, */NULL);
+ g_object_set (G_OBJECT (flt), "caps", caps, NULL);
+ gst_caps_unref(caps);
+ }
+
+ sink = gst_element_factory_make ("alsasink", "alsa-output");
+ if (!sink)
+ m_error_message += "failed to create Gstreamer element alsasink\n";
+
+ if (source && decoder && conv && sink)
+ all_ok = 1;
+ break;
+ }
}
- sink = gst_element_factory_make ("alsasink", "alsa-output");
- if (!sink)
- m_error_message += "failed to create Gstreamer element alsasink\n";
-
- if (source && decoder && conv && sink)
- all_ok = 1;
}
if (m_gst_pipeline && all_ok)
{
@@ -384,8 +494,9 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp
}
gst_bin_add_many(GST_BIN(m_gst_pipeline), source, videodemux, audio, queue_audio, video, queue_video, switch_audio, NULL);
- if ( sourceinfo.containertype == ctVCD )
+ if ( sourceinfo.containertype == ctVCD && gst_bin_get_by_name(GST_BIN(m_gst_pipeline),"file-source") )
{
+ eDebug("servicemp3: this is a fake video cd... we use filesrc ! cdxaparse !");
GstElement *cdxaparse = gst_element_factory_make("cdxaparse", "cdxaparse");
gst_bin_add(GST_BIN(m_gst_pipeline), cdxaparse);
gst_element_link(source, cdxaparse);
@@ -401,29 +512,52 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp
} else /* is audio*/
{
- queue_audio = gst_element_factory_make("queue", "queue_audio");
-
- g_signal_connect (decoder, "new-decoded-pad", G_CALLBACK(gstCBnewPad), this);
- g_signal_connect (decoder, "unknown-type", G_CALLBACK(gstCBunknownType), this);
-
- g_object_set (G_OBJECT (sink), "preroll-queue-len", 80, NULL);
-
- /* gst_bin will take the 'floating references' */
- gst_bin_add_many (GST_BIN (m_gst_pipeline),
- source, queue_audio, decoder, NULL);
-
- /* in decodebin's case we can just connect the source with the decodebin, and decodebin will take care about id3demux (or whatever is required) */
- gst_element_link_many(source, queue_audio, decoder, NULL);
-
- /* create audio bin with the audioconverter, the capsfilter and the audiosink */
- audio = gst_bin_new ("audiobin");
-
- GstPad *audiopad = gst_element_get_static_pad (conv, "sink");
- gst_bin_add_many(GST_BIN(audio), conv, flt, sink, NULL);
- gst_element_link_many(conv, flt, sink, NULL);
- gst_element_add_pad(audio, gst_ghost_pad_new ("sink", audiopad));
- gst_object_unref(audiopad);
- gst_bin_add (GST_BIN(m_gst_pipeline), audio);
+ if ( decoder )
+ {
+ queue_audio = gst_element_factory_make("queue", "queue_audio");
+
+ g_signal_connect (decoder, "new-decoded-pad", G_CALLBACK(gstCBnewPad), this);
+ g_signal_connect (decoder, "unknown-type", G_CALLBACK(gstCBunknownType), this);
+
+ g_object_set (G_OBJECT (sink), "preroll-queue-len", 80, NULL);
+
+ /* gst_bin will take the 'floating references' */
+ gst_bin_add_many (GST_BIN (m_gst_pipeline),
+ source, queue_audio, decoder, NULL);
+
+ /* in decodebin's case we can just connect the source with the decodebin, and decodebin will take care about id3demux (or whatever is required) */
+ gst_element_link_many(source, queue_audio, decoder, NULL);
+
+ /* create audio bin with the audioconverter, the capsfilter and the audiosink */
+ audio = gst_bin_new ("audiobin");
+
+ GstPad *audiopad = gst_element_get_static_pad (conv, "sink");
+ gst_bin_add_many(GST_BIN(audio), conv, flt, sink, NULL);
+ gst_element_link_many(conv, flt, sink, NULL);
+ gst_element_add_pad(audio, gst_ghost_pad_new ("sink", audiopad));
+ gst_object_unref(audiopad);
+ gst_bin_add (GST_BIN(m_gst_pipeline), audio);
+ }
+ else
+ {
+ gst_bin_add_many (GST_BIN (m_gst_pipeline), source, sink, NULL);
+ if ( parser && id3demux )
+ {
+ gst_bin_add_many (GST_BIN (m_gst_pipeline), parser, id3demux, NULL);
+ gst_element_link(source, id3demux);
+ g_signal_connect(id3demux, "pad-added", G_CALLBACK (gstCBpadAdded), this);
+ gst_element_link(parser, sink);
+ }
+ if ( audiodemux )
+ {
+ gst_bin_add (GST_BIN (m_gst_pipeline), audiodemux);
+ g_signal_connect(audiodemux, "pad-added", G_CALLBACK (gstCBpadAdded), this);
+ gst_element_link(source, audiodemux);
+ }
+ audioStream audio;
+ audio.type = sourceinfo.audiotype;
+ m_audioStreams.push_back(audio);
+ }
}
} else
{
@@ -647,13 +781,13 @@ RESULT eServiceMP3::getPlayPosition(pts_t &pts)
return -1;
if (m_state != stRunning)
return -1;
-
+
GstFormat fmt = GST_FORMAT_TIME;
gint64 len;
if (!gst_element_query_position(m_gst_pipeline, &fmt, &len))
return -1;
-
+
/* len is in nanoseconds. we have 90 000 pts per second. */
pts = len / 11111;
return 0;
@@ -691,6 +825,11 @@ int eServiceMP3::getInfo(int w)
switch (w)
{
+ case sVideoHeight: return m_height;
+ case sVideoWidth: return m_width;
+ case sFrameRate: return m_framerate;
+ case sProgressive: return m_progressive;
+ case sAspect: return m_aspect;
case sTitle:
case sArtist:
case sAlbum:
@@ -898,103 +1037,165 @@ void eServiceMP3::gstBusCall(GstBus *bus, GstMessage *msg)
#endif
switch (GST_MESSAGE_TYPE (msg))
{
- case GST_MESSAGE_EOS:
- m_event((iPlayableService*)this, evEOF);
- break;
- case GST_MESSAGE_ERROR:
- {
- gchar *debug;
- GError *err;
-
- gst_message_parse_error (msg, &err, &debug);
- g_free (debug);
- eWarning("Gstreamer error: %s (%i)", err->message, err->code );
- if ( err->domain == GST_STREAM_ERROR && err->code == GST_STREAM_ERROR_DECODE )
+ case GST_MESSAGE_EOS:
+ m_event((iPlayableService*)this, evEOF);
+ break;
+ case GST_MESSAGE_ERROR:
{
- if ( g_strrstr(sourceName, "videosink") )
- m_event((iPlayableService*)this, evUser+11);
+ gchar *debug;
+ GError *err;
+
+ gst_message_parse_error (msg, &err, &debug);
+ g_free (debug);
+ eWarning("Gstreamer error: %s (%i) from %s", err->message, err->code, sourceName );
+ if ( err->domain == GST_STREAM_ERROR )
+ {
+ if ( err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND && g_strrstr(sourceName, "videosink") )
+ m_event((iPlayableService*)this, evUser+11);
+ else if ( err->code == GST_STREAM_ERROR_FAILED && g_strrstr(sourceName, "file-source") )
+ {
+ eWarning("error in tag parsing, linking mp3parse directly to file-sink, bypassing id3demux...");
+ GstElement *source = gst_bin_get_by_name(GST_BIN(m_gst_pipeline),"file-source");
+ GstElement *parser = gst_bin_get_by_name(GST_BIN(m_gst_pipeline),"audiosink");
+ gst_element_set_state(m_gst_pipeline, GST_STATE_NULL);
+ gst_element_unlink(source, gst_bin_get_by_name(GST_BIN(m_gst_pipeline),"id3demux"));
+ gst_element_link(source, parser);
+ gst_element_set_state (m_gst_pipeline, GST_STATE_PLAYING);
+ }
+ }
+ g_error_free(err);
+ break;
}
- g_error_free(err);
- /* TODO: signal error condition to user */
- break;
- }
- case GST_MESSAGE_TAG:
- {
- GstTagList *tags, *result;
- gst_message_parse_tag(msg, &tags);
-
- result = gst_tag_list_merge(m_stream_tags, tags, GST_TAG_MERGE_PREPEND);
- if (result)
+ case GST_MESSAGE_INFO:
{
- if (m_stream_tags)
- gst_tag_list_free(m_stream_tags);
- m_stream_tags = result;
+ gchar *debug;
+ GError *inf;
+
+ gst_message_parse_info (msg, &inf, &debug);
+ g_free (debug);
+ if ( inf->domain == GST_STREAM_ERROR && inf->code == GST_STREAM_ERROR_DECODE )
+ {
+ if ( g_strrstr(sourceName, "videosink") )
+ m_event((iPlayableService*)this, evUser+14);
+ }
+ g_error_free(inf);
+ break;
}
-
- gchar *g_audiocodec;
- if ( gst_tag_list_get_string(tags, GST_TAG_AUDIO_CODEC, &g_audiocodec) && m_audioStreams.size() == 0 )
+ case GST_MESSAGE_TAG:
{
- GstPad* pad = gst_element_get_pad (GST_ELEMENT(source), "src");
- GstCaps* caps = gst_pad_get_caps(pad);
- GstStructure* str = gst_caps_get_structure(caps, 0);
- if ( !str )
- break;
- audioStream audio;
- audio.type = gstCheckAudioPad(str);
- m_audioStreams.push_back(audio);
+ GstTagList *tags, *result;
+ gst_message_parse_tag(msg, &tags);
+
+ result = gst_tag_list_merge(m_stream_tags, tags, GST_TAG_MERGE_PREPEND);
+ if (result)
+ {
+ if (m_stream_tags)
+ gst_tag_list_free(m_stream_tags);
+ m_stream_tags = result;
+ }
+
+ gchar *g_audiocodec;
+ if ( gst_tag_list_get_string(tags, GST_TAG_AUDIO_CODEC, &g_audiocodec) && m_audioStreams.size() == 0 )
+ {
+ GstPad* pad = gst_element_get_pad (GST_ELEMENT(source), "src");
+ GstCaps* caps = gst_pad_get_caps(pad);
+ GstStructure* str = gst_caps_get_structure(caps, 0);
+ if ( !str )
+ break;
+ audioStream audio;
+ audio.type = gstCheckAudioPad(str);
+ m_audioStreams.push_back(audio);
+ }
+
+ const GValue *gv_image = gst_tag_list_get_value_index(tags, GST_TAG_IMAGE, 0);
+ if ( gv_image )
+ {
+ GstBuffer *buf_image;
+ buf_image = gst_value_get_buffer (gv_image);
+ int fd = open("/tmp/.id3coverart", O_CREAT|O_WRONLY|O_TRUNC, 0644);
+ write(fd, GST_BUFFER_DATA(buf_image), GST_BUFFER_SIZE(buf_image));
+ close(fd);
+ m_event((iPlayableService*)this, evUser+13);
+ }
+
+ gst_tag_list_free(tags);
+ m_event((iPlayableService*)this, evUpdatedInfo);
+ break;
}
-
- gst_tag_list_free(tags);
- m_event((iPlayableService*)this, evUpdatedInfo);
- break;
- }
- case GST_MESSAGE_ASYNC_DONE:
- {
- GstTagList *tags;
- for (std::vector<audioStream>::iterator IterAudioStream(m_audioStreams.begin()); IterAudioStream != m_audioStreams.end(); ++IterAudioStream)
+ case GST_MESSAGE_ASYNC_DONE:
{
- if ( IterAudioStream->pad )
+ GstTagList *tags;
+ for (std::vector<audioStream>::iterator IterAudioStream(m_audioStreams.begin()); IterAudioStream != m_audioStreams.end(); ++IterAudioStream)
{
- g_object_get(IterAudioStream->pad, "tags", &tags, NULL);
- gchar *g_language;
- if ( gst_is_tag_list(tags) && gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_language) )
+ if ( IterAudioStream->pad )
{
- eDebug("found audio language %s",g_language);
- IterAudioStream->language_code = std::string(g_language);
- g_free (g_language);
+ g_object_get(IterAudioStream->pad, "tags", &tags, NULL);
+ gchar *g_language;
+ if ( tags && gst_is_tag_list(tags) && gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_language) )
+ {
+ eDebug("found audio language %s",g_language);
+ IterAudioStream->language_code = std::string(g_language);
+ g_free (g_language);
+ }
}
}
- }
- for (std::vector<subtitleStream>::iterator IterSubtitleStream(m_subtitleStreams.begin()); IterSubtitleStream != m_subtitleStreams.end(); ++IterSubtitleStream)
- {
- if ( IterSubtitleStream->pad )
+ for (std::vector<subtitleStream>::iterator IterSubtitleStream(m_subtitleStreams.begin()); IterSubtitleStream != m_subtitleStreams.end(); ++IterSubtitleStream)
{
- g_object_get(IterSubtitleStream->pad, "tags", &tags, NULL);
- gchar *g_language;
- if ( gst_is_tag_list(tags) && gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_language) )
+ if ( IterSubtitleStream->pad )
{
- eDebug("found subtitle language %s",g_language);
- IterSubtitleStream->language_code = std::string(g_language);
- g_free (g_language);
+ g_object_get(IterSubtitleStream->pad, "tags", &tags, NULL);
+ gchar *g_language;
+ if ( tags && gst_is_tag_list(tags) && gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_language) )
+ {
+ eDebug("found subtitle language %s",g_language);
+ IterSubtitleStream->language_code = std::string(g_language);
+ g_free (g_language);
+ }
}
}
}
- }
- case GST_MESSAGE_ELEMENT:
- {
- if ( gst_is_missing_plugin_message(msg) )
+ case GST_MESSAGE_ELEMENT:
{
- gchar *description = gst_missing_plugin_message_get_description(msg);
- if ( description )
+ if ( gst_is_missing_plugin_message(msg) )
+ {
+ gchar *description = gst_missing_plugin_message_get_description(msg);
+ if ( description )
+ {
+ m_error_message = "GStreamer plugin " + (std::string)description + " not available!\n";
+ g_free(description);
+ m_event((iPlayableService*)this, evUser+12);
+ }
+ }
+ else if (const GstStructure *msgstruct = gst_message_get_structure(msg))
{
- m_error_message = "GStreamer plugin " + (std::string)description + " not available!\n";
- g_free(description);
- m_event((iPlayableService*)this, evUser+12);
+ const gchar *eventname = gst_structure_get_name(msgstruct);
+ if ( eventname )
+ {
+ if (!strcmp(eventname, "eventSizeChanged") || !strcmp(eventname, "eventSizeAvail"))
+ {
+ gst_structure_get_int (msgstruct, "aspect_ratio", &m_aspect);
+ gst_structure_get_int (msgstruct, "width", &m_width);
+ gst_structure_get_int (msgstruct, "height", &m_height);
+ if (strstr(eventname, "Changed"))
+ m_event((iPlayableService*)this, evVideoSizeChanged);
+ }
+ else if (!strcmp(eventname, "eventFrameRateChanged") || !strcmp(eventname, "eventFrameRateAvail"))
+ {
+ gst_structure_get_int (msgstruct, "frame_rate", &m_framerate);
+ if (strstr(eventname, "Changed"))
+ m_event((iPlayableService*)this, evVideoFramerateChanged);
+ }
+ else if (!strcmp(eventname, "eventProgressiveChanged") || !strcmp(eventname, "eventProgressiveAvail"))
+ {
+ gst_structure_get_int (msgstruct, "progressive", &m_progressive);
+ if (strstr(eventname, "Changed"))
+ m_event((iPlayableService*)this, evVideoProgressiveChanged);
+ }
+ }
}
}
- }
- default:
- break;
+ default:
+ break;
}
g_free (sourceName);
}
@@ -1081,8 +1282,14 @@ void eServiceMP3::gstCBpadAdded(GstElement *decodebin, GstPad *pad, gpointer use
}
else
{
- gst_pad_link(pad, gst_element_get_static_pad(gst_bin_get_by_name(pipeline,"queue_audio"), "sink"));
- _this->m_audioStreams.push_back(audio);
+ GstElement *queue_audio = gst_bin_get_by_name(pipeline , "queue_audio");
+ if ( queue_audio )
+ {
+ gst_pad_link(pad, gst_element_get_static_pad(queue_audio, "sink"));
+ _this->m_audioStreams.push_back(audio);
+ }
+ else
+ gst_pad_link(pad, gst_element_get_static_pad(gst_bin_get_by_name(pipeline , "audiosink"), "sink"));
}
}
if (g_strrstr(type,"video"))
@@ -1232,14 +1439,17 @@ eAutoInitPtr<eServiceFactoryMP3> init_eServiceFactoryMP3(eAutoInitNumbers::servi
void eServiceMP3::gstCBsubtitleAvail(GstElement *element, GstBuffer *buffer, GstPad *pad, gpointer user_data)
{
gint64 duration_ns = GST_BUFFER_DURATION(buffer);
- const unsigned char *text = (unsigned char *)GST_BUFFER_DATA(buffer);
- eDebug("gstCBsubtitleAvail: %s",text);
+ size_t len = GST_BUFFER_SIZE(buffer);
+ unsigned char tmp[len+1];
+ memcpy(tmp, GST_BUFFER_DATA(buffer), len);
+ tmp[len] = 0;
+ eDebug("gstCBsubtitleAvail: %s", tmp);
eServiceMP3 *_this = (eServiceMP3*)user_data;
if ( _this->m_subtitle_widget )
{
ePangoSubtitlePage page;
gRGB rgbcol(0xD0,0xD0,0xD0);
- page.m_elements.push_back(ePangoSubtitlePageElement(rgbcol, (const char*)text));
+ page.m_elements.push_back(ePangoSubtitlePageElement(rgbcol, (const char*)tmp));
page.m_timeout = duration_ns / 1000000;
(_this->m_subtitle_widget)->setPage(page);
}
diff --git a/lib/service/servicemp3.h b/lib/service/servicemp3.h
index a43c8ad9..5e706e9b 100644
--- a/lib/service/servicemp3.h
+++ b/lib/service/servicemp3.h
@@ -180,6 +180,7 @@ private:
static void gstCBsubtitlePadEvent(GstPad *pad, GstEvent *event, gpointer user_data);
GstPad* gstCreateSubtitleSink(eServiceMP3* _this, subtype_t type);
void gstPoll(const int&);
+ gint m_aspect, m_width, m_height, m_framerate, m_progressive;
};
#endif