use video stc for display. make skipping look a bit better.
[enigma2.git] / lib / python / Screens / InfoBarGenerics.py
index 22cba7a21f5d94963e60f868ec3d0c8dd4ddc40b..677816338140cea161615d16ddfa016f7ad1f190 100644 (file)
@@ -1,24 +1,35 @@
 from Screen import Screen
 from Screen import Screen
-from Components.ActionMap import ActionMap
+from Components.ActionMap import ActionMap, HelpableActionMap
 from Components.ActionMap import NumberActionMap
 from Components.ActionMap import NumberActionMap
-from Components.Label import Label
-from Components.config import configfile
+from Components.Label import *
+from Components.ProgressBar import *
+from Components.config import configfile, configsequencearg
+from Components.config import config, configElement, ConfigSubsection, configSequence
 from ChannelSelection import ChannelSelection
 
 from ChannelSelection import ChannelSelection
 
+from Components.Pixmap import Pixmap, PixmapConditional
+from Components.BlinkingPixmap import BlinkingPixmapConditional
 from Components.ServiceName import ServiceName
 from Components.EventInfo import EventInfo
 
 from Components.ServiceName import ServiceName
 from Components.EventInfo import EventInfo
 
+from ServiceReference import ServiceReference
 from EpgSelection import EPGSelection
 
 from Screens.MessageBox import MessageBox
 from Screens.Volume import Volume
 from Screens.Mute import Mute
 from EpgSelection import EPGSelection
 
 from Screens.MessageBox import MessageBox
 from Screens.Volume import Volume
 from Screens.Mute import Mute
+from Screens.Dish import Dish
 from Screens.Standby import Standby
 from Screens.Standby import Standby
+from Screens.EventView import EventView
+from Components.Harddisk import harddiskmanager
+
+from Tools import Notifications
 
 #from enigma import eTimer, eDVBVolumecontrol, quitMainloop
 from enigma import *
 
 import time
 
 #from enigma import eTimer, eDVBVolumecontrol, quitMainloop
 from enigma import *
 
 import time
+import os
 
 # hack alert!
 from Menu import MainMenu, mdom
 
 # hack alert!
 from Menu import MainMenu, mdom
@@ -26,8 +37,10 @@ from Menu import MainMenu, mdom
 class InfoBarVolumeControl:
        """Volume control, handles volUp, volDown, volMute actions and display 
        a corresponding dialog"""
 class InfoBarVolumeControl:
        """Volume control, handles volUp, volDown, volMute actions and display 
        a corresponding dialog"""
-       
        def __init__(self):
        def __init__(self):
+               config.audio = ConfigSubsection()
+               config.audio.volume = configElement("config.audio.volume", configSequence, [100], configsequencearg.get("INTEGER", (0, 100)))
+
                self["VolumeActions"] = ActionMap( ["InfobarVolumeActions"] ,
                        {
                                "volumeUp": self.volUp,
                self["VolumeActions"] = ActionMap( ["InfobarVolumeActions"] ,
                        {
                                "volumeUp": self.volUp,
@@ -40,18 +53,32 @@ class InfoBarVolumeControl:
 
                self.hideVolTimer = eTimer()
                self.hideVolTimer.timeout.get().append(self.volHide)
 
                self.hideVolTimer = eTimer()
                self.hideVolTimer.timeout.get().append(self.volHide)
+
+               vol = config.audio.volume.value[0]
+               self.volumeDialog.setValue(vol)
+               eDVBVolumecontrol.getInstance().setVolume(vol, vol)
        
        
+       def volSave(self):
+               config.audio.volume.value = eDVBVolumecontrol.getInstance().getVolume()
+               config.audio.volume.save()
+               
        def     volUp(self):
        def     volUp(self):
+               if (eDVBVolumecontrol.getInstance().isMuted()):
+                       self.volMute()
                eDVBVolumecontrol.getInstance().volumeUp()
                self.volumeDialog.instance.show()
                self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
                eDVBVolumecontrol.getInstance().volumeUp()
                self.volumeDialog.instance.show()
                self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
-               self.hideVolTimer.start(3000)
+               self.volSave()
+               self.hideVolTimer.start(3000, True)
 
        def     volDown(self):
 
        def     volDown(self):
+               if (eDVBVolumecontrol.getInstance().isMuted()):
+                       self.volMute()
                eDVBVolumecontrol.getInstance().volumeDown()
                self.volumeDialog.instance.show()
                self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
                eDVBVolumecontrol.getInstance().volumeDown()
                self.volumeDialog.instance.show()
                self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
-               self.hideVolTimer.start(3000)
+               self.volSave()
+               self.hideVolTimer.start(3000, True)
                
        def volHide(self):
                self.volumeDialog.instance.hide()
                
        def volHide(self):
                self.volumeDialog.instance.hide()
@@ -65,6 +92,11 @@ class InfoBarVolumeControl:
                else:
                        self.muteDialog.instance.hide()
 
                else:
                        self.muteDialog.instance.hide()
 
+class InfoBarDish:
+       def __init__(self):
+               self.dishDialog = self.session.instantiateDialog(Dish)
+               self.onShown.append(self.dishDialog.instance.hide)
+
 class InfoBarShowHide:
        """ InfoBar show/hide control, accepts toggleShow and hide actions, might start
        fancy animations. """
 class InfoBarShowHide:
        """ InfoBar show/hide control, accepts toggleShow and hide actions, might start
        fancy animations. """
@@ -80,16 +112,27 @@ class InfoBarShowHide:
                                "hide": self.hide,
                        })
 
                                "hide": self.hide,
                        })
 
