fix Stop and delete for instant recording
[openblackhole/openblackhole-enigma2.git] / lib / python / Screens / InfoBarGenerics.py
index f36a95a..0e4cb62 100644 (file)
@@ -9,9 +9,10 @@ from Components.MovieList import AUDIO_EXTENSIONS, MOVIE_EXTENSIONS, DVD_EXTENSI
 from Components.PluginComponent import plugins
 from Components.ServiceEventTracker import ServiceEventTracker
 from Components.Sources.Boolean import Boolean
-from Components.config import config, ConfigBoolean, ConfigClock
+from Components.config import config, ConfigBoolean, ConfigClock, ConfigText
 from Components.SystemInfo import SystemInfo
 from Components.UsageConfig import preferredInstantRecordPath, defaultMoviePath, ConfigSelection
+from Components.VolumeControl import VolumeControl
 from Components.Sources.StaticText import StaticText
 from EpgSelection import EPGSelection
 from Plugins.Plugin import PluginDescriptor
@@ -21,7 +22,7 @@ from Screens import ScreenSaver
 from Screens import Standby
 from Screens.ChoiceBox import ChoiceBox
 from Screens.Dish import Dish
-from Screens.EventView import EventViewEPGSelect, EventViewSimple, EventViewRecording
+from Screens.EventView import EventViewEPGSelect, EventViewSimple
 from Screens.InputBox import InputBox
 from Screens.MessageBox import MessageBox
 from Screens.MinuteInput import MinuteInput
@@ -41,8 +42,6 @@ from enigma import eTimer, eServiceCenter, eDVBServicePMTHandler, iServiceInform
        iPlayableService, eServiceReference, eEPGCache, eActionMap
 
 from time import time, localtime, strftime
-from os import stat as os_stat
-from os import rename as os_rename
 import os
 from bisect import insort
 from sys import maxint
@@ -187,7 +186,7 @@ class InfoBarScreenSaver:
                flag = self.seekstate[0]
                if not flag:
                        ref = self.session.nav.getCurrentlyPlayingServiceOrGroup()
-                       if ref:
+                       if ref and not (hasattr(self.session, "pipshown") and self.session.pipshown):
                                ref = ref.toString().split(":")
                                flag = ref[2] == "2" or os.path.splitext(ref[10])[1].lower() in AUDIO_EXTENSIONS
                if time and flag:
@@ -309,7 +308,7 @@ class InfoBarShowHide(InfoBarScreenSaver):
                        else:
                                idx = config.usage.infobar_timeout.index
                        if idx:
-                               self.hideTimer.start(idx*1000, True)
+                               self.hideTimer.startLongTimer(idx)
 
        def doShow(self):
                self.show()
@@ -328,18 +327,30 @@ class InfoBarShowHide(InfoBarScreenSaver):
 
        def toggleShow(self):
                if self.__state == self.STATE_HIDDEN:
-                       self.show()
-                       if self.secondInfoBarScreen:
-                               self.secondInfoBarScreen.hide()
-               elif isStandardInfoBar(self) and config.usage.show_second_infobar.value == "EPG":
-                       self.showDefaultEPG()
+                       self.showFirstInfoBar()
+               else:
+                       self.showSecondInfoBar()
+
+       def showSecondInfoBar(self):
+               if isStandardInfoBar(self) and config.usage.show_second_infobar.value == "EPG":
+                       if not(hasattr(self, "hotkeyGlobal") and self.hotkeyGlobal("info") != 0):
+                               self.showDefaultEPG()
                elif self.secondInfoBarScreen and config.usage.show_second_infobar.value and not self.secondInfoBarScreen.shown:
+                       self.show()
                        self.secondInfoBarScreen.show()
                        self.startHideTimer()
                else:
                        self.hide()
                        self.hideTimer.stop()
 
+       def showFirstInfoBar(self):
+               if self.__state == self.STATE_HIDDEN or self.secondInfoBarScreen and self.secondInfoBarScreen.shown:
+                       self.secondInfoBarScreen and self.secondInfoBarScreen.hide()
+                       self.show()
+               else:
+                       self.hide()
+                       self.hideTimer.stop()
+
        def lockShow(self):
                self.__locked = self.__locked + 1
                if self.execing:
@@ -351,13 +362,41 @@ class InfoBarShowHide(InfoBarScreenSaver):
                if self.execing:
                        self.startHideTimer()
 
-#      def startShow(self):
-#              self.instance.m_animation.startMoveAnimation(ePoint(0, 600), ePoint(0, 380), 100)
-#              self.__state = self.STATE_SHOWN
-#
-#      def startHide(self):
-#              self.instance.m_animation.startMoveAnimation(ePoint(0, 380), ePoint(0, 600), 100)
-#              self.__state = self.STATE_HIDDEN
+class BufferIndicator(Screen):
+       def __init__(self, session):
+               Screen.__init__(self, session)
+               self["status"] = Label()
+               self.mayShow = False
+               self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
+                       {
+                               iPlayableService.evBuffering: self.bufferChanged,
+                               iPlayableService.evStart: self.__evStart,
+                               iPlayableService.evGstreamerPlayStarted: self.__evGstreamerPlayStarted,
+                       })
+
+       def bufferChanged(self):
+               if self.mayShow:
+                       service = self.session.nav.getCurrentService()
+                       info = service and service.info()
+                       if info:
+                               value = info.getInfo(iServiceInformation.sBuffer)
+                               if value and value != 100:
+                                       self["status"].setText(_("Buffering %d%%") % value)
+                                       if not self.shown:
+                                               self.show()
+
+       def __evStart(self):
+               self.mayShow = True
+               self.hide()
+
+       def __evGstreamerPlayStarted(self):
+               self.mayShow = False
+               self.hide()
+
+class InfoBarBuffer():
+       def __init__(self):
+               self.bufferScreen = self.session.instantiateDialog(BufferIndicator)
+               self.bufferScreen.hide()
 
 class NumberZap(Screen):
        def quit(self):
