fix bluescreen in ci menu when no entries in a menulist an ok is pressed
[enigma2.git] / lib / python / Screens / Menu.py
index 41d18d1ea54dea790323b271b7abc69dfba8302d..f1a013483dba6ff255686caaed3f5f82ac0cedb1 100644 (file)
@@ -1,30 +1,14 @@
-#from Screen import *
+from Screen import *
 from Components.MenuList import MenuList
 from Components.ActionMap import ActionMap
 from Components.Header import Header
 from Components.Button import Button
 from Components.Label import Label
 from Components.ProgressBar import ProgressBar
 from Components.MenuList import MenuList
 from Components.ActionMap import ActionMap
 from Components.Header import Header
 from Components.Button import Button
 from Components.Label import Label
 from Components.ProgressBar import ProgressBar
+from Components.config import configfile
+from Components.Clock import Clock
 
 
-# hack ... must be made dynamic
-#from Screens.Setup import Setup
-#from ServiceScan import ServiceScan
-#from ScartLoopThrough import ScartLoopThrough
-#from HarddiskSetup import HarddiskSelection
-#from ConfigMenu import *
-
-#from About import *
-
-#from Network import *
-
-#from TimerEdit import *
-
-# hack.... dynamically importing all screens
-from __init__ import __all__
-for i in __all__:
-       print "import " + i
-       if (i is not "Menu" ):
-               exec "from " + i + " import *"
+from Tools.Directories import resolveFilename, SCOPE_SKIN
 
 from enigma import quitMainloop
 
 
 from enigma import quitMainloop
 
@@ -32,6 +16,8 @@ import xml.dom.minidom
 from xml.dom import EMPTY_NAMESPACE
 from skin import elementsWithTag
 
 from xml.dom import EMPTY_NAMESPACE
 from skin import elementsWithTag
 
+from Screens.Setup import *
+
 from Tools import XMLTools
 
 # some screens
 from Tools import XMLTools
 
 # some screens
@@ -47,17 +33,11 @@ def doGlobal(screen):
 
 
 # read the menu
 
 
 # read the menu
-try:
-       # first we search in the current path
-       menufile = file('data/menu.xml', 'r')
-except:
-       # if not found in the current path, we use the global datadir-path
-       menufile = file('/usr/share/enigma2/menu.xml', 'r')
+menufile = file(resolveFilename(SCOPE_SKIN, 'menu.xml'), 'r')
 mdom = xml.dom.minidom.parseString(menufile.read())
 menufile.close()
 
 
 mdom = xml.dom.minidom.parseString(menufile.read())
 menufile.close()
 
 
-
 def getValbyAttr(x, attr):
        for p in range(x.attributes.length):
                a = x.attributes.item(p)
 def getValbyAttr(x, attr):
        for p in range(x.attributes.length):
                a = x.attributes.item(p)
@@ -74,35 +54,53 @@ class boundFunction:
                self.args = args
        def __call__(self):
                self.fnc(*self.args)
                self.args = args
        def __call__(self):
                self.fnc(*self.args)
+               
+class MenuUpdater:
+       def __init__(self):
+               self.updatedMenuItems = {}
+       
+       def addMenuItem(self, id, pos, text, module, screen):
+               if not self.updatedMenuAvailable(id):
+                       self.updatedMenuItems[id] = []
+               self.updatedMenuItems[id].append([text, pos, module, screen])
+       
+       def delMenuItem(self, id, pos, text, module, screen):
+               self.updatedMenuItems[id].remove([text, pos, module, screen])
+       
+       def updatedMenuAvailable(self, id):
+               return self.updatedMenuItems.has_key(id)
+       
+       def getUpdatedMenu(self, id):
+               return self.updatedMenuItems[id]
+       
+menuupdater = MenuUpdater()
 
 
-class configOSD(Screen):
-       #this needs focus handling - so not useable
+class MenuSummary(Screen):
+       skin = """
+       <screen position="0,0" size="132,64">
+               <widget name="MenuTitle" position="0,4" size="132,21" font="Regular;18" />
+               <widget name="MenuEntry" position="0,25" size="132,21" font="Regular;16" />
+               <widget name="Clock" position="50,46" size="82,18" font="Regular;16" />
+       </screen>"""
 
 
-       def okbuttonClick(self):
-               self.close
-       def __init__(self, session):
+       def __init__(self, session, parent):
                Screen.__init__(self, session)
                Screen.__init__(self, session)