-               self.state = self.STATE_HIDDEN
+               self.state = self.STATE_SHOWN
+               
+               self.onExecBegin.append(self.show)
+               self.onClose.append(self.delHideTimer)
                
                self.hideTimer = eTimer()
                self.hideTimer.timeout.get().append(self.doTimerHide)
                
                self.hideTimer = eTimer()
                self.hideTimer.timeout.get().append(self.doTimerHide)
-               #self.hideTimer.start(1000)
+               self.hideTimer.start(5000, True)
+
+       def delHideTimer(self):
+               del self.hideTimer
 
        def hide(self): 
                self.instance.hide()
 
        def hide(self): 
                self.instance.hide()
+               
+       def show(self):
+               self.state = self.STATE_SHOWN
+               self.hideTimer.start(5000, True)
 
        def doTimerHide(self):
 
        def doTimerHide(self):
+               self.hideTimer.stop()
                if self.state == self.STATE_SHOWN:
                        self.instance.hide()
                        self.state = self.STATE_HIDDEN
                if self.state == self.STATE_SHOWN:
                        self.instance.hide()
                        self.state = self.STATE_HIDDEN
@@ -99,14 +142,12 @@ class InfoBarShowHide:
                        self.instance.hide()
                        #pls check animation support, sorry
 #                      self.startHide()
                        self.instance.hide()
                        #pls check animation support, sorry
 #                      self.startHide()
+                       self.hideTimer.stop()
                        self.state = self.STATE_HIDDEN
                        self.state = self.STATE_HIDDEN
-               else:
+               elif self.state == self.STATE_HIDDEN:
                        self.instance.show()
                        self.instance.show()
-#                      self.startShow()
-                       self.state = self.STATE_SHOWN
-                       #TODO: make it customizable
-                       self.hideTimer.start(5000)
-
+                       self.show()
+                       
        def startShow(self):
                self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100)
                self.state = self.STATE_SHOWN
        def startShow(self):
                self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100)
                self.state = self.STATE_SHOWN
@@ -118,15 +159,14 @@ class InfoBarShowHide:
 class NumberZap(Screen):
        def quit(self):
                self.Timer.stop()
 class NumberZap(Screen):
        def quit(self):
                self.Timer.stop()
-               self.close()
+               self.close(0)
 
        def keyOK(self):
                self.Timer.stop()
 
        def keyOK(self):
                self.Timer.stop()
-               print "do the action here"
-               self.close()
+               self.close(int(self["number"].getText()))
 
        def keyNumberGlobal(self, number):
 
        def keyNumberGlobal(self, number):
-               self.Timer.start(3000)          #reset timer
+               self.Timer.start(3000, True)            #reset timer
                self.field = self.field + str(number)
                self["number"].setText(self.field)
                if len(self.field) >= 4:
                self.field = self.field + str(number)
                self["number"].setText(self.field)
                if len(self.field) >= 4:
@@ -135,7 +175,9 @@ class NumberZap(Screen):
        def __init__(self, session, number):
                Screen.__init__(self, session)
                self.field = str(number)
        def __init__(self, session, number):
                Screen.__init__(self, session)
                self.field = str(number)
-               
+
+               self["channel"] = Label(_("Channel:"))
+
                self["number"] = Label(self.field)
 
                self["actions"] = NumberActionMap( [ "SetupActions" ], 
                self["number"] = Label(self.field)
 
                self["actions"] = NumberActionMap( [ "SetupActions" ], 
@@ -156,7 +198,7 @@ class NumberZap(Screen):
 
                self.Timer = eTimer()
                self.Timer.timeout.get().append(self.keyOK)
 
                self.Timer = eTimer()
                self.Timer.timeout.get().append(self.keyOK)
-               self.Timer.start(3000)
+               self.Timer.start(3000, True)
 
 class InfoBarPowerKey:
        """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
 
 class InfoBarPowerKey:
        """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
@@ -164,10 +206,12 @@ class InfoBarPowerKey:
        def __init__(self):
                self.powerKeyTimer = eTimer()
                self.powerKeyTimer.timeout.get().append(self.powertimer)
        def __init__(self):
                self.powerKeyTimer = eTimer()
                self.powerKeyTimer.timeout.get().append(self.powertimer)
-               self["PowerKeyActions"] = ActionMap( ["PowerKeyActions"],
+               self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions",
                        {
                                "powerdown": self.powerdown,
                                "powerup": self.powerup,
                        {
                                "powerdown": self.powerdown,
                                "powerup": self.powerup,
+                               "discreteStandby": (self.standby, "Go standby"),
+                               "discretePowerOff": (self.quit, "Go to deep standby"),
                        })
 
        def powertimer(self):   
                        })
 
        def powertimer(self):   
@@ -176,25 +220,20 @@ class InfoBarPowerKey:
        
        def powerdown(self):
                self.standbyblocked = 0
        
        def powerdown(self):
                self.standbyblocked = 0
-               self.powerKeyTimer.start(3000)
+               self.powerKeyTimer.start(3000, True)
 
        def powerup(self):
                self.powerKeyTimer.stop()
                if self.standbyblocked == 0:
                        self.standbyblocked = 1
 
        def powerup(self):
                self.powerKeyTimer.stop()
                if self.standbyblocked == 0:
                        self.standbyblocked = 1
-                       self.session.open(Standby, self)
+                       self.standby()
 
 
-       def quit(self):
-               #       self.session.open(Standby, self)
-               ref = self.session.nav.getCurrentlyPlayingServiceReference()
-               if ref is not None:
-                       refstr = ref.toString()
-               else:
-                       refstr = ""     
-               
-               #configfile.save()
-               quitMainloop(0)
+       def standby(self):
+               self.session.open(Standby, self)
 
 
+       def quit(self):
+               # halt
+               quitMainloop(1)
 
 class InfoBarNumberZap:
        """ Handles an initial number for NumberZapping """
 
 class InfoBarNumberZap:
        """ Handles an initial number for NumberZapping """
@@ -214,8 +253,49 @@ class InfoBarNumberZap:
                        })
 
        def keyNumberGlobal(self, number):
                        })
 
        def keyNumberGlobal(self, number):