@@ -478,8 +517,8 @@ class InfoBarNumberZap:
                                serviceIterator = servicelist.getNext()
                return None
 
-       def searchNumber(self, number, firstBouquetOnly = False):
-               bouquet = self.servicelist.getRoot()
+       def searchNumber(self, number, firstBouquetOnly=False, bouquet=None):
+               bouquet = bouquet or self.servicelist.getRoot()
                service = None
                serviceHandler = eServiceCenter.getInstance()
                if not firstBouquetOnly:
@@ -503,7 +542,7 @@ class InfoBarNumberZap:
                return service, bouquet
 
        def selectAndStartService(self, service, bouquet):
-               if service:
+               if service and not service.flags & eServiceReference.isMarker:
                        if self.servicelist.getRoot() != bouquet: #already in correct bouquet?
                                self.servicelist.clearPath()
                                if self.servicelist.bouquet_root != bouquet:
@@ -575,24 +614,34 @@ class InfoBarChannelSelection:
        def keyUpCheck(self):
                if config.usage.oldstyle_zap_controls.value:
                        self.zapDown()
+               elif config.usage.volume_instead_of_channelselection.value:
+                       VolumeControl.instance and VolumeControl.instance.volUp()
                else:
                        self.switchChannelUp()
 
        def keyDownCheck(self):
                if config.usage.oldstyle_zap_controls.value:
                        self.zapUp()
+               elif config.usage.volume_instead_of_channelselection.value:
+                       VolumeControl.instance and VolumeControl.instance.volDown()
                else:
                        self.switchChannelDown()
 
        def keyLeftCheck(self):
                if config.usage.oldstyle_zap_controls.value:
-                       self.switchChannelUp()
+                       if config.usage.volume_instead_of_channelselection.value:
+                               VolumeControl.instance and VolumeControl.instance.volDown()
+                       else:
+                               self.switchChannelUp()
                else:
                        self.zapUp()
 
        def keyRightCheck(self):
                if config.usage.oldstyle_zap_controls.value:
-                       self.switchChannelDown()
+                       if config.usage.volume_instead_of_channelselection.value:
+                               VolumeControl.instance and VolumeControl.instance.volUp()
+                       else:
+                               self.switchChannelDown()
                else:
                        self.zapDown()
 
@@ -612,34 +661,46 @@ class InfoBarChannelSelection:
                if config.usage.oldstyle_zap_controls.value:
                        value = _("Switch to next channel")
                else:
-                       value = _("Open service list")
-                       if not "keep" in config.usage.servicelist_cursor_behavior.value:
-                               value += " " + _("and select previous channel")
+                       if config.usage.volume_instead_of_channelselection.value:
+                               value = _("Volume up")
+                       else:
+                               value = _("Open service list")
+                               if not "keep" in config.usage.servicelist_cursor_behavior.value:
+                                       value += " " + _("and select previous channel")
                return value
 
        def getKeyDownHelpText(self):
                if config.usage.oldstyle_zap_controls.value:
                        value = _("Switch to previous channel")
                else:
-                       value = _("Open service list")
-                       if not "keep" in config.usage.servicelist_cursor_behavior.value:
-                               value += " " + _("and select next channel")
+                       if config.usage.volume_instead_of_channelselection.value:
+                               value = _("Volume down")
+                       else:
+                               value = _("Open service list")
+                               if not "keep" in config.usage.servicelist_cursor_behavior.value:
+                                       value += " " + _("and select next channel")
                return value
 
        def getKeyLeftHelptext(self):
                if config.usage.oldstyle_zap_controls.value:
-                       value = _("Open service list")
-                       if not "keep" in config.usage.servicelist_cursor_behavior.value:
-                               value += " " + _("and select previous channel")
+                       if config.usage.volume_instead_of_channelselection.value:
+                               value = _("Volume down")
+                       else:
+                               value = _("Open service list")
+                               if not "keep" in config.usage.servicelist_cursor_behavior.value:
+                                       value += " " + _("and select previous channel")
                else:
                        value = _("Switch to previous channel")
                return value
 
        def getKeyRightHelptext(self):
                if config.usage.oldstyle_zap_controls.value:
-                       value = _("Open service list")
-                       if not "keep" in config.usage.servicelist_cursor_behavior.value:
-                               value += " " + _("and select next channel")
+                       if config.usage.volume_instead_of_channelselection.value:
+                               value = _("Volume up")
+                       else:
+                               value = _("Open service list")
+                               if not "keep" in config.usage.servicelist_cursor_behavior.value:
+                                       value += " " + _("and select next channel")
                else:
                        value = _("Switch to next channel")
                return value
@@ -704,6 +765,10 @@ class InfoBarChannelSelection:
                        self.servicelist.moveDown()
                self.servicelist.zap(enable_pipzap = True)
 
+       def openFavouritesList(self):
+               self.servicelist.showFavourites()
+               self.openServiceList()
+
        def openServiceList(self):
                self.session.execDialog(self.servicelist)
 
@@ -817,8 +882,6 @@ class InfoBarEPG:
                self.bouquetSel = None
                self.eventView = None
                self.epglist = []
