class Menu(Screen, ProtectedScreen): ALLOW_SUSPEND = True def okbuttonClick(self): if self.number: self["menu"].setIndex(self.number - 1) self.resetNumberKey() selection = self["menu"].getCurrent() if selection and selection[1]: selection[1]() def execText(self, text): exec text def runScreen(self, arg): # arg[0] is the module (as string) # arg[1] is Screen inside this module # plus possible arguments, as # string (as we want to reference # stuff which is just imported) # FIXME. somehow if arg[0] != "": exec "from " + arg[0] + " import *" self.openDialog(*eval(arg[1])) def nothing(self): #dummy pass def openDialog(self, *dialog): # in every layer needed self.session.openWithCallback(self.menuClosed, *dialog) def openSetup(self, dialog): self.session.openWithCallback(self.menuClosed, Setup, dialog) def addMenu(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return 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) else: a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node) #TODO add check if !empty(node.childNodes) destList.append((MenuTitle, a, entryID, weight)) def menuClosedWithConfigFlush(self, *res): configfile.save() self.menuClosed(*res) def menuClosed(self, *res): if res and res[0]: self.close(True) else: self.createMenuList() def addItem(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return conditional = node.get("conditional") if conditional and not eval(conditional): return 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 # print module, screen if module: module = "Screens." + module else: module = "" # check for arguments. they will be appended to the # openDialog call args = x.text or "" screen += ", " + args destList.append((_(item_text or "??"), boundFunction(self.runScreen, (module, screen)), entryID, weight)) return elif x.tag == 'code': destList.append((_(item_text or "??"), boundFunction(self.execText, x.text), entryID, weight)) return elif x.tag == 'setup': id = x.get("id") if item_text == "": item_text = _(getSetupTitle(id)) else: item_text = _(item_text) destList.append((item_text, boundFunction(self.openSetup, id), entryID, weight)) return destList.append((item_text, self.nothing, entryID, weight)) def sortByName(self, listentry): return listentry[0].lower() def __init__(self, session, parent): self.parentmenu = parent Screen.__init__(self, session) self["menu"] = List([]) self["menu"].enableWrapAround = True self.createMenuList() # for the skin: first try a menu_<menuID>, then Menu self.skinName = [ ] if self.menuID: self.skinName.append("menu_" + self.menuID) self.skinName.append("Menu") ProtectedScreen.__init__(self) self["actions"] = NumberActionMap(["OkCancelActions", "MenuActions", "NumberActions"], { "ok": self.okbuttonClick, "cancel": self.closeNonRecursive, "menu": self.closeRecursive, "0": self.keyNumberGlobal, "1": self.keyNumberGlobal, "2": self.keyNumberGlobal, "3": self.keyNumberGlobal, "4": self.keyNumberGlobal, "5": self.keyNumberGlobal, "6": self.keyNumberGlobal, "7": self.keyNumberGlobal, "8": self.keyNumberGlobal, "9": self.keyNumberGlobal }) if config.usage.menu_sort_mode.value == "user": self["EditActions"] = ActionMap(["ColorActions"], { "blue": self.keyBlue, }) title = parent.get("title", "").encode("UTF-8") or None title = title and _(title) or _(parent.get("text", "").encode("UTF-8")) title = self.__class__.__name__ == "MenuSort" and _("Menusort (%s)") % title or title self["title"] = StaticText(title) self.setScreenPathMode(True) self.setTitle(title) self.number = 0 self.nextNumberTimer = eTimer() self.nextNumberTimer.callback.append(self.okbuttonClick) def createMenuList(self): self.list = [] self.menuID = None for x in self.parentmenu: #walk through the actual nodelist if not x.tag: continue if x.tag == 'item': item_level = int(x.get("level", 0)) if item_level <= config.usage.setup_level.index: self.addItem(self.list, x) count += 1 elif x.tag == 'menu': item_level = int(x.get("level", 0)) if item_level <= config.usage.setup_level.index: self.addMenu(self.list, x) count += 1 elif x.tag == "id": self.menuID = x.get("val") count = 0 if self.menuID: # menuupdater? if menuupdater.updatedMenuAvailable(self.menuID): for x in menuupdater.getUpdatedMenu(self.menuID): if x[1] == count: self.list.append((x[0], boundFunction(self.runScreen, (x[2], x[3] + ", ")), x[4])) count += 1 if self.menuID: # plugins for l in plugins.getPluginsForMenu(self.menuID): # check if a plugin overrides an existing menu plugin_menuid = l[2] for x in self.list: if x[2] == plugin_menuid: self.list.remove(x) break self.list.append((l[0], boundFunction(l[1], self.session, close=self.close), l[2], l[3] or 50)) if config.usage.menu_sort_mode.value == "user" and self.menuID == "mainmenu": plugin_list = [] id_list = [] for l in plugins.getPlugins([PluginDescriptor.WHERE_PLUGINMENU ,PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO]): l.id = (l.name.lower()).replace(' ','_') if l.id not in id_list: id_list.append(l.id) plugin_list.append((l.name, boundFunction(l.__call__, self.session), l.id, 200)) if self.menuID is not None and config.usage.menu_sort_mode.value == "user": self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue(self.menuID, "submenu") or {} idx = 0 for x in self.list: entry = list(self.list.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue(entry[2], "sort") or entry[3] entry.append(m_weight) self.list.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], "sort", m_weight) idx += 1 self.full_list = list(self.list) if config.usage.menu_sort_mode.value == "a_z": # Sort by Name self.list.sort(key=self.sortByName) elif config.usage.menu_sort_mode.value == "user": self.hide_show_entries() else: # Sort by Weight self.list.sort(key=lambda x: int(x[3])) if config.usage.menu_show_numbers.value: self.list = [(str(x[0] + 1) + " " +x[1][0], x[1][1], x[1][2]) for x in enumerate(self.list)] self["menu"].updateList(self.list) def keyNumberGlobal(self, number): self.number = self.number * 10 + number if self.number and self.number <= len(self["menu"].list): if number * 10 > len(self["menu"].list) or self.number >= 10: self.okbuttonClick() else: self.nextNumberTimer.start(1500, True) else: self.resetNumberKey() def resetNumberKey(self): self.nextNumberTimer.stop() self.number = 0 def closeNonRecursive(self): self.resetNumberKey() self.close(False) def closeRecursive(self): self.resetNumberKey() self.close(True) def createSummary(self): return MenuSummary def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value and not(hasattr(self.session, 'infobar') and self.session.infobar is None): return self.menuID == "mainmenu" elif config.ParentalControl.config_sections.configuration.value and self.menuID == "setup": return True elif config.ParentalControl.config_sections.timer_menu.value and self.menuID == "timermenu": return True elif config.ParentalControl.config_sections.standby_menu.value and self.menuID == "shutdown": return True def keyBlue(self): if config.usage.menu_sort_mode.value == "user": self.session.openWithCallback(self.menuSortCallBack, MenuSort, self.parentmenu) def menuSortCallBack(self, key=False): self.createMenuList() def keyCancel(self): self.closeNonRecursive() def hide_show_entries(self): self.list = [] for entry in self.full_list: if not self.sub_menu_sort.getConfigValue(entry[2], "hidden"): self.list.append(entry) if not self.list: self.list.append(('',None,'dummy','10',10)) self.list.sort(key=lambda listweight : int(listweight[4]))
class Menu(Screen, ProtectedScreen): ALLOW_SUSPEND = True png_cache = {} def okbuttonClick(self): global lastMenuID if self.number: self["menu"].setIndex(self.number - 1) self.resetNumberKey() selection = self["menu"].getCurrent() if selection and selection[1]: lastMenuID = selection[2] selection[1]() def execText(self, text): exec(text) def runScreen(self, arg): # arg[0] is the module (as string) # arg[1] is Screen inside this module # plus possible arguments, as # string (as we want to reference # stuff which is just imported) if arg[0] != "": exec("from %s import %s" % (arg[0], arg[1].split(",")[0])) self.openDialog(*eval(arg[1])) def nothing(self): # dummy pass def openDialog(self, *dialog): # in every layer needed self.session.openWithCallback(self.menuClosed, *dialog) def openSetup(self, dialog): self.session.openWithCallback(self.menuClosed, Setup, dialog) def addMenu(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return 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) else: a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node) # TODO add check if !empty(node.childNodes) destList.append((MenuTitle, a, entryID, weight)) def menuClosedWithConfigFlush(self, *res): configfile.save() self.menuClosed(*res) def menuClosed(self, *res): global lastMenuID if res and res[0]: lastMenuID = None self.close(True) elif len(self.list) == 1: self.close() else: self.createMenuList() def addItem(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return conditional = node.get("conditional") if conditional and not eval(conditional): return 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 # print(module, screen) if module: module = "Screens." + module else: module = "" # check for arguments. they will be appended to the # openDialog call args = x.text or "" screen += ", " + args destList.append( (_(item_text or "??"), boundFunction(self.runScreen, (module, screen)), entryID, weight)) return elif x.tag == 'code': destList.append( (_(item_text or "??"), boundFunction(self.execText, x.text), entryID, weight)) return elif x.tag == 'setup': id = x.get("id") if item_text == "": item_text = _(getSetupTitle(id)) else: item_text = _(item_text) destList.append( (item_text, boundFunction(self.openSetup, id), entryID, weight)) return destList.append((item_text, self.nothing, entryID, weight)) def sortByName(self, listentry): return listentry[0].lower() def __init__(self, session, parent): self.parentmenu = parent Screen.__init__(self, session) self["key_blue"] = StaticText("") self["menu"] = List([]) self["menu"].enableWrapAround = True self.showNumericHelp = False self.createMenuList() # for the skin: first try a menu_<menuID>, then Menu self.skinName = [] if self.menuID is not None: if config.usage.menutype.value == 'horzanim' and findSkinScreen( "Animmain"): self.skinName.append('Animmain') elif config.usage.menutype.value == 'horzicon' and findSkinScreen( "Iconmain"): self.skinName.append('Iconmain') else: self.skinName.append('menu_' + self.menuID) self.skinName.append("Menu") ProtectedScreen.__init__(self) self["actions"] = NumberActionMap( [ "OkCancelActions", "MenuActions", "NumberActions", "HelpActions", "ColorActions" ], { "ok": self.okbuttonClick, "cancel": self.closeNonRecursive, "menu": self.closeRecursive, "0": self.keyNumberGlobal, "1": self.keyNumberGlobal, "2": self.keyNumberGlobal, "3": self.keyNumberGlobal, "4": self.keyNumberGlobal, "5": self.keyNumberGlobal, "6": self.keyNumberGlobal, "7": self.keyNumberGlobal, "8": self.keyNumberGlobal, "9": self.keyNumberGlobal, "displayHelp": self.showHelp, "blue": self.keyBlue, }) title = parent.get("title", "").encode("UTF-8") or None title = title and _(title) or _(parent.get("text", "").encode("UTF-8")) title = self.__class__.__name__ == "MenuSort" and _( "Menusort (%s)") % title or title if title is None: title = _(parent.get('text', '').encode('UTF-8')) else: t_history.reset() self["title"] = StaticText(title) self.setTitle(title) self.menu_title = title self['thistory'] = StaticText(t_history.thistory) history_len = len(t_history.thistory) self['title0'] = StaticText('') self['title1'] = StaticText('') self['title2'] = StaticText('') if history_len < 13: self['title0'] = StaticText(title) elif history_len < 21: self['title0'] = StaticText('') self['title1'] = StaticText(title) else: self['title0'] = StaticText('') self['title1'] = StaticText('') self['title2'] = StaticText(title) if t_history.thistory == '': t_history.thistory = str(title) + ' > ' else: t_history.thistory = t_history.thistory + str(title) + ' > ' if config.usage.menutype.value == 'horzanim' and findSkinScreen( "Animmain"): self['label1'] = StaticText() self['label2'] = StaticText() self['label3'] = StaticText() self['label4'] = StaticText() self['label5'] = StaticText() self.onShown.append(self.openTestA) elif config.usage.menutype.value == 'horzicon' and findSkinScreen( "Iconmain"): self['label1'] = StaticText() self['label2'] = StaticText() self['label3'] = StaticText() self['label4'] = StaticText() self['label5'] = StaticText() self['label6'] = StaticText() self['label1s'] = StaticText() self['label2s'] = StaticText() self['label3s'] = StaticText() self['label4s'] = StaticText() self['label5s'] = StaticText() self['label6s'] = StaticText() self['pointer'] = Pixmap() self['pixmap1'] = Pixmap() self['pixmap2'] = Pixmap() self['pixmap3'] = Pixmap() self['pixmap4'] = Pixmap() self['pixmap5'] = Pixmap() self['pixmap6'] = Pixmap() self.onShown.append(self.openTestB) self.number = 0 self.nextNumberTimer = eTimer() self.nextNumberTimer.callback.append(self.okbuttonClick) if len(self.list) == 1: self.onExecBegin.append(self.__onExecBegin) def openTestA(self): self.session.open(AnimMain, self.list, self.menu_title) self.close() def openTestB(self): self.session.open(IconMain, self.list, self.menu_title) self.close() def __onExecBegin(self): self.onExecBegin.remove(self.__onExecBegin) self.okbuttonClick() def showHelp(self): if config.usage.menu_show_numbers.value not in ("menu&plugins", "menu"): self.showNumericHelp = not self.showNumericHelp self.createMenuList(self.showNumericHelp) def createMenuList(self, showNumericHelp=False): self["key_blue"].text = _( "Edit menu") if config.usage.menu_sort_mode.value == "user" else "" self.list = [] self.menuID = None for x in self.parentmenu: # walk through the actual nodelist if not x.tag: continue if x.tag == 'item': item_level = int(x.get("level", 0)) if item_level <= config.usage.setup_level.index: self.addItem(self.list, x) count += 1 elif x.tag == 'menu': item_level = int(x.get("level", 0)) if item_level <= config.usage.setup_level.index: self.addMenu(self.list, x) count += 1 elif x.tag == "id": self.menuID = x.get("val") count = 0 if self.menuID: # menuupdater? if menuupdater.updatedMenuAvailable(self.menuID): for x in menuupdater.getUpdatedMenu(self.menuID): if x[1] == count: self.list.append( (x[0], boundFunction(self.runScreen, (x[2], x[3] + ", ")), x[4])) count += 1 if self.menuID: # plugins for l in plugins.getPluginsForMenu(self.menuID): # check if a plugin overrides an existing menu plugin_menuid = l[2] for x in self.list: if x[2] == plugin_menuid: self.list.remove(x) break self.list.append( (l[0], boundFunction(l[1], self.session, close=self.close), l[2], l[3] or 50)) if "user" in config.usage.menu_sort_mode.value and self.menuID == "mainmenu": plugin_list = [] id_list = [] for l in plugins.getPlugins([ PluginDescriptor.WHERE_PLUGINMENU, PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO ]): l.id = (l.name.lower()).replace(' ', '_') if l.id not in id_list: id_list.append(l.id) plugin_list.append( (l.name, boundFunction(l.__call__, self.session), l.id, 200)) if self.menuID is not None and "user" in config.usage.menu_sort_mode.value: self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue( self.menuID, "submenu") or {} idx = 0 for x in self.list: entry = list(self.list.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue( entry[2], "sort") or entry[3] entry.append(m_weight) self.list.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], "sort", m_weight) idx += 1 self.full_list = list(self.list) if config.usage.menu_sort_mode.value == "a_z": # Sort by Name self.list.sort(key=self.sortByName) elif "user" in config.usage.menu_sort_mode.value: self.hide_show_entries() else: # Sort by Weight self.list.sort(key=lambda x: int(x[3])) if config.usage.menu_show_numbers.value in ("menu&plugins", "menu") or showNumericHelp: self.list = [(str(x[0] + 1) + " " + x[1][0], x[1][1], x[1][2]) for x in enumerate(self.list)] self["menu"].setList(self.list) def keyNumberGlobal(self, number): self.number = self.number * 10 + number if self.number and self.number <= len(self["menu"].list): if number * 10 > len(self["menu"].list) or self.number >= 10: self.okbuttonClick() else: self.nextNumberTimer.start(1500, True) else: self.resetNumberKey() def resetNumberKey(self): self.nextNumberTimer.stop() self.number = 0 def closeNonRecursive(self): self.resetNumberKey() self.close(False) def closeRecursive(self): self.resetNumberKey() self.close(True) def createSummary(self): if config.usage.menutype.value == "standard": return MenuSummary def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value and not ( hasattr(self.session, 'infobar') and self.session.infobar is None): return self.menuID == "mainmenu" elif config.ParentalControl.config_sections.configuration.value and self.menuID == "setup": return True elif config.ParentalControl.config_sections.timer_menu.value and self.menuID == "timermenu": return True elif config.ParentalControl.config_sections.standby_menu.value and self.menuID == "shutdown": return True def keyBlue(self): if "user" in config.usage.menu_sort_mode.value: self.session.openWithCallback(self.menuSortCallBack, MenuSort, self.parentmenu) else: return 0 def menuSortCallBack(self, key=False): self.createMenuList() def keyCancel(self): self.closeNonRecursive() def hide_show_entries(self): self.list = [] for entry in self.full_list: if not self.sub_menu_sort.getConfigValue(entry[2], "hidden"): self.list.append(entry) if not self.list: self.list.append(('', None, 'dummy', '10', 10)) self.list.sort(key=lambda listweight: int(listweight[4]))
class Menu(Screen, ProtectedScreen): ALLOW_SUSPEND = True def okbuttonClick(self): # print "okbuttonClick" selection = self["menu"].getCurrent() if selection is not None and selection[1] is not None: selection[1]() def execText(self, text): exec(text) def runScreen(self, arg): # arg[0] is the module (as string) # arg[1] is Screen inside this module # plus possible arguments, as # string (as we want to reference # stuff which is just imported) # FIXME. somehow if arg[0] != "": exec("from " + arg[0] + " import *") self.openDialog(*eval(arg[1])) def nothing(self): #dummy pass def gotoStandby(self, *res): from Screens.Standby import Standby2 self.session.open(Standby2) self.close(True) def openDialog(self, *dialog): # in every layer needed self.session.openWithCallback(self.menuClosed, *dialog) def openSetup(self, dialog): self.session.openWithCallback(self.menuClosed, Setup, dialog) def addMenu(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return MenuTitle = _(six.ensure_str(node.get("text", "??"))) 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) else: a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node) #TODO add check if !empty(node.childNodes) destList.append((MenuTitle, a, entryID, weight)) def menuClosedWithConfigFlush(self, *res): configfile.save() self.menuClosed(*res) def menuClosed(self, *res): if res and res[0]: self.close(True) def addItem(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return configCondition = node.get("configcondition") if configCondition and not eval(configCondition + ".value"): return item_text = six.ensure_str(node.get("text", "")) 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 # print module, screen if module: module = "Screens." + module else: module = "" # check for arguments. they will be appended to the # openDialog call args = x.text or "" screen += ", " + args destList.append( (_(item_text or "??"), boundFunction(self.runScreen, (module, screen)), entryID, weight)) return elif x.tag == 'plugin': extensions = x.get("extensions") system = x.get("system") screen = x.get("screen") if extensions: module = extensions elif system: module = system if screen is None: screen = module if extensions: module = "Plugins.Extensions." + extensions + '.plugin' elif system: module = "Plugins.SystemPlugins." + system + '.plugin' else: module = "" # check for arguments. they will be appended to the # openDialog call args = x.text or "" screen += ", " + args destList.append( (_(item_text or "??"), boundFunction(self.runScreen, (module, screen)), entryID, weight)) return elif x.tag == 'code': destList.append( (_(item_text or "??"), boundFunction(self.execText, x.text), entryID, weight)) return elif x.tag == 'setup': id = x.get("id") if item_text == "": item_text = _(getSetupTitle(id)) else: item_text = _(item_text) destList.append( (item_text, boundFunction(self.openSetup, id), entryID, weight)) return destList.append((item_text, self.nothing, entryID, weight)) def sortByName(self, listentry): return listentry[0].lower() def __init__(self, session, parent): Screen.__init__(self, session) self.sort_mode = False self.selected_entry = None self.sub_menu_sort = None self["green"] = Label() self["yellow"] = Label() self["blue"] = Label() m_list = [] menuID = None for x in parent: #walk through the actual nodelist if not x.tag: continue if x.tag == 'item': item_level = int(x.get("level", 0)) if item_level <= config.usage.setup_level.index: self.addItem(m_list, x) count += 1 elif x.tag == 'menu': item_level = int(x.get("level", 0)) if item_level <= config.usage.setup_level.index: self.addMenu(m_list, x) count += 1 elif x.tag == "id": menuID = x.get("val") count = 0 if menuID is not None: # menuupdater? if menuupdater.updatedMenuAvailable(menuID): for x in menuupdater.getUpdatedMenu(menuID): if x[1] == count: m_list.append( (x[0], boundFunction(self.runScreen, (x[2], x[3] + ", ")), x[4])) count += 1 self.menuID = menuID if menuID is not None: # plugins for l in plugins.getPluginsForMenu(menuID): # check if a plugin overrides an existing menu plugin_menuid = l[2] for x in m_list: if x[2] == plugin_menuid: m_list.remove(x) break if len(l) > 4 and l[4]: m_list.append( (l[0], boundFunction(l[1], self.session, self.close), l[2], l[3] or 50)) else: m_list.append( (l[0], boundFunction(l[1], self.session), l[2], l[3] or 50)) # for the skin: first try a menu_<menuID>, then Menu self.skinName = [] if menuID is not None: self.skinName.append("menu_" + menuID) self.skinName.append("Menu") self.menuID = menuID ProtectedScreen.__init__(self) if config.plugins.infopanel_usermenus is not None and menuID == "mainmenu": plugin_list = [] id_list = [] for l in plugins.getPlugins([ PluginDescriptor.WHERE_PLUGINMENU, PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO ]): l.id = (l.name.lower()).replace(' ', '_') if l.id not in id_list: id_list.append(l.id) plugin_list.append( (l.name, boundFunction(l.__call__, session), l.id, 200)) addlist = config.plugins.infopanel_usermenus.value addlist = addlist.split(',') for entry in plugin_list: if entry[2] in addlist: list.append(entry) self.list = list # Sort by Weight #if config.usage.sort_menus.value: # list.sort() #else: if config.usage.menu_sort_mode.value == "user" and menuID == "mainmenu": plugin_list = [] id_list = [] for l in plugins.getPlugins([ PluginDescriptor.WHERE_PLUGINMENU, PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO ]): l.id = (l.name.lower()).replace(' ', '_') if l.id not in id_list: id_list.append(l.id) plugin_list.append( (l.name, boundFunction(l.__call__, session), l.id, 200)) self.list = m_list if menuID is not None and config.usage.menu_sort_mode.value == "user": self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue( self.menuID, "submenu") or {} idx = 0 for x in self.list: entry = list(self.list.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue( entry[2], "sort") or entry[3] entry.append(m_weight) self.list.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], "sort", m_weight) idx += 1 self.full_list = list(m_list) if config.usage.menu_sort_mode.value == "a_z": # Sort by Name m_list.sort(key=self.sortByName) elif config.usage.menu_sort_mode.value == "user": self["blue"].setText(_("Edit mode on")) self.hide_show_entries() m_list = self.list else: # Sort by Weight m_list.sort(key=lambda x: int(x[3])) self["menu"] = List(m_list) self["menu"].enableWrapAround = True if config.usage.menu_sort_mode.value == "user": self["menu"].onSelectionChanged.append(self.selectionChanged) self["actions"] = NumberActionMap( ["OkCancelActions", "MenuActions", "NumberActions"], { "ok": self.okbuttonClick, "cancel": self.closeNonRecursive, "menu": self.closeRecursive, "0": self.resetSortOrder, "1": self.keyNumberGlobal, "2": self.keyNumberGlobal, "3": self.keyNumberGlobal, "4": self.keyNumberGlobal, "5": self.keyNumberGlobal, "6": self.keyNumberGlobal, "7": self.keyNumberGlobal, "8": self.keyNumberGlobal, "9": self.keyNumberGlobal }) if config.usage.menu_sort_mode.value == "user": self["MoveActions"] = ActionMap( ["WizardActions"], { "left": self.keyLeft, "right": self.keyRight, "up": self.keyUp, "down": self.keyDown, }, -1) self["EditActions"] = ActionMap( ["ColorActions"], { "green": self.keyGreen, "yellow": self.keyYellow, "blue": self.keyBlue, }) a = six.ensure_str(parent.get("title", "")) or None a = a and _(a) if a is None: a = _(six.ensure_str(parent.get("text", ""))) else: t_history.reset() self["title"] = StaticText(a) Screen.setTitle(self, a) self.menu_title = a self["thistory"] = StaticText(t_history.thistory) history_len = len(t_history.thistory) self["title0"] = StaticText('') self["title1"] = StaticText('') self["title2"] = StaticText('') if history_len < 13: self["title0"] = StaticText(a) elif history_len < 21: self["title0"] = StaticText('') self["title1"] = StaticText(a) else: self["title0"] = StaticText('') self["title1"] = StaticText('') self["title2"] = StaticText(a) if (t_history.thistory == ''): t_history.thistory = str(a) + ' > ' else: t_history.thistory = t_history.thistory + str(a) + ' > ' def keyNumberGlobal(self, number): # print "menu keyNumber:", number # Calculate index number -= 1 if len(self["menu"].list) > number: self["menu"].setIndex(number) self.okbuttonClick() def closeNonRecursive(self): t_history.reducehistory() self.close(False) def closeRecursive(self): t_history.reset() self.close(True) def createSummary(self): return MenuSummary def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value and not ( hasattr(self.session, 'infobar') and self.session.infobar is None): return self.menuID == "mainmenu" elif config.ParentalControl.config_sections.configuration.value and self.menuID == "setup": return True elif config.ParentalControl.config_sections.timer_menu.value and self.menuID == "timermenu": return True elif config.ParentalControl.config_sections.standby_menu.value and self.menuID == "shutdown": return True def updateList(self): self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue( self.menuID, "submenu") or None idx = 0 for x in self.list: entry = list(self.list.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue(entry[2], "sort") or entry[3] entry.append(m_weight) self.list.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], "sort", m_weight) if not self.sort_mode and self.sub_menu_sort.getConfigValue( entry[2], "hidden"): self.list.remove(x) idx += 1 def keyLeft(self): self.cur_idx = self["menu"].getSelectedIndex() self["menu"].pageUp() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyRight(self): self.cur_idx = self["menu"].getSelectedIndex() self["menu"].pageDown() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyDown(self): self.cur_idx = self["menu"].getSelectedIndex() self["menu"].down() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyUp(self): self.cur_idx = self["menu"].getSelectedIndex() self["menu"].up() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyOk(self): if self.sort_mode and len(self.list): m_entry = selection = self["menu"].getCurrent() select = False if self.selected_entry is None: select = True elif self.selected_entry != m_entry[2]: select = True if not select: self["green"].setText(_("Move mode on")) self.selected_entry = None else: self["green"].setText(_("Move mode off")) idx = 0 for x in self.list: if m_entry[2] == x[2] and select == True: self.selected_entry = m_entry[2] break elif m_entry[2] == x[2] and select == False: self.selected_entry = None break idx += 1 elif not self.sort_mode: self.okbuttonClick() def moveAction(self): tmp_list = list(self.list) entry = tmp_list.pop(self.cur_idx) newpos = self["menu"].getSelectedIndex() tmp_list.insert(newpos, entry) self.list = list(tmp_list) self["menu"].updateList(self.list) def keyBlue(self): if config.usage.menu_sort_mode.value == "user": self.toggleSortMode() def keyYellow(self): if self.sort_mode: m_entry = selection = self["menu"].getCurrent()[2] hidden = self.sub_menu_sort.getConfigValue(m_entry, "hidden") or 0 if hidden: self.sub_menu_sort.removeConfigValue(m_entry, "hidden") self["yellow"].setText(_("hide")) else: self.sub_menu_sort.changeConfigValue(m_entry, "hidden", 1) self["yellow"].setText(_("show")) def keyGreen(self): if self.sort_mode: self.keyOk() def keyCancel(self): if self.sort_mode: self.toggleSortMode() else: self.closeNonRecursive() def resetSortOrder(self, key=None): config.usage.menu_sort_weight.value = {"mainmenu": {"submenu": {}}} config.usage.menu_sort_weight.save() self.closeRecursive() def toggleSortMode(self): if self.sort_mode: self["green"].setText("") self["yellow"].setText("") self["blue"].setText(_("Edit mode on")) self.sort_mode = False i = 10 idx = 0 for x in self.list: self.sub_menu_sort.changeConfigValue(x[2], "sort", i) if len(x) >= 5: entry = list(x) entry[4] = i entry = tuple(entry) self.list.pop(idx) self.list.insert(idx, entry) if self.selected_entry is not None: if x[2] == self.selected_entry: self.selected_entry = None i += 10 idx += 1 self.full_list = list(self.list) config.usage.menu_sort_weight.changeConfigValue( self.menuID, "submenu", self.sub_menu_sort.value) config.usage.menu_sort_weight.save() self.hide_show_entries() self["menu"].setList(self.list) else: self["green"].setText(_("Move mode on")) self["blue"].setText(_("Edit mode off")) self.sort_mode = True self.hide_show_entries() self["menu"].updateList(self.list) self.selectionChanged() def hide_show_entries(self): m_list = list(self.full_list) if not self.sort_mode: rm_list = [] for entry in m_list: if self.sub_menu_sort.getConfigValue(entry[2], "hidden"): rm_list.append(entry) for entry in rm_list: if entry in m_list: m_list.remove(entry) if not len(m_list): m_list.append(('', None, 'dummy', '10', 10)) m_list.sort(key=lambda listweight: int(listweight[4])) self.list = list(m_list) def selectionChanged(self): if self.sort_mode: selection = self["menu"].getCurrent()[2] if self.sub_menu_sort.getConfigValue(selection, "hidden"): self["yellow"].setText(_("show")) else: self["yellow"].setText(_("hide")) else: self["yellow"].setText("")
class Menu(Screen, ProtectedScreen): ALLOW_SUSPEND = True def okbuttonClick(self): if self.number: self["menu"].setIndex(self.number - 1) self.resetNumberKey() selection = self["menu"].getCurrent() if selection and selection[1]: selection[1]() def execText(self, text): exec text def runScreen(self, arg): # arg[0] is the module (as string) # arg[1] is Screen inside this module # plus possible arguments, as # string (as we want to reference # stuff which is just imported) # FIXME. somehow if str(arg[0]).find('Screens.Bh') != -1: self.openBhMenu(arg[0]) else: if arg[0] != "": exec "from " + arg[0] + " import *" self.openDialog(*eval(arg[1])) def openBhMenu(self, module): module = module.replace("Screens", "Blackhole") exec "from " + module + " import *" if module == "Blackhole.BhSettings": self.session.openWithCallback(self.menuClosed, DeliteSettings) elif module == "Blackhole.BhEpgPanel": self.session.openWithCallback(self.menuClosed, DeliteEpgPanel) elif module == "Blackhole.BhAddons": self.session.openWithCallback(self.menuClosed, DeliteAddons) elif module == "Blackhole.BhRed": exec "from Blackhole.BhUtils import BhU_check_proc_version" flash = True mounted = False bh_ver = BhU_check_proc_version() un_ver = bh_ver f = open("/proc/mounts", 'r') for line in f.readlines(): if line.find('/universe') != -1: if line.find('ext') != -1: mounted = True f.close() if fileExists("/.meoinfo"): flash = False if flash == True: if mounted == True: if fileExists("/universe/.buildv"): f = open("/universe/.buildv", 'r') un_ver = f.readline().strip() f.close() else: out = open("/universe/.buildv", 'w') out.write(bh_ver) out.close() system("chmod a-w /universe/.buildv") if un_ver == bh_ver: self.session.openWithCallback(self.menuClosed, BhRedPanel) else: self.session.openWithCallback(self.menuClosed, BhRedWrong) else: self.session.openWithCallback(self.menuClosed, BhRedDisabled, "0") else: self.session.openWithCallback(self.menuClosed, BhRedDisabled, "flash") def nothing(self): #dummy pass def openDialog(self, *dialog): # in every layer needed self.session.openWithCallback(self.menuClosed, *dialog) def openSetup(self, dialog): self.session.openWithCallback(self.menuClosed, Setup, dialog) def addMenu(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return 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) else: a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node) #TODO add check if !empty(node.childNodes) destList.append((MenuTitle, a, entryID, weight)) def menuClosedWithConfigFlush(self, *res): configfile.save() self.menuClosed(*res) def menuClosed(self, *res): if res and res[0]: self.close(True) else: self.createMenuList() def addItem(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return configCondition = node.get("configcondition") if configCondition and not eval(configCondition + ".value"): return 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 # print module, screen if module: module = "Screens." + module else: module = "" # check for arguments. they will be appended to the # openDialog call args = x.text or "" screen += ", " + args destList.append( (_(item_text or "??"), boundFunction(self.runScreen, (module, screen)), entryID, weight)) return elif x.tag == 'code': destList.append( (_(item_text or "??"), boundFunction(self.execText, x.text), entryID, weight)) return elif x.tag == 'setup': id = x.get("id") if item_text == "": item_text = _(getSetupTitle(id)) else: item_text = _(item_text) destList.append( (item_text, boundFunction(self.openSetup, id), entryID, weight)) return destList.append((item_text, self.nothing, entryID, weight)) def sortByName(self, listentry): return listentry[0].lower() def __init__(self, session, parent): self.parentmenu = parent Screen.__init__(self, session) self["menu"] = List([]) self["menu"].enableWrapAround = True self.createMenuList() # for the skin: first try a menu_<menuID>, then Menu self.skinName = [] if self.menuID: self.skinName.append("menu_" + self.menuID) self.skinName.append("Menu") ProtectedScreen.__init__(self) self["actions"] = NumberActionMap( ["OkCancelActions", "MenuActions", "NumberActions"], { "ok": self.okbuttonClick, "cancel": self.closeNonRecursive, "menu": self.closeRecursive, "0": self.keyNumberGlobal, "1": self.keyNumberGlobal, "2": self.keyNumberGlobal, "3": self.keyNumberGlobal, "4": self.keyNumberGlobal, "5": self.keyNumberGlobal, "6": self.keyNumberGlobal, "7": self.keyNumberGlobal, "8": self.keyNumberGlobal, "9": self.keyNumberGlobal }) if config.usage.menu_sort_mode.value == "user": self["EditActions"] = ActionMap(["ColorActions"], { "blue": self.keyBlue, }) title = parent.get("title", "").encode("UTF-8") or None title = title and _(title) or _(parent.get("text", "").encode("UTF-8")) title = self.__class__.__name__ == "MenuSort" and _( "Menusort (%s)") % title or title self["title"] = StaticText(title) self.setScreenPathMode(True) self.setTitle(title) self.number = 0 self.nextNumberTimer = eTimer() self.nextNumberTimer.callback.append(self.okbuttonClick) def createMenuList(self): self.list = [] self.menuID = None for x in self.parentmenu: #walk through the actual nodelist if not x.tag: continue if x.tag == 'item': item_level = int(x.get("level", 0)) if item_level <= config.usage.setup_level.index: self.addItem(self.list, x) count += 1 elif x.tag == 'menu': item_level = int(x.get("level", 0)) if item_level <= config.usage.setup_level.index: self.addMenu(self.list, x) count += 1 elif x.tag == "id": self.menuID = x.get("val") count = 0 if self.menuID: # menuupdater? if menuupdater.updatedMenuAvailable(self.menuID): for x in menuupdater.getUpdatedMenu(self.menuID): if x[1] == count: self.list.append( (x[0], boundFunction(self.runScreen, (x[2], x[3] + ", ")), x[4])) count += 1 if self.menuID: # plugins for l in plugins.getPluginsForMenu(self.menuID): # check if a plugin overrides an existing menu plugin_menuid = l[2] for x in self.list: if x[2] == plugin_menuid: self.list.remove(x) break self.list.append( (l[0], boundFunction(l[1], self.session, close=self.close), l[2], l[3] or 50)) if config.usage.menu_sort_mode.value == "user" and self.menuID == "mainmenu": plugin_list = [] id_list = [] for l in plugins.getPlugins([ PluginDescriptor.WHERE_PLUGINMENU, PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO ]): l.id = (l.name.lower()).replace(' ', '_') if l.id not in id_list: id_list.append(l.id) plugin_list.append( (l.name, boundFunction(l.__call__, self.session), l.id, 200)) if self.menuID is not None and config.usage.menu_sort_mode.value == "user": self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue( self.menuID, "submenu") or {} idx = 0 for x in self.list: entry = list(self.list.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue( entry[2], "sort") or entry[3] entry.append(m_weight) self.list.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], "sort", m_weight) idx += 1 self.full_list = list(self.list) if config.usage.menu_sort_mode.value == "a_z": # Sort by Name self.list.sort(key=self.sortByName) elif config.usage.menu_sort_mode.value == "user": self.hide_show_entries() else: # Sort by Weight self.list.sort(key=lambda x: int(x[3])) if config.usage.menu_show_numbers.value: self.list = [(str(x[0] + 1) + " " + x[1][0], x[1][1], x[1][2]) for x in enumerate(self.list)] self["menu"].updateList(self.list) def keyNumberGlobal(self, number): self.number = self.number * 10 + number if self.number and self.number <= len(self["menu"].list): if number * 10 > len(self["menu"].list) or self.number >= 10: self.okbuttonClick() else: self.nextNumberTimer.start(1500, True) else: self.resetNumberKey() def resetNumberKey(self): self.nextNumberTimer.stop() self.number = 0 def closeNonRecursive(self): self.resetNumberKey() self.close(False) def closeRecursive(self): self.resetNumberKey() self.close(True) def createSummary(self): return MenuSummary def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value and not ( hasattr(self.session, 'infobar') and self.session.infobar is None): return self.menuID == "mainmenu" elif config.ParentalControl.config_sections.configuration.value and self.menuID == "setup": return True elif config.ParentalControl.config_sections.timer_menu.value and self.menuID == "timermenu": return True elif config.ParentalControl.config_sections.standby_menu.value and self.menuID == "shutdown": return True def keyBlue(self): if config.usage.menu_sort_mode.value == "user": self.session.openWithCallback(self.menuSortCallBack, MenuSort, self.parentmenu) def menuSortCallBack(self, key=False): self.createMenuList() def keyCancel(self): self.closeNonRecursive() def hide_show_entries(self): self.list = [] for entry in self.full_list: if not self.sub_menu_sort.getConfigValue(entry[2], "hidden"): self.list.append(entry) if not self.list: self.list.append(('', None, 'dummy', '10', 10)) self.list.sort(key=lambda listweight: int(listweight[4]))
class Menu(Screen, HelpableScreen, ProtectedScreen): ALLOW_SUSPEND = True skin = [ """ <screen name="Menu" title="Menu" position="center,center" size="980,600" resolution="1280,720"> <widget source="menu" render="Listbox" position="0,0" size="730,490"> <convert type="TemplatedMultiContent"> { "templates": { "default": (%d, [ MultiContentEntryText(pos=(%d, 0), size=(%d, %d), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=0) ]), "text": (%d, [ MultiContentEntryText(pos=(%d, 0), size=(%d, %d), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=3), ]), "number": (%d, [ MultiContentEntryText(pos=(%d, 0), size=(%d, %d), font=0, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=2), MultiContentEntryText(pos=(%d, 0), size=(%d, %d), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=3), ]), "image": (%d, [ MultiContentEntryPixmapAlphaBlend(pos=(%d, %d), size=(%d, %d), png=1, flags=BT_SCALE | BT_KEEP_ASPECT_RATIO), MultiContentEntryText(pos=(%d, 0), size=(%d, %d), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=3), ]), "both": (%d, [ MultiContentEntryPixmapAlphaBlend(pos=(%d, %d), size=(%d, %d), png=1, flags=BT_SCALE | BT_KEEP_ASPECT_RATIO), MultiContentEntryText(pos=(%d, 0), size=(%d, %d), font=0, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=2), MultiContentEntryText(pos=(%d, 0), size=(%d, %d), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=3), ]) }, "fonts": [parseFont("Regular;%d")] } </convert> </widget> <widget name="menuimage" position="780,0" size="200,200" alphatest="blend" conditional="menuimage" scaleFlags="scaleCenter" transparent="1" /> <widget source="description" render="Label" position="0,e-110" size="e,50" conditional="description" font="Regular;20" valign="center" /> <widget source="key_red" render="Label" position="10,e-50" size="180,40" backgroundColor="key_red" font="Regular;20" foregroundColor="key_text" halign="center" noWrap="1" valign="center"> <convert type="ConditionalShowHide" /> </widget> <widget source="key_green" render="Label" position="200,e-50" size="180,40" backgroundColor="key_green" font="Regular;20" foregroundColor="key_text" halign="center" noWrap="1" valign="center"> <convert type="ConditionalShowHide" /> </widget> <widget source="key_yellow" render="Label" position="390,e-50" size="180,40" backgroundColor="key_yellow" conditional="key_yellow" font="Regular;20" foregroundColor="key_text" halign="center" noWrap="1" valign="center"> <convert type="ConditionalShowHide" /> </widget> <widget source="key_blue" render="Label" position="580,e-50" size="180,40" backgroundColor="key_blue" conditional="key_blue" font="Regular;20" foregroundColor="key_text" halign="center" noWrap="1" valign="center"> <convert type="ConditionalShowHide" /> </widget> <widget source="key_menu" render="Label" position="e-300,e-50" size="90,40" backgroundColor="key_back" conditional="key_menu" font="Regular;20" foregroundColor="key_text" halign="center" noWrap="1" valign="center"> <convert type="ConditionalShowHide" /> </widget> <widget source="key_info" render="Label" position="e-200,e-50" size="90,40" backgroundColor="key_back" conditional="key_info" font="Regular;20" foregroundColor="key_text" halign="center" noWrap="1" valign="center"> <convert type="ConditionalShowHide" /> </widget> <widget source="key_help" render="Label" position="e-100,e-50" size="90,40" backgroundColor="key_back" font="Regular;20" conditional="key_help" foregroundColor="key_text" halign="center" noWrap="1" valign="center"> <convert type="ConditionalShowHide" /> </widget> </screen>""", 35, # Template "default". 15, 710, 35, 35, # Template "text". 20, 660, 35, 35, # Template "number". 15, 30, 35, 65, 610, 35, 35, # Template "image". 15, 2, 31, 31, 65, 610, 35, 35, # Template "both". 15, 2, 31, 31, 65, 40, 35, 125, 550, 35, 25 # Template "fonts". ] def __init__(self, session, parentMenu): self.session = session self.parentMenu = parentMenu Screen.__init__(self, session) HelpableScreen.__init__(self) self.menuList = [] self["menu"] = List(self.menuList) self["menu"].onSelectionChanged.append(self.selectionChanged) self["menuimage"] = Pixmap() self["description"] = StaticText() self["key_menu"] = StaticText(_("MENU")) self["key_red"] = StaticText(_("Exit")) self["key_green"] = StaticText() self["key_yellow"] = StaticText() self["key_blue"] = StaticText() menuImageLibrary = resolveFilename(SCOPE_GUISKIN, "mainmenu") self.menuImageLibrary = menuImageLibrary if isdir( menuImageLibrary) else None self.showNumericHelp = False self.sortMode = False self.selectedEntry = None self.subMenuSort = None self.createMenuList() ProtectedScreen.__init__(self) # ProtectedScreen needs self.menuID # For the skin: first try a menu_<menuID>, then Menu. self.skinName = [] if self.menuID is not None: if config.usage.menuType.value == "horzanim" and findSkinScreen( "Animmain"): self.skinName.append("Animmain") elif config.usage.menuType.value == "horzicon" and findSkinScreen( "Iconmain"): self.skinName.append("Iconmain") else: self.skinName.append("Menu%s" % self.menuID) self.skinName.append("menu_%s" % self.menuID) self.skinName.append("Menu") if config.usage.menuType.value == "horzanim" and findSkinScreen( "Animmain"): self.onShown.append(self.openTestA) elif config.usage.menuType.value == "horzicon" and findSkinScreen( "Iconmain"): self.onShown.append(self.openTestB) self["menuActions"] = HelpableNumberActionMap( self, [ "OkCancelActions", "MenuActions", "ColorActions", "NumberActions" ], { "ok": (self.okbuttonClick, _("Select the current menu item")), "cancel": (self.closeNonRecursive, _("Exit menu")), "close": (self.closeRecursive, _("Exit all menus")), "menu": (self.keySetupMenu, _("Change OSD Settings")), "red": (self.closeNonRecursive, _("Exit menu")), "1": (self.keyNumberGlobal, _("Direct menu item selection")), "2": (self.keyNumberGlobal, _("Direct menu item selection")), "3": (self.keyNumberGlobal, _("Direct menu item selection")), "4": (self.keyNumberGlobal, _("Direct menu item selection")), "5": (self.keyNumberGlobal, _("Direct menu item selection")), "6": (self.keyNumberGlobal, _("Direct menu item selection")), "7": (self.keyNumberGlobal, _("Direct menu item selection")), "8": (self.keyNumberGlobal, _("Direct menu item selection")), "9": (self.keyNumberGlobal, _("Direct menu item selection")), "0": (self.keyNumberGlobal, _("Direct menu item selection")) }, prio=0, description=_("Menu Common Actions")) if config.usage.menuSortOrder.value == "user": self["moveActions"] = HelpableActionMap( self, ["NavigationActions"], { "top": (self.keyTop, _("Move to first line / screen")), "pageUp": (self.keyPageUp, _("Move up a screen")), "up": (self.keyUp, _("Move up a line")), # "first": (self.keyFirst, _("Jump to first item in list or the start of text")), # "left": (self.keyLeft, _("Select the previous item in list or move cursor left")), "left": (self.keyPageUp, _("Move up a screen")), "right": (self.keyPageDown, _("Move down a screen")), # "right": (self.keyRight, _("Select the next item in list or move cursor right")), # "last": (self.keyLast, _("Jump to last item in list or the end of text")), "down": (self.keyDown, _("Move down a line")), "pageDown": (self.keyPageDown, _("Move down a screen")), "bottom": (self.keyBottom, _("Move to last line / screen")) }, prio=-1, description=_("Menu Navigation Actions")) self["editActions"] = HelpableActionMap( self, ["ColorActions"], { "green": (self.keyGreen, _("Toggle item move mode on/off")), "yellow": (self.keyYellow, _("Toggle hide/show of the current item")), "blue": (self.toggleSortMode, _("Toggle item edit mode on/off")) }, prio=0, description=_("Menu Edit Actions")) title = parentMenu.get("title", "") or None title = title and _(title) if title is None: title = _(parentMenu.get("text", "")) self.setTitle(title) self.number = 0 self.nextNumberTimer = eTimer() self.nextNumberTimer.callback.append(self.okbuttonClick) if len( self.menuList ) == 1: # Does this menu have only one item, if so just run that item. self.onExecBegin.append(self.singleItemMenu) self.onLayoutFinish.append(self.layoutFinished) def createMenuList(self, showNumericHelp=False): self.menuID = self.parentMenu.get("key") self.menuList = [] for menu in self.parentMenu: # Walk through the menu node list. if not menu.tag: continue if menu.tag == "item": itemLevel = int(menu.get("level", 0)) if itemLevel <= config.usage.setup_level.index: data = self.addItem(menu) if data: self.menuList.append(data) elif menu.tag == "menu": itemLevel = int(menu.get("level", 0)) if itemLevel <= config.usage.setup_level.index: data = self.addMenu(menu) if data: self.menuList.append(data) if self.menuID: for plugin in plugins.getPluginsForMenu(self.menuID): # Plugins. # print("[Menu] DEBUG 1: Plugin data=%s." % str(plugin)) pluginKey = plugin[ PLUGIN_KEY] # Check if a plugin overrides an existing menu. for entry in self.menuList: if entry[PLUGIN_KEY] == pluginKey: self.menuList.remove(entry) break description = plugins.getDescriptionForMenuEntryID( self.menuID, pluginKey ) # It is assumed that description is already translated by the plugin! if "%s %s" in description: description = description % (DISPLAY_BRAND, DISPLAY_MODEL) image = self.getMenuEntryImage(plugin[PLUGIN_KEY], lastKey) if len(plugin) > PLUGIN_CLOSEALL and plugin[ PLUGIN_CLOSEALL]: # Was "len(plugin) > 4". self.menuList.append( (plugin[PLUGIN_TEXT], boundFunction(plugin[PLUGIN_MODULE], self.session, self.close), plugin[PLUGIN_KEY], plugin[PLUGIN_WEIGHT] or 50, description, image)) else: self.menuList.append( (plugin[PLUGIN_TEXT], boundFunction(plugin[PLUGIN_MODULE], self.session), plugin[PLUGIN_KEY], plugin[PLUGIN_WEIGHT] or 50, description, image)) if config.usage.menuSortOrder.value == "user" and self.menuID == "mainmenu": idList = [] for plugin in plugins.getPlugins([ PluginDescriptor.WHERE_PLUGINMENU, PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO ]): # print("[Menu] DEBUG 2: Plugin data=%s." % str(plugin)) plugin.id = (plugin.name.lower()).replace(" ", "_") if plugin.id not in idList: idList.append(plugin.id) if self.menuID is not None and config.usage.menuSortOrder.value == "user": self.subMenuSort = NoSave(ConfigDictionarySet()) self.subMenuSort.value = config.usage.menu_sort_weight.getConfigValue( self.menuID, "submenu") or {} for index, entry in enumerate(self.menuList): data = list(self.menuList.pop(index)) sort = self.subMenuSort.getConfigValue( data[MENU_KEY], "sort") or data[MENU_WEIGHT] data.append(sort) self.menuList.insert(index, tuple(data)) self.subMenuSort.changeConfigValue(data[MENU_KEY], "sort", sort) self.fullMenuList = list(self.menuList) if config.usage.menuSortOrder.value == "alpha": # Sort by menu item text. self.menuList.sort(key=lambda x: x[MENU_TEXT].lower()) elif config.usage.menuSortOrder.value == "user": # Sort by user defined sequence. self["key_blue"].setText(_("Edit Mode On")) self.hideShowEntries() else: # Sort by menu item weight. self.menuList.sort(key=lambda x: int(x[MENU_WEIGHT])) self.setMenuList(self.menuList) def addItem(self, menu): requires = menu.get("requires") if requires: if requires[0] == "!": if BoxInfo.getItem(requires[1:], False): return None elif not BoxInfo.getItem(requires, False): return None conditional = menu.get("conditional") if conditional and not eval(conditional): return None text = self.processDisplayedText(menu.get("text")) key = menu.get("key", "undefined") weight = menu.get("weight", 50) description = self.processDisplayedText(menu.get("description")) image = self.getMenuEntryImage(key, lastKey) for menuItem in menu: if menuItem.tag == "screen": module = menuItem.get("module") screen = menuItem.get("screen") if screen is None: screen = module module = "Screens.%s" % module if module else "" screen = "%s, %s" % ( screen, menuItem.text or "" ) # Check for arguments, they will be appended to the openDialog call. return (text, boundFunction(self.runScreen, (module, screen)), key, weight, description, image) elif menuItem.tag == "plugin": extensions = menuItem.get("extensions") system = menuItem.get("system") screen = menuItem.get("screen") if extensions: module = extensions elif system: module = system if screen is None: screen = module if extensions: module = "Plugins.Extensions.%s.plugin" % extensions elif system: module = "Plugins.SystemPlugins.%s.plugin" % system else: module = "" screen = "%s, %s" % ( screen, menuItem.text or "" ) # Check for arguments, they will be appended to the openDialog call. return (text, boundFunction(self.runScreen, (module, screen)), key, weight, description, image) elif menuItem.tag == "code": return (text, boundFunction(self.execText, menuItem.text), key, weight, description, image) elif menuItem.tag == "setup": setupKey = menuItem.get("setupKey", "Undefined") return (text, boundFunction(self.openSetup, setupKey), key, weight, description, image) return (text, self.nothing, key, weight, description, image) def addMenu(self, menu): requires = menu.get("requires") if requires: if requires[0] == "!": if BoxInfo.getItem(requires[1:], False): return elif not BoxInfo.getItem(requires, False): return text = self.processDisplayedText(menu.get("text")) key = menu.get("key", "undefined") weight = menu.get("weight", 50) description = self.processDisplayedText(menu.get("description")) image = self.getMenuEntryImage(key, lastKey) if menu.get("flushConfigOnClose"): module = boundFunction(self.session.openWithCallback, self.menuClosedWithConfigFlush, Menu, menu) else: module = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, menu) # TODO: Add check if !empty(menu.childNodes). return (text, module, key, weight, description, image) def processDisplayedText(self, text): text = _(text) if text else "" if "%s %s" in text: text = text % (DISPLAY_BRAND, DISPLAY_MODEL) return text def getMenuEntryImage(self, key, lastKey): global imageCache image = imageCache.get(key) if image is None: imageFile = resolveFilename( SCOPE_GUISKIN, "mainmenu/%s.png" % key if self.menuImageLibrary else menus.get(key, "")) if imageFile and isfile(imageFile): image = LoadPixmap(imageFile, cached=True) if image: print("[Menu] Menu image for menu ID '%s' is '%s'." % (key, imageFile)) imageCache[key] = image else: print("[Menu] Error: Unable to load image '%s'!" % imageFile) if lastKey: image = imageCache.get(lastKey) if image is None: image = imageCache.get("default") if image is None: imageFile = resolveFilename( SCOPE_GUISKIN, "mainmenu/missing.png" if self.menuImageLibrary else menus.get("default", "")) if imageFile and isfile(imageFile): image = LoadPixmap(imageFile, cached=True) if image: print("[Menu] Default menu image is '%s'." % imageFile) imageCache["default"] = image else: print( "[Menu] Error: Unable to load default image '%s'!" % imageFile) imageCache["default"] = "N/A" else: print("[Menu] Error: Default image '%s' is not a file!" % imageFile) imageCache["default"] = "N/A" elif image == "N/A": image = None return image def setMenuList(self, menuList): menu = [] for number, entry in enumerate(menuList): number += 1 numberText = "%d %s" % ( number, entry[MENU_TEXT] ) if config.usage.menuEntryStyle.value in ( "number", "both") else entry[ MENU_TEXT] # This is for compatibility with older skins. menu.append( (numberText, entry[MENU_IMAGE], str(number), entry[MENU_TEXT], entry[MENU_DESCRIPTION], entry[MENU_KEY], entry[MENU_WEIGHT], entry[MENU_MODULE])) self["menu"].setList(menu) def layoutFinished(self): # self["menu"].allowNativeKeys(False) self["menu"].setStyle(config.usage.menuEntryStyle.value) self.selectionChanged() def selectionChanged(self): current = self["menu"].getCurrent() if current: self["menuimage"].instance.setPixmap(current[WIDGET_IMAGE]) self["description"].setText(current[WIDGET_DESCRIPTION]) if self.sortMode: self["key_yellow"].setText( _("Show") if self.subMenuSort.getConfigValue( current[WIDGET_KEY], "hidden") else _("Hide")) else: self["key_yellow"].setText("") def okbuttonClick(self): global lastKey self.resetNumberKey() current = self["menu"].getCurrent() if current and current[WIDGET_MODULE]: lastKey = current[WIDGET_KEY] current[WIDGET_MODULE]() def menuClosedWithConfigFlush(self, *result): configfile.save() self.menuClosed(*result) def menuClosed(self, *result): global lastKey if result and result[0]: lastKey = None self.close(True) def execText(self, text): exec(text) def runScreen(self, arg): # arg[0] is the module (as string) # arg[1] is Screen inside this module # plus possible arguments, as # string (as we want to reference # stuff which is just imported) if arg[0] != "": exec("from %s import %s" % (arg[0], arg[1].split(",")[0])) self.openDialog(*eval(arg[1])) def nothing(self): # Dummy. pass def openDialog(self, *dialog): # In every layer needed. self.session.openWithCallback(self.menuClosed, *dialog) def openSetup(self, dialog): self.session.openWithCallback(self.menuClosed, Setup, dialog) def openTestA(self): self.session.open(AnimMain, self.menuList, self.getTitle()) self.close() def openTestB(self): self.session.open(IconMain, self.menuList, self.getTitle()) self.close() def singleItemMenu(self): self.onExecBegin.remove(self.singleItemMenu) if config.usage.menuType.value == "horzanim" and findSkinScreen( "Animmain"): return elif config.usage.menuType.value == "horzicon" and findSkinScreen( "Iconmain"): return else: self.okbuttonClick() def closeRecursive(self): self.resetNumberKey() self.close(True) def createSummary(self): if config.usage.menuType.value == "standard": return MenuSummary def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value and not ( hasattr(self.session, "infobar") and self.session.infobar is None): return self.menuID == "mainmenu" elif config.ParentalControl.config_sections.configuration.value and self.menuID == "setup": return True elif config.ParentalControl.config_sections.timer_menu.value and self.menuID == "timermenu": return True elif config.ParentalControl.config_sections.standby_menu.value and self.menuID == "shutdown": return True def keyOk(self): if self.sortMode and len(self.menuList): current = self["menu"].getCurrent() select = False if self.selectedEntry is None: select = True elif self.selectedEntry != current[WIDGET_KEY]: select = True if not select: self["key_green"].setText(_("Move Mode On")) self.selectedEntry = None else: self["key_green"].setText(_("Move Mode Off")) for entry in self.menuList: if current[WIDGET_KEY] == entry[MENU_KEY] and select == True: self.selectedEntry = current[WIDGET_KEY] break elif current[WIDGET_KEY] == entry[MENU_KEY] and select == False: self.selectedEntry = None break elif not self.sortMode: self.okbuttonClick() def keySetupMenu(self): self.openSetup("UserInterface") def keyYellow(self): if self.sortMode: key = self["menu"].getCurrent()[WIDGET_KEY] hidden = self.subMenuSort.getConfigValue(key, "hidden") or False if hidden: self.subMenuSort.removeConfigValue(key, "hidden") self["key_yellow"].setText(_("Hide")) else: self.subMenuSort.changeConfigValue(key, "hidden", True) self["key_yellow"].setText(_("Show")) def keyGreen(self): if self.sortMode: self.keyOk() def keyCancel(self): if self.sortMode: self.toggleSortMode() else: self.closeNonRecursive() def keyNumberGlobal(self, number): self.number = self.number * 10 + number count = self["menu"].count() if self.number and self.number <= count: self["menu"].setIndex(self.number - 1) if count < 10 or self.number >= 10: self.okbuttonClick() else: self.nextNumberTimer.start(1500, True) else: self.resetNumberKey() def resetNumberKey(self): self.nextNumberTimer.stop() self.number = 0 def closeNonRecursive(self): self.resetNumberKey() self.close(False) def keyTop(self): self.currentIndex = self["menu"].getSelectedIndex() self["menu"].top() if self.sortMode and self.selectedEntry is not None: self.moveAction() def keyPageUp(self): self.currentIndex = self["menu"].getSelectedIndex() self["menu"].pageUp() if self.sortMode and self.selectedEntry is not None: self.moveAction() def keyUp(self): self.currentIndex = self["menu"].getSelectedIndex() self["menu"].up() if self.sortMode and self.selectedEntry is not None: self.moveAction() def keyDown(self): self.currentIndex = self["menu"].getSelectedIndex() self["menu"].down() if self.sortMode and self.selectedEntry is not None: self.moveAction() def keyPageDown(self): self.currentIndex = self["menu"].getSelectedIndex() self["menu"].pageDown() if self.sortMode and self.selectedEntry is not None: self.moveAction() def keyBottom(self): self.currentIndex = self["menu"].getSelectedIndex() self["menu"].bottom() if self.sortMode and self.selectedEntry is not None: self.moveAction() def moveAction(self): menuListCopy = list(self.menuList) entry = menuListCopy.pop(self.currentIndex) newPos = self["menu"].getSelectedIndex() menuListCopy.insert(newPos, entry) self.menuList = menuListCopy self.setMenuList(self.menuList) def resetSortOrder(self, key=None): config.usage.menu_sort_weight.value = {"mainmenu": {"submenu": {}}} config.usage.menu_sort_weight.save() self.closeRecursive() def toggleSortMode(self): if self.sortMode: self["key_green"].setText("") self["key_yellow"].setText("") self["key_blue"].setText(_("Edit Mode On")) self.sortMode = False for index, entry in enumerate(self.menuList): sort = (index + 1) * 10 self.subMenuSort.changeConfigValue(entry[MENU_KEY], "sort", sort) if len(entry) >= MAX_MENU: data = list(entry) data[MENU_SORT] = sort data = tuple(data) self.menuList.pop(index) self.menuList.insert(index, data) if self.selectedEntry is not None: if entry[MENU_KEY] == self.selectedEntry: self.selectedEntry = None self.fullMenuList = list(self.menuList) config.usage.menu_sort_weight.changeConfigValue( self.menuID, "submenu", self.subMenuSort.value) config.usage.menu_sort_weight.save() self.hideShowEntries() self.setMenuList(self.menuList) else: self["key_green"].setText(_("Move Mode On")) self["key_blue"].setText(_("Edit Mode Off")) self.sortMode = True self.hideShowEntries() self.setMenuList(self.menuList) def hideShowEntries(self): menuList = list(self.fullMenuList) if not self.sortMode: removeList = [] for entry in menuList: if self.subMenuSort.getConfigValue(entry[MENU_KEY], "hidden"): removeList.append(entry) for entry in removeList: if entry in menuList: menuList.remove(entry) if not len(menuList): menuList.append(("", None, "dummy", 10, "", None, 10)) menuList.sort(key=lambda x: int(x[MENU_SORT])) self.menuList = list(menuList) def gotoStandby(self, *res): from Screens.Standby import Standby2 self.session.open(Standby2) self.close(True)
class Menu(Screen, ProtectedScreen): ALLOW_SUSPEND = True def okbuttonClick(self): # print "okbuttonClick" selection = self["menu"].getCurrent() if selection and selection[1]: selection[1]() def execText(self, text): exec text def runScreen(self, arg): # arg[0] is the module (as string) # arg[1] is Screen inside this module # plus possible arguments, as # string (as we want to reference # stuff which is just imported) # FIXME. somehow if arg[0] != "": exec "from " + arg[0] + " import *" self.openDialog(*eval(arg[1])) def nothing(self): #dummy pass def openDialog(self, *dialog): # in every layer needed self.session.openWithCallback(self.menuClosed, *dialog) def openSetup(self, dialog): self.session.openWithCallback(self.menuClosed, Setup, dialog) def addMenu(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return 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) else: a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node) #TODO add check if !empty(node.childNodes) destList.append((MenuTitle, a, entryID, weight)) def menuClosedWithConfigFlush(self, *res): configfile.save() self.menuClosed(*res) def menuClosed(self, *res): if res and res[0]: self.close(True) def addItem(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return configCondition = node.get("configcondition") if configCondition and not eval(configCondition + ".value"): return 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 # print module, screen if module: module = "Screens." + module else: module = "" # check for arguments. they will be appended to the # openDialog call args = x.text or "" screen += ", " + args destList.append( (_(item_text or "??"), boundFunction(self.runScreen, (module, screen)), entryID, weight)) return elif x.tag == 'code': destList.append( (_(item_text or "??"), boundFunction(self.execText, x.text), entryID, weight)) return elif x.tag == 'setup': id = x.get("id") if item_text == "": item_text = _(getSetupTitle(id)) else: item_text = _(item_text) destList.append( (item_text, boundFunction(self.openSetup, id), entryID, weight)) return destList.append((item_text, self.nothing, entryID, weight)) def sortByName(self, listentry): return listentry[0].lower() def __init__(self, session, parent): self.parentmenu = parent Screen.__init__(self, session) self["menu"] = List([]) self["menu"].enableWrapAround = True self.createMenuList() # for the skin: first try a menu_<menuID>, then Menu self.skinName = [] if self.menuID: self.skinName.append("menu_" + self.menuID) self.skinName.append("Menu") ProtectedScreen.__init__(self) self["actions"] = NumberActionMap( ["OkCancelActions", "MenuActions", "NumberActions"], { "ok": self.okbuttonClick, "cancel": self.closeNonRecursive, "menu": self.closeRecursive, "1": self.keyNumberGlobal, "2": self.keyNumberGlobal, "3": self.keyNumberGlobal, "4": self.keyNumberGlobal, "5": self.keyNumberGlobal, "6": self.keyNumberGlobal, "7": self.keyNumberGlobal, "8": self.keyNumberGlobal, "9": self.keyNumberGlobal }) if config.usage.menu_sort_mode.value == "user": self["EditActions"] = ActionMap(["ColorActions"], { "blue": self.keyBlue, }) self["key_blue"] = Label(_("Sort")) title = parent.get("title", "").encode("UTF-8") or None title = title and _(title) or _(parent.get("text", "").encode("UTF-8")) self["title"] = StaticText(title) Screen.setTitle(self, title) self.menu_title = title global menu_path if not menu_path or menu_path[-1] != title: menu_path.append(title) self["menu_path"] = StaticText(" > ".join(menu_path) + " >") self["menu_path_compressed"] = StaticText( len(menu_path) > 1 and " > ".join(menu_path[:-1]) + " >" or "") def createMenuList(self): self.list = [] self.menuID = None for x in self.parentmenu: #walk through the actual nodelist if not x.tag: continue if x.tag == 'item': item_level = int(x.get("level", 0)) if item_level <= config.usage.setup_level.index: self.addItem(self.list, x) count += 1 elif x.tag == 'menu': item_level = int(x.get("level", 0)) if item_level <= config.usage.setup_level.index: self.addMenu(self.list, x) count += 1 elif x.tag == "id": self.menuID = x.get("val") count = 0 if self.menuID: # menuupdater? if menuupdater.updatedMenuAvailable(self.menuID): for x in menuupdater.getUpdatedMenu(self.menuID): if x[1] == count: self.list.append( (x[0], boundFunction(self.runScreen, (x[2], x[3] + ", ")), x[4])) count += 1 if self.menuID: # plugins for l in plugins.getPluginsForMenu(self.menuID): # check if a plugin overrides an existing menu plugin_menuid = l[2] for x in self.list: if x[2] == plugin_menuid: self.list.remove(x) break if len(l) > 4 and l[4]: self.list.append( (l[0], boundFunction(l[1], self.session, self.close), l[2], l[3] or 50)) else: self.list.append( (l[0], boundFunction(l[1], self.session), l[2], l[3] or 50)) if config.usage.menu_sort_mode.value == "user" and self.menuID == "mainmenu": plugin_list = [] id_list = [] for l in plugins.getPlugins([ PluginDescriptor.WHERE_PLUGINMENU, PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO ]): l.id = (l.name.lower()).replace(' ', '_') if l.id not in id_list: id_list.append(l.id) plugin_list.append( (l.name, boundFunction(l.__call__, self.session), l.id, 200)) if self.menuID is not None and config.usage.menu_sort_mode.value == "user": self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue( self.menuID, "submenu") or {} idx = 0 for x in self.list: entry = list(self.list.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue( entry[2], "sort") or entry[3] entry.append(m_weight) self.list.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], "sort", m_weight) idx += 1 self.full_list = list(self.list) if config.usage.menu_sort_mode.value == "a_z": # Sort by Name self.list.sort(key=self.sortByName) elif config.usage.menu_sort_mode.value == "user": self.hide_show_entries() else: # Sort by Weight self.list.sort(key=lambda x: int(x[3])) self["menu"].updateList(self.list) def keyNumberGlobal(self, number): # print "menu keyNumber:", number # Calculate index number -= 1 if len(self["menu"].list) > number: self["menu"].setIndex(number) self.okbuttonClick() def closeNonRecursive(self): global menu_path menu_path = menu_path and menu_path[:-1] self.close(False) def closeRecursive(self): global menu_path menu_path = [] self.close(True) def createSummary(self): return MenuSummary def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value and not ( hasattr(self.session, 'infobar') and self.session.infobar is None): return self.menuID == "mainmenu" elif config.ParentalControl.config_sections.configuration.value and self.menuID == "setup": return True elif config.ParentalControl.config_sections.timer_menu.value and self.menuID == "timermenu": return True elif config.ParentalControl.config_sections.standby_menu.value and self.menuID == "shutdown": return True def keyBlue(self): if config.usage.menu_sort_mode.value == "user": self.session.openWithCallback(self.menuSortCallBack, MenuSort, self.parentmenu) def menuSortCallBack(self, key=False): self.createMenuList() def keyCancel(self): self.closeNonRecursive() def hide_show_entries(self): self.list = [] for entry in self.full_list: if not self.sub_menu_sort.getConfigValue(entry[2], "hidden"): self.list.append(entry) if not self.list: self.list.append(('', None, 'dummy', '10', 10)) self.list.sort(key=lambda listweight: int(listweight[4]))
def runScreenTest(): config.misc.startCounter.value += 1 profile("readPluginList") plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) profile("Init:Session") nav = Navigation(config.misc.nextWakeup.value) #nav = Navigation(config.misc.isNextRecordTimerAfterEventActionAuto.value, config.misc.isNextPowerTimerAfterEventActionAuto.value) session = Session(desktop = enigma.getDesktop(0), summary_desktop = enigma.getDesktop(1), navigation = nav) CiHandler.setSession(session) profile("wizards") screensToRun = [] RestoreSettings = None import hashlib import os from os import path from pathlib import Path import fileinput, sys def md5_update_from_file(filename, hash): assert Path(filename).is_file() with open(str(filename), "rb") as f: for chunk in iter(lambda: f.read(4096), b""): hash.update(chunk) return hash def md5_file(filename): return md5_update_from_file(filename, hashlib.md5()).hexdigest() def md5_update_from_dir(directory, hash): assert Path(directory).is_dir() for path in sorted(Path(directory).iterdir()): hash.update(path.name.encode()) if path.is_file(): hash = md5_update_from_file(path, hash) elif path.is_dir(): hash = md5_update_from_dir(path, hash) return hash def md5_dir(directory): return md5_update_from_dir(directory, hashlib.md5()).hexdigest() sha256hash = () myfilecheck = "/usr/lib/enigma2/python/Plugins/Extensions/Infopanel" sha256save = "/var/lib/opkg/info/enigma2-plugin-extensions-infopanel.sha256" if config.misc.firstrun.value == True: myfile = Path(sha256save) if os.path.isfile(sha256save): os.remove(sha256save) myfile.touch(exist_ok=True) sha256hash = md5_dir(myfilecheck) sha_f = open(sha256save, "a") sha_f.write(sha256hash) sha_f.close() else: if os.path.isfile(sha256save): sha256hash = md5_dir(myfilecheck) try: sha256read = open(sha256save,'r') sha256hash1 = sha256read.read() print("sha256hash1:", sha256hash1) print("sha256hash:", sha256hash) if sha256hash == sha256hash1: print("all ok with Infopanel") else: print("Sorry, but you change our Infopanel so we had to disable it!!") sub_menu_sort = NoSave(ConfigDictionarySet()) sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue("mainmenu", "submenu") m_weight = sub_menu_sort.getConfigValue('Infopanel', "sort") m_weight1 = sub_menu_sort.getConfigValue('Infopanel', "hidden") sub_menu_sort.changeConfigValue('Infopanel', "hidden", "1") config.usage.menu_sort_weight.save() configfile.save() sha256read.close() except: print("Sorry, but you change our Infopanel so we had to disable it!!") sub_menu_sort = NoSave(ConfigDictionarySet()) sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue("mainmenu", "submenu") m_weight = sub_menu_sort.getConfigValue('Infopanel', "sort") m_weight1 = sub_menu_sort.getConfigValue('Infopanel', "hidden") sub_menu_sort.changeConfigValue('Infopanel', "hidden", "1") config.usage.menu_sort_weight.save() configfile.save() else: print("Sorry, but you change our Infopanel so we had to disable it!!") sub_menu_sort = NoSave(ConfigDictionarySet()) sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue("mainmenu", "submenu") m_weight = sub_menu_sort.getConfigValue('Infopanel', "sort") m_weight1 = sub_menu_sort.getConfigValue('Infopanel', "hidden") sub_menu_sort.changeConfigValue('Infopanel', "hidden", "1") config.usage.menu_sort_weight.save() configfile.save() if os.path.exists("/media/hdd/images/config/settings") and config.misc.firstrun.value: if autorestoreLoop(): RestoreSettings = True from Plugins.SystemPlugins.SoftwareManager.BackupRestore import RestoreScreen os.system("rm /media/hdd/images/config/settings") session.open(RestoreScreen, runRestore = True) else: os.system("rm /media/hdd/images/config/settings") screensToRun = [ p.__call__ for p in plugins.getPlugins(PluginDescriptor.WHERE_WIZARD) ] screensToRun += wizardManager.getWizards() else: if os.path.exists("/media/hdd/images/config/autorestore"): os.system('rm -f /media/hdd/images/config/autorestore') screensToRun = [ p.__call__ for p in plugins.getPlugins(PluginDescriptor.WHERE_WIZARD) ] screensToRun += wizardManager.getWizards() screensToRun.append((100, InfoBar.InfoBar)) screensToRun.sort() print(screensToRun) enigma.ePythonConfigQuery.setQueryFunc(configfile.getResolvedKey) def runNextScreen(session, screensToRun, *result): config.easysetup = ConfigSubsection() config.easysetup.restart = ConfigBoolean(default = False) if config.easysetup.restart.value == True: print("restart after Wizard2") config.easysetup.restart.setValue(False) config.easysetup.restart.save() enigma.quitMainloop(3) if result: print("[mytest.py] quitMainloop #3") enigma.quitMainloop(*result) return screen = screensToRun[0][1] args = screensToRun[0][2:] if screensToRun: session.openWithCallback(boundFunction(runNextScreen, session, screensToRun[1:]), screen, *args) else: session.open(screen, *args) if not RestoreSettings: runNextScreen(session, screensToRun) profile("Init:VolumeControl") vol = VolumeControl(session) profile("Init:PowerKey") power = PowerKey(session) power.timerstdby() if boxtype in ('alien5', 'osninopro', 'osnino', 'osninoplus', 'alphatriple', 'spycat4kmini', 'tmtwin4k', 'mbmicrov2', 'revo4k', 'force3uhd', 'wetekplay', 'wetekplay2', 'wetekhub', 'dm7020hd', 'dm7020hdv2', 'osminiplus', 'osmega', 'sf3038', 'spycat', 'e4hd', 'e4hdhybrid', 'mbmicro', 'et7500', 'mixosf5', 'mixosf7', 'mixoslumi', 'gi9196m', 'maram9', 'ixussone', 'ixusszero', 'uniboxhd1', 'uniboxhd2', 'uniboxhd3', 'sezam5000hd', 'mbtwin', 'sezam1000hd', 'mbmini', 'atemio5x00', 'beyonwizt3', '9910lx', '9911lx', '9920lx') or getBrandOEM() in ('fulan') or getMachineBuild() in ('u41', 'dags7362', 'dags73625', 'dags5', 'ustym4kpro', 'beyonwizv2', 'viper4k', 'sf8008', 'sf8008m', 'cc1', 'gbmv200'): profile("VFDSYMBOLS") import Components.VfdSymbols Components.VfdSymbols.SymbolsCheck(session) # we need session.scart to access it from within menu.xml session.scart = AutoScartControl(session) profile("Init:Trashcan") import Tools.Trashcan Tools.Trashcan.init(session) profile("Init:AutoVideoMode") import Screens.VideoMode Screens.VideoMode.autostart(session) profile("RunReactor") profile_final() if boxtype in ('sf8', 'classm', 'axodin', 'axodinc', 'starsatlx', 'genius', 'evo'): f = open("/dev/dbox/oled0", "w") f.write('-E2-') f.close() print("lastshutdown=%s (True = last shutdown was OK)" % config.usage.shutdownOK.value) print("NOK shutdown action=%s" % config.usage.shutdownNOK_action.value) print("bootup action=%s" % config.usage.boot_action.value) if not config.usage.shutdownOK.value and not config.usage.shutdownNOK_action.value == 'normal' or not config.usage.boot_action.value == 'normal': print("last shutdown = %s" % config.usage.shutdownOK.value) import Screens.PowerLost Screens.PowerLost.PowerLost(session) config.usage.shutdownOK.setValue(False) config.usage.shutdownOK.save() if not RestoreSettings: configfile.save() # kill showiframe if it is running (sh4 hack...) if getMachineBuild() in ('spark', 'spark7162'): os.system("killall -9 showiframe") runReactor() print("[mytest.py] normal shutdown") config.misc.startCounter.save() config.usage.shutdownOK.setValue(True) config.usage.shutdownOK.save() profile("wakeup") #get currentTime nowTime = time() if not config.misc.SyncTimeUsing.value == "0" or getBoxType().startswith('gb') or getMachineProcModel().startswith('ini'): print("dvb time sync disabled... so set RTC now to current linux time!", strftime("%Y/%m/%d %H:%M", localtime(nowTime))) setRTCtime(nowTime) wakeupList = [ x for x in ((session.nav.RecordTimer.getNextRecordingTime(), 0, session.nav.RecordTimer.isNextRecordAfterEventActionAuto()), (session.nav.RecordTimer.getNextZapTime(), 1), (plugins.getNextWakeupTime(), 2), (session.nav.PowerTimer.getNextPowerManagerTime(), 3, session.nav.PowerTimer.isNextPowerManagerAfterEventActionAuto())) if x[0] != -1 ] wakeupList.sort() recordTimerWakeupAuto = False if wakeupList and wakeupList[0][1] != 3: startTime = wakeupList[0] if (startTime[0] - nowTime) < 270: # no time to switch box back on wptime = nowTime + 30 # so switch back on in 30 seconds else: if getBoxType().startswith("gb"): wptime = startTime[0] - 120 # Gigaboxes already starts 2 min. before wakeup time else: wptime = startTime[0] - 240 if startTime[1] == 3: nextPluginName = " (%s)" % nextPluginName #if not config.misc.SyncTimeUsing.value == "0" or getBoxType().startswith('gb'): # print "dvb time sync disabled... so set RTC now to current linux time!", strftime("%Y/%m/%d %H:%M", localtime(nowTime)) # setRTCtime(nowTime) print("set wakeup time to", strftime("%Y/%m/%d %H:%M", localtime(wptime))) setFPWakeuptime(wptime) recordTimerWakeupAuto = startTime[1] == 0 and startTime[2] print('recordTimerWakeupAuto',recordTimerWakeupAuto) config.misc.isNextRecordTimerAfterEventActionAuto.value = recordTimerWakeupAuto config.misc.isNextRecordTimerAfterEventActionAuto.save() PowerTimerWakeupAuto = False if wakeupList and wakeupList[0][1] == 3: startTime = wakeupList[0] if (startTime[0] - nowTime) < 60: # no time to switch box back on wptime = nowTime + 30 # so switch back on in 30 seconds else: if getBoxType().startswith("gb"): wptime = startTime[0] + 120 # Gigaboxes already starts 2 min. before wakeup time else: wptime = startTime[0] #if not config.misc.SyncTimeUsing.value == "0" or getBoxType().startswith('gb'): # print "dvb time sync disabled... so set RTC now to current linux time!", strftime("%Y/%m/%d %H:%M", localtime(nowTime)) # setRTCtime(nowTime) print("set wakeup time to", strftime("%Y/%m/%d %H:%M", localtime(wptime+60))) setFPWakeuptime(wptime) PowerTimerWakeupAuto = startTime[1] == 3 and startTime[2] print('PowerTimerWakeupAuto',PowerTimerWakeupAuto) config.misc.isNextPowerTimerAfterEventActionAuto.value = PowerTimerWakeupAuto config.misc.isNextPowerTimerAfterEventActionAuto.save() profile("stopService") session.nav.stopService() profile("nav shutdown") session.nav.shutdown() profile("configfile.save") configfile.save() from Screens import InfoBarGenerics InfoBarGenerics.saveResumePoints() return 0
class Menu(Screen, ProtectedScreen): ALLOW_SUSPEND = True def okbuttonClick(self): selection = self['menu'].getCurrent() if selection and selection[1]: selection[1]() def execText(self, text): exec text def runScreen(self, arg): if str(arg[0]).find('Screens.Bh') != -1: self.openBhMenu(arg[0]) else: if arg[0] != '': exec 'from ' + arg[0] + ' import *' self.openDialog(*eval(arg[1])) def openBhMenu(self, module): module = module.replace('Screens', 'Blackhole') exec 'from ' + module + ' import *' if module == 'Blackhole.BhSettings': self.session.openWithCallback(self.menuClosed, DeliteSettings) elif module == 'Blackhole.BhEpgPanel': self.session.openWithCallback(self.menuClosed, DeliteEpgPanel) elif module == 'Blackhole.BhAddons': self.session.openWithCallback(self.menuClosed, DeliteAddons) elif module == 'Blackhole.BhRed': exec 'from Blackhole.BhUtils import BhU_check_proc_version' flash = True mounted = False bh_ver = BhU_check_proc_version() un_ver = bh_ver f = open('/proc/mounts', 'r') for line in f.readlines(): if line.find('/universe') != -1: if line.find('ext') != -1: mounted = True f.close() if fileExists('/.meoinfo'): flash = False if fileExists('/.bainfo'): flash = False if flash == True: if mounted == True: if fileExists('/universe/.buildv'): f = open('/universe/.buildv', 'r') un_ver = f.readline().strip() f.close() else: out = open('/universe/.buildv', 'w') out.write(bh_ver) out.close() system('chmod a-w /universe/.buildv') if un_ver == bh_ver: self.session.openWithCallback(self.menuClosed, BhRedPanel) else: self.session.openWithCallback(self.menuClosed, BhRedWrong) else: self.session.openWithCallback(self.menuClosed, BhRedDisabled, '0') else: self.session.openWithCallback(self.menuClosed, BhRedDisabled, 'flash') def nothing(self): pass def openDialog(self, *dialog): self.session.openWithCallback(self.menuClosed, *dialog) def openSetup(self, dialog): self.session.openWithCallback(self.menuClosed, Setup, dialog) def addMenu(self, destList, node): requires = node.get('requires') if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return 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) else: a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node) destList.append((MenuTitle, a, entryID, weight)) def menuClosedWithConfigFlush(self, *res): configfile.save() self.menuClosed(*res) def menuClosed(self, *res): if res and res[0]: self.close(True) def addItem(self, destList, node): requires = node.get('requires') if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return configCondition = node.get('configcondition') if configCondition and not eval(configCondition + '.value'): return 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 if module: module = 'Screens.' + module else: module = '' args = x.text or '' screen += ', ' + args destList.append((_(item_text or '??'), boundFunction(self.runScreen, (module, screen)), entryID, weight)) return if x.tag == 'code': destList.append((_(item_text or '??'), boundFunction(self.execText, x.text), entryID, weight)) return if x.tag == 'setup': id = x.get('id') if item_text == '': item_text = _(getSetupTitle(id)) else: item_text = _(item_text) destList.append((item_text, boundFunction(self.openSetup, id), entryID, weight)) return destList.append((item_text, self.nothing, entryID, weight)) def sortByName(self, listentry): return listentry[0].lower() def __init__(self, session, parent): self.parentmenu = parent Screen.__init__(self, session) self['menu'] = List([]) self['menu'].enableWrapAround = True self.createMenuList() self.skinName = [] if self.menuID: self.skinName.append('menu_' + self.menuID) self.skinName.append('Menu') ProtectedScreen.__init__(self) self['actions'] = NumberActionMap(['OkCancelActions', 'MenuActions', 'NumberActions'], {'ok': self.okbuttonClick, 'cancel': self.closeNonRecursive, 'menu': self.closeRecursive, '1': self.keyNumberGlobal, '2': self.keyNumberGlobal, '3': self.keyNumberGlobal, '4': self.keyNumberGlobal, '5': self.keyNumberGlobal, '6': self.keyNumberGlobal, '7': self.keyNumberGlobal, '8': self.keyNumberGlobal, '9': self.keyNumberGlobal}) if config.usage.menu_sort_mode.value == 'user': self['EditActions'] = ActionMap(['ColorActions'], {'blue': self.keyBlue}) title = parent.get('title', '').encode('UTF-8') or None title = title and _(title) or _(parent.get('text', '').encode('UTF-8')) title = self.__class__.__name__ == 'MenuSort' and _('Menusort (%s)') % title or title self['title'] = StaticText(title) self.setScreenPathMode(True) self.setTitle(title) def createMenuList(self): self.list = [] self.menuID = None for x in self.parentmenu: if not x.tag: continue if x.tag == 'item': item_level = int(x.get('level', 0)) if item_level <= config.usage.setup_level.index: self.addItem(self.list, x) count += 1 elif x.tag == 'menu': item_level = int(x.get('level', 0)) if item_level <= config.usage.setup_level.index: self.addMenu(self.list, x) count += 1 elif x.tag == 'id': self.menuID = x.get('val') count = 0 if self.menuID: if menuupdater.updatedMenuAvailable(self.menuID): for x in menuupdater.getUpdatedMenu(self.menuID): if x[1] == count: self.list.append((x[0], boundFunction(self.runScreen, (x[2], x[3] + ', ')), x[4])) count += 1 if self.menuID: for l in plugins.getPluginsForMenu(self.menuID): plugin_menuid = l[2] for x in self.list: if x[2] == plugin_menuid: self.list.remove(x) break self.list.append((l[0], boundFunction(l[1], self.session, close=self.close), l[2], l[3] or 50)) if config.usage.menu_sort_mode.value == 'user' and self.menuID == 'mainmenu': plugin_list = [] id_list = [] for l in plugins.getPlugins([PluginDescriptor.WHERE_PLUGINMENU, PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO]): l.id = l.name.lower().replace(' ', '_') if l.id not in id_list: id_list.append(l.id) plugin_list.append((l.name, boundFunction(l.__call__, self.session), l.id, 200)) if self.menuID is not None and config.usage.menu_sort_mode.value == 'user': self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue(self.menuID, 'submenu') or {} idx = 0 for x in self.list: entry = list(self.list.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue(entry[2], 'sort') or entry[3] entry.append(m_weight) self.list.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], 'sort', m_weight) idx += 1 self.full_list = list(self.list) if config.usage.menu_sort_mode.value == 'a_z': self.list.sort(key=self.sortByName) elif config.usage.menu_sort_mode.value == 'user': self.hide_show_entries() else: self.list.sort(key=lambda x: int(x[3])) self['menu'].updateList(self.list) def keyNumberGlobal(self, number): number -= 1 if len(self['menu'].list) > number: self['menu'].setIndex(number) self.okbuttonClick() def closeNonRecursive(self): self.close(False) def closeRecursive(self): self.close(True) def createSummary(self): return MenuSummary def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value and not (hasattr(self.session, 'infobar') and self.session.infobar is None): return self.menuID == 'mainmenu' if config.ParentalControl.config_sections.configuration.value and self.menuID == 'setup': return True if config.ParentalControl.config_sections.timer_menu.value and self.menuID == 'timermenu': return True if config.ParentalControl.config_sections.standby_menu.value and self.menuID == 'shutdown': return True def keyBlue(self): self.session.openWithCallback(self.menuSortCallBack, MenuSort, self.parentmenu) def menuSortCallBack(self, key = False): self.createMenuList() def keyCancel(self): self.closeNonRecursive() def hide_show_entries(self): self.list = [] for entry in self.full_list: if not self.sub_menu_sort.getConfigValue(entry[2], 'hidden'): self.list.append(entry) if not self.list: self.list.append(('', None, 'dummy', '10', 10)) self.list.sort(key=lambda listweight: int(listweight[4]))
class Menu(Screen, HelpableScreen, ProtectedScreen): ALLOW_SUSPEND = True png_cache = {} def __init__(self, session, parent): Screen.__init__(self, session) HelpableScreen.__init__(self) self.parentMenu = parent self.menuList = [] self["menu"] = List(self.menuList) self["menu"].enableWrapAround = True self["menu"].onSelectionChanged.append(self.selectionChanged) self.showNumericHelp = False self["green"] = Label() self["yellow"] = Label() self["blue"] = Label() self.sort_mode = False self.selected_entry = None self.sub_menu_sort = None self.createMenuList() ProtectedScreen.__init__(self) # for the skin: first try a menu_<menuID>, then Menu self.skinName = [] if self.menuID is not None: if config.usage.menutype.value == "horzanim" and findSkinScreen( "Animmain"): self.skinName.append("Animmain") elif config.usage.menutype.value == "horzicon" and findSkinScreen( "Iconmain"): self.skinName.append("Iconmain") else: self.skinName.append("menu_" + self.menuID) self.skinName.append("Menu") if config.usage.menu_sort_mode.value == "user": self["MoveActions"] = ActionMap( ["WizardActions"], { "left": self.keyLeft, "right": self.keyRight, "up": self.keyUp, "down": self.keyDown, }, -1) self["EditActions"] = ActionMap( ["ColorActions"], { "green": self.keyGreen, "yellow": self.keyYellow, "blue": self.keyBlue, }) self["menuActions"] = HelpableNumberActionMap( self, ["OkCancelActions", "NumberActions", "MenuActions"], { "ok": (self.okbuttonClick, _("Select the current menu item")), "cancel": (self.closeNonRecursive, _("Exit menu")), "close": (self.closeRecursive, _("Exit all menus")), "menu": (self.closeRecursive, _("Exit all menus")), "1": (self.keyNumberGlobal, _("Direct menu item selection")), "2": (self.keyNumberGlobal, _("Direct menu item selection")), "3": (self.keyNumberGlobal, _("Direct menu item selection")), "4": (self.keyNumberGlobal, _("Direct menu item selection")), "5": (self.keyNumberGlobal, _("Direct menu item selection")), "6": (self.keyNumberGlobal, _("Direct menu item selection")), "7": (self.keyNumberGlobal, _("Direct menu item selection")), "8": (self.keyNumberGlobal, _("Direct menu item selection")), "9": (self.keyNumberGlobal, _("Direct menu item selection")), "0": (self.keyNumberGlobal, _("Direct menu item selection")) }, prio=0, description=_("Common Menu Actions")) title = parent.get("title", "").encode("UTF-8") if PY2 else parent.get( "title", "") or None title = title and _(title) if title is None: title = _(parent.get("text", "").encode( "UTF-8", "ignore")) if PY2 else _(parent.get("text", "")) else: t_history.reset() self["title"] = StaticText(title) self.setTitle(title) self.menu_title = title self["thistory"] = StaticText(t_history.thistory) history_len = len(t_history.thistory) self["title0"] = StaticText("") self["title1"] = StaticText("") self["title2"] = StaticText("") if history_len < 13: self["title0"] = StaticText(title) elif history_len < 21: self["title0"] = StaticText("") self["title1"] = StaticText(title) else: self["title0"] = StaticText("") self["title1"] = StaticText("") self["title2"] = StaticText(title) if t_history.thistory == "": t_history.thistory = str(title) + " > " else: t_history.thistory = t_history.thistory + str(title) + " > " if config.usage.menutype.value == "horzanim" and findSkinScreen( "Animmain"): self["label1"] = StaticText() self["label2"] = StaticText() self["label3"] = StaticText() self["label4"] = StaticText() self["label5"] = StaticText() self.onShown.append(self.openTestA) elif config.usage.menutype.value == "horzicon" and findSkinScreen( "Iconmain"): self["label1"] = StaticText() self["label2"] = StaticText() self["label3"] = StaticText() self["label4"] = StaticText() self["label5"] = StaticText() self["label6"] = StaticText() self["label1s"] = StaticText() self["label2s"] = StaticText() self["label3s"] = StaticText() self["label4s"] = StaticText() self["label5s"] = StaticText() self["label6s"] = StaticText() self["pointer"] = Pixmap() self["pixmap1"] = Pixmap() self["pixmap2"] = Pixmap() self["pixmap3"] = Pixmap() self["pixmap4"] = Pixmap() self["pixmap5"] = Pixmap() self["pixmap6"] = Pixmap() self.onShown.append(self.openTestB) self.number = 0 self.nextNumberTimer = eTimer() self.nextNumberTimer.callback.append(self.okbuttonClick) if len(self.menuList) == 1: self.onExecBegin.append(self.__onExecBegin) self.onLayoutFinish.append(self.layoutFinished) def createMenuList(self, showNumericHelp=False): self.menuList = [] self.menuID = None for x in self.parentMenu: # walk through the actual nodelist if not x.tag: continue if x.tag == "item": itemLevel = int(x.get("level", 0)) if itemLevel <= config.usage.setup_level.index: self.addItem(self.menuList, x) count += 1 elif x.tag == "menu": itemLevel = int(x.get("level", 0)) if itemLevel <= config.usage.setup_level.index: self.addMenu(self.menuList, x) count += 1 elif x.tag == "id": self.menuID = x.get("val") count = 0 if self.menuID: # menuupdater? if menuUpdater.updatedMenuAvailable(self.menuID): for x in menuUpdater.getUpdatedMenu(self.menuID): if x[1] == count: description = _( x.get("description", "").encode( "UTF-8", "ignore")) if PY2 else _( x.get("description", "")) menupng = MenuEntryPixmap(self.menuID, self.png_cache, lastMenuID) self.menuList.append( (x[0], boundFunction(self.runScreen, (x[2], x[3] + ", ")), x[4], description, menupng)) count += 1 if self.menuID: # plugins for l in plugins.getPluginsForMenu(self.menuID): # check if a plugin overrides an existing menu plugin_menuid = l[2] for x in self.menuList: if x[2] == plugin_menuid: self.menuList.remove(x) break description = plugins.getDescriptionForMenuEntryID( self.menuID, plugin_menuid) menupng = MenuEntryPixmap(l[2], self.png_cache, lastMenuID) if len(l) > 4 and l[4]: self.menuList.append( (l[0], boundFunction(l[1], self.session, self.close), l[2], l[3] or 50, description, menupng)) else: self.menuList.append( (l[0], boundFunction(l[1], self.session), l[2], l[3] or 50, description, menupng)) if config.usage.menu_sort_mode.value == "user" and self.menuID == "mainmenu": plugin_list = [] id_list = [] for l in plugins.getPlugins([ PluginDescriptor.WHERE_PLUGINMENU, PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO ]): l.id = (l.name.lower()).replace(" ", "_") if l.id not in id_list: id_list.append(l.id) plugin_list.append( (l.name, boundFunction(l.__call__, self.session), l.id, 200)) if self.menuID is not None and config.usage.menu_sort_mode.value == "user": self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue( self.menuID, "submenu") or {} idx = 0 for x in self.menuList: entry = list(self.menuList.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue( entry[2], "sort") or entry[3] entry.append(m_weight) self.menuList.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], "sort", m_weight) idx += 1 self.full_list = list(self.menuList) if config.usage.menu_sort_mode.value == "a_z": # Sort by Name self.menuList.sort(key=self.sortByName) elif config.usage.menu_sort_mode.value == "user": self["blue"].setText(_("Edit Mode On")) self.hide_show_entries() else: # Sort by Weight self.menuList.sort(key=lambda x: int(x[3])) if config.usage.menu_show_numbers.value: self.menuList = [(str(x[0] + 1) + " " + x[1][0], x[1][1], x[1][2]) for x in enumerate(self.menuList)] self["menu"].setList(self.menuList) def layoutFinished(self): self.selectionChanged() def selectionChanged(self): if self.sort_mode: selection = self["menu"].getCurrent()[2] if self.sub_menu_sort.getConfigValue(selection, "hidden"): self["yellow"].setText(_("Show")) else: self["yellow"].setText(_("Hide")) else: self["yellow"].setText("") def okbuttonClick(self): global lastMenuID # print "okbuttonClick" self.resetNumberKey() selection = self["menu"].getCurrent() if selection is not None and selection[1] is not None: lastMenuID = selection[2] selection[1]() def execText(self, text): exec(text) def runScreen(self, arg): # arg[0] is the module (as string) # arg[1] is Screen inside this module # plus possible arguments, as # string (as we want to reference # stuff which is just imported) if arg[0] != "": exec("from %s import %s" % (arg[0], arg[1].split(",")[0])) self.openDialog(*eval(arg[1])) def nothing(self): # dummy pass def gotoStandby(self, *res): from Screens.Standby import Standby2 self.session.open(Standby2) self.close(True) def openDialog(self, *dialog): # in every layer needed self.session.openWithCallback(self.menuClosed, *dialog) def openSetup(self, dialog): self.session.openWithCallback(self.menuClosed, Setup, dialog) def addMenu(self, destList, node): requires = node.get("requires") if requires: if requires[0] == "!": if BoxInfo.getItem(requires[1:], False): return elif not BoxInfo.getItem(requires, False): return MenuTitle = _(node.get("text", "??").encode( "UTF-8", "ignore")) if PY2 else _(node.get("text", "??")) entryID = node.get("entryID", "undefined") weight = node.get("weight", 50) description = _(node.get("description", "").encode( "UTF-8", "ignore")) if PY2 else _(node.get("description", "")) menupng = MenuEntryPixmap(entryID, self.png_cache, lastMenuID) x = node.get("flushConfigOnClose") if x: a = boundFunction(self.session.openWithCallback, self.menuClosedWithConfigFlush, Menu, node) else: a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node) # TODO add check if !empty(node.childNodes) destList.append((MenuTitle, a, entryID, weight, description, menupng)) def menuClosedWithConfigFlush(self, *res): configfile.save() self.menuClosed(*res) def menuClosed(self, *res): global lastMenuID if res and res[0]: lastMenuID = None self.close(True) def addItem(self, destList, node): requires = node.get("requires") if requires: if requires[0] == "!": if BoxInfo.getItem(requires[1:], False): return elif not BoxInfo.getItem(requires, False): return conditional = node.get("conditional") if conditional and not eval(conditional): return item_text = node.get("text", "").encode( "UTF-8", "ignore") if PY2 else node.get("text", "") entryID = node.get("entryID", "undefined") weight = node.get("weight", 50) description = _(node.get("description", "").encode( "UTF-8", "ignore")) if PY2 else _(node.get("description", "")) menupng = MenuEntryPixmap(entryID, self.png_cache, lastMenuID) for x in node: if x.tag == "screen": module = x.get("module") screen = x.get("screen") if screen is None: screen = module # print(module, screen) if module: module = "Screens." + module else: module = "" # check for arguments. they will be appended to the # openDialog call args = x.text or "" screen += ", " + args destList.append( (_(item_text or "??"), boundFunction(self.runScreen, (module, screen)), entryID, weight, description, menupng)) return elif x.tag == 'plugin': extensions = x.get("extensions") system = x.get("system") screen = x.get("screen") if extensions: module = extensions elif system: module = system if screen is None: screen = module if extensions: module = "Plugins.Extensions." + extensions + '.plugin' elif system: module = "Plugins.SystemPlugins." + system + '.plugin' else: module = "" # check for arguments. they will be appended to the # openDialog call args = x.text or "" screen += ", " + args destList.append( (_(item_text or "??"), boundFunction(self.runScreen, (module, screen)), entryID, weight, description, menupng)) return elif x.tag == "code": destList.append( (_(item_text or "??"), boundFunction(self.execText, x.text), entryID, weight, description, menupng)) return elif x.tag == "setup": id = x.get("id") if item_text == "": if getSetupTitleLevel(id) > config.usage.setup_level.index: return item_text = _(getSetupTitle(id)) else: item_text = _(item_text) destList.append((item_text, boundFunction(self.openSetup, id), entryID, weight, description, menupng)) return destList.append( (item_text, self.nothing, entryID, weight, description, menupng)) def sortByName(self, listentry): return listentry[0].lower() def openTestA(self): self.session.open(AnimMain, self.menuList, self.menu_title) self.close() def openTestB(self): self.session.open(IconMain, self.menuList, self.menu_title) self.close() def __onExecBegin(self): self.onExecBegin.remove(self.__onExecBegin) if config.usage.menutype.value == "horzanim" and findSkinScreen( "Animmain"): return elif config.usage.menutype.value == "horzicon" and findSkinScreen( "Iconmain"): return else: self.okbuttonClick() def keyNumberGlobal(self, number): self.number = self.number * 10 + number if self.number and self.number <= len(self["menu"].list): self["menu"].setIndex(self.number - 1) if len(self["menu"].list) < 10 or self.number >= 10: self.okbuttonClick() else: self.nextNumberTimer.start(1500, True) else: self.resetNumberKey() def resetNumberKey(self): self.nextNumberTimer.stop() self.number = 0 def closeNonRecursive(self): self.resetNumberKey() t_history.reducehistory() self.close(False) def closeRecursive(self): self.resetNumberKey() t_history.reset() self.close(True) def createSummary(self): if config.usage.menutype.value == "standard": return MenuSummary def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value and not ( hasattr(self.session, "infobar") and self.session.infobar is None): return self.menuID == "mainmenu" elif config.ParentalControl.config_sections.configuration.value and self.menuID == "setup": return True elif config.ParentalControl.config_sections.timer_menu.value and self.menuID == "timermenu": return True elif config.ParentalControl.config_sections.standby_menu.value and self.menuID == "shutdown": return True def keyBlue(self): if config.usage.menu_sort_mode.value == "user": self.toggleSortMode() def updateList(self): self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue( self.menuID, "submenu") or None idx = 0 for x in self.menuList: entry = list(self.menuList.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue(entry[2], "sort") or entry[3] entry.append(m_weight) self.menuList.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], "sort", m_weight) if not self.sort_mode and self.sub_menu_sort.getConfigValue( entry[2], "hidden"): self.menuList.remove(x) idx += 1 def keyLeft(self): self.cur_idx = self["menu"].getSelectedIndex() self["menu"].pageUp() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyRight(self): self.cur_idx = self["menu"].getSelectedIndex() self["menu"].pageDown() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyDown(self): self.cur_idx = self["menu"].getSelectedIndex() self["menu"].down() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyUp(self): self.cur_idx = self["menu"].getSelectedIndex() self["menu"].up() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyOk(self): if self.sort_mode and len(self.menuList): m_entry = selection = self["menu"].getCurrent() select = False if self.selected_entry is None: select = True elif self.selected_entry != m_entry[2]: select = True if not select: self["green"].setText(_("Move Mode On")) self.selected_entry = None else: self["green"].setText(_("Move Mode Off")) idx = 0 for x in self.menuList: if m_entry[2] == x[2] and select == True: self.selected_entry = m_entry[2] break elif m_entry[2] == x[2] and select == False: self.selected_entry = None break idx += 1 elif not self.sort_mode: self.okbuttonClick() def moveAction(self): tmp_list = list(self.menuList) entry = tmp_list.pop(self.cur_idx) newpos = self["menu"].getSelectedIndex() tmp_list.insert(newpos, entry) self.menuList = list(tmp_list) self["menu"].updateList(self.menuList) def keyYellow(self): if self.sort_mode: m_entry = selection = self["menu"].getCurrent()[2] hidden = self.sub_menu_sort.getConfigValue(m_entry, "hidden") or 0 if hidden: self.sub_menu_sort.removeConfigValue(m_entry, "hidden") self["yellow"].setText(_("Hide")) else: self.sub_menu_sort.changeConfigValue(m_entry, "hidden", 1) self["yellow"].setText(_("Show")) def keyGreen(self): if self.sort_mode: self.keyOk() def keyCancel(self): if self.sort_mode: self.toggleSortMode() else: self.closeNonRecursive() def resetSortOrder(self, key=None): config.usage.menu_sort_weight.value = {"mainmenu": {"submenu": {}}} config.usage.menu_sort_weight.save() self.closeRecursive() def toggleSortMode(self): if self.sort_mode: self["green"].setText("") self["yellow"].setText("") self["blue"].setText(_("Edit Mode On")) self.sort_mode = False i = 10 idx = 0 for x in self.menuList: self.sub_menu_sort.changeConfigValue(x[2], "sort", i) if len(x) >= 7: entry = list(x) entry[6] = i entry = tuple(entry) self.menuList.pop(idx) self.menuList.insert(idx, entry) if self.selected_entry is not None: if x[2] == self.selected_entry: self.selected_entry = None i += 10 idx += 1 self.full_list = list(self.menuList) config.usage.menu_sort_weight.changeConfigValue( self.menuID, "submenu", self.sub_menu_sort.value) config.usage.menu_sort_weight.save() self.hide_show_entries() self["menu"].setList(self.menuList) else: self["green"].setText(_("Move Mode On")) self["blue"].setText(_("Edit Mode Off")) self.sort_mode = True self.hide_show_entries() self["menu"].updateList(self.menuList) self.selectionChanged() def hide_show_entries(self): m_list = list(self.full_list) if not self.sort_mode: rm_list = [] for entry in m_list: if self.sub_menu_sort.getConfigValue(entry[2], "hidden"): rm_list.append(entry) for entry in rm_list: if entry in m_list: m_list.remove(entry) if not len(m_list): m_list.append(('', None, 'dummy', '10', '', None, 10)) m_list.sort(key=lambda listweight: int(listweight[6])) self.menuList = list(m_list)
class Menu(Screen, ProtectedScreen): ALLOW_SUSPEND = True def okbuttonClick(self): print "okbuttonClick" selection = self["menu"].getCurrent() if selection is not None: selection[1]() def execText(self, text): exec text def runScreen(self, arg): # arg[0] is the module (as string) # arg[1] is Screen inside this module # plus possible arguments, as # string (as we want to reference # stuff which is just imported) # FIXME. somehow if arg[0] != "": exec "from " + arg[0] + " import *" self.openDialog(*eval(arg[1])) def nothing(self): #dummy pass def openDialog(self, *dialog): # in every layer needed self.session.openWithCallback(self.menuClosed, *dialog) def openSetup(self, dialog): self.session.openWithCallback(self.menuClosed, Setup, dialog) def addMenu(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return 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) else: a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node) #TODO add check if !empty(node.childNodes) destList.append((MenuTitle, a, entryID, weight)) def menuClosedWithConfigFlush(self, *res): configfile.save() self.menuClosed(*res) def menuClosed(self, *res): if res and res[0]: self.close(True) def addItem(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return configCondition = node.get("configcondition") if configCondition and not eval(configCondition + ".value"): return 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 print module, screen if module: module = "Screens." + module else: module = "" # check for arguments. they will be appended to the # openDialog call args = x.text or "" screen += ", " + args destList.append((_(item_text or "??"), boundFunction(self.runScreen, (module, screen)), entryID, weight)) return elif x.tag == 'code': destList.append((_(item_text or "??"), boundFunction(self.execText, x.text), entryID, weight)) return elif x.tag == 'setup': id = x.get("id") if item_text == "": item_text = _(getSetupTitle(id)) else: item_text = _(item_text) destList.append((item_text, boundFunction(self.openSetup, id), entryID, weight)) return destList.append((item_text, self.nothing, entryID, weight)) def __init__(self, session, parent): Screen.__init__(self, session) list = [] menuID = None for x in parent: #walk through the actual nodelist if not x.tag: continue 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.tag == 'menu': self.addMenu(list, x) count += 1 elif x.tag == "id": menuID = x.get("val") count = 0 if menuID is not None: # menuupdater? if menuupdater.updatedMenuAvailable(menuID): for x in menuupdater.getUpdatedMenu(menuID): if x[1] == count: list.append((x[0], boundFunction(self.runScreen, (x[2], x[3] + ", ")), x[4])) count += 1 if menuID is not None: # plugins for l in plugins.getPluginsForMenu(menuID): # check if a plugin overrides an existing menu plugin_menuid = l[2] for x in list: if x[2] == plugin_menuid: list.remove(x) break list.append((l[0], boundFunction(l[1], self.session, close=self.close), l[2], l[3] or 50)) # for the skin: first try a menu_<menuID>, then Menu self.skinName = [ ] if menuID is not None: if menuID == "vtimain": self.skinName.append("menu_system") else: self.skinName.append("menu_" + menuID) self.skinName.append("Menu") ## VTi function moved from VTiPanel to Menu Screen if config.usage.menu_sort_mode.value == "user" and menuID == "mainmenu": plugin_list = [] id_list = [] for l in plugins.getPlugins([PluginDescriptor.WHERE_PLUGINMENU ,PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO]): l.id = (l.name.lower()).replace(' ','_') if l.id not in id_list: id_list.append(l.id) plugin_list.append((l.name, boundFunction(l.__call__, session), l.id, 200)) addlist = config.plugins.vtipanel.menushown.value addlist = addlist.split(',') for entry in plugin_list: if entry[2] in addlist: m_list.append(entry) self.list = m_list if menuID is not None and config.usage.menu_sort_mode.value == "user": self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue(self.menuID, "submenu") or {} idx = 0 for x in self.list: entry = list(self.list.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue(entry[2], "sort") or entry[3] entry.append(m_weight) self.list.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], "sort", m_weight) idx += 1 self.full_list = list(m_list) if config.usage.menu_sort_mode.value == "a_z": # Sort by Name m_list.sort(key=self.sortByName) elif config.usage.menu_sort_mode.value == "user": self["blue"].setText(_("Edit mode on")) self.hide_show_entries() m_list = self.list else: # Sort by Weight m_list.sort(key=lambda x: int(x[3])) self["menu"] = List(m_list) self["menu"].enableWrapAround = True if config.usage.menu_sort_mode.value == "user": self["menu"].onSelectionChanged.append(self.selectionChanged) self["actions"] = NumberActionMap(["OkCancelActions", "MenuActions", "NumberActions"], { "ok": self.keyOk, "cancel": self.keyCancel, "menu": self.closeRecursive, "0": self.resetSortOrder, "1": self.keyNumberGlobal, "2": self.keyNumberGlobal, "3": self.keyNumberGlobal, "4": self.keyNumberGlobal, "5": self.keyNumberGlobal, "6": self.keyNumberGlobal, "7": self.keyNumberGlobal, "8": self.keyNumberGlobal, "9": self.keyNumberGlobal, }) if config.usage.menu_sort_mode.value == "user": self["MoveActions"] = ActionMap(["WizardActions"], { "left": self.keyLeft, "right": self.keyRight, "up": self.keyUp, "down": self.keyDown, }, -1 ) self["EditActions"] = ActionMap(["ColorActions"], { "green": self.keyGreen, "yellow": self.keyYellow, "blue": self.keyBlue, }) a = parent.get("title", "").encode("UTF-8") or None a = a and _(a) if a is None: a = _(parent.get("text", "").encode("UTF-8")) # ikseong - enter Main menu else: t_history.reset() self["title"] = StaticText(a) self.menu_title = a # ikseong make menu title self["thistory"] = StaticText(t_history.thistory) history_len = len(t_history.thistory) self["title0"] = StaticText('') self["title1"] = StaticText('') self["title2"] = StaticText('') if history_len < 13 : self["title0"] = StaticText(a) elif history_len < 21 : self["title0"] = StaticText('') self["title1"] = StaticText(a) else: self["title0"] = StaticText('') self["title1"] = StaticText('') self["title2"] = StaticText(a) # english title # if(t_history.thistory ==''): # t_history.thistory = str(etitle) + ' > ' # else: # t_history.thistory = t_history.thistory + str(etitle) + ' > ' if(t_history.thistory ==''): t_history.thistory = str(a) + ' > ' else: t_history.thistory = t_history.thistory + str(a) + ' > ' # def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value and self.menuID == "mainmenu": return True elif config.ParentalControl.config_sections.configuration.value and self.menuID == "setup": return True elif config.ParentalControl.config_sections.vti_menu.value and self.menuID == "vtimain": return True elif config.ParentalControl.config_sections.standby_menu.value and self.menuID == "shutdown": return True def keyNumberGlobal(self, number): print "menu keyNumber:", number # Calculate index number -= 1 if len(self["menu"].list) > number: self["menu"].setIndex(number) self.okbuttonClick() def closeNonRecursive(self): self.close(False) def closeRecursive(self): self.close(True) def createSummary(self): return MenuSummary def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value and not(hasattr(self.session, 'infobar') and self.session.infobar is None): return self.menuID == "mainmenu" elif config.ParentalControl.config_sections.configuration.value and self.menuID == "setup": return True elif config.ParentalControl.config_sections.standby_menu.value and self.menuID == "shutdown": return True
class Menu(Screen, ProtectedScreen): ALLOW_SUSPEND = True png_cache = {} def okbuttonClick(self): global lastMenuID self.resetNumberKey() selection = self['menu'].getCurrent() if selection is not None and selection[1] is not None: lastMenuID = selection[2] selection[1]() def execText(self, text): exec text def runScreen(self, arg): if arg[0] != '': exec 'from %s import %s' % (arg[0], arg[1].split(',')[0]) self.openDialog(*eval(arg[1])) def nothing(self): pass def gotoStandby(self, *res): from Screens.Standby import Standby2 self.session.open(Standby2) self.close(True) def openDialog(self, *dialog): self.session.openWithCallback(self.menuClosed, *dialog) def openSetup(self, dialog): self.session.openWithCallback(self.menuClosed, Setup, dialog) def addMenu(self, destList, node): requires = node.get('requires') if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return MenuTitle = _(node.get('text', '??').encode('UTF-8')) entryID = node.get('entryID', 'undefined') weight = node.get('weight', 50) description = node.get('description', '').encode('UTF-8') or None description = description and _(description) menupng = MenuEntryPixmap(entryID, self.png_cache, lastMenuID) x = node.get('flushConfigOnClose') if x: a = boundFunction(self.session.openWithCallback, self.menuClosedWithConfigFlush, Menu, node) else: a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node) destList.append((MenuTitle, a, entryID, weight, description, menupng)) def menuClosedWithConfigFlush(self, *res): configfile.save() self.menuClosed(*res) def menuClosed(self, *res): global lastMenuID if res and res[0]: lastMenuID = None self.close(True) def addItem(self, destList, node): requires = node.get('requires') if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return configCondition = node.get('configcondition') if configCondition and not eval(configCondition + '.value'): return item_text = node.get('text', '').encode('UTF-8') entryID = node.get('entryID', 'undefined') weight = node.get('weight', 50) description = node.get('description', '').encode('UTF-8') or '' description = description and _(description) menupng = MenuEntryPixmap(entryID, self.png_cache, lastMenuID) for x in node: if x.tag == 'screen': module = x.get('module') screen = x.get('screen') if screen is None: screen = module if module: module = 'Screens.' + module else: module = '' args = x.text or '' screen += ', ' + args destList.append( (_(item_text or '??'), boundFunction(self.runScreen, (module, screen)), entryID, weight, description, menupng)) return if x.tag == 'plugin': extensions = x.get('extensions') system = x.get('system') screen = x.get('screen') if extensions: module = extensions elif system: module = system if screen is None: screen = module if extensions: module = 'Plugins.Extensions.' + extensions + '.plugin' elif system: module = 'Plugins.SystemPlugins.' + system + '.plugin' else: module = '' args = x.text or '' screen += ', ' + args destList.append( (_(item_text or '??'), boundFunction(self.runScreen, (module, screen)), entryID, weight, description, menupng)) return if x.tag == 'code': destList.append( (_(item_text or '??'), boundFunction(self.execText, x.text), entryID, weight, description, menupng)) return if x.tag == 'setup': id = x.get('id') if item_text == '': if getSetupTitleLevel(id) > config.usage.setup_level.index: return item_text = _(getSetupTitle(id)) else: item_text = _(item_text) destList.append((item_text, boundFunction(self.openSetup, id), entryID, weight, description, menupng)) return destList.append( (item_text, self.nothing, entryID, weight, description, menupng)) def sortByName(self, listentry): return listentry[0].lower() def __init__(self, session, parent): Screen.__init__(self, session) self.sort_mode = False self.selected_entry = None self.sub_menu_sort = None self['key_green'] = Label() self['key_yellow'] = Label() self['key_blue'] = Label() m_list = [] menuID = None for x in parent: if not x.tag: continue if x.tag == 'item': item_level = int(x.get('level', 0)) if item_level <= config.usage.setup_level.index: self.addItem(m_list, x) count += 1 elif x.tag == 'menu': item_level = int(x.get('level', 0)) if item_level <= config.usage.setup_level.index: self.addMenu(m_list, x) count += 1 elif x.tag == 'id': menuID = x.get('val') count = 0 if menuID is not None: if menuupdater.updatedMenuAvailable(menuID): for x in menuupdater.getUpdatedMenu(menuID): if x[1] == count: description = x.get('description', '').encode('UTF-8') or None description = description and _(description) menupng = MenuEntryPixmap(menuID, self.png_cache, lastMenuID) m_list.append( (x[0], boundFunction(self.runScreen, (x[2], x[3] + ', ')), x[4], description, menupng)) count += 1 self.menuID = menuID if config.ParentalControl.configured.value: ProtectedScreen.__init__(self) if menuID is not None: for l in plugins.getPluginsForMenu(menuID): plugin_menuid = l[2] for x in m_list: if x[2] == plugin_menuid: m_list.remove(x) break description = plugins.getDescriptionForMenuEntryID( menuID, plugin_menuid) menupng = MenuEntryPixmap(l[2], self.png_cache, lastMenuID) if len(l) > 4 and l[4]: m_list.append( (l[0], boundFunction(l[1], self.session, self.close), l[2], l[3] or 50, description, menupng)) else: m_list.append( (l[0], boundFunction(l[1], self.session), l[2], l[3] or 50, description, menupng)) self.skinName = [] if menuID is not None: if config.usage.menutype.value == 'horzanim' and skin.dom_screens.has_key( 'Animmain'): self.skinName.append('Animmain') elif config.usage.menutype.value == 'horzicon' and skin.dom_screens.has_key( 'Iconmain'): self.skinName.append('Iconmain') else: self.skinName.append('menu_' + menuID) self.skinName.append('Menu') self.menuID = menuID ProtectedScreen.__init__(self) if config.usage.menu_sort_mode.value == 'user' and menuID == 'mainmenu': plugin_list = [] id_list = [] for l in plugins.getPlugins([ PluginDescriptor.WHERE_PLUGINMENU, PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO ]): l.id = l.name.lower().replace(' ', '_') if l.id not in id_list: id_list.append(l.id) plugin_list.append( (l.name, boundFunction(l.__call__, session), l.id, 200)) self.list = m_list if menuID is not None and config.usage.menu_sort_mode.value == 'user': self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue( self.menuID, 'submenu') or {} idx = 0 for x in self.list: entry = list(self.list.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue( entry[2], 'sort') or entry[3] entry.append(m_weight) self.list.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], 'sort', m_weight) idx += 1 self.full_list = list(m_list) if config.usage.menu_sort_mode.value == 'a_z': m_list.sort(key=self.sortByName) elif config.usage.menu_sort_mode.value == 'user': self['key_blue'].setText(_('Edit mode on')) self.hide_show_entries() m_list = self.list else: m_list.sort(key=lambda x: int(x[3])) if config.usage.menu_show_numbers.value: m_list = [(str(x[0] + 1) + ' ' + x[1][0], x[1][1], x[1][2]) for x in enumerate(m_list)] self['menu'] = List(m_list) self['menu'].enableWrapAround = True if config.usage.menu_sort_mode.value == 'user': self['menu'].onSelectionChanged.append(self.selectionChanged) self['actions'] = NumberActionMap( ['OkCancelActions', 'MenuActions', 'NumberActions'], { 'ok': self.okbuttonClick, 'cancel': self.closeNonRecursive, 'menu': self.closeRecursive, '0': self.keyNumberGlobal, '1': self.keyNumberGlobal, '2': self.keyNumberGlobal, '3': self.keyNumberGlobal, '4': self.keyNumberGlobal, '5': self.keyNumberGlobal, '6': self.keyNumberGlobal, '7': self.keyNumberGlobal, '8': self.keyNumberGlobal, '9': self.keyNumberGlobal }) if config.usage.menu_sort_mode.value == 'user': self['MoveActions'] = ActionMap( ['WizardActions'], { 'left': self.keyLeft, 'right': self.keyRight, 'up': self.keyUp, 'down': self.keyDown }, -1) self['EditActions'] = ActionMap( ['ColorActions'], { 'green': self.keyGreen, 'yellow': self.keyYellow, 'blue': self.keyBlue }) a = parent.get('title', '').encode('UTF-8') or None a = a and _(a) if a is None: a = _(parent.get('text', '').encode('UTF-8')) else: t_history.reset() self['title'] = StaticText(a) Screen.setTitle(self, a) self.menu_title = a self['thistory'] = StaticText(t_history.thistory) history_len = len(t_history.thistory) self['title0'] = StaticText('') self['title1'] = StaticText('') self['title2'] = StaticText('') if history_len < 13: self['title0'] = StaticText(a) elif history_len < 21: self['title0'] = StaticText('') self['title1'] = StaticText(a) else: self['title0'] = StaticText('') self['title1'] = StaticText('') self['title2'] = StaticText(a) if t_history.thistory == '': t_history.thistory = str(a) + ' > ' else: t_history.thistory = t_history.thistory + str(a) + ' > ' if config.usage.menutype.value == 'horzanim' and skin.dom_screens.has_key( 'Animmain'): self['label1'] = StaticText() self['label2'] = StaticText() self['label3'] = StaticText() self['label4'] = StaticText() self['label5'] = StaticText() self.onShown.append(self.openTestA) elif config.usage.menutype.value == 'horzicon' and skin.dom_screens.has_key( 'Iconmain'): self['label1'] = StaticText() self['label2'] = StaticText() self['label3'] = StaticText() self['label4'] = StaticText() self['label5'] = StaticText() self['label6'] = StaticText() self['label1s'] = StaticText() self['label2s'] = StaticText() self['label3s'] = StaticText() self['label4s'] = StaticText() self['label5s'] = StaticText() self['label6s'] = StaticText() self['pointer'] = Pixmap() self['pixmap1'] = Pixmap() self['pixmap2'] = Pixmap() self['pixmap3'] = Pixmap() self['pixmap4'] = Pixmap() self['pixmap5'] = Pixmap() self['pixmap6'] = Pixmap() self.onShown.append(self.openTestB) self.number = 0 self.nextNumberTimer = eTimer() self.nextNumberTimer.callback.append(self.okbuttonClick) def openTestA(self): self.session.open(AnimMain, self.list, self.menu_title) self.close() def openTestB(self): self.session.open(IconMain, self.list, self.menu_title) self.close() def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value and self.menuID == 'mainmenu': return True if config.ParentalControl.config_sections.configuration.value and self.menuID == 'setup': return True if config.ParentalControl.config_sections.timer_menu.value and self.menuID == 'timermenu': return True if config.ParentalControl.config_sections.standby_menu.value and self.menuID == 'shutdown': return True def keyNumberGlobal(self, number): self.number = self.number * 10 + number if self.number and self.number <= len(self['menu'].list): self['menu'].setIndex(self.number - 1) if len(self['menu'].list) < 10 or self.number >= 10: self.okbuttonClick() else: self.nextNumberTimer.start(1500, True) else: self.number = 0 def resetNumberKey(self): self.nextNumberTimer.stop() self.number = 0 def closeNonRecursive(self): self.resetNumberKey() t_history.reducehistory() self.close(False) def closeRecursive(self): self.resetNumberKey() t_history.reset() self.close(True) def createSummary(self): if config.usage.menutype.value == 'standard': return MenuSummary def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value: return self.menuID == 'mainmenu' if config.ParentalControl.config_sections.configuration.value and self.menuID == 'setup': return True if config.ParentalControl.config_sections.timer_menu.value and self.menuID == 'timermenu': return True if config.ParentalControl.config_sections.standby_menu.value and self.menuID == 'shutdown': return True def updateList(self): self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue( self.menuID, 'submenu') or None idx = 0 for x in self.list: entry = list(self.list.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue(entry[2], 'sort') or entry[3] entry.append(m_weight) self.list.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], 'sort', m_weight) if not self.sort_mode and self.sub_menu_sort.getConfigValue( entry[2], 'hidden'): self.list.remove(x) idx += 1 def keyLeft(self): self.cur_idx = self['menu'].getSelectedIndex() self['menu'].pageUp() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyRight(self): self.cur_idx = self['menu'].getSelectedIndex() self['menu'].pageDown() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyDown(self): self.cur_idx = self['menu'].getSelectedIndex() self['menu'].down() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyUp(self): self.cur_idx = self['menu'].getSelectedIndex() self['menu'].up() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyOk(self): if self.sort_mode and len(self.list): m_entry = selection = self['menu'].getCurrent() select = False if self.selected_entry is None: select = True elif self.selected_entry != m_entry[2]: select = True if not select: self['key_green'].setText(_('Move mode on')) self.selected_entry = None else: self['key_green'].setText(_('Move mode off')) idx = 0 for x in self.list: if m_entry[2] == x[2] and select == True: self.selected_entry = m_entry[2] break elif m_entry[2] == x[2] and select == False: self.selected_entry = None break idx += 1 elif not self.sort_mode: self.okbuttonClick() def moveAction(self): tmp_list = list(self.list) entry = tmp_list.pop(self.cur_idx) newpos = self['menu'].getSelectedIndex() tmp_list.insert(newpos, entry) self.list = list(tmp_list) self['menu'].updateList(self.list) def keyBlue(self): if config.usage.menu_sort_mode.value == 'user': self.toggleSortMode() def keyYellow(self): if self.sort_mode: m_entry = selection = self['menu'].getCurrent()[2] hidden = self.sub_menu_sort.getConfigValue(m_entry, 'hidden') or 0 if hidden: self.sub_menu_sort.removeConfigValue(m_entry, 'hidden') self['key_yellow'].setText(_('Hide')) else: self.sub_menu_sort.changeConfigValue(m_entry, 'hidden', 1) self['key_yellow'].setText(_('Show')) def keyGreen(self): if self.sort_mode: self.keyOk() def keyCancel(self): if self.sort_mode: self.toggleSortMode() else: self.closeNonRecursive() def resetSortOrder(self, key=None): config.usage.menu_sort_weight.value = {'mainmenu': {'submenu': {}}} config.usage.menu_sort_weight.save() self.closeRecursive() def toggleSortMode(self): if self.sort_mode: self['key_green'].setText('') self['key_yellow'].setText('') self['key_blue'].setText(_('Edit mode on')) self.sort_mode = False i = 10 idx = 0 for x in self.list: self.sub_menu_sort.changeConfigValue(x[2], 'sort', i) if len(x) >= 7: entry = list(x) entry[6] = i entry = tuple(entry) self.list.pop(idx) self.list.insert(idx, entry) if self.selected_entry is not None: if x[2] == self.selected_entry: self.selected_entry = None i += 10 idx += 1 self.full_list = list(self.list) config.usage.menu_sort_weight.changeConfigValue( self.menuID, 'submenu', self.sub_menu_sort.value) config.usage.menu_sort_weight.save() self.hide_show_entries() self['menu'].setList(self.list) else: self['key_green'].setText(_('Move mode on')) self['key_blue'].setText(_('Edit mode off')) self.sort_mode = True self.hide_show_entries() self['menu'].updateList(self.list) self.selectionChanged() def hide_show_entries(self): m_list = list(self.full_list) if not self.sort_mode: rm_list = [] for entry in m_list: if self.sub_menu_sort.getConfigValue(entry[2], 'hidden'): rm_list.append(entry) for entry in rm_list: if entry in m_list: m_list.remove(entry) if not len(m_list): m_list.append(('', None, 'dummy', '10', '', None, 10)) m_list.sort(key=lambda listweight: int(listweight[6])) self.list = list(m_list) def selectionChanged(self): if self.sort_mode: selection = self['menu'].getCurrent()[2] if self.sub_menu_sort.getConfigValue(selection, 'hidden'): self['key_yellow'].setText(_('Show')) else: self['key_yellow'].setText(_('Hide')) else: self['key_yellow'].setText('')
class Menu(Screen, ProtectedScreen): ALLOW_SUSPEND = True png_cache = {} def okbuttonClick(self): global lastMenuID print 'okbuttonClick' if self.number: self["menu"].setIndex(self.number - 1) self.resetNumberKey() selection = self['menu'].getCurrent() if selection is not None: lastMenuID = selection[2] selection[1]() def execText(self, text): exec text def runScreen(self, arg): if arg[0] != '': exec 'from ' + arg[0] + ' import *' self.openDialog(*eval(arg[1])) def nothing(self): pass def openDialog(self, *dialog): # in every layer needed self.session.openWithCallback(self.menuClosed, *dialog) def openSetup(self, dialog): self.session.openWithCallback(self.menuClosed, Setup, dialog) def addMenu(self, destList, node): requires = node.get('requires') if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return MenuTitle = _(node.get('text', '??').encode('UTF-8')) entryID = node.get('entryID', 'undefined') weight = node.get('weight', 50) description = node.get('description', '').encode('UTF-8') or None description = description and _(description) menupng = MenuEntryPixmap(entryID, self.png_cache, lastMenuID) x = node.get('flushConfigOnClose') if x: a = boundFunction(self.session.openWithCallback, self.menuClosedWithConfigFlush, Menu, node) else: a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node) destList.append((MenuTitle, a, entryID, weight, description, menupng)) def menuClosedWithConfigFlush(self, *res): configfile.save() self.menuClosed(*res) def menuClosed(self, *res): global lastMenuID if res and res[0]: lastMenuID = None self.close(True) else: self.createMenuList() def addItem(self, destList, node): requires = node.get('requires') if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return configCondition = node.get('configcondition') if configCondition and not eval(configCondition + '.value'): return item_text = node.get('text', '').encode('UTF-8') entryID = node.get('entryID', 'undefined') weight = node.get('weight', 50) description = node.get('description', '').encode('UTF-8') or None description = description and _(description) menupng = MenuEntryPixmap(entryID, self.png_cache, lastMenuID) for x in node: if x.tag == 'screen': module = x.get('module') screen = x.get('screen') if screen is None: screen = module if module: module = 'Screens.' + module else: module = '' args = x.text or '' screen += ', ' + args destList.append( (_(item_text or '??'), boundFunction(self.runScreen, (module, screen)), entryID, weight, description, menupng)) return if x.tag == 'code': destList.append( (_(item_text or '??'), boundFunction(self.execText, x.text), entryID, weight)) return if x.tag == 'setup': id = x.get('id') if item_text == '': item_text = _(getSetupTitle(id)) else: item_text = _(item_text) destList.append((item_text, boundFunction(self.openSetup, id), entryID, weight, description, menupng)) return destList.append( (item_text, self.nothing, entryID, weight, description, menupng)) def sortByName(self, listentry): return listentry[0].lower() def __init__(self, session, parent): self.parentmenu = parent Screen.__init__(self, session) self['menu'] = List([]) self['menu'].enableWrapAround = True self.createMenuList() self.skinName = [] if self.menuID is not None: self.skinName.append('menu_' + self.menuID) self.skinName.append('Menu') ProtectedScreen.__init__(self) self['actions'] = NumberActionMap( ['OkCancelActions', 'MenuActions', 'NumberActions'], { 'ok': self.okbuttonClick, 'cancel': self.closeNonRecursive, 'menu': self.closeRecursive, '0': self.keyNumberGlobal, '1': self.keyNumberGlobal, '2': self.keyNumberGlobal, '3': self.keyNumberGlobal, '4': self.keyNumberGlobal, '5': self.keyNumberGlobal, '6': self.keyNumberGlobal, '7': self.keyNumberGlobal, '8': self.keyNumberGlobal, '9': self.keyNumberGlobal }) if config.usage.menu_sort_mode.value == 'user': self['EditActions'] = ActionMap(['ColorActions'], {'blue': self.keyBlue}) title = parent.get('title', '').encode('UTF-8') or None title = title and _(title) or _(parent.get('text', '').encode('UTF-8')) title = self.__class__.__name__ == 'MenuSort' and _( 'Menusort (%s)') % title or title self['title'] = StaticText(title) self.setScreenPathMode(True) self.setTitle(title) self.number = 0 self.nextNumberTimer = eTimer() self.nextNumberTimer.callback.append(self.okbuttonClick) def createMenuList(self): self.list = [] self.menuID = None count = 0 for x in self.parentmenu: #walk through the actual nodelist if not x.tag: continue if x.tag == 'item': item_level = int(x.get('level', 0)) if item_level <= config.usage.setup_level.index: self.addItem(self.list, x) count += 1 elif x.tag == 'menu': item_level = int(x.get('level', 0)) if item_level <= config.usage.setup_level.index: self.addMenu(self.list, x) count += 1 elif x.tag == 'id': self.menuID = x.get('val') count = 0 if self.menuID is not None: if menuupdater.updatedMenuAvailable(self.menuID): for x in menuupdater.getUpdatedMenu(self.menuID): if x[1] == count: description = x.get('description', '').encode('UTF-8') or None description = description and _(description) menupng = MenuEntryPixmap(self.menuID, self.png_cache, lastMenuID) self.list.append( (x[0], boundFunction(self.runScreen, (x[2], x[3] + ', ')), x[4], description, menupng)) count += 1 if self.menuID is not None: for l in plugins.getPluginsForMenu(self.menuID): plugin_menuid = l[2] for x in self.list: if x[2] == plugin_menuid: self.list.remove(x) break description = plugins.getDescriptionForMenuEntryID( self.menuID, plugin_menuid) menupng = MenuEntryPixmap(l[2], self.png_cache, lastMenuID) self.list.append((l[0], boundFunction(l[1], self.session), l[2], l[3] or 50, description, menupng)) if config.usage.menu_sort_mode.value == 'user' and self.menuID == 'mainmenu': plugin_list = [] id_list = [] for l in plugins.getPlugins([ PluginDescriptor.WHERE_PLUGINMENU, PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO ]): l.id = l.name.lower().replace(' ', '_') if l.id not in id_list: id_list.append(l.id) plugin_list.append( (l.name, boundFunction(l.__call__, self.session), l.id, 200)) if self.menuID is not None and config.usage.menu_sort_mode.value == 'user': self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue( self.menuID, 'submenu') or {} idx = 0 for x in self.list: entry = list(self.list.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue( entry[2], 'sort') or entry[3] entry.append(m_weight) self.list.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], 'sort', m_weight) idx += 1 self.full_list = list(self.list) if config.usage.menu_sort_mode.value == 'a_z': self.list.sort(key=self.sortByName) elif config.usage.menu_sort_mode.value == 'user': self.hide_show_entries() else: self.list.sort(key=lambda x: int(x[3])) if config.usage.menu_show_numbers.value: self.list = [(str(x[0] + 1) + " " + x[1][0], x[1][1], x[1][2]) for x in enumerate(self.list)] self['menu'].updateList(self.list) def keyNumberGlobal(self, number): self.number = self.number * 10 + number if self.number and self.number <= len(self["menu"].list): if number * 10 > len(self["menu"].list) or self.number >= 10: self.okbuttonClick() else: self.nextNumberTimer.start(1500, True) else: self.resetNumberKey() def resetNumberKey(self): self.nextNumberTimer.stop() self.number = 0 def closeNonRecursive(self): self.resetNumberKey() self.close(False) def closeRecursive(self): self.resetNumberKey() self.close(True) def createSummary(self): return MenuSummary def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value and not ( hasattr(self.session, 'infobar') and self.session.infobar is None): return self.menuID == 'mainmenu' if config.ParentalControl.config_sections.configuration.value and self.menuID == 'setup': return True if config.ParentalControl.config_sections.timer_menu.value and self.menuID == 'timermenu': return True if config.ParentalControl.config_sections.standby_menu.value and self.menuID == 'shutdown': return True def keyBlue(self): if config.usage.menu_sort_mode.value == "user": self.session.openWithCallback(self.menuSortCallBack, MenuSort, self.parentmenu) def menuSortCallBack(self, key=False): self.createMenuList() def keyCancel(self): self.closeNonRecursive() def hide_show_entries(self): self.list = [] for entry in self.full_list: if not self.sub_menu_sort.getConfigValue(entry[2], 'hidden'): self.list.append(entry) if not self.list: self.list.append(('', None, 'dummy', '10', 10, None, 10)) newlist = [] for item in self.list: if 'Factory reset' in item: #item=list(item) item = (item[0], item[1], item[2], item[3], item[3], "None", "50") newlist.append(item) self.list = newlist self.list.sort(key=lambda listweight: int(listweight[6]))
class Menu(Screen, ProtectedScreen): ALLOW_SUSPEND = True def okbuttonClick(self): # print "okbuttonClick" selection = self["menu"].getCurrent() if selection is not None and selection[1] is not None: selection[1]() def execText(self, text): exec text def runScreen(self, arg): # arg[0] is the module (as string) # arg[1] is Screen inside this module # plus possible arguments, as # string (as we want to reference # stuff which is just imported) # FIXME. somehow if arg[0] != "": exec "from " + arg[0] + " import *" self.openDialog(*eval(arg[1])) def nothing(self): #dummy pass def openDialog(self, *dialog): # in every layer needed self.session.openWithCallback(self.menuClosed, *dialog) def openSetup(self, dialog): self.session.openWithCallback(self.menuClosed, Setup, dialog) def addMenu(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return 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) else: a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node) #TODO add check if !empty(node.childNodes) destList.append((MenuTitle, a, entryID, weight)) def menuClosedWithConfigFlush(self, *res): configfile.save() self.menuClosed(*res) def menuClosed(self, *res): if res and res[0]: self.close(True) def addItem(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return configCondition = node.get("configcondition") if configCondition and not eval(configCondition + ".value"): return 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 # print module, screen if module: module = "Screens." + module else: module = "" # check for arguments. they will be appended to the # openDialog call args = x.text or "" screen += ", " + args destList.append((_(item_text or "??"), boundFunction(self.runScreen, (module, screen)), entryID, weight)) return elif x.tag == 'code': destList.append((_(item_text or "??"), boundFunction(self.execText, x.text), entryID, weight)) return elif x.tag == 'setup': id = x.get("id") if item_text == "": item_text = _(getSetupTitle(id)) else: item_text = _(item_text) destList.append((item_text, boundFunction(self.openSetup, id), entryID, weight)) return destList.append((item_text, self.nothing, entryID, weight)) def sortByName(self, listentry): return listentry[0].lower() def __init__(self, session, parent): Screen.__init__(self, session) self.sort_mode = False self.selected_entry = None self.sub_menu_sort = None self["green"] = Label() self["yellow"] = Label() self["blue"] = Label() m_list = [] menuID = None for x in parent: #walk through the actual nodelist if not x.tag: continue if x.tag == 'item': item_level = int(x.get("level", 0)) if item_level <= config.usage.setup_level.index: self.addItem(m_list, x) count += 1 elif x.tag == 'menu': item_level = int(x.get("level", 0)) if item_level <= config.usage.setup_level.index: self.addMenu(m_list, x) count += 1 elif x.tag == "id": menuID = x.get("val") count = 0 if menuID is not None: # menuupdater? if menuupdater.updatedMenuAvailable(menuID): for x in menuupdater.getUpdatedMenu(menuID): if x[1] == count: m_list.append((x[0], boundFunction(self.runScreen, (x[2], x[3] + ", ")), x[4])) count += 1 self.menuID = menuID if menuID is not None: # plugins for l in plugins.getPluginsForMenu(menuID): # check if a plugin overrides an existing menu plugin_menuid = l[2] for x in m_list: if x[2] == plugin_menuid: m_list.remove(x) break if len(l) > 4 and l[4]: m_list.append((l[0], boundFunction(l[1], self.session, self.close), l[2], l[3] or 50)) else: m_list.append((l[0], boundFunction(l[1], self.session), l[2], l[3] or 50)) # for the skin: first try a menu_<menuID>, then Menu self.skinName = [ ] if menuID is not None: self.skinName.append("menu_" + menuID) self.skinName.append("Menu") self.menuID = menuID ProtectedScreen.__init__(self) if config.usage.menu_sort_mode.value == "user" and menuID == "mainmenu": plugin_list = [] id_list = [] for l in plugins.getPlugins([PluginDescriptor.WHERE_PLUGINMENU ,PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO]): l.id = (l.name.lower()).replace(' ','_') if l.id not in id_list: id_list.append(l.id) plugin_list.append((l.name, boundFunction(l.__call__, session), l.id, 200)) self.list = m_list if menuID is not None and config.usage.menu_sort_mode.value == "user": self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue(self.menuID, "submenu") or {} idx = 0 for x in self.list: entry = list(self.list.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue(entry[2], "sort") or entry[3] entry.append(m_weight) self.list.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], "sort", m_weight) idx += 1 self.full_list = list(m_list) if config.usage.menu_sort_mode.value == "a_z": # Sort by Name m_list.sort(key=self.sortByName) elif config.usage.menu_sort_mode.value == "user": self["blue"].setText(_("Edit mode on")) self.hide_show_entries() m_list = self.list else: # Sort by Weight m_list.sort(key=lambda x: int(x[3])) self["menu"] = List(m_list) self["menu"].enableWrapAround = True if config.usage.menu_sort_mode.value == "user": self["menu"].onSelectionChanged.append(self.selectionChanged) self["actions"] = NumberActionMap(["OkCancelActions", "MenuActions", "NumberActions"], { "ok": self.okbuttonClick, "cancel": self.closeNonRecursive, "menu": self.closeRecursive, "0": self.resetSortOrder, "1": self.keyNumberGlobal, "2": self.keyNumberGlobal, "3": self.keyNumberGlobal, "4": self.keyNumberGlobal, "5": self.keyNumberGlobal, "6": self.keyNumberGlobal, "7": self.keyNumberGlobal, "8": self.keyNumberGlobal, "9": self.keyNumberGlobal }) if config.usage.menu_sort_mode.value == "user": self["MoveActions"] = ActionMap(["WizardActions"], { "left": self.keyLeft, "right": self.keyRight, "up": self.keyUp, "down": self.keyDown, }, -1 ) self["EditActions"] = ActionMap(["ColorActions"], { "green": self.keyGreen, "yellow": self.keyYellow, "blue": self.keyBlue, }) a = parent.get("title", "").encode("UTF-8") or None a = a and _(a) or _(parent.get("text", "").encode("UTF-8")) self["title"] = StaticText(a) Screen.setTitle(self, a) self.menu_title = a global menu_path self.menu_path_compressed = menu_path menu_path = menu_path and menu_path + " > " + a or a self["menu_path"] = StaticText(menu_path) self["menu_path_compressed"] = StaticText(self.menu_path_compressed and self.menu_path_compressed + " >" or "") def keyNumberGlobal(self, number): # print "menu keyNumber:", number # Calculate index number -= 1 if len(self["menu"].list) > number: self["menu"].setIndex(number) self.okbuttonClick() def closeNonRecursive(self): global menu_path menu_path = self.menu_path_compressed self.close(False) def closeRecursive(self): global menu_path menu_path = "" self.close(True) def createSummary(self): return MenuSummary def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value and not(hasattr(self.session, 'infobar') and self.session.infobar is None): return self.menuID == "mainmenu" elif config.ParentalControl.config_sections.configuration.value and self.menuID == "setup": return True elif config.ParentalControl.config_sections.timer_menu.value and self.menuID == "timermenu": return True elif config.ParentalControl.config_sections.standby_menu.value and self.menuID == "shutdown": return True def updateList(self): self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue(self.menuID, "submenu") or None idx = 0 for x in self.list: entry = list(self.list.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue(entry[2], "sort") or entry[3] entry.append(m_weight) self.list.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], "sort", m_weight) if not self.sort_mode and self.sub_menu_sort.getConfigValue(entry[2], "hidden"): self.list.remove(x) idx += 1 def keyLeft(self): self.cur_idx = self["menu"].getSelectedIndex() self["menu"].pageUp() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyRight(self): self.cur_idx = self["menu"].getSelectedIndex() self["menu"].pageDown() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyDown(self): self.cur_idx = self["menu"].getSelectedIndex() self["menu"].down() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyUp(self): self.cur_idx = self["menu"].getSelectedIndex() self["menu"].up() if self.sort_mode and self.selected_entry is not None: self.moveAction() def keyOk(self): if self.sort_mode and len(self.list): m_entry = selection = self["menu"].getCurrent() select = False if self.selected_entry is None: select = True elif self.selected_entry != m_entry[2]: select = True if not select: self["green"].setText(_("Move mode on")) self.selected_entry = None else: self["green"].setText(_("Move mode off")) idx = 0 for x in self.list: if m_entry[2] == x[2] and select == True: self.selected_entry = m_entry[2] break elif m_entry[2] == x[2] and select == False: self.selected_entry = None break idx += 1 elif not self.sort_mode: self.okbuttonClick() def moveAction(self): tmp_list = list(self.list) entry = tmp_list.pop(self.cur_idx) newpos = self["menu"].getSelectedIndex() tmp_list.insert(newpos, entry) self.list = list(tmp_list) self["menu"].updateList(self.list) def keyBlue(self): if config.usage.menu_sort_mode.value == "user": self.toggleSortMode() def keyYellow(self): if self.sort_mode: m_entry = selection = self["menu"].getCurrent()[2] hidden = self.sub_menu_sort.getConfigValue(m_entry, "hidden") or 0 if hidden: self.sub_menu_sort.removeConfigValue(m_entry, "hidden") self["yellow"].setText(_("hide")) else: self.sub_menu_sort.changeConfigValue(m_entry, "hidden", 1) self["yellow"].setText(_("show")) def keyGreen(self): if self.sort_mode: self.keyOk() def keyCancel(self): if self.sort_mode: self.toggleSortMode() else: self.closeNonRecursive() def resetSortOrder(self, key = None): config.usage.menu_sort_weight.value = { "mainmenu" : {"submenu" : {} }} config.usage.menu_sort_weight.save() self.closeRecursive() def toggleSortMode(self): if self.sort_mode: self["green"].setText("") self["yellow"].setText("") self["blue"].setText(_("Edit mode on")) self.sort_mode = False i = 10 idx = 0 for x in self.list: self.sub_menu_sort.changeConfigValue(x[2], "sort", i) if len(x) >= 5: entry = list(x) entry[4] = i entry = tuple(entry) self.list.pop(idx) self.list.insert(idx, entry) if self.selected_entry is not None: if x[2] == self.selected_entry: self.selected_entry = None i += 10 idx += 1 self.full_list = list(self.list) config.usage.menu_sort_weight.changeConfigValue(self.menuID, "submenu", self.sub_menu_sort.value) config.usage.menu_sort_weight.save() self.hide_show_entries() self["menu"].setList(self.list) else: self["green"].setText(_("Move mode on")) self["blue"].setText(_("Edit mode off")) self.sort_mode = True self.hide_show_entries() self["menu"].updateList(self.list) self.selectionChanged() def hide_show_entries(self): m_list = list(self.full_list) if not self.sort_mode: rm_list = [] for entry in m_list: if self.sub_menu_sort.getConfigValue(entry[2], "hidden"): rm_list.append(entry) for entry in rm_list: if entry in m_list: m_list.remove(entry) if not len(m_list): m_list.append(('',None,'dummy','10',10)) m_list.sort(key=lambda listweight : int(listweight[4])) self.list = list(m_list) def selectionChanged(self): if self.sort_mode: selection = self["menu"].getCurrent()[2] if self.sub_menu_sort.getConfigValue(selection, "hidden"): self["yellow"].setText(_("show")) else: self["yellow"].setText(_("hide")) else: self["yellow"].setText("")
class Menu(Screen, HelpableScreen, ProtectedScreen): ALLOW_SUSPEND = True def okbuttonClick(self): if self.number: if self.menuHorizontal: self.horzIndex = self.number - 1 else: self["menu"].setIndex(self.number - 1) self.resetNumberKey() selection = self.list[self.horzIndex] if self.menuHorizontal else self["menu"].getCurrent() if selection and selection[1]: selection[1]() def execText(self, text): exec(text) def runScreen(self, arg): # arg[0] is the module (as string) # arg[1] is Screen inside this module # plus possible arguments, as # string (as we want to reference # stuff which is just imported) if arg[0] != "": exec("from %s import %s" % (arg[0], arg[1].split(",")[0])) self.openDialog(*eval(arg[1])) def nothing(self): #dummy pass def openDialog(self, *dialog): # in every layer needed self.session.openWithCallback(self.menuClosed, *dialog) def openSetup(self, dialog): self.session.openWithCallback(self.menuClosed, Setup, dialog) def addMenu(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return # print("[Menu][addMenu] Menu text=", node.get("text", "??")) MenuTitle = str(_(node.get("text", "??"))) 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) else: a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node) #TODO add check if !empty(node.childNodes) destList.append((MenuTitle, a, entryID, weight)) def menuClosedWithConfigFlush(self, *res): configfile.save() self.menuClosed(*res) def menuClosed(self, *res): if res and res[0]: self.close(True) elif len(self.list) == 1: self.close() else: self.createMenuList() def addItem(self, destList, node): requires = node.get("requires") if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return conditional = node.get("conditional") if conditional and not eval(conditional): return # print("[Menu][addItem] item text=", node.get("text", "* Undefined *")) item_text = str(node.get("text", "* Undefined *")) if item_text: item_text = _(item_text) 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 # print module, screen if module: module = "Screens." + module else: module = "" # check for arguments. they will be appended to the # openDialog call args = x.text or "" screen += ", " + args destList.append((item_text, boundFunction(self.runScreen, (module, screen)), entryID, weight)) return elif x.tag == 'plugin': extensions = x.get("extensions") system = x.get("system") screen = x.get("screen") if extensions: module = extensions elif system: module = system if screen is None: screen = module if extensions: module = "Plugins.Extensions." + extensions + '.plugin' elif system: module = "Plugins.SystemPlugins." + system + '.plugin' else: module = "" # check for arguments. they will be appended to the # openDialog call args = x.text or "" screen += ", " + args destList.append((item_text, boundFunction(self.runScreen, (module, screen)), entryID, weight)) return elif x.tag == 'code': destList.append((item_text, boundFunction(self.execText, x.text), entryID, weight)) return elif x.tag == 'setup': id = x.get("id") destList.append((item_text, boundFunction(self.openSetup, id), entryID, weight)) return destList.append((item_text, self.nothing, entryID, weight)) def __init__(self, session, parent): self.parentmenu = parent Screen.__init__(self, session) self.menuHorizontalSkinName = "MenuHorizontal" self.menuHorizontal = self.__class__.__name__ != "MenuSort" and config.usage.menu_style.value == "horizontal" and findSkinScreen(self.menuHorizontalSkinName) self.onHorizontalSelectionChanged = [] self["key_blue"] = StaticText("") HelpableScreen.__init__(self) self.menulength = 0 if not self.menuHorizontal: self["menu"] = List([]) self["menu"].enableWrapAround = True self.createMenuList() # for the skin: first try a menu_<menuID>, then Menu self.skinName = [] if self.menuHorizontal: if self.menuID: self.skinName.append(self.menuHorizontalSkinName + "_" + self.menuID) self.skinName.append(self.menuHorizontalSkinName) elif self.menuID: self.skinName.append("menu_" + self.menuID) self.skinName.append("Menu") ProtectedScreen.__init__(self) self["menuActions"] = HelpableActionMap(self, ["OkCancelActions", "MenuActions"], { "ok": (self.okbuttonClick, self.okbuttontext if hasattr(self, "okbuttontext") else _("Select the current menu item")), "cancel": (self.closeNonRecursive, self.exitbuttontext if hasattr(self, "exitbuttontext") else _("Exit menu")), "close": (self.closeRecursive, self.exitbuttontext if hasattr(self, "exitbuttontext") else _("Exit all menus")), "menu": (self.closeRecursive, _("Exit all menus")), }, prio=0, description=_("Common Menu Actions")) if self.__class__.__name__ != "MenuSort": self["menuActions2"] = HelpableNumberActionMap(self, ["NumberActions", "ColorActions"], { "0": (self.keyNumberGlobal, _("Direct menu item selection")), "1": (self.keyNumberGlobal, _("Direct menu item selection")), "2": (self.keyNumberGlobal, _("Direct menu item selection")), "3": (self.keyNumberGlobal, _("Direct menu item selection")), "4": (self.keyNumberGlobal, _("Direct menu item selection")), "5": (self.keyNumberGlobal, _("Direct menu item selection")), "6": (self.keyNumberGlobal, _("Direct menu item selection")), "7": (self.keyNumberGlobal, _("Direct menu item selection")), "8": (self.keyNumberGlobal, _("Direct menu item selection")), "9": (self.keyNumberGlobal, _("Direct menu item selection")), "blue": (self.keyBlue, _("Sort menu")), }, prio=0, description=_("Common Menu Actions")) title = parent.get("title", "") title = title and _(title) or _(parent.get("text", "")) title = self.__class__.__name__ == "MenuSort" and _("Menusort (%s)") % title or title self["title"] = StaticText(title) self.setTitle(title) self.number = 0 self.nextNumberTimer = eTimer() self.nextNumberTimer.callback.append(self.okbuttonClick) if len(self.list) == 1: self.onExecBegin.append(self.__onExecBegin) if self.menuHorizontal: self.initMenuHorizontal() def __onExecBegin(self): self.onExecBegin.remove(self.__onExecBegin) self.okbuttonClick() def createMenuList(self): if self.__class__.__name__ != "MenuSort": self["key_blue"].text = _("Edit menu") if config.usage.menu_sort_mode.value == "user" else "" self.list = [] self.menuID = None for x in self.parentmenu: #walk through the actual nodelist if not x.tag: continue if x.tag == 'item': item_level = int(x.get("level", 0)) if item_level <= config.usage.setup_level.index: self.addItem(self.list, x) count += 1 elif x.tag == 'menu': item_level = int(x.get("level", 0)) if item_level <= config.usage.setup_level.index: self.addMenu(self.list, x) count += 1 elif x.tag == "id": self.menuID = x.get("val") count = 0 if self.menuID is not None: # menuupdater? if menuupdater.updatedMenuAvailable(self.menuID): for x in menuupdater.getUpdatedMenu(self.menuID): if x[1] == count: self.list.append((x[0], boundFunction(self.runScreen, (x[2], x[3] + ", ")), x[4])) count += 1 if self.menuID is not None: # plugins for l in plugins.getPluginsForMenu(self.menuID): # check if a plugin overrides an existing menu plugin_menuid = l[2] for x in self.list: if x[2] == plugin_menuid: self.list.remove(x) break if len(l) > 4 and l[4]: self.list.append((l[0], boundFunction(l[1], self.session, self.close), l[2], l[3] or 50)) else: self.list.append((l[0], boundFunction(l[1], self.session), l[2], l[3] or 50)) if "user" in config.usage.menu_sort_mode.value and self.menuID == "mainmenu": plugin_list = [] id_list = [] for l in plugins.getPlugins([PluginDescriptor.WHERE_PLUGINMENU, PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO]): l.id = (l.name.lower()).replace(' ', '_') if l.id not in id_list: id_list.append(l.id) plugin_list.append((l.name, boundFunction(l.fnc, self.session), l.id, 200)) if self.menuID is not None and "user" in config.usage.menu_sort_mode.value: self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue(self.menuID, "submenu") or {} idx = 0 for x in self.list: entry = list(self.list.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue(entry[2], "sort") or entry[3] entry.append(m_weight) self.list.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], "sort", m_weight) idx += 1 self.full_list = list(self.list) if config.usage.menu_sort_mode.value == "a_z": # Sort alphabetical self.list.sort(key=lambda x: x[0].lower()) elif "user" in config.usage.menu_sort_mode.value: self.hide_show_entries() else: # Sort by Weight self.list.sort(key=lambda x: int(x[3])) if config.usage.menu_show_numbers.value: self.list = [(str(x[0] + 1) + " " + x[1][0], x[1][1], x[1][2]) for x in enumerate(self.list)] if self.menulength != len(self.list): # updateList must only be used on a list of the same length. If length is different we call setList. self.menulength = len(self.list) if not self.menuHorizontal: self["menu"].setList(self.list) if not self.menuHorizontal: self["menu"].updateList(self.list) def keyNumberGlobal(self, number): self.number = self.number * 10 + number if self.number and self.number <= self.menulength: if number * 10 > self.menulength or self.number >= 10: self.okbuttonClick() else: self.nextNumberTimer.start(1500, True) else: self.resetNumberKey() def resetNumberKey(self): self.nextNumberTimer.stop() self.number = 0 def closeNonRecursive(self): self.resetNumberKey() self.close(False) def closeRecursive(self): self.resetNumberKey() self.close(True) def createSummary(self): if not self.menuHorizontal: return MenuSummary else: return MenuHorizontalSummary def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value and not(hasattr(self.session, 'infobar') and self.session.infobar is None): return self.menuID == "mainmenu" elif config.ParentalControl.config_sections.configuration.value and self.menuID == "setup": return True elif config.ParentalControl.config_sections.standby_menu.value and self.menuID == "shutdown": return True def keyBlue(self): if "user" in config.usage.menu_sort_mode.value: self.session.openWithCallback(self.menuSortCallBack, MenuSort, self.parentmenu) else: return 0 def menuSortCallBack(self, key=False): self.createMenuList() def keyCancel(self): self.closeNonRecursive() def hide_show_entries(self): self.list = [] for entry in self.full_list: if not self.sub_menu_sort.getConfigValue(entry[2], "hidden"): self.list.append(entry) if not self.list: self.list.append(('', None, 'dummy', '10', 10)) self.list.sort(key=lambda listweight: int(listweight[4])) # for horizontal menu def updateMenuHorz(self): i = self.horzIndex L = self.menulength self["label1"].setText(self.list[(i-2)%L][0] if L > 3 else "") self["label2"].setText(self.list[(i-1)%L][0] if L > 1 else "") self["label3"].setText(self.list[i][0]) self["label4"].setText(self.list[(i+1)%L][0] if L > 1 else "") self["label5"].setText(self.list[(i+2)%L][0] if L > 3 else "") def keyLeftHorz(self): self.horzIndex = (self.horzIndex - 1) % self.menulength self.updateMenuHorz() self.horizontalSelectionChanged() def keyRightHorz(self): self.horzIndex = (self.horzIndex + 1) % self.menulength self.updateMenuHorz() self.horizontalSelectionChanged() def horizontalSelectionChanged(self): for x in self.onHorizontalSelectionChanged: if callable(x): x() def initMenuHorizontal(self): self["label1"] = StaticText() self["label2"] = StaticText() self["label3"] = StaticText() self["label4"] = StaticText() self["label5"] = StaticText() self["menuActions3"] = HelpableActionMap(self, ["OkCancelActions", "DirectionActions"], { "left": (self.keyLeftHorz, _("Scroll menu")), "right": (self.keyRightHorz, _("Scroll menu")), }, prio=0, description=_("Common Menu Actions")) self["menuActions3"].setEnabled(bool(self.menulength)) if self.menulength: self.horzIndex = 0 self.updateMenuHorz()
class Menu(Screen, ProtectedScreen): ALLOW_SUSPEND = True png_cache = {} def okbuttonClick(self): global lastMenuID print 'okbuttonClick' if self.number: self["menu"].setIndex(self.number - 1) self.resetNumberKey() selection = self['menu'].getCurrent() if selection is not None: lastMenuID = selection[2] selection[1]() def execText(self, text): exec text def runScreen(self, arg): if arg[0] != '': exec 'from ' + arg[0] + ' import *' self.openDialog(*eval(arg[1])) def nothing(self): pass def openDialog(self, *dialog): # in every layer needed self.session.openWithCallback(self.menuClosed, *dialog) def openSetup(self, dialog): self.session.openWithCallback(self.menuClosed, Setup, dialog) def addMenu(self, destList, node): requires = node.get('requires') if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return MenuTitle = _(node.get('text', '??').encode('UTF-8')) entryID = node.get('entryID', 'undefined') weight = node.get('weight', 50) description = node.get('description', '').encode('UTF-8') or None description = description and _(description) menupng = MenuEntryPixmap(entryID, self.png_cache, lastMenuID) x = node.get('flushConfigOnClose') if x: a = boundFunction(self.session.openWithCallback, self.menuClosedWithConfigFlush, Menu, node) else: a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node) destList.append((MenuTitle, a, entryID, weight, description, menupng)) def menuClosedWithConfigFlush(self, *res): configfile.save() self.menuClosed(*res) def menuClosed(self, *res): global lastMenuID if res and res[0]: lastMenuID = None self.close(True) else: self.createMenuList() def addItem(self, destList, node): requires = node.get('requires') if requires: if requires[0] == '!': if SystemInfo.get(requires[1:], False): return elif not SystemInfo.get(requires, False): return configCondition = node.get('configcondition') if configCondition and not eval(configCondition + '.value'): return item_text = node.get('text', '').encode('UTF-8') entryID = node.get('entryID', 'undefined') weight = node.get('weight', 50) description = node.get('description', '').encode('UTF-8') or None description = description and _(description) menupng = MenuEntryPixmap(entryID, self.png_cache, lastMenuID) for x in node: if x.tag == 'screen': module = x.get('module') screen = x.get('screen') if screen is None: screen = module if module: module = 'Screens.' + module else: module = '' args = x.text or '' screen += ', ' + args destList.append((_(item_text or '??'), boundFunction(self.runScreen, (module, screen)), entryID, weight, description, menupng)) return if x.tag == 'code': destList.append((_(item_text or '??'), boundFunction(self.execText, x.text), entryID, weight)) return if x.tag == 'setup': id = x.get('id') if item_text == '': item_text = _(getSetupTitle(id)) else: item_text = _(item_text) destList.append((item_text, boundFunction(self.openSetup, id), entryID, weight, description, menupng)) return destList.append((item_text, self.nothing, entryID, weight, description, menupng)) def sortByName(self, listentry): return listentry[0].lower() def __init__(self, session, parent): self.parentmenu = parent Screen.__init__(self, session) self['menu'] = List([]) self['menu'].enableWrapAround = True self.createMenuList() self.skinName = [] if self.menuID is not None: self.skinName.append('menu_' + self.menuID) self.skinName.append('Menu') ProtectedScreen.__init__(self) self['actions'] = NumberActionMap(['OkCancelActions', 'MenuActions', 'NumberActions'], {'ok': self.okbuttonClick, 'cancel': self.closeNonRecursive, 'menu': self.closeRecursive, '0': self.keyNumberGlobal, '1': self.keyNumberGlobal, '2': self.keyNumberGlobal, '3': self.keyNumberGlobal, '4': self.keyNumberGlobal, '5': self.keyNumberGlobal, '6': self.keyNumberGlobal, '7': self.keyNumberGlobal, '8': self.keyNumberGlobal, '9': self.keyNumberGlobal}) if config.usage.menu_sort_mode.value == 'user': self['EditActions'] = ActionMap(['ColorActions'], {'blue': self.keyBlue}) title = parent.get('title', '').encode('UTF-8') or None title = title and _(title) or _(parent.get('text', '').encode('UTF-8')) title = self.__class__.__name__ == 'MenuSort' and _('Menusort (%s)') % title or title self['title'] = StaticText(title) self.setScreenPathMode(True) self.setTitle(title) self.number = 0 self.nextNumberTimer = eTimer() self.nextNumberTimer.callback.append(self.okbuttonClick) def createMenuList(self): self.list = [] self.menuID = None count = 0 for x in self.parentmenu: #walk through the actual nodelist if not x.tag: continue if x.tag == 'item': item_level = int(x.get('level', 0)) if item_level <= config.usage.setup_level.index: self.addItem(self.list, x) count += 1 elif x.tag == 'menu': item_level = int(x.get('level', 0)) if item_level <= config.usage.setup_level.index: self.addMenu(self.list, x) count += 1 elif x.tag == 'id': self.menuID = x.get('val') count = 0 if self.menuID is not None: if menuupdater.updatedMenuAvailable(self.menuID): for x in menuupdater.getUpdatedMenu(self.menuID): if x[1] == count: description = x.get('description', '').encode('UTF-8') or None description = description and _(description) menupng = MenuEntryPixmap(self.menuID, self.png_cache, lastMenuID) self.list.append((x[0], boundFunction(self.runScreen, (x[2], x[3] + ', ')), x[4], description, menupng)) count += 1 if self.menuID is not None: for l in plugins.getPluginsForMenu(self.menuID): plugin_menuid = l[2] for x in self.list: if x[2] == plugin_menuid: self.list.remove(x) break description = plugins.getDescriptionForMenuEntryID(self.menuID, plugin_menuid) menupng = MenuEntryPixmap(l[2], self.png_cache, lastMenuID) self.list.append((l[0], boundFunction(l[1], self.session), l[2], l[3] or 50, description, menupng)) if config.usage.menu_sort_mode.value == 'user' and self.menuID == 'mainmenu': plugin_list = [] id_list = [] for l in plugins.getPlugins([PluginDescriptor.WHERE_PLUGINMENU, PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO]): l.id = l.name.lower().replace(' ', '_') if l.id not in id_list: id_list.append(l.id) plugin_list.append((l.name, boundFunction(l.__call__, self.session), l.id, 200)) if self.menuID is not None and config.usage.menu_sort_mode.value == 'user': self.sub_menu_sort = NoSave(ConfigDictionarySet()) self.sub_menu_sort.value = config.usage.menu_sort_weight.getConfigValue(self.menuID, 'submenu') or {} idx = 0 for x in self.list: entry = list(self.list.pop(idx)) m_weight = self.sub_menu_sort.getConfigValue(entry[2], 'sort') or entry[3] entry.append(m_weight) self.list.insert(idx, tuple(entry)) self.sub_menu_sort.changeConfigValue(entry[2], 'sort', m_weight) idx += 1 self.full_list = list(self.list) if config.usage.menu_sort_mode.value == 'a_z': self.list.sort(key=self.sortByName) elif config.usage.menu_sort_mode.value == 'user': self.hide_show_entries() else: self.list.sort(key=lambda x: int(x[3])) if config.usage.menu_show_numbers.value: self.list = [(str(x[0] + 1) + " " +x[1][0], x[1][1], x[1][2]) for x in enumerate(self.list)] self['menu'].updateList(self.list) def keyNumberGlobal(self, number): self.number = self.number * 10 + number if self.number and self.number <= len(self["menu"].list): if number * 10 > len(self["menu"].list) or self.number >= 10: self.okbuttonClick() else: self.nextNumberTimer.start(1500, True) else: self.resetNumberKey() def resetNumberKey(self): self.nextNumberTimer.stop() self.number = 0 def closeNonRecursive(self): self.resetNumberKey() self.close(False) def closeRecursive(self): self.resetNumberKey() self.close(True) def createSummary(self): return MenuSummary def isProtected(self): if config.ParentalControl.setuppinactive.value: if config.ParentalControl.config_sections.main_menu.value and not (hasattr(self.session, 'infobar') and self.session.infobar is None): return self.menuID == 'mainmenu' if config.ParentalControl.config_sections.configuration.value and self.menuID == 'setup': return True if config.ParentalControl.config_sections.timer_menu.value and self.menuID == 'timermenu': return True if config.ParentalControl.config_sections.standby_menu.value and self.menuID == 'shutdown': return True def keyBlue(self): if config.usage.menu_sort_mode.value == "user": self.session.openWithCallback(self.menuSortCallBack, MenuSort, self.parentmenu) def menuSortCallBack(self, key = False): self.createMenuList() def keyCancel(self): self.closeNonRecursive() def hide_show_entries(self): self.list = [] for entry in self.full_list: if not self.sub_menu_sort.getConfigValue(entry[2], 'hidden'): self.list.append(entry) if not self.list: self.list.append(('', None, 'dummy', '10', 10,None,10)) newlist=[] for item in self.list: if 'Factory reset' in item: #item=list(item) item=(item[0],item[1],item[2],item[3],item[3],"None","50") newlist.append(item) self.list=newlist self.list.sort(key=lambda listweight: int(listweight[6]))