IBTS 0.6
[enigma2-plugins.git] / infobartunerstate / src / plugin.py
1 #######################################################################
2 #
3 #    InfoBar Tuner State for Enigma-2
4 #    Vesion 0.6
5 #    Coded by betonme (c)2011
6 #    Support: IHAD
7 #
8 #    This program is free software; you can redistribute it and/or
9 #    modify it under the terms of the GNU General Public License
10 #    as published by the Free Software Foundation; either version 2
11 #    of the License, or (at your option) any later version.
12 #
13 #    This program is distributed in the hope that it will be useful,
14 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 #    GNU General Public License for more details.
17 #
18 #######################################################################
19
20 import math
21 import os
22 import NavigationInstance
23
24 from collections import defaultdict
25 from operator import attrgetter, itemgetter
26
27 from Components.ActionMap import ActionMap
28 from Components.Button import Button
29 from Components.config import *
30 from Components.ConfigList import ConfigListScreen
31 from Components.Label import Label
32 from Components.Language import *
33 from Components.Pixmap import Pixmap
34 from Components.ServiceEventTracker import ServiceEventTracker
35 from Components.Sources.StaticText import StaticText
36
37 from Screens.InfoBar import InfoBar
38 from Screens.InfoBarGenerics import InfoBarShowHide
39 from Screens.Screen import Screen
40 from Plugins.Plugin import PluginDescriptor
41 from time import time
42
43 from enigma import iServiceInformation, ePoint, eSize, getDesktop, iFrontendInformation
44
45 from enigma import eTimer
46
47 from enigma import iPlayableService, iRecordableService
48
49 from enigma import eDVBResourceManager, eActionMap, eListboxPythonMultiContent, eListboxPythonStringContent, eListbox, gFont, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER, eEPGCache, eServiceCenter, eServiceReference
50
51 # GUI (Summary)
52 from Screens.Setup import SetupSummary
53
54 from skin import parseColor, parseFont
55
56 #try:
57 #       # try to import EMC module to check for its existence
58 #       from Plugins.Extensions.EnhancedMovieCenter.EnhancedMovieCenter import EMCMediaCenter 
59 #except ImportError, ie:
60 #       class EMCMediaCenter: pass
61
62 Version = "V0.6.0"
63 #TODO About
64
65
66 # Globals
67 gInfoBarTunerState = None
68 InfoBarShowHideSHOW = None
69 InfoBarShowHideHIDE = None
70
71
72 config.infobartunerstate                           = ConfigSubsection()
73
74 config.infobartunerstate.about                     = ConfigSelection(default = "1", choices = [("1", " ")])
75 config.infobartunerstate.enabled                   = ConfigEnableDisable(default = True)                                        #TODO needs a restart
76
77 config.infobartunerstate.show_infobar              = ConfigYesNo(default = True)
78 config.infobartunerstate.show_events               = ConfigYesNo(default = True)                #TODO Show on start, end, start/end
79 config.infobartunerstate.show_overwrite            = ConfigYesNo(default = False)
80
81 config.infobartunerstate.number_finished_records   = ConfigSelectionNumber(0, 10, 1, default = 5)
82 config.infobartunerstate.timeout_finished_records  = ConfigSelectionNumber(0, 600, 10, default = 60)
83
84
85 def Plugins(**kwargs):
86         
87         #TODO localeInit()
88         
89         descriptors = []
90         
91         if config.infobartunerstate.enabled.value:
92                 # AutoStart and SessionStart
93                 descriptors.append( PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, fnc = start) )
94                 descriptors.append( PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, fnc = start) )
95         
96         #TODO Extension List show InfoBarTunerState ?
97         
98         #TODO icon
99         descriptors.append( PluginDescriptor(name = "InfoBar Tuner State", description = "InfoBar Tuner State " +_("configuration"), where = PluginDescriptor.WHERE_PLUGINMENU, fnc = setup) ) #icon = "/EnhancedMovieCenter.png"
100
101         return descriptors
102
103
104 def setup(session, **kwargs):
105         #TODO config
106         # Overwrite Skin Position
107         # Show Live TV Tuners PiP Stream ...
108         # Background: Transparent, Block, Dynamic(Farbverlauf)
109         # Width: FullRow, Adapted/Fitting, Symmetrical
110         # Icon or Text for type
111         # Order of elements
112         # Allow Enable disable of elements 
113         # Sort order of entry rows
114         #               Type: Live pip stream record endedrecords
115         #               Tuner A B C D
116         #               Number
117         #               Channel
118         #               Name
119         #               Remaining >0 infinite -
120         #Rec A 2 RTL blabla 10min to /media/hdd/serien 
121         #Rec A 2 RTL /media/hdd/serien/blabla 10min
122         #alltime permanent display
123         #free space of destination path only records
124         # destination ip only streams
125         try:
126                 session.open(InfoBarTunerStateMenu)
127         except Exception, e:
128                 print "InfoBarTunerStateMenu exception " + str(e)
129                 import sys, traceback
130                 traceback.print_stack(None, file=sys.stdout)
131
132
133 class InfoBarTunerStateMenu(Screen, ConfigListScreen):
134         def __init__(self, session):
135                 Screen.__init__(self, session)
136                 self.skinName = [ "InfoBarTunerStateMenu", "Setup" ]
137                 
138                 # Summary
139                 self.setup_title = _("InfoBarTunerStateMenu Configuration ") + Version
140                 self.onChangedEntry = []
141                 
142                 # Buttons
143                 self["key_red"] = StaticText(_("Cancel"))
144                 self["key_green"] = StaticText(_("OK"))
145                 
146                 # Define Actions
147                 self["custom_actions"] = ActionMap(["SetupActions", "ChannelSelectBaseActions"],
148                 {
149                         "cancel": self.keyCancel,
150                         "save": self.keySave,
151                         "nextBouquet": self.pageUp,
152                         "prevBouquet": self.pageDown,
153                 }, -2) # higher priority
154                 
155                 # Initialize Configuration part
156                 self.list = []
157                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
158                 
159                 self.config = []
160                 self.defineConfig()
161                 self.createConfig()
162                 
163                 # Trigger change
164                 self.changed()
165
166                 self.onLayoutFinish.append(self.layoutFinished)
167
168         def defineConfig(self):
169                 
170                 separator = "".ljust(250,"-")
171                 seperatorE2Usage = "- E2 "+_("Usage")+" "
172                 seperatorE2Usage = seperatorE2Usage.ljust(250-len(seperatorE2Usage),"-")
173                 
174 #         _config list entry
175 #         _                                                     , config element
176                 self.config = [ 
177                         #(  _("About")                                             , config.infobartunerstate.about ),
178                         
179                         (  _("Enable InfoBarTunerState")                          , config.infobartunerstate.enabled ),
180                         (  separator                                              , config.infobartunerstate.about ),
181                         
182                         (  _("Show and hide with InfoBar")                        , config.infobartunerstate.show_infobar ),
183                         (  _("Show on Events")                                    , config.infobartunerstate.show_events ),
184                         (  _("MoviePlayer integration")                           , config.infobartunerstate.show_overwrite ),
185                         
186                         (  _("Number of finished records in list")                , config.infobartunerstate.number_finished_records ),
187                         (  _("Number of seconds for displaying finished records") , config.infobartunerstate.timeout_finished_records ),
188                         
189                         (  seperatorE2Usage                                       , config.infobartunerstate.about ),
190                         (  _("Infobar timeout")                                   , config.usage.infobar_timeout ),
191                         (  _("Show Message when Recording starts")                , config.usage.show_message_when_recording_starts ),
192                 ]
193
194         def createConfig(self):
195                 list = []
196                 for conf in self.config:
197                         # 0 entry text
198                         # 1 variable
199                         # 2 validation
200                         list.append( getConfigListEntry( conf[0], conf[1]) )
201                 self.list = list
202                 self["config"].setList(self.list)
203
204         def layoutFinished(self):
205                 self.setTitle(self.setup_title)
206
207         def changed(self):
208                 for x in self.onChangedEntry:
209                         x()
210                 #self.createConfig()
211
212         def close(self):
213                 # Overwrite Screen close function
214                 # Handle new config
215                 #TODO enable disable plugin
216                 #TODO append onClose  remove events undooverwrite
217                 if config.infobartunerstate.show_overwrite.value:
218                         overwriteInfoBar()
219                 else:
220                         undoOverwriteInfoBar()
221                 
222                 # Call baseclass function
223                 Screen.close(self)
224
225         def getCurrentEntry(self):
226                 return self["config"].getCurrent()[0]
227
228         def getCurrentValue(self):
229                 return str(self["config"].getCurrent()[1].getText())
230
231         def createSummary(self):
232                 return SetupSummary
233
234         def pageUp(self):
235                 self["config"].instance.moveSelection(self["config"].instance.pageUp)
236
237         def pageDown(self):
238                 self["config"].instance.moveSelection(self["config"].instance.pageDown)
239
240
241 def start(reason, **kwargs):
242         #print "InfoBarTunerState autostart "
243         #print str(reason)
244         #print str(kwargs)
245         if reason == 0: # start
246                 if kwargs.has_key("session"):
247                         global gInfoBarTunerState
248                         session = kwargs["session"]
249                         gInfoBarTunerState = InfoBarTunerState(session)
250
251
252 # InfoBarShowHide for MoviePlayer integration
253 def overwriteInfoBar():
254         global InfoBarShowHideSHOW, InfoBarShowHideHIDE
255         if InfoBarShowHideSHOW is None:
256                 # Backup original function
257                 #InfoBarShowHideSHOW = InfoBarShowHide.startHideTimer   # show not working
258                 InfoBarShowHideSHOW = InfoBarShowHide._InfoBarShowHide__onShow
259                 # Overwrite function
260                 #InfoBarShowHide.startHideTimer = InfoBarShowHideShow
261                 InfoBarShowHide._InfoBarShowHide__onShow = InfoBarShowHideShow
262         if InfoBarShowHideHIDE is None:
263                 # Backup original function
264                 #InfoBarShowHideHIDE = InfoBarShowHide.doTimerHide   #hide not working
265                 InfoBarShowHideHIDE = InfoBarShowHide._InfoBarShowHide__onHide
266                 # Overwrite function
267                 #InfoBarShowHide.doTimerHide = InfoBarShowHideHide
268                 InfoBarShowHide._InfoBarShowHide__onHide = InfoBarShowHideHide
269
270 def undoOverwriteInfoBar():
271         global InfoBarShowHideSHOW, InfoBarShowHideHIDE
272         if InfoBarShowHideSHOW:
273                 InfoBarShowHide._InfoBarShowHide__onShow = InfoBarShowHideSHOW
274                 InfoBarShowHideSHOW = None
275         if InfoBarShowHideHIDE:
276                 InfoBarShowHide._InfoBarShowHide__onHide = InfoBarShowHideHIDE
277                 InfoBarShowHideHIDE = None
278
279 def InfoBarShowHideShow(self):
280         global gInfoBarTunerState, InfoBarShowHideSHOW
281         if InfoBarShowHideSHOW:
282                 InfoBarShowHideSHOW(self)
283         print "InfoBarShowHideShow"
284         if gInfoBarTunerState:
285                 gInfoBarTunerState.tunerShow()
286
287 def InfoBarShowHideHide(self):
288         global gInfoBarTunerState, InfoBarShowHideHIDE
289         if InfoBarShowHideHIDE:
290                 InfoBarShowHideHIDE(self)
291         print "InfoBarShowHideHide"
292         if gInfoBarTunerState:
293                 gInfoBarTunerState.tunerHide()
294
295
296 # Type Enum
297 RecordStarted, RecordFinished, Streaming = range(3)
298
299
300 class InfoBarTunerState(Screen):
301         def __init__(self, session):
302                 Screen.__init__(self, session)
303                 
304                 self.hideTimer = eTimer()
305                 self.hideTimer.callback.append(self.tunerHide)
306                 
307                 #self.availTimer = eTimer()
308                 #self.availTimer.callback.append(self.tunerShow)
309                 
310                 self.forceBindInfoBarTimer = eTimer()
311                 self.forceBindInfoBarTimer.callback.append(self.bindInfoBar)
312                 
313                 self.tunerInfo = defaultdict(list)
314                 
315                 self.posy = getDesktop(0).size().height()
316                 
317                 # Recording Events
318                 # If we append our function, we will never see the timer state StateEnded for repeating timer
319                 self.session.nav.RecordTimer.on_state_change.insert(0, self.__onRecordingEvent)
320                 # Streaming Events
321                 self.session.nav.record_event.append(self.__onStreamingEvent)
322                 # Zapping Events
323                 #self.session.nav.event.append(self.__onPlayableEvent)
324                 #self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
325                 #       {
326                 #               iPlayableService.evStart: self.__onPlayableEvent,
327                 #               #iPlayableService.evEnd: self.bindInfoBar,
328                 #       })
329                 
330                 #res_mgr = eDVBResourceManager.getInstance()
331                 #if res_mgr:
332                 #       res_mgr.frontendUseMaskChanged.get().append(self.__onTunerUseMaskChanged)
333                 
334                 # Add current running records 
335                 self.updateRecordTimer()
336                 
337                 #self.onLayoutFinish.append(self.bindInfoBar)
338                 
339                 # Bind InfoBarEvents
340                 #self.bindInfoBar()
341                 # Workaround
342                 # The Plugin starts before the InfoBar is instantiated
343                 # Check every second if the InfoBar instance exists and try to bind our functions
344                 # Is there an alternative solution?
345                 self.forceBindInfoBarTimer.start(1000, False)
346                 
347                 if config.infobartunerstate.show_overwrite.value:
348                         overwriteInfoBar()
349                 
350                 #TODO PiP
351                 #self.session.
352                 #InfoBar.instance.session
353                 #pip.currentService = service
354                 #pip.pipservice = iPlayableService
355                 #Events:
356                 #eventNewProgramInfo
357                 #decoder state
358                 
359         #def test(self, event):
360         #       print "InfoBarTuner test " + str(event)
361         
362         def bindInfoBar(self):
363                 # Reimport InfoBar to force update of the class instance variable
364                 # Rebind only if it isn't done already 
365                 from Screens.InfoBar import InfoBar
366                 print "InfoBarTunerState InfoBar.instance " + str(InfoBar.instance)
367                 if InfoBar.instance:
368                         bindShow = False
369                         bindHide = False
370                         if hasattr(InfoBar.instance, "onShow"):
371                                 if self.__onInfoBarEventShow not in InfoBar.instance.onShow:
372                                         InfoBar.instance.onShow.append(self.__onInfoBarEventShow)
373                                 bindShow = True
374                         if hasattr(InfoBar.instance, "onHide"):
375                                 if self.__onInfoBarEventHide not in InfoBar.instance.onHide:
376                                         InfoBar.instance.onHide.append(self.__onInfoBarEventHide)
377                                 bindHide = True
378                         if bindShow and bindHide:
379                                 # Bind was successful
380                                 self.forceBindInfoBarTimer.stop()
381
382         def __onTunerUseMaskChanged(self, mask):
383                 print "__onTunerUseMaskChanged    " +str(mask)
384
385         def __onInfoBarEventShow(self):
386                 if config.infobartunerstate.show_infobar.value:
387                         #TODO check recordings streams ...
388                         if self.hideTimer.isActive():
389                                 self.hideTimer.stop()
390                         self.tunerShow()
391
392         def __onInfoBarEventHide(self):
393                 if config.infobartunerstate.show_infobar.value:
394                         #TODO check recordings streams ...
395                         self.tunerHide()
396
397         def __onRecordingEvent(self, timer):
398                 if timer.state == timer.StatePrepared:
399                         print "__onRecordingEventPrep    " +str(timer)
400                 elif timer.state == timer.StateRunning: # timer.isRunning()
401                         if not timer.justplay:
402                                 type = RecordStarted
403                                 
404                                 #TEST find unique record identifier
405                                 print "__onRecordingEventRun    " +str(timer)
406                                 print "__onRecordingEventRun    " +str(timer.eit)
407                                 print "__onRecordingEventRun    " +str(timer.service_ref)
408                                 print "__onRecordingEventRun    " +str(timer.service_ref.ref)
409                                 channel = timer.service_ref.getServiceName()
410                                 tuner = getTuner(timer.record_service)
411                                 name = timer.name               # No EPG data available: name = instant record
412                                 end = timer.end
413                                 
414                                 #TEST Bug Repeating timer blocking tuner and are not marked as finished
415                                 #timer.timeChanged = self.__OnTimeChanged
416                                 
417                                 id = str(timer)
418                                 if not id in self.tunerInfo:
419                                         win = self.session.instantiateDialog(TunerState, type, tuner, channel, name, end)
420                                         self.tunerInfo[id] = win
421                                         self.showWithTimer()
422                         
423                 #elif timer.state == timer.StateEnded:
424                 else:
425                         type = RecordFinished
426                         print "__onRecordingEventEnd    " +str(timer.state)
427                         
428                         id = str(timer)
429                         if id in self.tunerInfo:
430                                 #TODO config 
431                                 #if config.delete_immediately 
432 #                               print "__onRecordingEvent removed "
433                                 win = self.tunerInfo[id]
434 #                               win.hide()
435 #                               self.session.deleteDialog(win)
436 #                               del self.tunerInfo[id]
437 #                               #TODO config
438                                 win.changeType(type)
439                                 #TODO config
440                                 self.showWithTimer()
441
442         def __onStreamingEvent(self, rec_service, event):
443                 print "__onStreamingEvent2    " +str(event)
444                 print "__onStreamingEvent2    " +str(rec_service)
445                 if event == iRecordableService.evStart:
446                         try:
447                                 from Plugins.Extensions.WebInterface.WebScreens import streamingScreens
448                                 from Plugins.Extensions.WebInterface.WebComponents.Sources.RequestData import RequestData
449                         except:
450                                 streamingScreens = []
451                         for stream in streamingScreens :
452                                 print stream.getRecordService()  # iRecordableService
453                                 print stream.getRecordServiceRef()  # eServiceReference
454 #                               if hasattr( stream, 'request' ):
455 #                                       print stream.request
456 #                                       #print "request TODO dir info " + str(dir(stream.request))
457 #                                       #print "request TODO vars info " + str(vars(stream.request))
458 #                                       #print stream.request.getRequestHostname()
459 #                                       print stream.request.host
460 #                                       #print str(stream.request.host.port)
461 #                                       print stream.request.method
462 #                                       print stream.request.path
463 #                                       print stream.request.uri
464 #                                       print stream.request.client
465 #                                       print stream.request.requestHeaders
466 #                                       print stream.request.site
467 #                                       print stream.request.content
468 #                               if stream.has_key( 'StreamService' ):
469 #                                       print stream["StreamService"]
470                                 #ServiceReference(stream.getRecordServiceRef())
471                 
472                 elif event == iRecordableService.evEnd:
473                         try:
474                                 from Plugins.Extensions.WebInterface.WebScreens import streamingScreens 
475                         except:
476                                 streamingScreens = []
477                         for stream in streamingScreens:
478                                 #Delete first second any difference !?
479                                 print stream.getRecordService()  # iRecordableService
480                                 print stream.getRecordServiceRef()  # eServiceReference
481
482         def __onPlayableEvent(self, event):
483                 #TEST PiP
484                 print "__onPlayableEvent    " + str(event)
485                 #TODO Filter events
486                 #self.showWithTimer()
487                 # Rebind InfoBar Events
488                 #self.bindInfoBar()
489                 
490         def __OnTimeChanged(self):
491                 #TODO Config show on timer time changed
492                 self.showWithTimer()
493
494         def updateRecordTimer(self):
495                 for timer in NavigationInstance.instance.RecordTimer.timer_list:
496                         if timer.isRunning() and not timer.justplay:
497                                 self.__onRecordingEvent(timer)
498
499         def showWithTimer(self):
500                 if config.infobartunerstate.show_events.value:
501                         #if self.availTimer.isActive():
502                         #       self.availTimer.stop()
503                         #self.availTimer.startLongTimer( 10 )
504                         
505                         # Start timer to avoid permanent displaying
506                         # Do not start timer if no timeout is configured
507                         idx = config.usage.infobar_timeout.index
508                         if idx:
509                                 if self.hideTimer.isActive():
510                                         self.hideTimer.stop()
511                                 self.hideTimer.startLongTimer( config.usage.infobar_timeout.index or 1 )
512                         
513                         # Show windows
514                         self.tunerShow()
515         
516         def tunerShow(self):
517                 # Rebind InfoBar Events
518                 #self.bindInfoBar()
519                 
520                 # Only show the Tuner information dialog,
521                 # if no screen is displayed or the InfoBar is visible
522                 #TODO Info can also be showed if info.rectangle is outside currentdialog.rectangle
523 #               if self.session.current_dialog is None \
524 #                       or isinstance(self.session.current_dialog, InfoBar):
525                 #MAYBE Tuner Informationen werden zusammen mit der EMCMediaCenter InfoBar angezeigt
526                 #or isinstance(self.session.current_dialog, EMCMediaCenter):
527                 
528                 # Delete entries:
529                 #  if entry reached timeout
530                 #  if number of entries is reached
531                 numberoffinished = 0
532                 for id, win in sorted( self.tunerInfo.items(), key=lambda x: (x[1].end), reverse=True ):
533                         if win.type == RecordFinished:
534                                 numberoffinished += 1
535                         
536                         if win.toberemoved == True \
537                                 or win.type == RecordFinished and numberoffinished > int( config.infobartunerstate.number_finished_records.value ):
538                                 # Delete Stopped Timers
539                                 self.session.deleteDialog(win)
540                                 del self.tunerInfo[id]
541                 
542                 # Dynamic column resizing and repositioning
543                 #TODO get Initial Position and Size from skin
544                 posy = self.posy
545                 posx, sizeh = 0, 0
546                 lentuner, lennumber, lenchannel, lenname, lenremaining = 0, 0, 0, 0, 0
547                 for id, win in self.tunerInfo.items():
548                         timer = getTimer( id )
549                         if timer:
550                                 win.update( timer )
551                                 if posx == 0:
552                                         posx = win.instance.position().x()
553                                         sizeh = win.instance.size().height()
554                                 posy       = min( win.instance.position().y(), posy )
555                                 lentuner   = max( win["Tuner"].instance.calculateSize().width(), lentuner )
556                                 lennumber  = max( win["Number"].instance.calculateSize().width(), lennumber )
557                                 lenchannel = max( win["Channel"].instance.calculateSize().width(), lenchannel )
558                                 lenname    = max( win["Name"].instance.calculateSize().width(), lenname )
559                                 lenremaining = max( win["Remaining"].instance.calculateSize().width(), lenremaining )
560                         else:
561                                 print "InfoBarTunerState Warning no timer found"
562                 
563                 self.posy = posy
564                 
565                 # Spacing between the column entries
566                 lentuner   += 15
567                 lennumber  += 15
568                 lenchannel += 15
569                 lenname    += 15
570                 lenremaining += 15
571                 
572                 # Resize, move and show windows
573                 for win in sorted( self.tunerInfo.itervalues(), key=lambda x: (x.type, x.remaining) ):
574                         win.resize(lentuner, lennumber, lenchannel, lenname, lenremaining)
575                         win.instance.move(ePoint(posx, posy))
576                         posy += sizeh
577                         # Show windows
578                         win.show()
579         
580         def tunerHide(self):
581                 if self.hideTimer.isActive():
582                         self.hideTimer.stop()
583                 for win in self.tunerInfo.itervalues():
584                         win.hide()
585
586
587 class TunerState(Screen):
588         skinfile = "/usr/lib/enigma2/python/Plugins/Extensions/InfoBarTunerState/skin.xml" 
589         skin = open(skinfile).read()
590
591         def __init__(self, session, type, tuner, channel, name, end):
592                 
593                 Screen.__init__(self, session)
594                 
595                 self.removeTimer = eTimer()
596                 self.removeTimer.callback.append(self.remove)
597                 self.toberemoved = False
598                 
599                 self.type = type
600                 self["Background"] = Pixmap()
601                 self["Record"] = Pixmap()
602                 self["Stopped"] = Pixmap()
603                 self.updateType()
604                 
605                 self["Tuner"] = Label(tuner)
606                 self["Number"] = Label()
607                 self["Channel"] = Label(channel)
608                 
609                 self["Name"] = Label(name)
610                 
611                 self.remaining = 0
612                 self["Remaining"] = Label()
613                 
614                 self.end = end
615                 
616 #               skin = None
617 #               CoolWide = getDesktop(0).size().width()
618 #               if CoolWide == 720:
619 #                       skin = "/usr/lib/enigma2/python/Plugins/Extensions/EnhancedMovieCenter/CoolSkin/EMCSelection_720.xml"
620 #               elif CoolWide == 1024:
621 #                       skin = "/usr/lib/enigma2/python/Plugins/Extensions/EnhancedMovieCenter/CoolSkin/EMCSelection_1024.xml"
622 #               elif CoolWide == 1280:
623 #                       skin = "/usr/lib/enigma2/python/Plugins/Extensions/EnhancedMovieCenter/CoolSkin/EMCSelection_1280.xml"
624 #               if skin:
625 #                       Cool = open(skin)
626 #                       self.skin = Cool.read()
627 #                       Cool.close()
628
629         def changeType(self, type):
630                 self.type = type
631                 self.updateType()
632
633         def updateType(self):
634                 if self.type == RecordStarted:
635                         self["Record"].show()
636                         self["Stopped"].hide()
637                 elif self.type == RecordFinished:
638                         self["Record"].hide()
639                         self["Stopped"].show()
640                         self["Tuner"].setText( "-" )
641                         # Check if timer is already started
642                         if not self.removeTimer.isActive():
643                                 # Check if timeout is configured
644                                 if config.infobartunerstate.timeout_finished_records.value:
645                                         self.removeTimer.startLongTimer( int( config.infobartunerstate.timeout_finished_records.value ) )
646
647         def update(self, timer):
648                 # Calculate remaining minutes
649                 if timer:
650                         self.end = timer.end
651                         if not timer.autoincrease:
652                                 if self.type == RecordFinished:
653                                         # Show recording length
654                                         duration = int( math.ceil( ( self.end - timer.begin ) / 60.0 ) )
655                                         self.remaining = 0
656                                         self["Remaining"].setText( str(duration) + _(" Min") )
657                                 elif self.end > 0:
658                                         # Show remaining recording time
659                                         self.remaining = int( math.ceil( ( self.end - time() ) / 60.0 ) )
660                                         self["Remaining"].setText( str(self.remaining) + _(" Min") )
661                                 else:
662                                         self.remaining = 0
663                                         self["Remaining"].setText( "" )
664                         else: 
665                                 # Add infinity symbol for indefinitely recordings
666                                 self.remaining = 0xFFFFFFFFFFFFFFFF
667                                 self["Remaining"].setText( u"\u221E".encode("utf-8") )
668                                 #TODO config update name of infinite recordings
669                                 epg = eEPGCache.getInstance()
670                                 event = epg and epg.lookupEventTime(timer.service_ref.ref, -1, 0)
671                                 if event: 
672                                         self["Name"].setText( event.getEventName() )
673                 else:
674                         # No timer available
675                         self.remaining = 0
676                         self["Remaining"].setText( "" )
677                 
678                 if not self["Number"].getText():
679                         if timer and timer.service_ref and timer.service_ref.ref:
680                                 number = getNumber(timer.service_ref.ref)
681                                 if number > 0:
682                                         self["Number"].setText( str(number) )
683                 
684                 #TODO Handle Live Entry - Update all Labels
685
686         def resize(self, lentuner, lennumber, lenchannel, lenname, lenremaining):
687                 sh = self.instance.size().height()
688                 
689                 self["Tuner"].instance.resize( eSize(lentuner, sh) )
690                 px = self["Tuner"].instance.position().x()
691                 py = self["Tuner"].instance.position().y()
692                 px += lentuner
693                 
694                 self["Number"].instance.resize( eSize(lennumber, sh) )
695                 self["Number"].instance.move( ePoint(px, py) )
696                 px += lennumber
697                 
698                 self["Channel"].instance.resize( eSize(lenchannel, sh) )
699                 self["Channel"].instance.move( ePoint(px, py) )
700                 px += lenchannel
701                 
702                 self["Name"].instance.resize( eSize(lenname, sh) )
703                 self["Name"].instance.move( ePoint(px, py) )
704                 px += lenname
705                 
706                 self["Remaining"].instance.resize( eSize(lenremaining, sh) )
707                 self["Remaining"].instance.move( ePoint(px, py) )
708                 px += lenremaining
709                 
710                 #TODO config width and style
711                 
712                 #if background dynamic
713                 #self["Background"].instance.resize( eSize(px, sh) )
714                 #self.instance.resize( eSize(px, sh) )
715                 
716                 #if background color gradiant
717                 bw = self["Background"].instance.size().width()
718                 self["Background"].instance.move( ePoint(px-bw, py) )
719                 self.instance.resize( eSize(px, sh) )
720
721         def remove(self):
722                 self.toberemoved = True 
723
724
725 # Global helper functions
726 def getTimer(strtimer):
727         #for timer in self.session.nav.RecordTimer.timer_list + self.session.nav.RecordTimer.processed_timers:
728         for timer in NavigationInstance.instance.RecordTimer.timer_list + NavigationInstance.instance.RecordTimer.processed_timers:
729                 if str(timer) == strtimer:
730                         return timer
731         return None
732
733 def getTuner(service):
734         # service must be an instance of iPlayableService or iRecordableService
735         feinfo = service and service.frontendInfo()
736         frontendData = feinfo and feinfo.getAll(False)
737         return chr( frontendData.get("tuner_number", -1) + ord('A') )
738
739 def getNumber(actservice):
740         # actservice must be an instance of eServiceReference
741         from Screens.InfoBar import InfoBar
742         Servicelist = None
743         if InfoBar and InfoBar.instance:
744                 Servicelist = InfoBar.instance.servicelist
745         mask = (eServiceReference.isMarker | eServiceReference.isDirectory)
746         number = 0
747         bouquets = Servicelist and Servicelist.getBouquetList()
748         if bouquets:
749                 actbouquet = Servicelist.getRoot()
750                 #TODO get alternative for actbouquet
751                 if actbouquet:
752                         serviceHandler = eServiceCenter.getInstance()
753                         for name, bouquet in bouquets:
754                                 if not bouquet.valid(): #check end of list
755                                         break
756                                 if bouquet.flags & eServiceReference.isDirectory:
757                                         servicelist = serviceHandler.list(bouquet)
758                                         if not servicelist is None:
759                                                 while True:
760                                                         service = servicelist.getNext()
761                                                         if not service.valid(): #check end of list
762                                                                 break
763                                                         playable = not (service.flags & mask)
764                                                         if playable:
765                                                                 number += 1
766                                                         if actbouquet == bouquet and actservice == service:
767                                                                 return number
768         return -1