-               self.defaultEPGType = self.getDefaultEPGtype()
-               self.defaultGuideType = self.getDefaultGuidetype()
                self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
                        {
                                iPlayableService.evUpdatedEventInfo: self.__evEventInfoChanged,
@@ -829,38 +892,19 @@ class InfoBarEPG:
                                "showEventInfo": (self.showDefaultEPG, _("Show EPG...")),
                                "showEventInfoSingleEPG": (self.showSingleEPG, _("Show single service EPG")),
                                "showEventInfoMultiEPG": (self.showMultiEPG, _("Show multi channel EPG")),
-                               "showEventInfoPlugin": (self.showEventInfoPlugins, _("List EPG functions...")),
-                               "showEventGuidePlugin": (self.showEventGuidePlugins, _("List EPG functions...")),
                                "showInfobarOrEpgWhenInfobarAlreadyVisible": self.showEventInfoWhenNotVisible,
                        })
 
        def getEPGPluginList(self, getAll=False):
-               pluginlist = [(p.name, boundFunction(self.runPlugin, p)) for p in plugins.getPlugins(where = PluginDescriptor.WHERE_EVENTINFO) \
-                               if 'selectedevent' not in p.__call__.func_code.co_varnames]
-               if pluginlist:
-                       from Components.ServiceEventTracker import InfoBarCount
-                       if getAll or InfoBarCount == 1:
-                               pluginlist.append((_("Show EPG for current channel..."), self.openSingleServiceEPG))
-                       pluginlist.append((_("Multi EPG"), self.openMultiServiceEPG))
-                       pluginlist.append((_("Current event EPG"), self.openEventView))
+               pluginlist = [(p.name, boundFunction(self.runPlugin, p), p.path) for p in plugins.getPlugins(where = PluginDescriptor.WHERE_EVENTINFO) \
+                               if 'selectedevent' not in p.__call__.func_code.co_varnames] or []
+               from Components.ServiceEventTracker import InfoBarCount
+               if getAll or InfoBarCount == 1:
+                       pluginlist.append((_("Show EPG for current channel..."), self.openSingleServiceEPG, "current_channel"))
+               pluginlist.append((_("Multi EPG"), self.openMultiServiceEPG, "multi_epg"))
+               pluginlist.append((_("Current event EPG"), self.openEventView, "event_epg"))
                return pluginlist
 
-       def getDefaultEPGtype(self):
-               pluginlist = self.getEPGPluginList()
-               config.usage.defaultEPGType=ConfigSelection(default = "None", choices = pluginlist)
-               for plugin in pluginlist:
-                       if plugin[0] == config.usage.defaultEPGType.value:
-                               return plugin[1]
-               return None
-
-       def getDefaultGuidetype(self):
-               pluginlist = self.getEPGPluginList()
-               config.usage.defaultGuideType=ConfigSelection(default = "None", choices = pluginlist)
-               for plugin in pluginlist:
-                       if plugin[0] == config.usage.defaultGuideType.value:
-                               return plugin[1]
-               return None
-
        def showEventInfoWhenNotVisible(self):
                if self.shown:
                        self.openEventView()
@@ -979,23 +1023,19 @@ class InfoBarEPG:
                self.serviceSel = None
 
        def openSingleServiceEPG(self):
-               from Components.ServiceEventTracker import InfoBarCount
-               if InfoBarCount > 1:
-                       self.openMultiServiceEPG(False)
-               else:
-                       ref = self.session.nav.getCurrentlyPlayingServiceOrGroup()
-                       if ref:
-                               if self.servicelist.getMutableList() is not None: # bouquet in channellist
-                                       current_path = self.servicelist.getRoot()
-                                       services = self.getBouquetServices(current_path)
-                                       self.serviceSel = SimpleServicelist(services)
-                                       if self.serviceSel.selectService(ref):
-                                               self.epg_bouquet = current_path
-                                               self.session.openWithCallback(self.SingleServiceEPGClosed, EPGSelection, ref, self.zapToService, serviceChangeCB = self.changeServiceCB)
-                                       else:
-                                               self.session.openWithCallback(self.SingleServiceEPGClosed, EPGSelection, ref)
+               ref = self.servicelist.getCurrentSelection()
+               if ref:
+                       if self.servicelist.getMutableList(): # bouquet in channellist
+                               current_path = self.servicelist.getRoot()
+                               services = self.getBouquetServices(current_path)
+                               self.serviceSel = SimpleServicelist(services)
+                               if self.serviceSel.selectService(ref):
+                                       self.epg_bouquet = current_path
+                                       self.session.openWithCallback(self.SingleServiceEPGClosed, EPGSelection, ref, self.zapToService, serviceChangeCB=self.changeServiceCB)
                                else:
-                                       self.session.open(EPGSelection, ref)
+                                       self.session.openWithCallback(self.SingleServiceEPGClosed, EPGSelection, ref)
+                       else:
+                               self.session.open(EPGSelection, ref)
 
        def runPlugin(self, plugin):
                plugin(session = self.session, servicelist = self.servicelist)
@@ -1003,8 +1043,7 @@ class InfoBarEPG:
        def showEventInfoPlugins(self):
                pluginlist = self.getEPGPluginList()
                if pluginlist:
-                       pluginlist.append((_("Select default EPG type..."), self.SelectDefaultInfoPlugin))
-                       self.session.openWithCallback(self.EventInfoPluginChosen, ChoiceBox, title=_("Please choose an extension..."), list = pluginlist, skin_name = "EPGExtensionsList")
+                       self.session.openWithCallback(self.EventInfoPluginChosen, ChoiceBox, title=_("Please choose an extension..."), list=pluginlist, skin_name="EPGExtensionsList", reorderConfig="eventinfo_order")
                else:
                        self.openSingleServiceEPG()
 