+               self["MenuTitle"] = Label(parent.menu_title)
+               self["MenuEntry"] = Label("")
+               self["Clock"] = Clock()
+               self.parent = parent
+               self.onShow.append(self.addWatcher)
+               self.onHide.append(self.removeWatcher)
+       
+       def addWatcher(self):
+               self.parent["menu"].onSelectionChanged.append(self.selectionChanged)
+               self.selectionChanged()
+       
+       def removeWatcher(self):
+               self.parent["menu"].onSelectionChanged.remove(self.selectionChanged)
 
 
-               self["actions"] = ActionMap(["OkCancelActions"], 
-                       {
-                               "ok": self.okbuttonClick,
-                               "cancel": self.close
-                       })
-
-               self["okbutton"] = Button("Save")
-
-               self["txt_alpha"] = Label("Alpha:")
-               self["sld_alpha"] = ProgressBar()
-               self["sld_alpha"].setValue(50)
-
-               self["txt_brightness"] = Label("Brightness:")
-               self["sld_brightness"] = ProgressBar()
-               self["sld_brightness"].setValue(50)
-
-               self["txt_gamma"] = Label("Contrast:")
-               self["sld_gamma"] = ProgressBar()
-               self["sld_gamma"].setValue(50)
+       def selectionChanged(self):
+               self["MenuEntry"].setText(self.parent["menu"].getCurrent()[0])
 
 class Menu(Screen):
        def okbuttonClick(self):
 
 class Menu(Screen):
        def okbuttonClick(self):
@@ -110,82 +108,136 @@ class Menu(Screen):
                selection = self["menu"].getCurrent()
                selection[1]()
 
                selection = self["menu"].getCurrent()
                selection[1]()
 
-       def evalText(self, text):
-               eval(text)
-               
+       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 nothing(self):                                                                                                                                      #dummy
                pass
 
-       def openDialog(self, dialog):                           # in every layer needed
-               self.session.open(dialog)
+       def openDialog(self, *dialog):                          # in every layer needed
+               self.session.open(*dialog)
 
        def openSetup(self, dialog):
 
        def openSetup(self, dialog):
-               self.session.open(Setup, dialog)
+               self.session.openWithCallback(self.menuClosed, Setup, dialog)
 
        def addMenu(self, destList, node):
 
        def addMenu(self, destList, node):
-               MenuTitle = getValbyAttr(node, "text")
+               MenuTitle = _(getValbyAttr(node, "text"))
                if MenuTitle != "":                                                                                                                                     #check for title
                if MenuTitle != "":                                                                                                                                     #check for title
-                       a = boundFunction(self.session.open, Menu, node, node.childNodes)
+                       x = getValbyAttr(node, "flushConfigOnClose")
+                       if x == "1":
+                               a = boundFunction(self.session.openWithCallback, self.menuClosedWithConfigFlush, Menu, node, node.childNodes)
+                       else:
+                               a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node, node.childNodes)
                        #TODO add check if !empty(node.childNodes)
                        destList.append((MenuTitle, a))
                        #TODO add check if !empty(node.childNodes)
                        destList.append((MenuTitle, a))
-               
+
+       def menuClosedWithConfigFlush(self, *res):
+               configfile.save()
+               self.menuClosed(*res)
+
+       def menuClosed(self, *res):
+               if len(res) and res[0]:
+                       self.close(True)
+
        def addItem(self, destList, node):
        def addItem(self, destList, node):
-               ItemText = getValbyAttr(node, "text")
+               ItemText = _(getValbyAttr(node, "text"))
                if ItemText != "":                                                                                                                                      #check for name
                if ItemText != "":                                                                                                                                      #check for name