-               print "You pressed number " + str(number)
-               self.session.open(NumberZap, number)
+#              print "You pressed number " + str(number)
+               self.session.openWithCallback(self.numberEntered, NumberZap, number)
+
+       def numberEntered(self, retval):
+#              print self.servicelist
+               if retval > 0:
+                       self.zapToNumber(retval)
+
+       def searchNumberHelper(self, serviceHandler, num, bouquet):
+               servicelist = serviceHandler.list(bouquet)
+               if not servicelist is None:
+                       while num:
+                               serviceIterator = servicelist.getNext()
+                               if not serviceIterator.valid(): #check end of list
+                                       break
+                               if serviceIterator.flags: #assume normal dvb service have no flags set
+                                       continue
+                               num -= 1;
+                       if not num: #found service with searched number ?
+                               return serviceIterator, 0
+               return None, num
+
+       def zapToNumber(self, number):
+               bouquet = self.servicelist.bouquet_root
+               service = None
+               serviceHandler = eServiceCenter.getInstance()
+               if bouquet.toString().find('FROM BOUQUET "bouquets.') == -1: #FIXME HACK
+                       service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
+               else:
+                       bouquetlist = serviceHandler.list(bouquet)
+                       if not bouquetlist is None:
+                               while number:
+                                       bouquet = bouquetlist.getNext()
+                                       if not bouquet.valid(): #check end of list
+                                               break
+                                       if ((bouquet.flags & eServiceReference.flagDirectory) != eServiceReference.flagDirectory):
+                                               continue
+                                       service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
+               if not service is None:
+                       self.session.nav.playService(service) #play service
+                       if self.servicelist.getRoot() != bouquet: #already in correct bouquet?
+                               self.servicelist.setRoot(bouquet)
+                       self.servicelist.setCurrentSelection(service) #select the service in servicelist
 
 class InfoBarChannelSelection:
        """ ChannelSelection - handles the channelSelection dialog and the initial 
 
 class InfoBarChannelSelection:
        """ ChannelSelection - handles the channelSelection dialog and the initial 
@@ -224,12 +304,12 @@ class InfoBarChannelSelection:
                #instantiate forever
                self.servicelist = self.session.instantiateDialog(ChannelSelection)
 
                #instantiate forever
                self.servicelist = self.session.instantiateDialog(ChannelSelection)
 
-               self["ChannelSelectActions"] = ActionMap( ["InfobarChannelSelection"],
+               self["ChannelSelectActions"] = HelpableActionMap(self, "InfobarChannelSelection",
                        {
                                "switchChannelUp": self.switchChannelUp,
                                "switchChannelDown": self.switchChannelDown,
                        {
                                "switchChannelUp": self.switchChannelUp,
                                "switchChannelDown": self.switchChannelDown,
-                               "zapUp": self.zapUp,
-                               "zapDown": self.zapDown,
+                               "zapUp": (self.zapUp, _("next channel")),
+                               "zapDown": (self.zapDown, _("previous channel")),
                        })
                        
        def switchChannelUp(self):      
                        })
                        
        def switchChannelUp(self):      
@@ -243,17 +323,21 @@ class InfoBarChannelSelection:
        def     zapUp(self):
                self.servicelist.moveUp()
                self.servicelist.zap()
        def     zapUp(self):
                self.servicelist.moveUp()
                self.servicelist.zap()
+               self.instance.show()
+               self.show()
 
        def     zapDown(self):
                self.servicelist.moveDown()
                self.servicelist.zap()
 
        def     zapDown(self):
                self.servicelist.moveDown()
                self.servicelist.zap()
-
+               self.instance.show()
+               self.show()
+               
 class InfoBarMenu:
        """ Handles a menu action, to open the (main) menu """
        def __init__(self):
 class InfoBarMenu:
        """ Handles a menu action, to open the (main) menu """
        def __init__(self):
-               self["MenuActions"] = ActionMap( [ "InfobarMenuActions" ]
+               self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions"
                        {
                        {
-                               "mainMenu": self.mainMenu,
+                               "mainMenu": (self.mainMenu, "Enter main menu..."),
                        })
 
        def mainMenu(self):
                        })
 
        def mainMenu(self):
@@ -265,9 +349,9 @@ class InfoBarMenu:
 class InfoBarEPG:
        """ EPG - Opens an EPG list when the showEPGList action fires """
        def __init__(self):
 class InfoBarEPG:
        """ EPG - Opens an EPG list when the showEPGList action fires """
        def __init__(self):
-               self["EPGActions"] = ActionMap( [ "InfobarEPGActions" ]
+               self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions"
                        {
                        {
-                               "showEPGList": self.showEPGList,
+                               "showEPGList": (self.showEPGList, _("show EPG...")),
                        })
 
        def showEPGList(self):
                        })
 
        def showEPGList(self):
@@ -275,10 +359,75 @@ class InfoBarEPG:
                ptr=eEPGCache.getInstance()
                if ptr.startTimeQuery(ref) != -1:
                        self.session.open(EPGSelection, ref)
                ptr=eEPGCache.getInstance()
                if ptr.startTimeQuery(ref) != -1:
                        self.session.open(EPGSelection, ref)