@@ -1012,36 +1051,6 @@ class InfoBarEPG:
                if answer is not None:
                        answer[1]()
 
-       def SelectDefaultInfoPlugin(self):
-               self.session.openWithCallback(self.DefaultInfoPluginChosen, ChoiceBox, title=_("Please select a default EPG type..."), list = self.getEPGPluginList(True), skin_name = "EPGExtensionsList")
-
-       def DefaultInfoPluginChosen(self, answer):
-               if answer is not None:
-                       self.defaultEPGType = answer[1]
-                       config.usage.defaultEPGType.value = answer[0]
-                       config.usage.defaultEPGType.save()
-
-       def showEventGuidePlugins(self):
-               pluginlist = self.getEPGPluginList()
-               if pluginlist:
-                       pluginlist.append((_("Select default EPG type..."), self.SelectDefaultGuidePlugin))
-                       self.session.openWithCallback(self.EventGuidePluginChosen, ChoiceBox, title=_("Please choose an extension..."), list = pluginlist, skin_name = "EPGExtensionsList")
-               else:
-                       self.openSingleServiceEPG()
-
-       def EventGuidePluginChosen(self, answer):
-               if answer is not None:
-                       answer[1]()
-
-       def SelectDefaultGuidePlugin(self):
-               self.session.openWithCallback(self.DefaultGuidePluginChosen, ChoiceBox, title=_("Please select a default EPG type..."), list = self.getEPGPluginList(True), skin_name = "EPGExtensionsList")
-
-       def DefaultGuidePluginChosen(self, answer):
-               if answer is not None:
-                       self.defaultGuideType = answer[1]
-                       config.usage.defaultGuideType.value = answer[0]
-                       config.usage.defaultGuideType.save()
-
        def openSimilarList(self, eventid, refstr):
                self.session.open(EPGSelection, refstr, None, eventid)
 
@@ -1064,23 +1073,12 @@ class InfoBarEPG:
                                self.eventView.setEvent(self.epglist[0])
 
        def showDefaultEPG(self):
-               if self.defaultEPGType is not None:
-                       self.defaultEPGType()
-                       return
                self.openEventView()
 
        def showSingleEPG(self):
-               if self.defaultGuideType is not None:
-                       self.defaultGuideType()
-                       return
-               pluginlist = self.getEPGPluginList()
                self.openSingleServiceEPG()
 
        def showMultiEPG(self):
-               if self.defaultGuideType is not None:
-                       self.defaultGuideType()
-                       return
-               pluginlist = self.getEPGPluginList()
                self.openMultiServiceEPG()
 
        def openEventView(self):
@@ -1098,7 +1096,7 @@ class InfoBarEPG:
                        if ptr:
                                epglist.append(ptr)
                        if epglist:
-                               self.session.open(EventViewRecording, epglist[0], ServiceReference(ref), self.eventViewCallback, self.openMultiServiceEPG, self.openSimilarList)
+                               self.session.open(EventViewEPGSelect, epglist[0], ServiceReference(ref), self.eventViewCallback, self.openSingleServiceEPG, self.openMultiServiceEPG, self.openSimilarList)
                else:
                        ref = self.session.nav.getCurrentlyPlayingServiceOrGroup()
                        self.getNowNext()
@@ -1371,10 +1369,12 @@ class InfoBarSeek:
                        self.pauseService()
 
        def okButton(self):
-               if self.seekstate == self.SEEK_STATE_PAUSE:
+               if self.seekstate == self.SEEK_STATE_PLAY:
+                       return 0
+               elif self.seekstate == self.SEEK_STATE_PAUSE:
                        self.pauseService()
                else:
-                       return 0
+                       self.unPauseService()
 
        def pauseService(self):
                if self.seekstate == self.SEEK_STATE_PAUSE:
@@ -1595,20 +1595,40 @@ class InfoBarPVRState:
                else:
                        self._mayShow()
 
+class TimeshiftLive(Screen):
+       def __init__(self, session):
+               Screen.__init__(self, session)
+
 class InfoBarTimeshiftState(InfoBarPVRState):
        def __init__(self):
                InfoBarPVRState.__init__(self, screen=TimeshiftState, force_show = True)
+               self.timeshiftLiveScreen = self.session.instantiateDialog(TimeshiftLive)
+               self.onHide.append(self.timeshiftLiveScreen.hide)
+               self.secondInfoBarScreen and self.secondInfoBarScreen.onShow.append(self.timeshiftLiveScreen.hide)
+               self.timeshiftLiveScreen.hide()
                self.__hideTimer = eTimer()
                self.__hideTimer.callback.append(self.__hideTimeshiftState)
+               self.onFirstExecBegin.append(self.pvrStateDialog.show)
 
        def _mayShow(self):
-               if self.shown and self.timeshiftEnabled():
-                       self.pvrStateDialog.show()
-                       if self.seekstate == self.SEEK_STATE_PLAY and not self.shown:
-                               self.__hideTimer.start(5*1000, True)
+               if self.timeshiftEnabled():
+                       if self.secondInfoBarScreen and self.secondInfoBarScreen.shown:
+                               self.secondInfoBarScreen.hide()
+                       if self.timeshiftActivated():
+                               self.pvrStateDialog.show()
+                               self.timeshiftLiveScreen.hide()
+                       elif self.showTimeshiftState:
+                               self.pvrStateDialog.hide()
+                               self.timeshiftLiveScreen.show()
+                               self.showTimeshiftState = False
+                       if self.seekstate == self.SEEK_STATE_PLAY and config.usage.infobar_timeout.index and (self.pvrStateDialog.shown or self.timeshiftLiveScreen.shown):
+                               self.__hideTimer.startLongTimer(config.usage.infobar_timeout.index)
+               else:
+                       self.__hideTimeshiftState()
 
        def __hideTimeshiftState(self):
                self.pvrStateDialog.hide()
