better (and more correct) fix
[enigma2.git] / lib / python / Screens / Screen.py
1 from Components.HTMLSkin import *
2 from Components.GUISkin import *
3 from Components.Sources.Source import Source
4
5 import sys
6
7 class Screen(dict, HTMLSkin, GUISkin):
8
9         ALLOW_SUSPEND = False
10
11         def __init__(self, session):
12                 self.skinName = self.__class__.__name__
13                 self.session = session
14                 GUISkin.__init__(self)
15
16                 self.onClose = [ ]
17                 self.onFirstExecBegin = [ ]
18                 self.onExecBegin = [ ]
19                 self.onShown = [ ]
20
21                 self.onShow = [ ]
22                 self.onHide = [ ]
23
24                 self.execing = False
25                 
26                 self.shown = True
27                 # already shown is false until the screen is really shown (after creation)
28                 self.already_shown = False
29
30                 self.renderer = [ ]
31
32                 # in order to support screens *without* a help,
33                 # we need the list in every screen. how ironic.
34                 self.helpList = [ ]
35
36                 self.close_on_next_exec = None
37
38                 # stand alone screens (for example web screens)
39                 # don't care about having or not having focus.
40                 self.stand_alone = False
41
42         def execBegin(self):
43                 self.active_components = [ ]
44                 if self.close_on_next_exec is not None:
45                         tmp = self.close_on_next_exec
46                         self.close_on_next_exec = None
47                         self.execing = True
48                         self.close(tmp)
49                 else:
50                         single = self.onFirstExecBegin
51                         self.onFirstExecBegin = []
52                         for x in self.onExecBegin + single:
53                                 x()
54                                 if not self.stand_alone and self.session.current_dialog != self:
55                                         return
56
57 #                       assert self.session == None, "a screen can only exec once per time"
58 #                       self.session = session
59
60                         for val in self.values() + self.renderer:
61                                 val.execBegin()
62                                 if not self.stand_alone and self.session.current_dialog != self:
63                                         return
64                                 self.active_components.append(val)
65
66                         self.execing = True
67         
68                         for x in self.onShown:
69                                 x()
70         
71         def execEnd(self):
72 #               for (name, val) in self.items():
73                 for val in self.active_components:
74                         val.execEnd()
75                 del self.active_components
76 #               assert self.session != None, "execEnd on non-execing screen!"
77 #               self.session = None
78                 self.execing = False
79         
80         # never call this directly - it will be called from the session!
81         def doClose(self):
82                 self.hide()
83                 for x in self.onClose:
84                         x()
85                 
86                 # fixup circular references
87                 del self.helpList
88                 GUISkin.close(self)
89
90                 # first disconnect all render from their sources.
91                 # we might split this out into a "unskin"-call,
92                 # but currently we destroy the screen afterwards
93                 # anyway.
94                 for val in self.renderer:
95                         val.disconnectAll()  # disconnected converter/sources and probably destroy them
96                 
97                 del self.session
98                 for (name, val) in self.items():
99                         val.destroy()
100                         del self[name]
101                 
102                 for val in self.renderer:
103                         val.destroy()
104                 
105                 self.renderer = [ ]
106                 
107                 # really delete all elements now
108                 self.__dict__.clear()
109         
110         def close(self, *retval):
111                 if not self.execing:
112                         self.close_on_next_exec = retval
113                 else:
114                         self.session.close(self, *retval)
115
116         def setFocus(self, o):
117                 self.instance.setFocus(o.instance)
118
119         def show(self):
120                 if (self.shown and self.already_shown) or not self.instance:
121                         return
122                 self.shown = True
123                 self.already_shown = True
124                 self.instance.show()
125                 for x in self.onShow:
126                         x()
127                 for val in self.values() + self.renderer:
128                         if isinstance(val, GUIComponent) or isinstance(val, Source):
129                                 val.onShow()
130
131         def hide(self):
132                 if not self.shown or not self.instance:
133                         return
134                 self.shown = False
135                 self.instance.hide()
136                 for x in self.onHide:
137                         x()
138                 for val in self.values() + self.renderer:
139                         if isinstance(val, GUIComponent) or isinstance(val, Source):
140                                 val.onHide()
141
142         def __repr__(self):
143                 return str(type(self))