-               else:
+               else: # try to show now/next
                        print 'no epg for service', ref.toString()
                        print 'no epg for service', ref.toString()
-
-class InfoBarEvent:    
+                       try:
+                               self.epglist = [ ]
+                               service = self.session.nav.getCurrentService()
+                               info = service.info()
+                               ptr=info.getEvent(0)
+                               if ptr:
+                                       self.epglist.append(ptr)
+                               ptr=info.getEvent(1)
+                               if ptr:
+                                       self.epglist.append(ptr)
+                               if len(self.epglist) > 0:
+                                       self.session.open(EventView, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
+                       except:
+                               pass
+
+       def eventViewCallback(self, setEvent, val): #used for now/next displaying
+               if len(self.epglist) > 1:
+                       tmp = self.epglist[0]
+                       self.epglist[0]=self.epglist[1]
+                       self.epglist[1]=tmp
+                       setEvent(self.epglist[0])
+
+from math import log
+
+class InfoBarTuner:
+       """provides a snr/agc/ber display"""
+       def __init__(self):
+               self["snr"] = Label()
+               self["agc"] = Label()
+               self["ber"] = Label()
+               self["snr_percent"] = Label()
+               self["agc_percent"] = Label()
+               self["ber_count"] = Label()
+               self["snr_progress"] = ProgressBar()
+               self["agc_progress"] = ProgressBar()
+               self["ber_progress"] = ProgressBar()
+               self.timer = eTimer()
+               self.timer.timeout.get().append(self.updateTunerInfo)
+               self.timer.start(1000)
+
+       def calc(self,val):
+               if not val:
+                       return 0
+               if val < 2500:
+                       return (long)(log(val)/log(2))
+               return val*100/65535
+
+       def updateTunerInfo(self):
+               if self.instance.isVisible():
+                       service = self.session.nav.getCurrentService()
+                       snr=0
+                       agc=0
+                       ber=0
+                       if service is not None:
+                               feinfo = service.frontendStatusInfo()
+                               if feinfo is not None:
+                                       ber=feinfo.getFrontendInfo(iFrontendStatusInformation.bitErrorRate)
+                                       snr=feinfo.getFrontendInfo(iFrontendStatusInformation.signalPower)*100/65536
+                                       agc=feinfo.getFrontendInfo(iFrontendStatusInformation.signalQuality)*100/65536
+                       self["snr_percent"].setText("%d%%"%(snr))
+                       self["agc_percent"].setText("%d%%"%(agc))
+                       self["ber_count"].setText("%d"%(ber))
+                       self["snr_progress"].setValue(snr)
+                       self["agc_progress"].setValue(agc)
+                       self["ber_progress"].setValue(self.calc(ber))
+
+class InfoBarEvent:
        """provides a current/next event info display"""
        def __init__(self):
                self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
        """provides a current/next event info display"""
        def __init__(self):
                self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime)
@@ -295,24 +444,100 @@ class InfoBarServiceName:
                self["ServiceName"] = ServiceName(self.session.nav)
 
 class InfoBarPVR:
                self["ServiceName"] = ServiceName(self.session.nav)
 
 class InfoBarPVR:
+
+       # ispause, isff, issm, skip
+       SEEK_STATE_PLAY = (0, 0, 0, 0)
+       SEEK_STATE_PAUSE = (1, 0, 0, 0)
+       SEEK_STATE_FF_2X = (0, 2, 0, 0)
+       SEEK_STATE_FF_4X = (0, 4, 0, 0)
+       SEEK_STATE_FF_8X = (0, 8, 0, 0)
+       SEEK_STATE_FF_32X = (0, 4, 0, 32)
+       SEEK_STATE_FF_64X = (0, 4, 0, 64)
+       SEEK_STATE_FF_128X = (0, 4, 0, 128)
+       
+       SEEK_STATE_BACK_4X = (0, 0, 0, -4)
+       SEEK_STATE_BACK_32X = (0, 0, 0, -32)
+       SEEK_STATE_BACK_64X = (0, 0, 0, -64)
+       SEEK_STATE_BACK_128X = (0, 0, 0, -128)
+       
+       SEEK_STATE_SM_HALF = (0, 0, 2, 0)
+       SEEK_STATE_SM_QUARTER = (0, 0, 4, 0)
+       SEEK_STATE_SM_EIGHTH = (0, 0, 8, 0)
+       
        """handles PVR specific actions like seeking, pause"""
        def __init__(self):
        """handles PVR specific actions like seeking, pause"""
        def __init__(self):