+               self.timeshiftLiveScreen.hide()
 
 class InfoBarShowMovies:
 
@@ -1669,8 +1689,12 @@ class InfoBarTimeshift:
                self.ts_rewind_timer.callback.append(self.rewindService)
                self.ts_start_delay_timer = eTimer()
                self.ts_start_delay_timer.callback.append(self.startTimeshiftWithoutPause)
+               self.ts_current_event_timer = eTimer()
+               self.ts_current_event_timer.callback.append(self.saveTimeshiftFileForEvent)
                self.save_timeshift_file = False
                self.timeshift_was_activated = False
+               self.showTimeshiftState = False
+               self.save_timeshift_only_current_event = False
 
                self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
                        {
@@ -1687,6 +1711,10 @@ class InfoBarTimeshift:
                ts = self.getTimeshift()
                return ts and ts.isTimeshiftEnabled()
 
+       def timeshiftActivated(self):
+               ts = self.getTimeshift()
+               return ts and ts.isTimeshiftActive()
+
        def startTimeshift(self, pauseService = True):
                print "enable timeshift"
                ts = self.getTimeshift()
@@ -1707,6 +1735,9 @@ class InfoBarTimeshift:
                                        # PAUSE.
                                        #self.setSeekState(self.SEEK_STATE_PAUSE)
                                        self.activateTimeshiftEnd(False)
+                                       self.showTimeshiftState = True
+                               else:
+                                       self.showTimeshiftState = False
 
                                # enable the "TimeshiftEnableActions", which will override
                                # the startTimeshift actions
@@ -1715,6 +1746,7 @@ class InfoBarTimeshift:
                                # get current timeshift filename and calculate new
                                self.save_timeshift_file = False
                                self.save_timeshift_in_movie_dir = False
+                               self.setCurrentEventTimer()
                                self.current_timeshift_filename = ts.getTimeshiftFilename()
                                self.new_timeshift_filename = self.generateNewTimeshiftFileName()
                        else:
@@ -1738,12 +1770,13 @@ class InfoBarTimeshift:
                if answer and ts:
                        ts.stopTimeshift()
                        self.pvrStateDialog.hide()
-
+                       self.setCurrentEventTimer()
                        # disable actions
                        self.__seekableStatusChanged()
 
        # activates timeshift, and seeks to (almost) the end
        def activateTimeshiftEnd(self, back = True):
+               self.showTimeshiftState = True
                ts = self.getTimeshift()
                print "activateTimeshiftEnd"
 
@@ -1823,10 +1856,14 @@ class InfoBarTimeshift:
                if self.timeshiftEnabled() and config.usage.check_timeshift.value and self.timeshift_was_activated:
                        message = _("Stop timeshift?")
                        if not self.save_timeshift_file:
-                               choice = [(_("yes"), "stop"), (_("no"), "continue"), (_("Yes and save"), "save"), (_("Yes and save in movie dir"), "save_movie")]
+                               choice = [(_("Yes"), "stop"), (_("No"), "continue"), (_("Yes and save"), "save"), (_("Yes and save in movie dir"), "save_movie")]
                        else:
-                               choice = [(_("yes"), "stop"), (_("no"), "continue")]
+                               choice = [(_("Yes"), "stop"), (_("No"), "continue")]
                                message += "\n" + _("Reminder, you have chosen to save timeshift file.")
+                               if self.save_timeshift_only_current_event:
+                                       remaining = self.currentEventTime()
+                                       if remaining > 0:
+                                               message += "\n" + _("The %d min remaining before the end of the event.") % abs(remaining / 60)
                        self.session.openWithCallback(boundFunction(self.checkTimeshiftRunningCallback, returnFunction), MessageBox, message, simple = True, list = choice)
                else:
                        returnFunction(True)
@@ -1848,6 +1885,7 @@ class InfoBarTimeshift:
        # renames/moves timeshift files if requested
        def __serviceEnd(self):
                self.saveTimeshiftFiles()
+               self.setCurrentEventTimer()
                self.timeshift_was_activated = False
 
        def saveTimeshiftFiles(self):
@@ -1867,6 +1905,49 @@ class InfoBarTimeshift:
 
                        moveFiles(fileList)
                        self.save_timeshift_file = False
+                       self.setCurrentEventTimer()
+
+       def currentEventTime(self):
+               remaining = 0
+               ref = self.session.nav.getCurrentlyPlayingServiceOrGroup()
+               if ref:
+                       epg = eEPGCache.getInstance()
+                       event = epg.lookupEventTime(ref, -1, 0)
+                       if event:
+                               now = int(time())
+                               start = event.getBeginTime()
+                               duration = event.getDuration()
+                               end = start + duration
+                               remaining = end - now
+               return remaining
+
+       def saveTimeshiftFileForEvent(self):
+               if self.timeshiftEnabled() and self.save_timeshift_only_current_event and self.timeshift_was_activated and self.save_timeshift_file:
+                       message = _("Current event is over.\nSelect an option to save the timeshift file.")
+                       choice = [(_("Save and stop timeshift"), "save"), (_("Save and restart timeshift"), "restart"), (_("Don't save and stop timeshift"), "stop"), (_("Do nothing"), "continue")]
+                       self.session.openWithCallback(self.saveTimeshiftFileForEventCallback, MessageBox, message, simple = True, list = choice, timeout=15)
+
+       def saveTimeshiftFileForEventCallback(self, answer):
+               self.save_timeshift_only_current_event = False
+               if answer:
+                       ts = self.getTimeshift()
+                       if ts and answer in ("save", "restart", "stop"):
+                               self.stopTimeshiftcheckTimeshiftRunningCallback(True)
+                               if answer in ("save", "restart"):
+                                       ts.saveTimeshiftFile()
+                                       del ts
+                                       self.saveTimeshiftFiles()
+                               if answer == "restart":
+                                       self.ts_start_delay_timer.start(1000, True)
+                               self.save_timeshift_file = False
+                               self.save_timeshift_in_movie_dir = False
+
+       def setCurrentEventTimer(self, duration=0):
+               self.ts_current_event_timer.stop()
+               self.save_timeshift_only_current_event = False
+               if duration > 0:
+                       self.save_timeshift_only_current_event = True
+                       self.ts_current_event_timer.startLongTimer(duration)
 
 from Screens.PiPSetup import PiPSetup
 
@@ -1930,7 +2011,7 @@ class InfoBarExtensions:
                list.extend([(x[0](), x) for x in extensionsList])
 
                keys += [""] * len(extensionsList)
-               self.session.openWithCallback(self.extensionCallback, ChoiceBox, title=_("Please choose an extension..."), list = list, keys = keys, skin_name = "ExtensionsList")
+               self.session.openWithCallback(self.extensionCallback, ChoiceBox, title=_("Please choose an extension..."), list=list, keys=keys, skin_name="ExtensionsList", reorderConfig="extension_order")
 
        def extensionCallback(self, answer):
                if answer is not None:
@@ -2058,6 +2139,8 @@ class InfoBarPiP:
                                                self.lastPiPServiceTimeoutTimer.startLongTimer(lastPiPServiceTimeout)
                                del self.session.pip
                                self.session.pipshown = False
+                       if hasattr(self, "ScreenSaverTimerStart"):
+                               self.ScreenSaverTimerStart()
                else:
                        self.session.pip = self.session.instantiateDialog(PictureInPicture)
                        self.session.pip.show()
@@ -2073,6 +2156,8 @@ class InfoBarPiP:
                                else:
                                        self.session.pipshown = False
                                        del self.session.pip
+                       if self.session.pipshown and hasattr(self, "screenSaverTimer"):
+                               self.screenSaverTimer.stop()
                        self.lastPiPService = None
 
        def clearLastPiPService(self):
@@ -2093,20 +2178,24 @@ class InfoBarPiP:
                        return _("Activate Picture in Picture")
 
        def swapPiP(self):
-               swapservice = self.session.nav.getCurrentlyPlayingServiceOrGroup()
-               pipref = self.session.pip.getCurrentService()
-               if swapservice and pipref and pipref.toString() != swapservice.toString():
-                       currentServicePath = self.servicelist.getCurrentServicePath()
-                       self.servicelist.setCurrentServicePath(self.session.pip.servicePath, doZap=False)
-                       self.session.pip.playService(swapservice)
-                       self.session.nav.playService(pipref, checkParentalControl=False, adjust=False)
-                       self.session.pip.servicePath = currentServicePath
-                       if self.servicelist.dopipzap:
-                               # This unfortunately won't work with subservices
-                               self.servicelist.setCurrentSelection(self.session.pip.getCurrentService())
+               if self.pipShown():
+                       swapservice = self.session.nav.getCurrentlyPlayingServiceOrGroup()
+                       pipref = self.session.pip.getCurrentService()
+                       if swapservice and pipref and pipref.toString() != swapservice.toString():
+                               currentServicePath = self.servicelist.getCurrentServicePath()
+                               currentBouquet = self.servicelist and self.servicelist.getRoot()
+                               self.servicelist.setCurrentServicePath(self.session.pip.servicePath, doZap=False)
+                               self.session.pip.playService(swapservice)
+                               self.session.nav.playService(pipref, checkParentalControl=False, adjust=False)
+                               self.session.pip.servicePath = currentServicePath
+                               self.session.pip.servicePath[1] = currentBouquet
+                               if self.servicelist.dopipzap:
+                                       # This unfortunately won't work with subservices
+                                       self.servicelist.setCurrentSelection(self.session.pip.getCurrentService())
 
        def movePiP(self):
-               self.session.open(PiPSetup, pip = self.session.pip)
+               if self.pipShown():
+                       self.session.open(PiPSetup, pip = self.session.pip)
 
        def pipDoHandle0Action(self):
                use = config.usage.pip_zero_button.value
@@ -2128,6 +2217,7 @@ class InfoBarInstantRecord:
                        {
                                "instantRecord": (self.instantRecord, _("Instant recording...")),
                        })
