aboutsummaryrefslogtreecommitdiff
path: root/lib/python
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python')
-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
92 files changed, 4697 insertions, 1993 deletions
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"abc2ABC") # 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"mno6MNO") # 6
- self.mapping.append (u"pqrs7PQRS") # 7
- self.mapping.append (u"tuv8TUV") # 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"abc2ABC") # 2
- self.mapping.append (u"def3DEF") # 3
- self.mapping.append (u"ghi4GHI") # 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"mno6MNO") # 6
+ self.mapping.append (u"mnñoóò6MNÑOÓÒ") # 6
self.mapping.append (u"pqrs7PQRS") # 7
- self.mapping.append (u"tuv8TUV") # 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"abc2ABC") # 2
- self.mapping.append (u"def3DEF") # 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"mno6MNO") # 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