-               self["PVRActions"] = ActionMap( [ "InfobarPVRActions" ]
+               self["PVRActions"] = HelpableActionMap(self, "InfobarPVRActions"
                        {
                        {
-                               "pauseService": self.pauseService,
-                               "unPauseService": self.unPauseService,
+                               "pauseService": (self.pauseService, "pause"),
+                               "unPauseService": (self.unPauseService, "continue"),
                                
                                
-                               "seekFwd": self.seekFwd,
-                               "seekBack": self.seekBack,
+                               "seekFwd": (self.seekFwd, "skip forward"),
+                               "seekBack": (self.seekBack, "skip backward"),
                        })
                        })
+
+               self.seekstate = self.SEEK_STATE_PLAY
+               self.seekTimer = eTimer()
+               self.seekTimer.timeout.get().append(self.seekTimerFired)
+               self.skipinterval = 500 # 500ms skip interval
+               self.onClose.append(self.delSeekTimer)
+       
+       def delSeekTimer(self):
+               del self.seekTimer
+       
+       def seekTimerFired(self):
+               self.seekbase += self.skipmode * self.skipinterval
+               
+               # check if we bounced against the beginning of the file
+               if self.seekbase < 0:
+                       self.seekbase = 0;
+                       self.setSeekState(self.SEEK_STATE_PLAY)
+                       
+               self.doSeek(self.seekbase)
+
+       def setSeekState(self, state):
+               oldstate = self.seekstate
+               
+               self.seekstate = state
+
+               service = self.session.nav.getCurrentService()
+               if service is None:
+                       return
+               
+               pauseable = service.pause()
+               
+               for i in range(4):
+                       if oldstate[i] != self.seekstate[i]:
+                               (self.session.nav.pause, pauseable.setFastForward, pauseable.setSlowMotion, self.setSkipMode)[i](self.seekstate[i])
+               
+       def setSkipMode(self, skipmode):
+               self.skipmode = skipmode
+               if skipmode == 0:
+                       self.seekTimer.stop()
+               else:
+                       self.seekTimer.start(500)
                
                
+               service = self.session.nav.getCurrentService()
+               if service is None:
+                       return
+               
+               seekable = service.seek()
+               if seekable is None:
+                       return
+
+               if skipmode:
+                       seekable.setTrickmode(1)
+               else:
+                       seekable.setTrickmode(0)
+               
+               self.seekbase = seekable.getPlayPosition()[1] / 90
+       
        def pauseService(self):
        def pauseService(self):
-               self.session.nav.pause(1)
+               self.setSeekState(self.SEEK_STATE_PAUSE);
                
        def unPauseService(self):
                
        def unPauseService(self):
-               self.session.nav.pause(0)
+               self.setSeekState(self.SEEK_STATE_PLAY);
        
        
-       def doSeek(self, dir, seektime):
+       def doSeek(self, seektime):
                service = self.session.nav.getCurrentService()
                if service is None:
                        return
                service = self.session.nav.getCurrentService()
                if service is None:
                        return
@@ -320,66 +545,127 @@ class InfoBarPVR:
                seekable = service.seek()
                if seekable is None:
                        return
                seekable = service.seek()
                if seekable is None:
                        return
-               seekable.seekRelative(dir, 90 * seektime)
+               seekable.seekTo(90 * seektime)
 
        def seekFwd(self):
 
        def seekFwd(self):
-               self.doSeek(+1, 60000)
+               lookup = {
+                               self.SEEK_STATE_PLAY: self.SEEK_STATE_FF_2X,
+                               self.SEEK_STATE_PAUSE: self.SEEK_STATE_SM_EIGHTH,
+                               self.SEEK_STATE_FF_2X: self.SEEK_STATE_FF_4X,
+                               self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_8X,
+                               self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_32X,
+                               self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_64X,
+                               self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_128X,
+                               self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_128X,
+                               self.SEEK_STATE_BACK_4X: self.SEEK_STATE_PLAY,
+                               self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_4X,
+                               self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_32X,
+                               self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_64X,
+                               self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_HALF,
+                               self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_HALF,
+                               self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_SM_QUARTER
+                       }
+               self.setSeekState(lookup[self.seekstate]);
        
        def seekBack(self):
        
        def seekBack(self):