+               self.SelectedInstantServiceRef = None
                if isStandardInfoBar(self):
                        self.recording = []
                else:
@@ -2136,22 +2226,45 @@ class InfoBarInstantRecord:
                        if InfoBarInstance:
                                self.recording = InfoBarInstance.recording
 
+       def moveToTrash(self, entry):
+               print "instantRecord stop and delete recording: ", entry.name
+               import Tools.Trashcan
+               trash = Tools.Trashcan.createTrashFolder(entry.Filename)
+               from MovieSelection import moveServiceFiles
+               moveServiceFiles(entry.Filename, trash, entry.name, allowCopy=False)
+
        def stopCurrentRecording(self, entry = -1):
                if entry is not None and entry != -1:
                        self.session.nav.RecordTimer.removeEntry(self.recording[entry])
+                       if self.deleteRecording:
+                               self.moveToTrash(self.recording[entry])
                        self.recording.remove(self.recording[entry])
 
+       def stopAllCurrentRecordings(self, list):
+               msg = ''
+               for entry in list:
+                       msg += entry[0].name + "\n"
+                       self.session.nav.RecordTimer.removeEntry(entry[0])
+                       self.recording.remove(entry[0])
+                       if self.deleteRecording:
+                               self.moveToTrash(entry[0])
+               self.session.open(MessageBox, _("Stopped recordings:") + "\n" + msg, MessageBox.TYPE_INFO, timeout=5)
+
        def getProgramInfoAndEvent(self, info, name):
