diff options
Diffstat (limited to 'lib/python/Components')
21 files changed, 766 insertions, 326 deletions
diff --git a/lib/python/Components/About.py b/lib/python/Components/About.py index 8e332e33..6b322c9d 100644..100755 --- a/lib/python/Components/About.py +++ b/lib/python/Components/About.py @@ -1,5 +1,6 @@ from Tools.Directories import resolveFilename, SCOPE_SYSETC from enigma import getEnigmaVersionString +from os import popen class About: def __init__(self): @@ -43,4 +44,14 @@ class About: def getEnigmaVersionString(self): return getEnigmaVersionString() + def getKernelVersionString(self): + try: + result = popen("uname -r","r").read().strip("\n").split('-') + kernel_version = result[0] + return kernel_version + except: + pass + + return "unknown" + about = About() diff --git a/lib/python/Components/ConfigList.py b/lib/python/Components/ConfigList.py index 418a1b67..24f917f7 100755 --- a/lib/python/Components/ConfigList.py +++ b/lib/python/Components/ConfigList.py @@ -61,12 +61,13 @@ class ConfigList(HTMLComponent, GUIComponent, object): GUI_WIDGET = eListbox def selectionChanged(self): - if self.current: + if isinstance(self.current,tuple) and len(self.current) == 2: self.current[1].onDeselect(self.session) self.current = self.getCurrent() - if self.current: + if isinstance(self.current,tuple) and len(self.current) == 2: self.current[1].onSelect(self.session) - + else: + return for x in self.onSelectionChanged: x() @@ -75,11 +76,11 @@ class ConfigList(HTMLComponent, GUIComponent, object): instance.setContent(self.l) def preWidgetRemove(self, instance): - if self.current: + if isinstance(self.current,tuple) and len(self.current) == 2: self.current[1].onDeselect(self.session) instance.selectionChanged.get().remove(self.selectionChanged) instance.setContent(None) - + def setList(self, l): self.timer.stop() self.__list = l @@ -87,7 +88,7 @@ class ConfigList(HTMLComponent, GUIComponent, object): if l is not None: for x in l: - assert isinstance(x[1], ConfigElement), "entry in ConfigList " + str(x[1]) + " must be a ConfigElement" + assert len(x) < 2 or isinstance(x[1], ConfigElement), "entry in ConfigList " + str(x[1]) + " must be a ConfigElement" def getList(self): return self.__list diff --git a/lib/python/Components/Converter/TemplatedMultiContent.py b/lib/python/Components/Converter/TemplatedMultiContent.py index b5a98449..b1d89f55 100644..100755 --- a/lib/python/Components/Converter/TemplatedMultiContent.py +++ b/lib/python/Components/Converter/TemplatedMultiContent.py @@ -53,14 +53,18 @@ class TemplatedMultiContent(StringList): template = self.template.get("template") itemheight = self.template["itemHeight"] selectionEnabled = self.template.get("selectionEnabled", True) + scrollbarMode = self.template.get("scrollbarMode", "showOnDemand") if templates and style and style in templates: # if we have a custom style defined in the source, and different templates in the skin, look it up template = templates[style][1] itemheight = templates[style][0] if len(templates[style]) > 2: selectionEnabled = templates[style][2] + if len(templates[style]) > 3: + scrollbarMode = templates[style][3] self.content.setTemplate(template) self.content.setItemHeight(itemheight) self.selectionEnabled = selectionEnabled + self.scrollbarMode = scrollbarMode self.active_style = style diff --git a/lib/python/Components/DreamInfoHandler.py b/lib/python/Components/DreamInfoHandler.py index 85e2b533..03d52157 100755 --- a/lib/python/Components/DreamInfoHandler.py +++ b/lib/python/Components/DreamInfoHandler.py @@ -16,7 +16,7 @@ class InfoHandlerParseError(Exception): return repr(self.value) class InfoHandler(xml.sax.ContentHandler): - def __init__(self, prerequisiteMet, directory, language = None): + def __init__(self, prerequisiteMet, directory): self.attributes = {} self.directory = directory self.list = [] @@ -26,9 +26,6 @@ class InfoHandler(xml.sax.ContentHandler): self.validFileTypes = ["skin", "config", "services", "favourites", "package"] self.prerequisitesMet = prerequisiteMet self.data = "" - self.language = language - self.translatedPackageInfos = {} - self.foundTranslation = None def printError(self, error): print "Error in defaults xml files:", error @@ -52,15 +49,6 @@ class InfoHandler(xml.sax.ContentHandler): if name == "info": self.foundTranslation = None self.data = "" - if not attrs.has_key("language"): - print "info tag with no language attribute" - else: - if attrs["language"] == 'en': # read default translations - self.foundTranslation = False - self.data = "" - elif attrs["language"] == self.language: - self.foundTranslation = True - self.data = "" if name == "files": if attrs.has_key("type"): @@ -91,20 +79,17 @@ class InfoHandler(xml.sax.ContentHandler): if attrs.has_key("details"): self.attributes["details"] = str(attrs["details"]) if attrs.has_key("name"): - self.attributes["name"] = str(attrs["name"].encode("utf-8")) + self.attributes["name"] = str(attrs["name"]) if attrs.has_key("packagename"): - self.attributes["packagename"] = str(attrs["packagename"].encode("utf-8")) + self.attributes["packagename"] = str(attrs["packagename"]) if attrs.has_key("packagetype"): - self.attributes["packagetype"] = str(attrs["packagetype"].encode("utf-8")) + self.attributes["packagetype"] = str(attrs["packagetype"]) if attrs.has_key("shortdescription"): - self.attributes["shortdescription"] = str(attrs["shortdescription"].encode("utf-8")) + self.attributes["shortdescription"] = str(attrs["shortdescription"]) if name == "screenshot": if attrs.has_key("src"): - if self.foundTranslation is False: - self.attributes["screenshot"] = str(attrs["src"]) - elif self.foundTranslation is True: - self.translatedPackageInfos["screenshot"] = str(attrs["src"]) + self.attributes["screenshot"] = str(attrs["src"]) def endElement(self, name): #print "endElement", name @@ -124,7 +109,7 @@ class InfoHandler(xml.sax.ContentHandler): self.attributes[self.filetype].append({ "name": str(self.fileattrs["name"]), "directory": directory }) if name in ( "default", "package" ): - self.list.append({"attributes": self.attributes, 'prerequisites': self.globalprerequisites ,"translation": self.translatedPackageInfos}) + self.list.append({"attributes": self.attributes, 'prerequisites': self.globalprerequisites}) self.attributes = {} self.globalprerequisites = {} @@ -133,30 +118,13 @@ class InfoHandler(xml.sax.ContentHandler): self.attributes["author"] = str(data) if self.elements[-1] == "name": self.attributes["name"] = str(data) - if self.foundTranslation is False: - if self.elements[-1] == "author": - self.attributes["author"] = str(data) - if self.elements[-1] == "name": - self.attributes["name"] = str(data) - if self.elements[-1] == "packagename": - self.attributes["packagename"] = str(data.encode("utf-8")) - if self.elements[-1] == "shortdescription": - self.attributes["shortdescription"] = str(data.encode("utf-8")) - if self.elements[-1] == "description": - self.data += data.strip() - self.attributes["description"] = str(self.data.encode("utf-8")) - elif self.foundTranslation is True: - if self.elements[-1] == "author": - self.translatedPackageInfos["author"] = str(data) - if self.elements[-1] == "name": - self.translatedPackageInfos["name"] = str(data) - if self.elements[-1] == "description": - self.data += data.strip() - self.translatedPackageInfos["description"] = str(self.data.encode("utf-8")) - if self.elements[-1] == "name": - self.translatedPackageInfos["name"] = str(data.encode("utf-8")) - if self.elements[-1] == "shortdescription": - self.translatedPackageInfos["shortdescription"] = str(data.encode("utf-8")) + if self.elements[-1] == "packagename": + self.attributes["packagename"] = str(data) + if self.elements[-1] == "shortdescription": + self.attributes["shortdescription"] = str(data) + if self.elements[-1] == "description": + self.data += data.strip() + self.attributes["description"] = str(self.data) #print "characters", data @@ -166,13 +134,12 @@ class DreamInfoHandler: STATUS_ERROR = 2 STATUS_INIT = 4 - def __init__(self, statusCallback, blocking = False, neededTag = None, neededFlag = None, language = None): + def __init__(self, statusCallback, blocking = False, neededTag = None, neededFlag = None): self.hardware_info = HardwareInfo() self.directory = "/" self.neededTag = neededTag self.neededFlag = neededFlag - self.language = language # caution: blocking should only be used, if further execution in enigma2 depends on the outcome of # the installer! @@ -203,8 +170,8 @@ class DreamInfoHandler: #print handler.list def readIndex(self, directory, file): - print "Reading .xml meta index file", file - handler = InfoHandler(self.prerequisiteMet, directory, self.language) + print "Reading .xml meta index file", directory, file + handler = InfoHandler(self.prerequisiteMet, directory) try: xml.sax.parse(file, handler) for entry in handler.list: @@ -216,7 +183,7 @@ class DreamInfoHandler: def readDetails(self, directory, file): self.packageDetails = [] print "Reading .xml meta details file", file - handler = InfoHandler(self.prerequisiteMet, directory, self.language) + handler = InfoHandler(self.prerequisiteMet, directory) try: xml.sax.parse(file, handler) for entry in handler.list: @@ -225,7 +192,6 @@ class DreamInfoHandler: print "file", file, "ignored due to errors in the file" #print handler.list - # prerequisites = True: give only packages matching the prerequisites def fillPackagesList(self, prerequisites = True): self.packageslist = [] @@ -254,20 +220,16 @@ class DreamInfoHandler: self.directory = [self.directory] for indexfile in os.listdir(self.directory[0]): - if indexfile.startswith("index"): - if indexfile.endswith("_en.xml"): #we first catch all english indexfiles - indexfileList.append(os.path.splitext(indexfile)[0][:-3]) - + if indexfile.startswith("index-"): + if indexfile.endswith(".xml"): + if indexfile[-7:-6] == "_": + continue + indexfileList.append(indexfile) if len(indexfileList): for file in indexfileList: neededFile = self.directory[0] + "/" + file - if self.language is not None: - if os.path.exists(neededFile + '_' + self.language + '.xml' ): - #print "translated index file found",neededFile + '_' + self.language + '.xml' - self.readIndex(self.directory[0] + "/", neededFile + '_' + self.language + '.xml') - else: - #print "reading original index file" - self.readIndex(self.directory[0] + "/", neededFile + '_en.xml') + if os.path.isfile(neededFile): + self.readIndex(self.directory[0] + "/" , neededFile) if prerequisites: for package in self.packagesIndexlist[:]: diff --git a/lib/python/Components/FileList.py b/lib/python/Components/FileList.py index 841a2fe5..1b7e81f5 100755 --- a/lib/python/Components/FileList.py +++ b/lib/python/Components/FileList.py @@ -28,7 +28,8 @@ EXTENSIONS = { "mpeg": "movie", "mkv": "movie", "mp4": "movie", - "mov": "movie" + "mov": "movie", + "m2ts": "movie", } def FileEntryComponent(name, absolute = None, isDir = False): @@ -196,6 +197,9 @@ class FileList(MenuList): if (self.matchingPattern is None) or re_compile(self.matchingPattern).search(path): self.list.append(FileEntryComponent(name = name, absolute = x , isDir = False)) + if self.showMountpoints and len(self.list) == 0: + self.list.append(FileEntryComponent(name = _("nothing connected"), absolute = None, isDir = False)) + self.l.setList(self.list) if select is not None: diff --git a/lib/python/Components/Harddisk.py b/lib/python/Components/Harddisk.py index e8e612a4..0f1a8fca 100755..100644 --- a/lib/python/Components/Harddisk.py +++ b/lib/python/Components/Harddisk.py @@ -5,23 +5,27 @@ from SystemInfo import SystemInfo import time from Components.Console import Console +def MajorMinor(path): + rdev = stat(path).st_rdev + return (major(rdev),minor(rdev)) + def readFile(filename): file = open(filename) data = file.read().strip() file.close() return data -class Harddisk: - DEVTYPE_UDEV = 0 - DEVTYPE_DEVFS = 1 +DEVTYPE_UDEV = 0 +DEVTYPE_DEVFS = 1 +class Harddisk: def __init__(self, device): self.device = device if access("/dev/.udev", 0): - self.type = self.DEVTYPE_UDEV + self.type = DEVTYPE_UDEV elif access("/dev/.devfsd", 0): - self.type = self.DEVTYPE_DEVFS + self.type = DEVTYPE_DEVFS else: print "Unable to determine structure of /dev" @@ -33,11 +37,11 @@ class Harddisk: self.disk_path = '' self.phys_path = path.realpath(self.sysfsPath('device')) - if self.type == self.DEVTYPE_UDEV: + if self.type == DEVTYPE_UDEV: self.dev_path = '/dev/' + self.device self.disk_path = self.dev_path - elif self.type == self.DEVTYPE_DEVFS: + elif self.type == DEVTYPE_DEVFS: tmp = readFile(self.sysfsPath('dev')).split(':') s_major = int(tmp[0]) s_minor = int(tmp[1]) @@ -60,9 +64,9 @@ class Harddisk: return self.device < ob.device def partitionPath(self, n): - if self.type == self.DEVTYPE_UDEV: + if self.type == DEVTYPE_UDEV: return self.dev_path + n - elif self.type == self.DEVTYPE_DEVFS: + elif self.type == DEVTYPE_DEVFS: return self.dev_path + '/part' + n def sysfsPath(self, filename): @@ -75,9 +79,9 @@ class Harddisk: def bus(self): # CF (7025 specific) - if self.type == self.DEVTYPE_UDEV: + if self.type == DEVTYPE_UDEV: ide_cf = False # FIXME - elif self.type == self.DEVTYPE_DEVFS: + elif self.type == DEVTYPE_DEVFS: ide_cf = self.device[:2] == "hd" and "host0" not in self.dev_path internal = "pci" in self.phys_path @@ -125,18 +129,20 @@ class Harddisk: for line in lines: parts = line.strip().split(" ") - if path.realpath(parts[0]).startswith(self.dev_path): - try: + real_path = path.realpath(parts[0]) + if not real_path[-1].isdigit(): + continue + try: + if MajorMinor(real_path) == MajorMinor(self.partitionPath(real_path[-1])): stat = statvfs(parts[1]) - except OSError: - continue - return stat.f_bfree/1000 * stat.f_bsize/1000 - + return stat.f_bfree/1000 * stat.f_bsize/1000 + except OSError: + pass return -1 def numPartitions(self): numPart = -1 - if self.type == self.DEVTYPE_UDEV: + if self.type == DEVTYPE_UDEV: try: devdir = listdir('/dev') except OSError: @@ -145,7 +151,7 @@ class Harddisk: if filename.startswith(self.device): numPart += 1 - elif self.type == self.DEVTYPE_DEVFS: + elif self.type == DEVTYPE_DEVFS: try: idedir = listdir(self.dev_path) except OSError: @@ -168,10 +174,17 @@ class Harddisk: cmd = "umount" - for line in lines: - parts = line.strip().split(" ") - if path.realpath(parts[0]).startswith(self.dev_path): - cmd = ' ' . join([cmd, parts[1]]) + for line in lines: + parts = line.strip().split(" ") + real_path = path.realpath(parts[0]) + if not real_path[-1].isdigit(): + continue + try: + if MajorMinor(real_path) == MajorMinor(self.partitionPath(real_path[-1])): + cmd = ' ' . join([cmd, parts[1]]) + break + except OSError: + pass res = system(cmd) return (res >> 8) @@ -201,10 +214,16 @@ class Harddisk: res = -1 for line in lines: parts = line.strip().split(" ") - if path.realpath(parts[0]) == self.partitionPath("1"): - cmd = "mount -t ext3 " + parts[0] - res = system(cmd) - break + real_path = path.realpath(parts[0]) + if not real_path[-1].isdigit(): + continue + try: + if MajorMinor(real_path) == MajorMinor(self.partitionPath(real_path[-1])): + cmd = "mount -t ext3 " + parts[0] + res = system(cmd) + break + except OSError: + pass return (res >> 8) @@ -394,24 +413,38 @@ class Partition: return True return False -DEVICEDB = \ +DEVICEDB_SR = \ {"dm8000": { - # 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", + "/devices/pci0000:01/0000:01:00.0/host0/target0:0:0/0:0:0:0": _("DVD Drive"), + "/devices/pci0000:01/0000:01:00.0/host1/target1:0:0/1:0:0:0": _("DVD Drive"), + "/devices/platform/brcm-ehci-1.1/usb2/2-1/2-1:1.0/host3/target3:0:0/3:0:0:0": _("DVD Drive"), + }, + "dm800": + { + }, + "dm7025": + { + } + } + +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.0/usb1/1-1/1-1.1/1-1.1:1.0": _("Front USB Slot"), + "/devices/platform/brcm-ehci-1.1/usb2/2-1/2-1:1.0/": _("Internal USB Slot"), + "/devices/platform/brcm-ohci-1.1/usb4/4-1/4-1:1.0/": _("Internal USB Slot"), }, "dm800": { - # dm800: "/devices/platform/brcm-ehci.0/usb1/1-2/1-2:1.0": "Upper USB Slot", "/devices/platform/brcm-ehci.0/usb1/1-1/1-1:1.0": "Lower USB Slot", }, "dm7025": { - # dm7025: "/devices/pci0000:00/0000:00:14.1/ide1/1.0": "CF Card Slot", #hdc "/devices/pci0000:00/0000:00:14.1/ide0/0.0": "Internal Harddisk" } @@ -422,6 +455,7 @@ class HarddiskManager: self.hdd = [ ] self.cd = "" self.partitions = [ ] + self.devices_scanned_on_init = [ ] self.on_partition_list_change = CList() @@ -489,24 +523,23 @@ class HarddiskManager: def enumerateBlockDevices(self): print "enumerating block devices..." for blockdev in listdir("/sys/block"): - 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) - for part in partitions: - self.addHotplugPartition(part) + error, blacklisted, removable, is_cdrom, partitions, medium_found = self.addHotplugPartition(blockdev) + if not error and not blacklisted: + if medium_found: + for part in partitions: + self.addHotplugPartition(part) + self.devices_scanned_on_init.append((blockdev, removable, is_cdrom, medium_found)) def getAutofsMountpoint(self, device): return "/autofs/%s/" % (device) + def is_hard_mounted(self, device): + mounts = file('/proc/mounts').read().split('\n') + for x in mounts: + if x.find('/autofs') == -1 and x.find(device) != -1: + return True + return False + def addHotplugPartition(self, device, physdev = None): if not physdev: dev, part = self.splitDeviceName(device) @@ -516,22 +549,36 @@ class HarddiskManager: 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) + error, blacklisted, removable, is_cdrom, partitions, medium_found = self.getBlockDevInfo(device) + print "found block device '%s':" % device, - p = Partition(mountpoint = self.getAutofsMountpoint(device), description = description, force_mounted = True, device = device) - self.partitions.append(p) - self.on_partition_list_change("add", p) + if blacklisted: + print "blacklisted" + else: + if error: + print "error querying properties" + elif not medium_found: + print "no medium" + else: + print "ok, removable=%s, cdrom=%s, partitions=%s" % (removable, is_cdrom, partitions) + + l = len(device) + if l: + # see if this is a harddrive + if not device[l-1].isdigit() and not removable and not is_cdrom: + self.hdd.append(Harddisk(device)) + self.hdd.sort() + SystemInfo["Harddisk"] = len(self.hdd) > 0 + + if (not removable or medium_found) and not self.is_hard_mounted(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 not device[l-1].isdigit(): - 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["Harddisk"] = len(self.hdd) > 0 + return error, blacklisted, removable, is_cdrom, partitions, medium_found def removeHotplugPartition(self, device): mountpoint = self.getAutofsMountpoint(device) @@ -589,15 +636,23 @@ class HarddiskManager: def getUserfriendlyDeviceName(self, dev, phys): dev, part = self.splitDeviceName(dev) description = "External Storage %s" % dev + have_model_descr = False try: description = readFile("/sys" + phys + "/model") + have_model_descr = True except IOError, s: print "couldn't read model: ", s from Tools.HardwareInfo import HardwareInfo - for physdevprefix, pdescription in DEVICEDB.get(HardwareInfo().device_name,{}).items(): + if dev.find('sr') == 0 and dev[2].isdigit(): + devicedb = DEVICEDB_SR + else: + devicedb = DEVICEDB + for physdevprefix, pdescription in devicedb.get(HardwareInfo().device_name,{}).items(): if phys.startswith(physdevprefix): - description = pdescription - + if have_model_descr: + description = pdescription + ' - ' + description + else: + description = pdescription # not wholedisk and not partition 1 if part and part != 1: description += " (Partition %d)" % part diff --git a/lib/python/Components/InputDevice.py b/lib/python/Components/InputDevice.py index 3c3bd7a1..d675ca3a 100644..100755 --- a/lib/python/Components/InputDevice.py +++ b/lib/python/Components/InputDevice.py @@ -1,29 +1,208 @@ -from config import config, ConfigSlider, ConfigSubsection +# coding: utf-8 +from config import config, configfile, ConfigSlider, ConfigSubsection, ConfigYesNo, ConfigText + +import struct, sys, time, errno +from fcntl import ioctl +from os import path as os_path, listdir, open as os_open, close as os_close, write as os_write, read as os_read, O_RDWR, O_NONBLOCK + +# asm-generic/ioctl.h +IOC_NRBITS = 8L +IOC_TYPEBITS = 8L +IOC_SIZEBITS = 13L +IOC_DIRBITS = 3L + +IOC_NRSHIFT = 0L +IOC_TYPESHIFT = IOC_NRSHIFT+IOC_NRBITS +IOC_SIZESHIFT = IOC_TYPESHIFT+IOC_TYPEBITS +IOC_DIRSHIFT = IOC_SIZESHIFT+IOC_SIZEBITS + +IOC_READ = 2L + +def EVIOCGNAME(length): + return (IOC_READ<<IOC_DIRSHIFT)|(length<<IOC_SIZESHIFT)|(0x45<<IOC_TYPESHIFT)|(0x06<<IOC_NRSHIFT) + class inputDevices: + + def __init__(self): + self.Devices = {} + self.currentDevice = "" + self.getInputDevices() + + def getInputDevices(self): + devices = listdir("/dev/input/") + + for evdev in devices: + try: + buffer = "\0"*512 + self.fd = os_open("/dev/input/" + evdev, O_RDWR | O_NONBLOCK) + self.name = ioctl(self.fd, EVIOCGNAME(256), buffer) + self.name = self.name[:self.name.find("\0")] + os_close(self.fd) + except (IOError,OSError), err: + print '[iInputDevices] getInputDevices <ERROR: ioctl(EVIOCGNAME): ' + str(err) + ' >' + self.name = None + + if self.name: + if self.name == 'dreambox front panel': + continue + if self.name == "dreambox advanced remote control (native)" and config.misc.rcused.value != 0: + continue + if self.name == "dreambox remote control (native)" and config.misc.rcused.value == 0: + continue + self.Devices[evdev] = {'name': self.name, 'type': self.getInputDeviceType(self.name),'enabled': False, 'configuredName': None } + + + def getInputDeviceType(self,name): + if name.find("remote control") != -1: + return "remote" + elif name.find("keyboard") != -1: + return "keyboard" + elif name.find("mouse") != -1: + return "mouse" + else: + print "Unknown device type:",name + return None + + def getDeviceName(self, x): + if x in self.Devices.keys(): + return self.Devices[x].get("name", x) + else: + return "Unknown device name" + + def getDeviceList(self): + return sorted(self.Devices.iterkeys()) + + def getDefaultRCdeviceName(self): + if config.misc.rcused.value == 0: + for device in self.Devices.iterkeys(): + if self.Devices[device]["name"] == "dreambox advanced remote control (native)": + return device + else: + for device in self.Devices.iterkeys(): + if self.Devices[device]["name"] == "dreambox remote control (native)": + return device + + def setDeviceAttribute(self, device, attribute, value): + #print "[iInputDevices] setting for device", device, "attribute", attribute, " to value", value + if self.Devices.has_key(device): + self.Devices[device][attribute] = value + + def getDeviceAttribute(self, device, attribute): + if self.Devices.has_key(device): + if self.Devices[device].has_key(attribute): + return self.Devices[device][attribute] + return None + + def setEnabled(self, device, value): + oldval = self.getDeviceAttribute(device, 'enabled') + #print "[iInputDevices] setEnabled for device %s to %s from %s" % (device,value,oldval) + self.setDeviceAttribute(device, 'enabled', value) + if oldval is True and value is False: + self.setDefaults(device) + + def setName(self, device, value): + #print "[iInputDevices] setName for device %s to %s" % (device,value) + self.setDeviceAttribute(device, 'configuredName', value) + + #struct input_event { + # struct timeval time; -> ignored + # __u16 type; -> EV_REP (0x14) + # __u16 code; -> REP_DELAY (0x00) or REP_PERIOD (0x01) + # __s32 value; -> DEFAULTS: 700(REP_DELAY) or 100(REP_PERIOD) + #}; -> size = 16 + + def setDefaults(self, device): + print "[iInputDevices] setDefaults for device %s" % (device) + self.setDeviceAttribute(device, 'configuredName', None) + event_repeat = struct.pack('iihhi', 0, 0, 0x14, 0x01, 100) + event_delay = struct.pack('iihhi', 0, 0, 0x14, 0x00, 700) + fd = os_open("/dev/input/" + device, O_RDWR) + os_write(fd, event_repeat) + os_write(fd, event_delay) + os_close(fd) + + def setRepeat(self, device, value): #REP_PERIOD + if self.getDeviceAttribute(device, 'enabled') == True: + print "[iInputDevices] setRepeat for device %s to %d ms" % (device,value) + event = struct.pack('iihhi', 0, 0, 0x14, 0x01, int(value)) + fd = os_open("/dev/input/" + device, O_RDWR) + os_write(fd, event) + os_close(fd) + + def setDelay(self, device, value): #REP_DELAY + if self.getDeviceAttribute(device, 'enabled') == True: + print "[iInputDevices] setDelay for device %s to %d ms" % (device,value) + event = struct.pack('iihhi', 0, 0, 0x14, 0x00, int(value)) + fd = os_open("/dev/input/" + device, O_RDWR) + os_write(fd, event) + os_close(fd) + + +class InitInputDevices: + def __init__(self): - pass - def setRepeat(self, value): - #print "setup rc repeat" - pass - def setDelay(self, value): - #print "setup rc delay" - pass - -def InitInputDevices(): - config.inputDevices = ConfigSubsection(); - config.inputDevices.repeat = ConfigSlider(default=5, limits=(1, 10)) - config.inputDevices.delay = ConfigSlider(default=4, limits=(1, 10)) - - #this instance anywhere else needed? - iDevices = inputDevices(); + self.currentDevice = "" + self.createConfig() - def inputDevicesRepeatChanged(configElement): - iDevices.setRepeat(configElement.value); + def createConfig(self, *args): + config.inputDevices = ConfigSubsection() + for device in sorted(iInputDevices.Devices.iterkeys()): + self.currentDevice = device + #print "[InitInputDevices] -> creating config entry for device: %s -> %s " % (self.currentDevice, iInputDevices.Devices[device]["name"]) + self.setupConfigEntries(self.currentDevice) + self.currentDevice = "" + + def inputDevicesEnabledChanged(self,configElement): + if self.currentDevice != "" and iInputDevices.currentDevice == "": + iInputDevices.setEnabled(self.currentDevice, configElement.value) + elif iInputDevices.currentDevice != "": + iInputDevices.setEnabled(iInputDevices.currentDevice, configElement.value) + + def inputDevicesNameChanged(self,configElement): + if self.currentDevice != "" and iInputDevices.currentDevice == "": + iInputDevices.setName(self.currentDevice, configElement.value) + if configElement.value != "": + devname = iInputDevices.getDeviceAttribute(self.currentDevice, 'name') + if devname != configElement.value: + cmd = "config.inputDevices." + self.currentDevice + ".enabled.value = False" + exec (cmd) + cmd = "config.inputDevices." + self.currentDevice + ".enabled.save()" + exec (cmd) + elif iInputDevices.currentDevice != "": + iInputDevices.setName(iInputDevices.currentDevice, configElement.value) + + def inputDevicesRepeatChanged(self,configElement): + if self.currentDevice != "" and iInputDevices.currentDevice == "": + iInputDevices.setRepeat(self.currentDevice, configElement.value) + elif iInputDevices.currentDevice != "": + iInputDevices.setRepeat(iInputDevices.currentDevice, configElement.value) + + def inputDevicesDelayChanged(self,configElement): + if self.currentDevice != "" and iInputDevices.currentDevice == "": + iInputDevices.setDelay(self.currentDevice, configElement.value) + elif iInputDevices.currentDevice != "": + iInputDevices.setDelay(iInputDevices.currentDevice, configElement.value) + + def setupConfigEntries(self,device): + cmd = "config.inputDevices." + device + " = ConfigSubsection()" + exec (cmd) + cmd = "config.inputDevices." + device + ".enabled = ConfigYesNo(default = False)" + exec (cmd) + cmd = "config.inputDevices." + device + ".enabled.addNotifier(self.inputDevicesEnabledChanged,config.inputDevices." + device + ".enabled)" + exec (cmd) + cmd = "config.inputDevices." + device + '.name = ConfigText(default="")' + exec (cmd) + cmd = "config.inputDevices." + device + ".name.addNotifier(self.inputDevicesNameChanged,config.inputDevices." + device + ".name)" + exec (cmd) + cmd = "config.inputDevices." + device + ".repeat = ConfigSlider(default=100, increment = 10, limits=(0, 500))" + exec (cmd) + cmd = "config.inputDevices." + device + ".repeat.addNotifier(self.inputDevicesRepeatChanged,config.inputDevices." + device + ".repeat)" + exec (cmd) + cmd = "config.inputDevices." + device + ".delay = ConfigSlider(default=700, increment = 100, limits=(0, 5000))" + exec (cmd) + cmd = "config.inputDevices." + device + ".delay.addNotifier(self.inputDevicesDelayChanged,config.inputDevices." + device + ".delay)" + exec (cmd) - def inputDevicesDelayChanged(configElement): - iDevices.setDelay(configElement.value); - # this will call the "setup-val" initial - config.inputDevices.repeat.addNotifier(inputDevicesRepeatChanged); - config.inputDevices.delay.addNotifier(inputDevicesDelayChanged); +iInputDevices = inputDevices() diff --git a/lib/python/Components/Ipkg.py b/lib/python/Components/Ipkg.py index 0ba1165c..71447775 100755 --- a/lib/python/Components/Ipkg.py +++ b/lib/python/Components/Ipkg.py @@ -1,4 +1,5 @@ from enigma import eConsoleAppContainer +from Tools.Directories import fileExists class IpkgComponent: EVENT_INSTALL = 0 @@ -20,7 +21,7 @@ class IpkgComponent: def __init__(self, ipkg = '/usr/bin/ipkg'): self.ipkg = ipkg - + self.opkgAvail = fileExists('/usr/bin/opkg') self.cmd = eConsoleAppContainer() self.cache = None self.callbackList = [] @@ -89,7 +90,10 @@ class IpkgComponent: if data.find('Downloading') == 0: self.callCallbacks(self.EVENT_DOWNLOAD, data.split(' ', 5)[1].strip()) elif data.find('Upgrading') == 0: - self.callCallbacks(self.EVENT_UPGRADE, data.split(' ', 1)[1].split(' ')[0]) + if self.opkgAvail: + self.callCallbacks(self.EVENT_UPGRADE, data.split(' ', 1)[1].split(' ')[0]) + else: + self.callCallbacks(self.EVENT_UPGRADE, data.split(' ', 1)[1].split(' ')[0]) elif data.find('Installing') == 0: self.callCallbacks(self.EVENT_INSTALL, data.split(' ', 1)[1].split(' ')[0]) elif data.find('Removing') == 0: diff --git a/lib/python/Components/Keyboard.py b/lib/python/Components/Keyboard.py index 820d1036..b026cd56 100755 --- a/lib/python/Components/Keyboard.py +++ b/lib/python/Components/Keyboard.py @@ -1,6 +1,7 @@ from Components.Console import Console from os import listdir as os_listdir, path as os_path from re import compile as re_compile +from enigma import eEnv class Keyboard: def __init__(self): @@ -8,9 +9,9 @@ class Keyboard: self.readKeyboardMapFiles() def readKeyboardMapFiles(self): - for keymapfile in os_listdir('/usr/share/keymaps/'): + for keymapfile in os_listdir(eEnv.resolve('${datadir}/keymaps/')): if (keymapfile.endswith(".info")): - f = open('/usr/share/keymaps/' + keymapfile) + f = open(eEnv.resolve('${datadir}/keymaps/') + keymapfile) mapfile = None mapname = None for line in f: @@ -32,7 +33,7 @@ class Keyboard: try: keymap = self.keyboardmaps[index] print "Activating keymap:",keymap[1] - keymappath = '/usr/share/keymaps/' + keymap[0] + keymappath = eEnv.resolve('${datadir}/keymaps/') + keymap[0] if os_path.exists(keymappath): Console().ePopen(("loadkmap < " + str(keymappath))) except: diff --git a/lib/python/Components/Network.py b/lib/python/Components/Network.py index b9da48d8..e980cb8c 100755 --- a/lib/python/Components/Network.py +++ b/lib/python/Components/Network.py @@ -4,6 +4,7 @@ from socket import * from enigma import eConsoleAppContainer from Components.Console import Console from Components.PluginComponent import plugins +from Components.About import about from Plugins.Plugin import PluginDescriptor class Network: @@ -26,6 +27,9 @@ class Network: self.DnsConsole = Console() self.PingConsole = Console() self.config_ready = None + self.friendlyNames = {} + self.lan_interfaces = [] + self.wlan_interfaces = [] self.getInterfaces() def onRemoteRootFS(self): @@ -309,13 +313,49 @@ class Network: return len(self.ifaces) def getFriendlyAdapterName(self, x): - # maybe this needs to be replaced by an external list. - friendlyNames = { - "eth0": _("Integrated Ethernet"), - "wlan0": _("Wireless"), - "ath0": _("Integrated Wireless") - } - return friendlyNames.get(x, x) # when we have no friendly name, use adapter name + if x in self.friendlyNames.keys(): + return self.friendlyNames.get(x, x) + else: + self.friendlyNames[x] = self.getFriendlyAdapterNaming(x) + return self.friendlyNames.get(x, x) # when we have no friendly name, use adapter name + + def getFriendlyAdapterNaming(self, iface): + if iface.startswith('eth'): + if iface not in self.lan_interfaces and len(self.lan_interfaces) == 0: + self.lan_interfaces.append(iface) + return _("LAN connection") + elif iface not in self.lan_interfaces and len(self.lan_interfaces) >= 1: + self.lan_interfaces.append(iface) + return _("LAN connection") + " " + str(len(self.lan_interfaces)) + else: + if iface not in self.wlan_interfaces and len(self.wlan_interfaces) == 0: + self.wlan_interfaces.append(iface) + return _("WLAN connection") + elif iface not in self.wlan_interfaces and len(self.wlan_interfaces) >= 1: + self.wlan_interfaces.append(iface) + return _("WLAN connection") + " " + str(len(self.wlan_interfaces)) + + def getFriendlyAdapterDescription(self, iface): + if iface == 'eth0': + return _("Internal LAN adapter.") + else: + classdir = "/sys/class/net/" + iface + "/device/" + driverdir = "/sys/class/net/" + iface + "/device/driver/" + if os_path.exists(classdir): + files = listdir(classdir) + if 'driver' in files: + if os_path.realpath(driverdir).endswith('ath_pci'): + return _("Atheros")+ " " + str(os_path.basename(os_path.realpath(driverdir))) + " " + _("WLAN adapter.") + elif os_path.realpath(driverdir).endswith('zd1211b'): + return _("Zydas")+ " " + str(os_path.basename(os_path.realpath(driverdir))) + " " + _("WLAN adapter.") + elif os_path.realpath(driverdir).endswith('rt73'): + return _("Ralink")+ " " + str(os_path.basename(os_path.realpath(driverdir))) + " " + _("WLAN adapter.") + elif os_path.realpath(driverdir).endswith('rt73usb'): + return _("Ralink")+ " " + str(os_path.basename(os_path.realpath(driverdir))) + " " + _("WLAN adapter.") + else: + return str(os_path.basename(os_path.realpath(driverdir))) + " " + _("WLAN adapter.") + else: + return _("Unknown network adapter.") def getAdapterName(self, iface): return iface @@ -569,24 +609,39 @@ class Network: if callback is not None: callback(True) - def detectWlanModule(self): + def detectWlanModule(self, iface = None): self.wlanmodule = None - rt73_dir = "/sys/bus/usb/drivers/rt73/" - zd1211b_dir = "/sys/bus/usb/drivers/zd1211b/" - madwifi_dir = "/sys/bus/pci/drivers/ath_pci/" - if os_path.exists(madwifi_dir): - files = listdir(madwifi_dir) - if len(files) >= 1: - self.wlanmodule = 'madwifi' - if os_path.exists(rt73_dir): - rtfiles = listdir(rt73_dir) - if len(rtfiles) == 2 or len(rtfiles) == 5: - self.wlanmodule = 'ralink' - if os_path.exists(zd1211b_dir): - zdfiles = listdir(zd1211b_dir) - if len(zdfiles) == 1 or len(zdfiles) == 5: - self.wlanmodule = 'zydas' - return self.wlanmodule + classdir = "/sys/class/net/" + iface + "/device/" + driverdir = "/sys/class/net/" + iface + "/device/driver/" + if os_path.exists(classdir): + classfiles = listdir(classdir) + driver_found = False + nl80211_found = False + for x in classfiles: + if x == 'driver': + driver_found = True + if x.startswith('ieee80211:'): + nl80211_found = True + + if driver_found and nl80211_found: + #print about.getKernelVersionString() + self.wlanmodule = "nl80211" + else: + if driver_found and not nl80211_found: + driverfiles = listdir(driverdir) + if os_path.realpath(driverdir).endswith('ath_pci'): + if len(driverfiles) >= 1: + self.wlanmodule = 'madwifi' + if os_path.realpath(driverdir).endswith('rt73'): + if len(driverfiles) == 2 or len(driverfiles) == 5: + self.wlanmodule = 'ralink' + if os_path.realpath(driverdir).endswith('zd1211b'): + if len(driverfiles) == 1 or len(driverfiles) == 5: + self.wlanmodule = 'zydas' + if self.wlanmodule is None: + self.wlanmodule = "wext" + print 'Using "%s" as wpa-supplicant driver' % (self.wlanmodule) + return self.wlanmodule def calc_netmask(self,nmask): from struct import pack, unpack diff --git a/lib/python/Components/NimManager.py b/lib/python/Components/NimManager.py index a69df009..7f7dd5c4 100644 --- a/lib/python/Components/NimManager.py +++ b/lib/python/Components/NimManager.py @@ -10,12 +10,15 @@ from enigma import eDVBSatelliteEquipmentControl as secClass, \ eDVBSatelliteDiseqcParameters as diseqcParam, \ eDVBSatelliteSwitchParameters as switchParam, \ eDVBSatelliteRotorParameters as rotorParam, \ - eDVBResourceManager, eDVBDB + eDVBResourceManager, eDVBDB, eEnv from time import localtime, mktime from datetime import datetime from Tools.BoundFunction import boundFunction +from Tools import Directories +import xml.etree.cElementTree + def getConfigSatlist(orbpos, satlist): default_orbpos = None for x in satlist: @@ -107,9 +110,16 @@ class SecConfigure: def setSatposDepends(self, sec, nim1, nim2): print "tuner", nim1, "depends on satpos of", nim2 sec.setTunerDepends(nim1, nim2) + + def linkInternally(self, slotid): + nim = self.NimManager.getNim(slotid) + if nim.internallyConnectableTo is not None: + nim.setInternalLink() def linkNIMs(self, sec, nim1, nim2): print "link tuner", nim1, "to tuner", nim2 + if nim2 == (nim1 - 1): + self.linkInternally(nim1) sec.setTunerLinked(nim1, nim2) def getRoot(self, slotid, connto): @@ -124,6 +134,9 @@ class SecConfigure: def update(self): sec = secClass.getInstance() self.configuredSatellites = set() + for slotid in self.NimManager.getNimListOfType("DVB-S"): + if self.NimManager.nimInternallyConnectableTo(slotid) is not None: + self.NimManager.nimRemoveInternalLink(slotid) sec.clear() ## this do unlinking NIMs too !! print "sec config cleared" @@ -137,7 +150,7 @@ class SecConfigure: for slot in nim_slots: if slot.type is not None: - used_nim_slots.append((slot.slot, slot.description, slot.config.configMode.value != "nothing" and True or False, slot.isCompatible("DVB-S2"))) + used_nim_slots.append((slot.slot, slot.description, slot.config.configMode.value != "nothing" and True or False, slot.isCompatible("DVB-S2"), slot.frontend_id is None and -1 or slot.frontend_id)) eDVBResourceManager.getInstance().setFrontendSlotInformations(used_nim_slots) for slot in nim_slots: @@ -234,6 +247,20 @@ class SecConfigure: print "sec config completed" def updateAdvanced(self, sec, slotid): + try: + if config.Nims[slotid].advanced.unicableconnected is not None: + if config.Nims[slotid].advanced.unicableconnected.value == True: + config.Nims[slotid].advanced.unicableconnectedTo.save_forced = True + self.linkNIMs(sec, slotid, int(config.Nims[slotid].advanced.unicableconnectedTo.value)) + connto = self.getRoot(slotid, int(config.Nims[slotid].advanced.unicableconnectedTo.value)) + if not self.linked.has_key(connto): + self.linked[connto] = [] + self.linked[connto].append(slotid) + else: + config.Nims[slotid].advanced.unicableconnectedTo.save_forced = False + except: + pass + lnbSat = {} for x in range(1,37): lnbSat[x] = [] @@ -276,24 +303,32 @@ class SecConfigure: sec.setLNBLOFH(10600000) sec.setLNBThreshold(11700000) elif currLnb.lof.value == "unicable": - sec.setLNBLOFL(9750000) - sec.setLNBLOFH(10600000) - sec.setLNBThreshold(11700000) + def setupUnicable(configManufacturer, ProductDict): + manufacturer_name = configManufacturer.value + manufacturer = ProductDict[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) + sec.setLNBSatCRpositions(manufacturer.positions[product_name][0].value) + sec.setLNBLOFL(manufacturer.lofl[product_name][0].value * 1000) + sec.setLNBLOFH(manufacturer.lofh[product_name][0].value * 1000) + sec.setLNBThreshold(manufacturer.loft[product_name][0].value * 1000) + configManufacturer.save_forced = True + manufacturer.product.save_forced = True + manufacturer.vco[product_name][manufacturer.scr[product_name].index].save_forced = True + if currLnb.unicable.value == "unicable_user": +#TODO satpositions for satcruser + sec.setLNBLOFL(currLnb.lofl.value * 1000) + sec.setLNBLOFH(currLnb.lofh.value * 1000) + sec.setLNBThreshold(currLnb.threshold.value * 1000) sec.setLNBSatCR(currLnb.satcruser.index) sec.setLNBSatCRvco(currLnb.satcrvcouser[currLnb.satcruser.index].value*1000) + sec.setLNBSatCRpositions(1) #HACK 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) + setupUnicable(currLnb.unicableMatrixManufacturer, currLnb.unicableMatrix) elif currLnb.unicable.value == "unicable_lnb": - manufacturer_name = currLnb.unicableLnbManufacturer.value - manufacturer = currLnb.unicableLnb[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) + setupUnicable(currLnb.unicableLnbManufacturer, currLnb.unicableLnb) elif currLnb.lof.value == "c_band": sec.setLNBLOFL(5150000) sec.setLNBLOFH(5150000) @@ -355,6 +390,7 @@ class SecConfigure: if currLnb.diseqcMode.value == "1_0": currCO = currLnb.commandOrder1_0.value + sec.setRepeats(0) else: currCO = currLnb.commandOrder.value @@ -446,7 +482,7 @@ class SecConfigure: self.update() class NIM(object): - def __init__(self, slot, type, description, has_outputs = True, internally_connectable = None, multi_type = {}): + def __init__(self, slot, type, description, has_outputs = True, internally_connectable = None, multi_type = {}, frontend_id = None, i2c = None, is_empty = False): self.slot = slot if type not in ("DVB-S", "DVB-C", "DVB-T", "DVB-S2", None): @@ -458,8 +494,13 @@ class NIM(object): self.has_outputs = has_outputs self.internally_connectable = internally_connectable self.multi_type = multi_type + self.i2c = i2c + self.frontend_id = frontend_id + self.__is_empty = is_empty def isCompatible(self, what): + if not self.isSupported(): + return False compatible = { None: (None,), "DVB-S": ("DVB-S", None), @@ -492,15 +533,35 @@ class NIM(object): def getSlotID(self): return chr(ord('A') + self.slot) + def getI2C(self): + return self.i2c + def hasOutputs(self): return self.has_outputs def internallyConnectableTo(self): return self.internally_connectable + def setInternalLink(self): + if self.internally_connectable is not None: + print "setting internal link on frontend id", self.frontend_id + open("/proc/stb/frontend/%d/rf_switch" % self.frontend_id, "w").write("internal") + + def removeInternalLink(self): + if self.internally_connectable is not None: + print "removing internal link on frontend id", self.frontend_id + open("/proc/stb/frontend/%d/rf_switch" % self.frontend_id, "w").write("external") + def isMultiType(self): return (len(self.multi_type) > 0) + def isEmpty(self): + return self.__is_empty + + # empty tuners are supported! + def isSupported(self): + return (self.frontend_id is not None) or self.__is_empty + # returns dict {<slotid>: <type>} def getMultiTypeList(self): return self.multi_type @@ -523,8 +584,10 @@ class NIM(object): if self.empty: nim_text += _("(empty)") + elif not self.isSupported(): + nim_text += self.description + " (" + _("not supported") + ")" else: - nim_text += self.description + " (" + self.friendly_type + ")" + nim_text += self.description + " (" + self.friendly_type + ")" return nim_text @@ -642,14 +705,19 @@ class NimManager: entries[current_slot] = {} elif line.strip().startswith("Type:"): entries[current_slot]["type"] = str(line.strip()[6:]) + entries[current_slot]["isempty"] = False elif line.strip().startswith("Name:"): entries[current_slot]["name"] = str(line.strip()[6:]) + entries[current_slot]["isempty"] = False elif line.strip().startswith("Has_Outputs:"): input = str(line.strip()[len("Has_Outputs:") + 1:]) entries[current_slot]["has_outputs"] = (input == "yes") elif line.strip().startswith("Internally_Connectable:"): input = int(line.strip()[len("Internally_Connectable:") + 1:]) entries[current_slot]["internally_connectable"] = input + elif line.strip().startswith("Frontend_Device:"): + input = int(line.strip()[len("Frontend_Device:") + 1:]) + entries[current_slot]["frontend_device"] = input elif line.strip().startswith("Mode"): # "Mode 0: DVB-T" -> ["Mode 0", " DVB-T"] split = line.strip().split(":") @@ -658,22 +726,35 @@ class NimManager: modes = entries[current_slot].get("multi_type", {}) modes[split2[1]] = split[1].strip() entries[current_slot]["multi_type"] = modes + elif line.strip().startswith("I2C_Device:"): + input = int(line.strip()[len("I2C_Device:") + 1:]) + entries[current_slot]["i2c"] = input elif line.strip().startswith("empty"): entries[current_slot]["type"] = None entries[current_slot]["name"] = _("N/A") + entries[current_slot]["isempty"] = True nimfile.close() + from os import path + for id, entry in entries.items(): if not (entry.has_key("name") and entry.has_key("type")): entry["name"] = _("N/A") entry["type"] = None + if not (entry.has_key("i2c")): + entry["i2c"] = None if not (entry.has_key("has_outputs")): entry["has_outputs"] = True - if not (entry.has_key("internally_connectable")): - entry["internally_connectable"] = None + if entry.has_key("frontend_device"): # check if internally connectable + if path.exists("/proc/stb/frontend/%d/rf_switch" % entry["frontend_device"]): + entry["internally_connectable"] = entry["frontend_device"] - 1 + else: + entry["internally_connectable"] = None + else: + entry["frontend_device"] = entry["internally_connectable"] = None if not (entry.has_key("multi_type")): entry["multi_type"] = {} - self.nim_slots.append(NIM(slot = id, description = entry["name"], type = entry["type"], has_outputs = entry["has_outputs"], internally_connectable = entry["internally_connectable"], multi_type = entry["multi_type"])) + self.nim_slots.append(NIM(slot = id, description = entry["name"], type = entry["type"], has_outputs = entry["has_outputs"], internally_connectable = entry["internally_connectable"], multi_type = entry["multi_type"], frontend_id = entry["frontend_device"], i2c = entry["i2c"], is_empty = entry["isempty"])) def hasNimType(self, chktype): for slot in self.nim_slots: @@ -692,6 +773,12 @@ class NimManager: def getNimName(self, slotid): return self.nim_slots[slotid].description + + def getNim(self, slotid): + return self.nim_slots[slotid] + + def getI2CDevice(self, slotid): + return self.nim_slots[slotid].getI2C() def getNimListOfType(self, type, exception = -1): # returns a list of indexes for NIMs compatible to the given type, except for 'exception' @@ -722,6 +809,12 @@ class NimManager: def hasOutputs(self, slotid): return self.nim_slots[slotid].hasOutputs() + def nimInternallyConnectableTo(self, slotid): + return self.nim_slots[slotid].internallyConnectableTo() + + def nimRemoveInternalLink(self, slotid): + self.nim_slots[slotid].removeInternalLink() + def canConnectTo(self, slotid): slots = [] if self.nim_slots[slotid].internallyConnectableTo() is not None: @@ -982,61 +1075,63 @@ def InitNimManager(nimmgr): lnb_choices = { "universal_lnb": _("Universal LNB"), -# "unicable": _("Unicable"), + "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")}} + unicablelnbproducts = {} + unicablematrixproducts = {} + doc = xml.etree.cElementTree.parse(eEnv.resolve("${datadir}/enigma2/unicable.xml")) + root = doc.getroot() + + entry = root.find("lnb") + for manufacturer in entry.getchildren(): + m={} + for product in manufacturer.getchildren(): + scr=[] + lscr=("scr1","scr2","scr3","scr4","scr5","scr6","scr7","scr8") + for i in range(len(lscr)): + scr.append(product.get(lscr[i],"0")) + for i in range(len(lscr)): + if scr[len(lscr)-i-1] == "0": + scr.pop() + else: + break; + lof=[] + lof.append(int(product.get("positions",1))) + lof.append(int(product.get("lofl",9750))) + lof.append(int(product.get("lofh",10600))) + lof.append(int(product.get("threshold",11700))) + scr.append(tuple(lof)) + m.update({product.get("name"):tuple(scr)}) + unicablelnbproducts.update({manufacturer.get("name"):m}) + + entry = root.find("matrix") + for manufacturer in entry.getchildren(): + m={} + for product in manufacturer.getchildren(): + scr=[] + lscr=("scr1","scr2","scr3","scr4","scr5","scr6","scr7","scr8") + for i in range(len(lscr)): + scr.append(product.get(lscr[i],"0")) + for i in range(len(lscr)): + if scr[len(lscr)-i-1] == "0": + scr.pop() + else: + break; + lof=[] + lof.append(int(product.get("positions",1))) + lof.append(int(product.get("lofl",9750))) + lof.append(int(product.get("lofh",10600))) + lof.append(int(product.get("threshold",11700))) + scr.append(tuple(lof)) + m.update({product.get("name"):tuple(scr)}) + unicablematrixproducts.update({manufacturer.get("name"):m}) + 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() @@ -1103,63 +1198,76 @@ def InitNimManager(nimmgr): else: section.unicable = ConfigSelection(choices = {"unicable_user": _("User defined")}, default = "unicable_user") - if lnb < 3: - section.unicableMatrix = ConfigSubDict() - section.unicableMatrixManufacturer = ConfigSelection(choices = UnicableMatrixManufacturers, default = UnicableMatrixManufacturers[0]) - for y in unicablematrixproducts: - products = unicablematrixproducts[y].keys() + def fillUnicableConf(sectionDict, unicableproducts, vco_null_check): + for y in unicableproducts: + products = unicableproducts[y].keys() products.sort() tmp = ConfigSubsection() tmp.product = ConfigSelection(choices = products, default = products[0]) tmp.scr = ConfigSubDict() tmp.vco = ConfigSubDict() + tmp.lofl = ConfigSubDict() + tmp.lofh = ConfigSubDict() + tmp.loft = ConfigSubDict() + tmp.positions = ConfigSubDict() for z in products: scrlist = [] - vcolist = unicablematrixproducts[y][z] + vcolist = unicableproducts[y][z] tmp.vco[z] = ConfigSubList() - for cnt in range(1,1+len(vcolist)): + for cnt in range(1,1+len(vcolist)-1): vcofreq = int(vcolist[cnt-1]) - if vcofreq == 0: + if vcofreq == 0 and vco_null_check: scrlist.append(("%d" %cnt,"SCR %d " %cnt +_("not used"))) else: scrlist.append(("%d" %cnt,"SCR %d" %cnt)) tmp.vco[z].append(ConfigInteger(default=vcofreq, limits = (vcofreq, vcofreq))) - tmp.scr[z] = ConfigSelection(choices = scrlist, default = scrlist[0][0]) - section.unicableMatrix[y] = tmp + tmp.scr[z] = ConfigSelection(choices = scrlist, default = scrlist[0][0]) + + positions = int(vcolist[len(vcolist)-1][0]) + tmp.positions[z] = ConfigSubList() + tmp.positions[z].append(ConfigInteger(default=positions, limits = (positions, positions))) + + lofl = vcolist[len(vcolist)-1][1] + tmp.lofl[z] = ConfigSubList() + tmp.lofl[z].append(ConfigInteger(default=lofl, limits = (lofl, lofl))) + + lofh = int(vcolist[len(vcolist)-1][2]) + tmp.lofh[z] = ConfigSubList() + tmp.lofh[z].append(ConfigInteger(default=lofh, limits = (lofh, lofh))) + + loft = int(vcolist[len(vcolist)-1][3]) + tmp.loft[z] = ConfigSubList() + tmp.loft[z].append(ConfigInteger(default=loft, limits = (loft, loft))) + sectionDict[y] = tmp + + if lnb < 3: + print "MATRIX" + section.unicableMatrix = ConfigSubDict() + section.unicableMatrixManufacturer = ConfigSelection(UnicableMatrixManufacturers, UnicableMatrixManufacturers[0]) + fillUnicableConf(section.unicableMatrix, unicablematrixproducts, True) if lnb < 2: + print "LNB" section.unicableLnb = ConfigSubDict() section.unicableLnbManufacturer = ConfigSelection(UnicableLnbManufacturers, UnicableLnbManufacturers[0]) - for y in unicablelnbproducts: - products = unicablelnbproducts[y].keys() - products.sort() - tmp = ConfigSubsection() - tmp.product = ConfigSelection(choices = products, default = products[0]) - tmp.scr = ConfigSubDict() - tmp.vco = ConfigSubDict() - for z in products: - scrlist = [] - vcolist = unicablelnbproducts[y][z] - tmp.vco[z] = ConfigSubList() - for cnt in range(1,1+len(vcolist)): - scrlist.append(("%d" %cnt,"SCR %d" %cnt)) - vcofreq = int(vcolist[cnt-1]) - tmp.vco[z].append(ConfigInteger(default=vcofreq, limits = (vcofreq, vcofreq))) - tmp.scr[z] = ConfigSelection(choices = scrlist, default = scrlist[0][0]) - section.unicableLnb[y] = tmp + fillUnicableConf(section.unicableLnb, unicablelnbproducts, False) +#TODO satpositions for satcruser section.satcruser = ConfigSelection(advanced_lnb_satcruser_choices, default="1") tmp = ConfigSubList() - tmp.append(ConfigInteger(default=1284, limits = (0, 9999))) - tmp.append(ConfigInteger(default=1400, limits = (0, 9999))) - tmp.append(ConfigInteger(default=1516, limits = (0, 9999))) - tmp.append(ConfigInteger(default=1632, limits = (0, 9999))) - tmp.append(ConfigInteger(default=1748, limits = (0, 9999))) - tmp.append(ConfigInteger(default=1864, limits = (0, 9999))) - tmp.append(ConfigInteger(default=1980, limits = (0, 9999))) - tmp.append(ConfigInteger(default=2096, limits = (0, 9999))) + tmp.append(ConfigInteger(default=1284, limits = (950, 2150))) + tmp.append(ConfigInteger(default=1400, limits = (950, 2150))) + tmp.append(ConfigInteger(default=1516, limits = (950, 2150))) + tmp.append(ConfigInteger(default=1632, limits = (950, 2150))) + tmp.append(ConfigInteger(default=1748, limits = (950, 2150))) + tmp.append(ConfigInteger(default=1864, limits = (950, 2150))) + tmp.append(ConfigInteger(default=1980, limits = (950, 2150))) + tmp.append(ConfigInteger(default=2096, limits = (950, 2150))) section.satcrvcouser = tmp + nim.advanced.unicableconnected = ConfigYesNo(default=False) + nim.advanced.unicableconnectedTo = ConfigSelection([(str(id), nimmgr.getNimDescription(id)) for id in nimmgr.getNimListOfType("DVB-S") if id != x]) + def configDiSEqCModeChanged(configElement): section = configElement.section if configElement.value == "1_2" and isinstance(section.longitude, ConfigNothing): @@ -1297,7 +1405,7 @@ def InitNimManager(nimmgr): nim = config.Nims[x] if slot.isCompatible("DVB-S"): - nim.toneAmplitude = ConfigSelection([("9", "600mV"), ("8", "700mV"), ("7", "800mV"), ("6", "900mV"), ("5", "1100mV")], "7") + nim.toneAmplitude = ConfigSelection([("11", "340mV"), ("10", "360mV"), ("9", "600mV"), ("8", "700mV"), ("7", "800mV"), ("6", "900mV"), ("5", "1100mV")], "7") nim.toneAmplitude.fe_id = x - empty_slots nim.toneAmplitude.slot_id = x nim.toneAmplitude.addNotifier(toneAmplitudeChanged) diff --git a/lib/python/Components/ParentalControl.py b/lib/python/Components/ParentalControl.py index 9942bca7..0ea65cd2 100644 --- a/lib/python/Components/ParentalControl.py +++ b/lib/python/Components/ParentalControl.py @@ -21,6 +21,8 @@ IMG_BLACKSERVICE = LIST_BLACKLIST + "-" + TYPE_SERVICE IMG_BLACKBOUQUET = LIST_BLACKLIST + "-" + TYPE_BOUQUET def InitParentalControl(): + global parentalControl + parentalControl = ParentalControl() config.ParentalControl = ConfigSubsection() config.ParentalControl.configured = ConfigYesNo(default = False) config.ParentalControl.mode = ConfigSelection(default = "simple", choices = [("simple", _("simple")), ("complex", _("complex"))]) @@ -55,11 +57,10 @@ def InitParentalControl(): class ParentalControl: def __init__(self): #Do not call open on init, because bouquets are not ready at that moment -# self.open() + self.open() self.serviceLevel = {} #Instead: Use Flags to see, if we already initialized config and called open self.configInitialized = False - self.filesOpened = False #This is the timer that is used to see, if the time for caching the pin is over #Of course we could also work without a timer and compare the times every #time we call isServicePlayable. But this might probably slow down zapping, @@ -89,9 +90,6 @@ class ParentalControl: def isServicePlayable(self, ref, callback): if not config.ParentalControl.configured.value or not config.ParentalControl.servicepinactive.value: return True - #Check if we already read the whitelists and blacklists. If not: call open - if self.filesOpened == False: - self.open() #Check if configuration has already been read or if the significant values have changed. #If true: read the configuration if self.configInitialized == False or self.storeServicePin != config.ParentalControl.storeservicepin.value or self.storeServicePinCancel != config.ParentalControl.storeservicepincancel.value: @@ -153,8 +151,6 @@ class ParentalControl: def getProtectionType(self, service): #New method used in ParentalControlList: This method does not only return #if a service is protected or not, it also returns, why (whitelist or blacklist, service or bouquet) - if self.filesOpened == False: - self.open() sImage = "" if (config.ParentalControl.type.value == LIST_WHITELIST): if self.whitelist.has_key(service): @@ -319,14 +315,10 @@ class ParentalControl: def save(self): # we need to open the files in case we havent's read them yet - if not self.filesOpened: - self.open() self.saveListToFile(LIST_BLACKLIST) self.saveListToFile(LIST_WHITELIST) def open(self): self.openListFromFile(LIST_BLACKLIST) self.openListFromFile(LIST_WHITELIST) - self.filesOpened = True -parentalControl = ParentalControl() diff --git a/lib/python/Components/ParentalControlList.py b/lib/python/Components/ParentalControlList.py index 797ea391..0e65257d 100644 --- a/lib/python/Components/ParentalControlList.py +++ b/lib/python/Components/ParentalControlList.py @@ -1,5 +1,5 @@ from MenuList import MenuList -from Components.ParentalControl import parentalControl, IMG_WHITESERVICE, IMG_WHITEBOUQUET, IMG_BLACKSERVICE, IMG_BLACKBOUQUET +from Components.ParentalControl import IMG_WHITESERVICE, IMG_WHITEBOUQUET, IMG_BLACKSERVICE, IMG_BLACKBOUQUET from Tools.Directories import SCOPE_SKIN_IMAGE, resolveFilename from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT @@ -32,13 +32,14 @@ class ParentalControlList(MenuList): self.l.setItemHeight(32) def toggleSelectedLock(self): + from Components.ParentalControl import parentalControl print "self.l.getCurrentSelection():", self.l.getCurrentSelection() print "self.l.getCurrentSelectionIndex():", self.l.getCurrentSelectionIndex() curSel = self.l.getCurrentSelection() if curSel[0][2]: parentalControl.unProtectService(self.l.getCurrentSelection()[0][0]) else: - parentalControl.protectService(self.l.getCurrentSelection()[0][0]) + parentalControl.protectService(self.l.getCurrentSelection()[0][0]) #Instead of just negating the locked- flag, now I call the getProtectionType every time... self.list[self.l.getCurrentSelectionIndex()] = ParentalControlEntryComponent(curSel[0][0], curSel[0][1], parentalControl.getProtectionType(curSel[0][0])) self.l.setList(self.list) diff --git a/lib/python/Components/RecordingConfig.py b/lib/python/Components/RecordingConfig.py index fe9284d9..40dfb2ca 100644..100755 --- a/lib/python/Components/RecordingConfig.py +++ b/lib/python/Components/RecordingConfig.py @@ -1,4 +1,4 @@ -from config import ConfigNumber, ConfigYesNo, ConfigSubsection, config +from config import ConfigNumber, ConfigYesNo, ConfigSubsection, ConfigSelection, config def InitRecordingConfig(): config.recording = ConfigSubsection(); @@ -8,3 +8,7 @@ def InitRecordingConfig(): config.recording.margin_after = ConfigNumber(default=0) config.recording.debug = ConfigYesNo(default = False) config.recording.ascii_filenames = ConfigYesNo(default = False) + config.recording.filename_composition = ConfigSelection(default = "standard", choices = [ + ("standard", _("standard")), + ("short", _("Short filenames")), + ("long", _("Long filenames")) ] )
\ No newline at end of file diff --git a/lib/python/Components/Renderer/Listbox.py b/lib/python/Components/Renderer/Listbox.py index 640121e1..716fe445 100644..100755 --- a/lib/python/Components/Renderer/Listbox.py +++ b/lib/python/Components/Renderer/Listbox.py @@ -19,6 +19,7 @@ class Listbox(Renderer, object): self.__content = None self.__wrap_around = False self.__selection_enabled = True + self.__scrollbarMode = "showOnDemand" GUI_WIDGET = eListbox @@ -38,6 +39,7 @@ class Listbox(Renderer, object): instance.selectionChanged.get().append(self.selectionChanged) self.wrap_around = self.wrap_around # trigger self.selection_enabled = self.selection_enabled # trigger + self.scrollbarMode = self.scrollbarMode # trigger def preWidgetRemove(self, instance): instance.setContent(None) @@ -76,9 +78,22 @@ class Listbox(Renderer, object): selection_enabled = property(lambda self: self.__selection_enabled, setSelectionEnabled) + def setScrollbarMode(self, mode): + self.__scrollbarMode = mode + if self.instance is not None: + self.instance.setScrollbarMode(int( + { "showOnDemand": 0, + "showAlways": 1, + "showNever": 2, + }[mode])) + + scrollbarMode = property(lambda self: self.__scrollbarMode, setScrollbarMode) + def changed(self, what): if hasattr(self.source, "selectionEnabled"): self.selection_enabled = self.source.selectionEnabled + if hasattr(self.source, "scrollbarMode"): + self.scrollbarMode = self.source.scrollbarMode if len(what) > 1 and isinstance(what[1], str) and what[1] == "style": return self.content = self.source.content diff --git a/lib/python/Components/Renderer/Picon.py b/lib/python/Components/Renderer/Picon.py index 5ae43ed8..51dc09a5 100644 --- a/lib/python/Components/Renderer/Picon.py +++ b/lib/python/Components/Renderer/Picon.py @@ -2,11 +2,11 @@ ## Picon renderer by Gruffy .. some speedups by Ghost ## from Renderer import Renderer -from enigma import ePixmap +from enigma import ePixmap, eEnv from Tools.Directories import fileExists, SCOPE_SKIN_IMAGE, SCOPE_CURRENT_SKIN, resolveFilename class Picon(Renderer): - searchPaths = ('/usr/share/enigma2/%s/', + searchPaths = (eEnv.resolve('${datadir}/enigma2/%s/'), '/media/cf/%s/', '/media/usb/%s/') diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 6095812a..cd055a82 100755..100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -7,6 +7,8 @@ from Tools.LoadPixmap import LoadPixmap from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN +from Components.config import config + class ServiceList(HTMLComponent, GUIComponent): MODE_NORMAL = 0 MODE_FAVOURITES = 1 @@ -62,6 +64,22 @@ class ServiceList(HTMLComponent, GUIComponent): self.l.setColor(eListboxServiceContent.markedBackgroundSelected, parseColor(value)) elif attrib == "foregroundColorServiceNotAvail": self.l.setColor(eListboxServiceContent.serviceNotAvail, parseColor(value)) + elif attrib == "colorEventProgressbar": + self.l.setColor(eListboxServiceContent.serviceEventProgressbarColor, parseColor(value)) + elif attrib == "colorEventProgressbarSelected": + self.l.setColor(eListboxServiceContent.serviceEventProgressbarColorSelected, parseColor(value)) + elif attrib == "colorEventProgressbarBorder": + self.l.setColor(eListboxServiceContent.serviceEventProgressbarBorderColor, parseColor(value)) + elif attrib == "colorEventProgressbarBorderSelected": + self.l.setColor(eListboxServiceContent.serviceEventProgressbarBorderColorSelected, parseColor(value)) + elif attrib == "colorServiceDescription": + self.l.setColor(eListboxServiceContent.serviceDescriptionColor, parseColor(value)) + elif attrib == "colorServiceDescriptionSelected": + self.l.setColor(eListboxServiceContent.serviceDescriptionColorSelected, parseColor(value)) + elif attrib == "picServiceEventProgressbar": + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, value)) + if pic: + self.l.setPixmap(self.l.picServiceEventProgressbar, pic) elif attrib == "serviceItemHeight": self.ItemHeight = int(value) elif attrib == "serviceNameFont": @@ -213,17 +231,24 @@ class ServiceList(HTMLComponent, GUIComponent): def setMode(self, mode): self.mode = mode + self.l.setItemHeight(self.ItemHeight) + self.l.setVisualMode(eListboxServiceContent.visModeComplex) if mode == self.MODE_NORMAL: - self.l.setItemHeight(self.ItemHeight) - self.l.setVisualMode(eListboxServiceContent.visModeComplex) + if config.usage.show_event_progress_in_servicelist.value: + self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(0, 0, 52, self.ItemHeight)) + else: + self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(0, 0, 0, 0)) self.l.setElementFont(self.l.celServiceName, self.ServiceNameFont) self.l.setElementPosition(self.l.celServiceName, eRect(0, 0, self.instance.size().width(), self.ItemHeight)) self.l.setElementFont(self.l.celServiceInfo, self.ServiceInfoFont) else: - self.l.setItemHeight(self.ItemHeight) - self.l.setVisualMode(eListboxServiceContent.visModeComplex) + if config.usage.show_event_progress_in_servicelist.value: + self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(60, 0, 52, self.ItemHeight)) + else: + self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(60, 0, 0, 0)) self.l.setElementFont(self.l.celServiceNumber, self.ServiceNumberFont) self.l.setElementPosition(self.l.celServiceNumber, eRect(0, 0, 50, self.ItemHeight)) self.l.setElementFont(self.l.celServiceName, self.ServiceNameFont) self.l.setElementPosition(self.l.celServiceName, eRect(60, 0, self.instance.size().width()-60, self.ItemHeight)) self.l.setElementFont(self.l.celServiceInfo, self.ServiceInfoFont) + diff --git a/lib/python/Components/Task.py b/lib/python/Components/Task.py index 2e4e757d..3a755405 100644 --- a/lib/python/Components/Task.py +++ b/lib/python/Components/Task.py @@ -64,11 +64,10 @@ class Job(object): def runNext(self): if self.current_task == len(self.tasks): if len(self.resident_tasks) == 0: - cb = self.callback - self.callback = None self.status = self.FINISHED self.state_changed() - cb(self, None, []) + self.callback(self, None, []) + self.callback = None else: print "still waiting for %d resident task(s) %s to finish" % (len(self.resident_tasks), str(self.resident_tasks)) else: diff --git a/lib/python/Components/TimerSanityCheck.py b/lib/python/Components/TimerSanityCheck.py index 8f48d1ec..b472a19e 100644 --- a/lib/python/Components/TimerSanityCheck.py +++ b/lib/python/Components/TimerSanityCheck.py @@ -12,8 +12,8 @@ class TimerSanityCheck: self.simultimer = [] self.rep_eventlist = [] self.nrep_eventlist = [] - self.bflag = 1 - self.eflag = -1 + self.bflag = -1 + self.eflag = 1 def check(self, ext_timer=1): print "check" diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index c0213d99..a265a169 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -1,7 +1,7 @@ from Components.Harddisk import harddiskmanager from config import ConfigSubsection, ConfigYesNo, config, ConfigSelection, ConfigText, ConfigNumber, ConfigSet, ConfigLocations from Tools.Directories import resolveFilename, SCOPE_HDD -from enigma import Misc_Options, setTunerTypePriorityOrder; +from enigma import Misc_Options, setTunerTypePriorityOrder, eEnv; from SystemInfo import SystemInfo import os @@ -51,7 +51,14 @@ def InitUsageConfig(): config.usage.on_long_powerpress = ConfigSelection(default = "show_menu", choices = [ ("show_menu", _("show shutdown menu")), - ("shutdown", _("immediate shutdown")) ] ) + ("shutdown", _("immediate shutdown")), + ("standby", _("Standby")) ] ) + + config.usage.on_short_powerpress = ConfigSelection(default = "standby", choices = [ + ("show_menu", _("show shutdown menu")), + ("shutdown", _("immediate shutdown")), + ("standby", _("Standby")) ] ) + config.usage.alternatives_priority = ConfigSelection(default = "0", choices = [ ("0", "DVB-S/-C/-T"), @@ -61,6 +68,8 @@ def InitUsageConfig(): ("4", "DVB-T/-C/-S"), ("5", "DVB-T/-S/-C") ]) + config.usage.show_event_progress_in_servicelist = ConfigYesNo(default = False) + config.usage.blinking_display_clock_during_recording = ConfigYesNo(default = False) config.usage.show_message_when_recording_starts = ConfigYesNo(default = True) @@ -85,7 +94,7 @@ def InitUsageConfig(): SystemInfo["12V_Output"] = Misc_Options.getInstance().detected_12V_output() - config.usage.keymap = ConfigText(default = "/usr/share/enigma2/keymap.xml") + config.usage.keymap = ConfigText(default = eEnv.resolve("${datadir}/enigma2/keymap.xml")) config.seek = ConfigSubsection() config.seek.selfdefined_13 = ConfigNumber(default=15) diff --git a/lib/python/Components/config.py b/lib/python/Components/config.py index 471b59ec..6e560857 100755 --- a/lib/python/Components/config.py +++ b/lib/python/Components/config.py @@ -29,6 +29,7 @@ from time import localtime, strftime class ConfigElement(object): def __init__(self): self.saved_value = None + self.save_forced = False self.last_value = None self.save_disabled = False self.__notifiers = None @@ -83,7 +84,7 @@ class ConfigElement(object): # you need to override this if str(self.value) doesn't work def save(self): - if self.save_disabled or self.value == self.default: + if self.save_disabled or (self.value == self.default and not self.save_forced): self.saved_value = None else: self.saved_value = self.tostring(self.value) @@ -1623,16 +1624,17 @@ class Config(ConfigSubsection): self.pickle_this("config", self.saved_value, result) return ''.join(result) - def unpickle(self, lines): + def unpickle(self, lines, base_file=True): tree = { } for l in lines: if not l or l[0] == '#': continue n = l.find('=') + name = l[:n] val = l[n+1:].strip() - names = l[:n].split('.') + names = name.split('.') # if val.find(' ') != -1: # val = val[:val.find(' ')] @@ -1643,6 +1645,15 @@ class Config(ConfigSubsection): base[names[-1]] = val + if not base_file: # not the initial config file.. + #update config.x.y.value when exist + try: + configEntry = eval(name) + if configEntry is not None: + configEntry.value = val + except (SyntaxError, KeyError): + pass + # we inherit from ConfigSubsection, so ... #object.__setattr__(self, "saved_value", tree["config"]) if "config" in tree: @@ -1654,9 +1665,9 @@ class Config(ConfigSubsection): f.write(text) f.close() - def loadFromFile(self, filename): + def loadFromFile(self, filename, base_file=False): f = open(filename, "r") - self.unpickle(f.readlines()) + self.unpickle(f.readlines(), base_file) f.close() config = Config() @@ -1667,7 +1678,7 @@ class ConfigFile: def load(self): try: - config.loadFromFile(self.CONFIG_FILE) + config.loadFromFile(self.CONFIG_FILE, True) except IOError, e: print "unable to load config (%s), assuming defaults..." % str(e) |