-                       b = XMLTools.mergeText(node.childNodes)
-                       if b != "":                                                                                                                                                             #check for function
-                               destList.append((ItemText,boundFunction(self.evalText,b)))
-                       else:
-                               destList.append((ItemText,self.nothing))                                #use dummy as function
+                       for x in node.childNodes:
+                               if x.nodeType != xml.dom.minidom.Element.nodeType:
+                                       continue
+                               elif x.tagName == 'screen':
+                                       module = getValbyAttr(x, "module")
+                                       screen = getValbyAttr(x, "screen")
+
+                                       if len(screen) == 0:
+                                               screen = module
+
+                                       if module != "":
+                                               module = "Screens." + module
+                                       
+                                       # check for arguments. they will be appended to the 
+                                       # openDialog call
+                                       args = XMLTools.mergeText(x.childNodes)
+                                       screen += ", " + args
+                                       
+                                       destList.append((ItemText, boundFunction(self.runScreen, (module, screen))))
+                                       return
+                               elif x.tagName == 'code':
+                                       destList.append((ItemText, boundFunction(self.execText, XMLTools.mergeText(x.childNodes))))
+                                       return
+                               elif x.tagName == 'setup':
+                                       id = getValbyAttr(x, "id")
+                                       destList.append((ItemText, boundFunction(self.openSetup, id)))
+                                       return
+                       
+                       destList.append((ItemText,self.nothing))
+
 
        def __init__(self, session, parent, childNode):
                Screen.__init__(self, session)
                
                list = []
 
        def __init__(self, session, parent, childNode):
                Screen.__init__(self, session)
                
                list = []
+               menuID = ""
 
 
-               for x in childNode:                                                     #walk through the actual nodelist
+               menuID = -1
+               for x in childNode:                                             #walk through the actual nodelist
                        if x.nodeType != xml.dom.minidom.Element.nodeType:
                            continue
                        elif x.tagName == 'item':
                                self.addItem(list, x)
                        if x.nodeType != xml.dom.minidom.Element.nodeType:
                            continue
                        elif x.tagName == 'item':
                                self.addItem(list, x)
+                               count += 1
                        elif x.tagName == 'menu':
                                self.addMenu(list, x)
                        elif x.tagName == 'menu':
                                self.addMenu(list, x)
+                               count += 1
+                       elif x.tagName == "id":
+                               menuID = getValbyAttr(x, "val")
+                               count = 0
+                       if menuID != -1:
+                               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] + ", "))))
+                                                       count += 1
+
 
                self["menu"] = MenuList(list)   
                                                        
 
                self["menu"] = MenuList(list)   
                                                        
-               self["actions"] = ActionMap(["OkCancelActions"], 
+               self["actions"] = ActionMap(["OkCancelActions", "MenuActions"], 
                        {
                                "ok": self.okbuttonClick,
                        {
                                "ok": self.okbuttonClick,
-                               "cancel": self.close
+                               "cancel": self.closeNonRecursive,
+                               "menu": self.closeRecursive
                        })
                
                a = getValbyAttr(parent, "title")
                if a == "":                                                                                                             #if empty use name
                        })
                
                a = getValbyAttr(parent, "title")
                if a == "":                                                                                                             #if empty use name
-                       a = getValbyAttr(parent, "text")
+                       a = _(getValbyAttr(parent, "text"))
                self["title"] = Header(a)
                self["title"] = Header(a)
+               self.menu_title = a
 
 
-class FixedMenu(Screen):
-       def okbuttonClick(self):
-               selection = self["menu"].getCurrent()
-               selection[1]()
+       def closeNonRecursive(self):
+               self.close(False)
 
 
-       def __init__(self, session, title, list):
-               Screen.__init__(self, session)
-               
-               self["menu"] = MenuList(list)   
-                                                       
-               self["actions"] = ActionMap(["OkCancelActions"], 
-                       {
-                               "ok": self.okbuttonClick,
-                               "cancel": self.close
-                       })
-               
-               self["title"] = Header(title)
+       def closeRecursive(self):
+               self.close(True)
 
 
+       def createSummary(self):
+               return MenuSummary
 
 class MainMenu(Menu):
        #add file load functions for the xml-file
 
 class MainMenu(Menu):
        #add file load functions for the xml-file
-       #remove old code (i.e. goScan / goClock...)
        
        def __init__(self, *x):
                Menu.__init__(self, *x)
        
        def __init__(self, *x):
                Menu.__init__(self, *x)
@@ -197,9 +249,6 @@ class MainMenu(Menu):
        def openSetup(self, dialog):
                self.session.open(Setup, dialog)
 
        def openSetup(self, dialog):
                self.session.open(Setup, dialog)
 
-       def goSetup(self):
-               self.session.open(configTest)
-       
        def setModeTV(self):
                print "set Mode to TV"
                pass
        def setModeTV(self):
                print "set Mode to TV"
                pass
@@ -211,9 +260,3 @@ class MainMenu(Menu):
        def setModeFile(self):
                print "set Mode to File"
                pass
        def setModeFile(self):
                print "set Mode to File"
                pass
-
-       def goScan(self):
-               self.session.open(ServiceScan)
-       
-       def goClock(self):
-               self.session.open(clockDisplay, Clock())