-               self.doSeek(-1, 60000)
+               lookup = {
+                               self.SEEK_STATE_PLAY: self.SEEK_STATE_BACK_4X,
+                               self.SEEK_STATE_PAUSE: self.SEEK_STATE_PAUSE,
+                               self.SEEK_STATE_FF_2X: self.SEEK_STATE_PLAY,
+                               self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_2X,
+                               self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_4X,
+                               self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_8X,
+                               self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_32X,
+                               self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_64X,
+                               self.SEEK_STATE_BACK_4X: self.SEEK_STATE_BACK_32X,
+                               self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_64X,
+                               self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_128X,
+                               self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_128X,
+                               self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_QUARTER,
+                               self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_EIGHTH,
+                               self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_PAUSE
+                       }
+               self.setSeekState(lookup[self.seekstate]);
+
+from RecordTimer import parseEvent
 
 class InfoBarInstantRecord:
        """Instant Record - handles the instantRecord action in order to 
        start/stop instant records"""
        def __init__(self):
 
 class InfoBarInstantRecord:
        """Instant Record - handles the instantRecord action in order to 
        start/stop instant records"""
        def __init__(self):
-               self["InstnantRecordActions"] = ActionMap( [ "InfobarInstantRecord" ],
+               self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
                        {
                        {
-                               "instantRecord": self.instantRecord,
+                               "instantRecord": (self.instantRecord, "Instant Record..."),
                        })
                self.recording = None
                        })
                self.recording = None
-
+               
+               self["BlinkingPoint"] = BlinkingPixmapConditional()
+               self.onShown.append(self["BlinkingPoint"].hideWidget)
+               self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
+               
        def stopCurrentRecording(self): 
                self.session.nav.RecordTimer.removeEntry(self.recording)
                self.recording = None
        def stopCurrentRecording(self): 
                self.session.nav.RecordTimer.removeEntry(self.recording)
                self.recording = None
-       
+                       
        def startInstantRecording(self):
                serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
        def startInstantRecording(self):
                serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
-                       
+               
                # try to get event info
                # try to get event info
-               epg = None
+               event = None
                try:
                        service = self.session.nav.getCurrentService()
                        info = service.info()
                        ev = info.getEvent(0)
                try:
                        service = self.session.nav.getCurrentService()
                        info = service.info()
                        ev = info.getEvent(0)
-                       epg = ev
+                       event = ev
                except:
                        pass
                
                except:
                        pass
                
+               if event is not None:
+                       data = parseEvent(event)
+                       data = (data[0], data[1] + 3600 * 10, data[2], data[3], data[4])
+               else:
+                       data = (time.time(), time.time() + 3600 * 10, "instant record", "", None)
+               
                # fix me, description. 
                # fix me, description. 
-               self.recording = self.session.nav.recordWithTimer(time.time(), time.time() + 3600, serviceref, epg, "instant record")
+               self.recording = self.session.nav.recordWithTimer(serviceref, *data)
+               self.recording.dontSave = True
+               
+               #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
+               
+       def isInstantRecordRunning(self):
+               if self.recording != None:
+                       if self.recording.isRunning():
+                               return True
+               return False
 
        def recordQuestionCallback(self, answer):
                if answer == False:
                        return
                
 
        def recordQuestionCallback(self, answer):
                if answer == False:
                        return
                
-               if self.recording != None:
+               if self.isInstantRecordRunning():
                        self.stopCurrentRecording()
                else:
                        self.startInstantRecording()
 
        def instantRecord(self):
                        self.stopCurrentRecording()
                else:
                        self.startInstantRecording()
 
        def instantRecord(self):
-               if self.recording != None:
-                       self.session.openWithCallback(self.recordQuestionCallback, MessageBox, "Do you want to stop the current\n(instant) recording?")
+               try:
+                       stat = os.stat("/hdd/movies")
+               except:
+                       self.session.open(MessageBox, "No HDD found!")
+                       return
+       
+               if self.isInstantRecordRunning():
+                       self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Do you want to stop the current\n(instant) recording?"))
                else:
                else:
