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, 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 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, 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 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("")