-               info["serviceref"] = self.session.nav.getCurrentlyPlayingServiceOrGroup()
+               info["serviceref"] = hasattr(self, "SelectedInstantServiceRef") and self.SelectedInstantServiceRef or self.session.nav.getCurrentlyPlayingServiceOrGroup()
 
                # try to get event info
                event = None
                try:
-                       service = self.session.nav.getCurrentService()
                        epg = eEPGCache.getInstance()
                        event = epg.lookupEventTime(info["serviceref"], -1, 0)
                        if event is None:
-                               event = service.info().getEvent(0)
+                               if hasattr(self, "SelectedInstantServiceRef") and self.SelectedInstantServiceRef:
+                                       service_info = eServiceCenter.getInstance().info(self.SelectedInstantServiceRef)
+                                       event = service_info and service_info.getEvent(self.SelectedInstantServiceRef)
+                               else:
+                                       service = self.session.nav.getCurrentService()
+                                       event = service and service.info().getEvent(0)
                except:
                        pass
 
@@ -2237,6 +2350,7 @@ class InfoBarInstantRecord:
                        elif x.dontSave and x.isRunning():
                                list.append((x, False))
 
+               self.deleteRecording = False
                if answer[1] == "changeduration":
                        if len(self.recording) == 1:
                                self.changeDuration(0)
@@ -2251,7 +2365,21 @@ class InfoBarInstantRecord:
                        import TimerEdit
                        self.session.open(TimerEdit.TimerEditList)
                elif answer[1] == "stop":
-                       self.session.openWithCallback(self.stopCurrentRecording, TimerSelection, list)
+                       if len(self.recording) == 1:
+                               self.stopCurrentRecording(0)
+                       else:
+                               self.session.openWithCallback(self.stopCurrentRecording, TimerSelection, list)
+               elif answer[1] == "stopdelete":
+                       self.deleteRecording = True
+                       if len(self.recording) == 1:
+                               self.stopCurrentRecording(0)
+                       else:
+                               self.session.openWithCallback(self.stopCurrentRecording, TimerSelection, list)
+               elif answer[1] == "stopall":
+                       self.stopAllCurrentRecordings(list)
+               elif answer[1] == "stopdeleteall":
+                       self.deleteRecording = True
+                       self.stopAllCurrentRecordings(list)
                elif answer[1] in ( "indefinitely" , "manualduration", "manualendtime", "event"):
                        self.startInstantRecording(limitEvent = answer[1] in ("event", "manualendtime") or False)
                        if answer[1] == "manualduration":
@@ -2265,6 +2393,10 @@ class InfoBarInstantRecord:
                                self.save_timeshift_file = True
                                if "movie" in answer[1]:
                                        self.save_timeshift_in_movie_dir = True
+                               if "event" in answer[1]:
+                                       remaining = self.currentEventTime()
+                                       if remaining > 0:
+                                               self.setCurrentEventTimer(remaining-15)
                print "after:\n", self.recording
 
        def setEndtime(self, entry):
@@ -2308,7 +2440,8 @@ class InfoBarInstantRecord:
                                                        identical += 1
                return timers > identical
 
-       def instantRecord(self):
+       def instantRecord(self, serviceRef=None):
+               self.SelectedInstantServiceRef = serviceRef
                pirr = preferredInstantRecordPath()
                if not findSafeRecordPath(pirr) and not findSafeRecordPath(defaultMoviePath()):
                        if not pirr:
@@ -2326,9 +2459,16 @@ class InfoBarInstantRecord:
                        common = ()
                if self.isInstantRecordRunning():
                        title =_("A recording is currently running.\nWhat do you want to do?")
-                       list = ((_("Stop recording"), "stop"),) + common + \
+                       list = common + \
                                ((_("Change recording (duration)"), "changeduration"),
                                (_("Change recording (endtime)"), "changeendtime"),)
+                       list += ((_("Stop recording"), "stop"),)
+                       if config.usage.movielist_trashcan.value:
+                               list += ((_("Stop and delete recording"), "stopdelete"),)
+                       if len(self.recording) > 1:
+                               list += ((_("Stop all current recordings"), "stopall"),)
+                               if config.usage.movielist_trashcan.value:
+                                       list += ((_("Stop and delete all current recordings"), "stopdeleteall"),)
                        if self.isTimerRecordRunning():
                                list += ((_("Stop timer recording"), "timer"),)
                        list += ((_("Do nothing"), "no"),)
@@ -2342,6 +2482,8 @@ class InfoBarInstantRecord:
                if isStandardInfoBar(self) and self.timeshiftEnabled():
                        list = list + ((_("Save timeshift file"), "timeshift"),
                                (_("Save timeshift file in movie directory"), "timeshift_movie"))