-                       self.session.openWithCallback(self.recordQuestionCallback, MessageBox, "Start recording?")
+                       self.session.openWithCallback(self.recordQuestionCallback, MessageBox, _("Start recording?"))
 
 from Screens.AudioSelection import AudioSelection
 
 class InfoBarAudioSelection:
        def __init__(self):
 
 from Screens.AudioSelection import AudioSelection
 
 class InfoBarAudioSelection:
        def __init__(self):
-               self["AudioSelectionAction"] = ActionMap( [ "InfobarAudioSelectionActions" ]
+               self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions"
                        {
                        {
-                               "audioSelection": self.audioSelection,
+                               "audioSelection": (self.audioSelection, "Audio Options..."),
                        })
 
        def audioSelection(self):
                        })
 
        def audioSelection(self):
@@ -388,3 +674,75 @@ class InfoBarAudioSelection:
                n = audio.getNumberOfTracks()
                if n > 0:
                        self.session.open(AudioSelection, audio)
                n = audio.getNumberOfTracks()
                if n > 0:
                        self.session.open(AudioSelection, audio)
+
+from Screens.SubserviceSelection import SubserviceSelection
+
+class InfoBarSubserviceSelection:
+       def __init__(self):
+               self["SubserviceSelectionAction"] = HelpableActionMap(self, "InfobarSubserviceSelectionActions",
+                       {
+                               "subserviceSelection": (self.subserviceSelection, "Subservice list..."),
+                       })
+
+       def subserviceSelection(self):
+               service = self.session.nav.getCurrentService()
+               subservices = service.subServices()
+               n = subservices.getNumberOfSubservices()
+               if n > 0:
+                       self.session.openWithCallback(self.subserviceSelected, SubserviceSelection, subservices)
+
+       def subserviceSelected(self, service):
+               if not service is None:
+                       self.session.nav.playService(service)
+
+class InfoBarAdditionalInfo:
+       def __init__(self):
+               self["DolbyActive"] = PixmapConditional()
+               # TODO: get the info from c++ somehow
+               self["DolbyActive"].setConnect(lambda: False)
+               
+               self["CryptActive"] = PixmapConditional()
+               # TODO: get the info from c++ somehow
+               self["CryptActive"].setConnect(lambda: False)
+               
+               self["FormatActive"] = PixmapConditional()
+               # TODO: get the info from c++ somehow
+               self["FormatActive"].setConnect(lambda: False)
+               
+               self["ButtonRed"] = PixmapConditional(withTimer = False)
+               self["ButtonRed"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
+               self.onShown.append(self["ButtonRed"].update)
+               self["ButtonRedText"] = LabelConditional(text = _("Record"), withTimer = False)
+               self["ButtonRedText"].setConnect(lambda: harddiskmanager.HDDCount() > 0)
+               self.onShown.append(self["ButtonRedText"].update)
+                               
+               self["ButtonGreen"] = PixmapConditional()
+               self["ButtonGreen"].setConnect(lambda: self.session.nav.getCurrentService().subServices().getNumberOfSubservices() > 0)
+               self["ButtonGreenText"] = LabelConditional(text = _("Subservices"))
+               self["ButtonGreenText"].setConnect(lambda: self.session.nav.getCurrentService().subServices().getNumberOfSubservices() > 0)
+
+               self["ButtonYellow"] = PixmapConditional()
+               self["ButtonYellow"].setConnect(lambda: False)
+
+               self["ButtonBlue"] = PixmapConditional()
+               self["ButtonBlue"].setConnect(lambda: False)
+
+class InfoBarNotifications:
+       def __init__(self):
+               self.onExecBegin.append(self.checkNotifications)
+               Notifications.notificationAdded.append(self.checkNotificationsIfExecing)
+       
+       def checkNotificationsIfExecing(self):
+               if self.execing:
+                       self.checkNotifications()
+
+       def checkNotifications(self):
+               if len(Notifications.notifications):
+                       n = Notifications.notifications[0]
+                       Notifications.notifications = Notifications.notifications[1:]
+                       print "open",n
+                       cb = n[0]
+                       if cb is not None:
+                               self.session.openWithCallback(cb, *n[1:])
+                       else:
+                               self.session.open(*n[1:])