some TimerEntry-fixes
[enigma2.git] / lib / python / Screens / ChannelSelection.py
1 from Screen import Screen
2 from Components.Button import Button
3 from Components.ServiceList import ServiceList
4 from Components.ActionMap import ActionMap
5 from EpgSelection import EPGSelection
6 from enigma import eServiceReference, eEPGCache, eEPGCachePtr, eServiceCenter, eServiceCenterPtr, iMutableServiceListPtr, iStaticServiceInformationPtr, eTimer
7 from Components.config import config, configElement, ConfigSubsection, configText
8
9 from Screens.FixedMenu import FixedMenu
10
11 import xml.dom.minidom
12
13 class BouquetSelector(FixedMenu):
14         def __init__(self, session, bouquets, parent):
15                 self.parent=parent
16                 entrys = [ ]
17                 for x in bouquets:
18                         entrys.append((x[0], self.bouquetSelected, x[1]))
19                 FixedMenu.__init__(self, session, "Bouquetlist", entrys)
20                 self.skinName = "Menu"
21
22         def bouquetSelected(self):
23                 self.parent.addCurrentServiceToBouquet(self["menu"].getCurrent()[2])
24                 self.close()
25
26 class ChannelContextMenu(FixedMenu):
27         def __init__(self, session, csel):
28                 self.csel = csel
29
30                 menu = [ ]
31
32                 #HACK
33                 inBouquetRootList = csel["list"].getRoot().toString().find('FROM BOUQUET "bouquets.') != -1
34                 inBouquet = csel.getMutableList() is not None
35
36                 if not csel.bouquet_mark_edit and not csel.movemode and not inBouquetRootList:
37                         menu.append(("add service to bouquet", self.addServiceToBouquetSelected))
38                         if inBouquet:
39                                 menu.append(("remove service", self.removeCurrentService))
40
41                 if inBouquet: # current list is editable?
42                         if not csel.bouquet_mark_edit:
43                                 if not csel.movemode:
44                                         menu.append(("enable move mode", self.toggleMoveMode))
45                                         if not inBouquetRootList: 
46                                                 menu.append(("enable bouquet edit", self.bouquetMarkStart))
47                                 else:
48                                         menu.append(("disable move mode", self.toggleMoveMode))
49                         elif not inBouquetRootList: 
50                                 menu.append(("end bouquet edit", self.bouquetMarkEnd))
51                                 menu.append(("abort bouquet edit", self.bouquetMarkAbort))
52
53                 menu.append(("back", self.close))
54
55                 FixedMenu.__init__(self, session, "Channel Selection", menu)
56                 self.skinName = "Menu"
57
58         def addServiceToBouquetSelected(self):
59                 bouquets = [ ]
60                 serviceHandler = eServiceCenter.getInstance()
61                 list = serviceHandler.list(self.csel.bouquet_root)
62                 if not list is None:
63                         while 1:
64                                 s = list.getNext()
65                                 if not s.valid():
66                                         break
67                                 if ((s.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
68                                         info = serviceHandler.info(s)
69                                         if not info is None:
70                                                 str = info.getName(s)
71                                                 bouquets.append((str, s))
72                 cnt = len(bouquets)
73                 if cnt > 1: # show bouquet list
74                         self.session.open(BouquetSelector, bouquets, self)
75                 elif cnt == 1: # add to only one existing bouquet
76                         self.addCurrentServiceToBouquet(bouquet[0][1])
77                 else: #no bouquets in root.. so assume only one favourite list is used
78                         self.addCurrentServiceToBouquet(self.csel.bouquet_root)
79
80         def addCurrentServiceToBouquet(self, dest):
81                 self.csel.addCurrentServiceToBouquet(dest)
82                 self.close()
83
84         def removeCurrentService(self):
85                 self.csel.removeCurrentService()
86                 self.close()
87
88         def toggleMoveMode(self):
89                 self.csel.toggleMoveMode()
90                 self.close()
91
92         def bouquetMarkStart(self):
93                 self.csel.startMarkedEdit()
94                 self.close()
95
96         def bouquetMarkEnd(self):
97                 self.csel.endMarkedEdit(abort=False)
98                 self.close()
99
100         def bouquetMarkAbort(self):
101                 self.csel.endMarkedEdit(abort=True)
102                 self.close()
103  
104 class ChannelSelection(Screen):
105         def lastService(self):
106                 self.lastServiceTimer.stop()
107                 #zap to last running tv service
108                 self.setRoot(eServiceReference(config.tv.lastroot.value))
109                 self.session.nav.playService(eServiceReference(config.tv.lastservice.value))
110         
111         def __init__(self, session):
112                 Screen.__init__(self, session)
113
114                 #config for lastservice
115                 config.tv = ConfigSubsection();
116                 config.tv.lastservice = configElement("config.tv.lastservice", configText, "", 0);
117                 config.tv.lastroot = configElement("config.tv.lastroot", configText, "", 0);
118
119                 self.entry_marked = False
120                 self.movemode = False
121                 self.bouquet_mark_edit = False
122                 self.bouquet_root = eServiceReference('1:7:1:0:0:0:0:0:0:0:(type == 1) FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet')
123                 self.mutableList = None
124
125                 self.__marked = [ ]
126
127                 self["key_red"] = Button("All")
128                 self["key_green"] = Button("Provider")
129                 self["key_yellow"] = Button("Satellite")
130                 self["key_blue"] = Button("Favourites")
131                 
132                 self["list"] = ServiceList()
133
134                 if config.tv.lastroot.value == "":
135                         self["list"].setRoot(eServiceReference("""1:0:1:0:0:0:0:0:0:0:(type == 1)"""))
136                 #self["okbutton"] = Button("ok", [self.channelSelected])
137
138                 self.lastServiceTimer = eTimer()
139                 self.lastServiceTimer.timeout.get().append(self.lastService)
140                 self.lastServiceTimer.start(100)
141
142                 class ChannelActionMap(ActionMap):
143                         def action(self, contexts, action):
144                                 if action[:7] == "bouquet":
145                                         l = self.csel
146                                         list = l["list"]
147                                         if action.find("FROM BOUQUET") != -1:
148                                                 l.setRoot(eServiceReference("1:7:1:0:0:0:0:0:0:0:" + action[8:]))
149                                         else:
150                                                 l.setRoot(eServiceReference("1:0:1:0:0:0:0:0:0:0:" + action[8:]))
151                                 else:
152                                         if action == "cancel":
153                                                 l = self.csel
154                                                 if l.movemode: #movemode active?
155                                                         l.channelSelected() # unmark
156                                                         l.toggleMoveMode() # disable move mode
157                                                 elif l.bouquet_mark_edit:
158                                                         l.endMarkedEdit(True) # abort edit mode
159                                         ActionMap.action(self, contexts, action)
160
161                 self["actions"] = ChannelActionMap(["ChannelSelectActions", "OkCancelActions", "ContextMenuActions"], 
162                         {
163                                 "cancel": self.close,
164                                 "ok": self.channelSelected,
165                                 "mark": self.doMark,
166                                 "contextMenu": self.doContext,
167                                 "showFavourites": self.showFavourites,
168                     "showEPGList": self.showEPGList
169                         })
170                 self["actions"].csel = self
171
172         def showEPGList(self):
173                 ref=self["list"].getCurrent()
174                 ptr=eEPGCache.getInstance()
175                 if ptr.startTimeQuery(ref) != -1:
176                         self.session.open(EPGSelection, ref)
177                 else:
178                         print 'no epg for service', ref.toString()
179
180         def getMutableList(self, root=eServiceReference()):
181                 if not self.mutableList is None:
182                         return self.mutableList
183                 serviceHandler = eServiceCenter.getInstance()
184                 if not root.valid():
185                         root=self["list"].getRoot()
186                 list = serviceHandler.list(root)
187                 mutableList = None
188                 if list is not None:
189                         mutableList = list.startEdit()
190                 return mutableList
191
192 #  multiple marked entry stuff ( edit mode, later multiepg selection )
193         def startMarkedEdit(self):
194                 self.mutableList = self.getMutableList()
195                 l = self["list"]
196                 # add all services from the current list to internal marked set in listboxservicecontent
197                 self.bouquetRoot = l.getRoot()
198                 self.clearMarks() # this clears the internal marked set in the listboxservicecontent
199                 self.bouquet_mark_edit = True
200                 self.__marked = l.getRootServices()
201                 for x in self.__marked:
202                         l.addMarked(eServiceReference(x))
203
204         def endMarkedEdit(self, abort):
205                 l = self["list"]
206                 if not abort and self.mutableList is not None:
207                         new_marked = set(l.getMarked())
208                         old_marked = set(self.__marked)
209                         removed = old_marked - new_marked
210                         added = new_marked - old_marked
211                         changed = False
212                         for x in removed:
213                                 changed = True
214                                 self.mutableList.removeService(eServiceReference(x))
215                         for x in added:
216                                 changed = True
217                                 self.mutableList.addService(eServiceReference(x))
218                         if changed:
219                                 self.mutableList.flushChanges()
220                                 self.setRoot(self.bouquetRoot)
221                                 #self.showFavourites()
222                 self.__marked = []
223                 self.clearMarks()
224                 self.bouquet_mark_edit = False
225                 self.bouquetRoot = None
226                 self.mutableList = None
227
228         def clearMarks(self):
229                 self["list"].clearMarks()
230
231         def doMark(self):
232                 ref = self["list"].getCurrent()
233                 if self["list"].isMarked(ref):
234                         self["list"].removeMarked(ref)
235                 else:
236                         self["list"].addMarked(ref)
237
238         def removeCurrentService(self):
239                 l = self["list"]
240                 ref = l.getCurrent()
241                 mutableList = self.getMutableList()
242                 if ref.valid() and mutableList is not None:
243                         if mutableList.removeService(ref) == 0:
244                                 mutableList.flushChanges() #FIXME dont flush on each single removed service
245                                 self.setRoot(l.getRoot())
246
247         def addCurrentServiceToBouquet(self, dest):
248                 mutableList = self.getMutableList(dest)
249                 if not mutableList is None:
250                         if mutableList.addService(self["list"].getCurrent()) == 0:
251                                 mutableList.flushChanges()
252                 self.close()
253
254         def setRoot(self, root):
255                 if not self.movemode: # dont change root when movemode is enabled
256                         list = self["list"]
257
258                         #HACK
259                         inBouquetRootList = root.toString().find('FROM BOUQUET "bouquets.') != -1
260
261                         if not inBouquetRootList and ((root.flags & eServiceReference.flagDirectory) == eServiceReference.flagDirectory):
262                                 list.setMode(list.MODE_FAVOURITES)
263                         else:
264                                 list.setMode(list.MODE_NORMAL)
265                         list.setRoot(root)
266
267         def channelSelected(self):
268                 ref = self["list"].getCurrent()
269                 if self.movemode:
270                         if self.entry_marked:
271                                 self["list"].setCurrentMarked(False)
272                                 self.entry_marked = False
273                         else:
274                                 self["list"].setCurrentMarked(True)
275                                 self.entry_marked = True
276                 elif (ref.flags & 7) == 7:
277                         self.setRoot(ref)
278                 elif self.bouquet_mark_edit:
279                         self.doMark()
280                 else:
281                         self.session.nav.playService(ref)
282                         self.saveChannel()
283                         self.close()
284
285         #called from infoBar
286         def zap(self):
287                 self.session.nav.playService(self["list"].getCurrent())
288                 self.saveChannel()
289
290         def moveUp(self):
291                 self["list"].moveUp()
292
293         def moveDown(self):
294                 self["list"].moveDown()
295
296         def doContext(self):
297                 self.session.open(ChannelContextMenu, self)
298
299         def toggleMoveMode(self):
300                 if self.movemode:
301                         if self.entry_marked:
302                                 self.channelSelected() # unmark current entry
303                         self.movemode = False
304                         self.mutableList.flushChanges() # FIXME add check if changes was made
305                         self.mutableList = None
306                 else:
307                         self.mutableList = self.getMutableList()
308                         self.movemode = True
309
310         def showFavourites(self):
311                 self.setRoot(self.bouquet_root)
312
313         def saveRoot(self, root):
314                 if root is not None:
315                         config.tv.lastroot.value = root.toString()
316                         config.tv.lastroot.save()
317
318         def saveChannel(self):
319                 ref = self.session.nav.getCurrentlyPlayingServiceReference()
320                 if ref is not None:
321                         refstr = ref.toString()
322                 else:
323                         refstr = ""
324                 config.tv.lastservice.value = refstr
325                 config.tv.lastservice.save()