+                       if self.currentEventTime() > 0:
+                               list += ((_("Save timeshift only for current event"), "timeshift_event"),)
                if list:
                        self.session.openWithCallback(self.recordQuestionCallback, ChoiceBox, title=title, list=list)
                else:
@@ -2699,8 +2841,8 @@ class InfoBarCueSheetSupport:
                        if (last > 900000) and (not length[1]  or (last < length[1] - 900000)):
                                self.resume_point = last
                                l = last / 90000
-                               if config.usage.on_movie_start.value == "ask" or not length[1]:
-                                       Notifications.AddNotificationWithCallback(self.playLastCB, MessageBox, _("Do you want to resume this playback?") + "\n" + (_("Resume position at %s") % ("%d:%02d:%02d" % (l/3600, l%3600/60, l%60))), timeout=10)
+                               if "ask" in config.usage.on_movie_start.value or not length[1]:
+                                       Notifications.AddNotificationWithCallback(self.playLastCB, MessageBox, _("Do you want to resume this playback?") + "\n" + (_("Resume position at %s") % ("%d:%02d:%02d" % (l/3600, l%3600/60, l%60))), timeout=10, default="yes" in config.usage.on_movie_start.value)
                                elif config.usage.on_movie_start.value == "resume":
 # TRANSLATORS: The string "Resuming playback" flashes for a moment
 # TRANSLATORS: at the start of a movie, when the user has selected
@@ -2928,7 +3070,7 @@ class InfoBarTeletextPlugin:
                        print "no teletext plugin found!"
 
        def startTeletext(self):
-               self.teletext_plugin(session=self.session, service=self.session.nav.getCurrentService())
+               self.teletext_plugin and self.teletext_plugin(session=self.session, service=self.session.nav.getCurrentService())
 
 class InfoBarSubtitleSupport(object):
        def __init__(self):
@@ -3011,10 +3153,13 @@ class InfoBarServiceErrorPopupSupport:
                Notifications.RemovePopup(id = "ZapError")
 
        def __tuneFailed(self):
-               if not config.usage.hide_zap_errors.value:
+               if not config.usage.hide_zap_errors.value or not config.usage.remote_fallback_enabled.value:
                        service = self.session.nav.getCurrentService()
                        info = service and service.info()
                        error = info and info.getInfo(iServiceInformation.sDVBState)
+                       if not config.usage.remote_fallback_enabled.value and (error == eDVBServicePMTHandler.eventMisconfiguration or error == eDVBServicePMTHandler.eventNoResources):
+                               self.session.nav.currentlyPlayingServiceReference = None
+                               self.session.nav.currentlyPlayingServiceOrGroup = None
 
                        if error == self.last_error:
                                error = None
@@ -3034,7 +3179,7 @@ class InfoBarServiceErrorPopupSupport:
                                eDVBServicePMTHandler.eventMisconfiguration: _("Service unavailable!\nCheck tuner configuration!"),
                        }.get(error) #this returns None when the key not exist in the dict
 
-                       if error:
+                       if error and not config.usage.hide_zap_errors.value:
                                self.closeNotificationInstantiateDialog()
                                if hasattr(self, "dishDialog") and not self.dishDialog.dishState():
                                        Notifications.AddPopup(text = error, type = MessageBox.TYPE_ERROR, timeout = 5, id = "ZapError")
@@ -3045,6 +3190,7 @@ class InfoBarPowersaver:
                self.inactivityTimer.callback.append(self.inactivityTimeout)
                self.restartInactiveTimer()
                self.sleepTimer = eTimer()
+               self.sleepStartTime = 0
                self.sleepTimer.callback.append(self.sleepTimerTimeout)
                eActionMap.getInstance().bindAction('', -maxint - 1, self.keypress)
 
@@ -3085,13 +3231,18 @@ class InfoBarPowersaver:
                else:
                        print "[InfoBarPowersaver] abort"
 
-       def setSleepTimer(self, time):
-               print "[InfoBarPowersaver] set sleeptimer", time
-               if time:
-                       message = _("And will put your receiver in standby over ")
-                       m = abs(time / 60)
-                       message = _("The sleep timer has been activated.") + "\n" + message + ngettext("%d minute", "%d minutes", m) % m
-                       self.sleepTimer.startLongTimer(time)
+       def sleepTimerState(self):
+               if self.sleepTimer.isActive():
+                       return (self.sleepStartTime - time()) / 60
+               return 0
+
+       def setSleepTimer(self, sleepTime):
+               print "[InfoBarPowersaver] set sleeptimer", sleepTime
+               if sleepTime:
+                       m = abs(sleepTime / 60)
+                       message = _("The sleep timer has been activated.") + "\n" + _("And will put your receiver in standby over ") + ngettext("%d minute", "%d minutes", m) % m
+                       self.sleepTimer.startLongTimer(sleepTime)
+                       self.sleepStartTime = time() + sleepTime
                else:
                        message = _("The sleep timer has been disabled.")
                        self.sleepTimer.stop()
@@ -3120,12 +3271,6 @@ class InfoBarPowersaver:
                        self.session.open(Screens.Standby.Standby)
 
 class InfoBarHDMI:
-       def __init__(self):
-               self["HDMIActions"] = HelpableActionMap(self, "InfobarHDMIActions",
-                       {
-                               "HDMIin":(self.HDMIIn, _("Switch to HDMI in mode")),
-                       }, prio=2)
-
        def HDMIIn(self):
                slist = self.servicelist
                if slist.dopipzap: