AutoTimer: add "Fast Scan" support
[vuplus_dvbapp-plugin] / autotimer / src / AutoTimerEditor.py
index fbe353e..0d623de 100644 (file)
@@ -15,12 +15,12 @@ from Screens.Setup import SetupSummary
 
 # GUI (Components)
 from Components.ActionMap import ActionMap
-from Components.Button import Button
+from Components.Sources.StaticText import StaticText
 
 # Configuration
 from Components.config import getConfigListEntry, ConfigEnableDisable, \
        ConfigYesNo, ConfigText, ConfigClock, ConfigNumber, ConfigSelection, \
-       config
+       config, NoSave
 
 # Timer
 from RecordTimer import AFTEREVENT
@@ -31,8 +31,8 @@ from time import localtime, mktime
 # Show ServiceName instead of ServiceReference
 from ServiceReference import ServiceReference
 
-# addAutotimerFromService
-from enigma import eServiceCenter, iServiceInformation
+# addAutotimerFromService, AutoTimerChannelSelection
+from enigma import eServiceCenter, eServiceReference, iServiceInformation
 
 # Default Record Directory
 from Tools import Directories
@@ -58,7 +58,7 @@ class ExtendedConfigText(ConfigText):
 
                # Workaround some characters currently not "typeable" using NumericalTextInput
                mapping = self.mapping
-               if len(mapping):
+               if mapping:
                        if "&" not in mapping[0]:
                                mapping[0] += "&"
                        if ";" not in mapping[0]:
@@ -71,7 +71,7 @@ class SimpleBouquetSelection(SimpleChannelSelection):
                SimpleChannelSelection.__init__(self, session, title)
                self.skinName = "SimpleChannelSelection"
 
-       def channelSelected(self): # just return selected service
+       def channelSelected(self):
                ref = self.getCurrentSelection()
                if (ref.flags & 7) == 7:
                        self.close(ref)
@@ -80,6 +80,28 @@ class SimpleBouquetSelection(SimpleChannelSelection):
                        # Asking the user if this is what he wants might be better though
                        self.close(self.servicePath[-1])
 
+class AutoTimerChannelSelection(SimpleChannelSelection):
+       def __init__(self, session, autotimer):
+               SimpleChannelSelection.__init__(self, session, _("Channel Selection"))
+               self.skinName = "SimpleChannelSelection"
+               self.autotimer = autotimer
+
+               self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
+                       {
+                               "showEPGList": self.channelSelected
+                       }
+               )
+
+       def channelSelected(self):
+               ref = self.getCurrentSelection()
+               if (ref.flags & 7) == 7:
+                       self.enterPath(ref)
+               elif not (ref.flags & eServiceReference.isMarker):
+                       self.session.open(
+                               AutoTimerEPGSelection,
+                               ref
+                       )
+
 class AutoTimerEPGSelection(EPGSelection):
        def __init__(self, *args):
                EPGSelection.__init__(self, *args)
@@ -108,30 +130,32 @@ class AutoTimerEditorBase:
                self.editingDefaults = editingDefaults
 
                # See if we are filtering some strings
-               self.excludes = (
+               excludes = (
                        timer.getExcludedTitle(),
                        timer.getExcludedShort(),
                        timer.getExcludedDescription(),
                        timer.getExcludedDays()
                )
-               self.includes = (
+               includes = (
                        timer.getIncludedTitle(),
                        timer.getIncludedShort(),
                        timer.getIncludedDescription(),
                        timer.getIncludedDays()
                )
-               if len(self.excludes[0]) or len(self.excludes[1]) \
-                               or len(self.excludes[2]) or len(self.excludes[3]) \
-                               or len(self.includes[0]) or len(self.includes[1]) \
-                               or len(self.includes[2]) or len(self.includes[3]):
+               if excludes[0] or excludes[1] \
+                               or excludes[2] or excludes[3] \
+                               or includes[0] or includes[1] \
+                               or includes[2] or includes[3]:
                        self.filterSet = True
                else:
                        self.filterSet = False
+               self.excludes = excludes
+               self.includes = includes
 
                # See if services are restricted
                self.services = timer.services
                self.bouquets = timer.bouquets
-               if len(self.services) or len(self.bouquets):
+               if self.services or self.bouquets:
                        self.serviceRestriction = True
                else:
                        self.serviceRestriction = False
@@ -140,14 +164,27 @@ class AutoTimerEditorBase:
 
        def createSetup(self, timer):
                # Name
-               self.name = ExtendedConfigText(default = timer.name, fixed_size = False)
+               self.name = NoSave(ExtendedConfigText(default = timer.name, fixed_size = False))
 
                # Match
-               self.match = ExtendedConfigText(default = timer.match, fixed_size = False)
-               self.match.setUseableChars('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789-_?!.:;,&%()\'"+/$@') # XXX: what exactly is useable? :-)
+               self.match = NoSave(ExtendedConfigText(default = timer.match, fixed_size = False))
+
+               # Encoding
+               default = timer.encoding
+               selection = ['UTF-8', 'ISO8859-15']
+               if default not in selection:
+                       selection.append(default)
+               self.encoding = NoSave(ConfigSelection(choices = selection, default = default))
+
+               # ...
+               self.searchType = NoSave(ConfigSelection(choices = [("partial", _("partial match")), ("exact", _("exact match"))], default = timer.searchType))
+               self.searchCase = NoSave(ConfigSelection(choices = [("sensitive", _("case-sensitive search")), ("insensitive", _("case-insensitive search"))], default = timer.searchCase))
+
+               # Alternatives override
+               self.overrideAlternatives = NoSave(ConfigYesNo(default = timer.overrideAlternatives))
 
                # Justplay
-               self.justplay = ConfigSelection(choices = [("zap", _("zap")), ("record", _("record"))], default = {0: "record", 1: "zap"}[int(timer.justplay)])
+               self.justplay = NoSave(ConfigSelection(choices = [("zap", _("zap")), ("record", _("record"))], default = {0: "record", 1: "zap"}[int(timer.justplay)]))
 
                # Timespan
                now = [x for x in localtime()]
@@ -167,9 +204,9 @@ class AutoTimerEditorBase:
                        now[3] = 23
                        now[4] = 15
                        end = mktime(now)
-               self.timespan = ConfigEnableDisable(default = default)
-               self.timespanbegin = ConfigClock(default = begin)
-               self.timespanend = ConfigClock(default = end)
+               self.timespan = NoSave(ConfigEnableDisable(default = default))
+               self.timespanbegin = NoSave(ConfigClock(default = begin))
+               self.timespanend = NoSave(ConfigClock(default = end))
 
                # Services have their own Screen
 
@@ -182,13 +219,13 @@ class AutoTimerEditorBase:
                        default = False
                        begin = 5
                        end = 5
-               self.offset = ConfigEnableDisable(default = default)
-               self.offsetbegin = ConfigNumber(default = begin)
-               self.offsetend = ConfigNumber(default = end)
+               self.offset = NoSave(ConfigEnableDisable(default = default))
+               self.offsetbegin = NoSave(ConfigNumber(default = begin))
+               self.offsetend = NoSave(ConfigNumber(default = end))
 
                # AfterEvent
                if timer.hasAfterEvent():
-                       afterevent = {
+                       default = {
                                None: "default",
                                AFTEREVENT.NONE: "nothing",
                                AFTEREVENT.DEEPSTANDBY: "deepstandby",
@@ -196,8 +233,12 @@ class AutoTimerEditorBase:
                                AFTEREVENT.AUTO: "auto"
                        }[timer.afterevent[0][0]]
                else:
-                       afterevent = "default"
-               self.afterevent = ConfigSelection(choices = [("default", _("standard")), ("nothing", _("do nothing")), ("standby", _("go to standby")), ("deepstandby", _("go to deep standby")), ("auto", _("auto"))], default = afterevent)
+                       default = "default"
+               self.afterevent = NoSave(ConfigSelection(choices = [
+                       ("default", _("standard")), ("nothing", _("do nothing")),
+                       ("standby", _("go to standby")),
+                       ("deepstandby", _("go to deep standby")),
+                       ("auto", _("auto"))], default = default))
 
                # AfterEvent (Timespan)
                if timer.hasAfterEvent() and timer.afterevent[0][1][0] is not None:
@@ -216,12 +257,12 @@ class AutoTimerEditorBase:
                        now[3] = 7
                        now[4] = 0
                        end = mktime(now)
-               self.afterevent_timespan = ConfigEnableDisable(default = default)
-               self.afterevent_timespanbegin = ConfigClock(default = begin)
-               self.afterevent_timespanend = ConfigClock(default = end)
+               self.afterevent_timespan = NoSave(ConfigEnableDisable(default = default))
+               self.afterevent_timespanbegin = NoSave(ConfigClock(default = begin))
+               self.afterevent_timespanend = NoSave(ConfigClock(default = end))
 
                # Enabled
-               self.enabled = ConfigYesNo(default = timer.enabled)
+               self.enabled = NoSave(ConfigYesNo(default = timer.enabled))
 
                # Maxduration
                if timer.hasDuration():
@@ -230,29 +271,30 @@ class AutoTimerEditorBase:
                else:
                        default = False
                        duration =70
-               self.duration = ConfigEnableDisable(default = default)
-               self.durationlength = ConfigNumber(default = duration)
+               self.duration = NoSave(ConfigEnableDisable(default = default))
+               self.durationlength = NoSave(ConfigNumber(default = duration))
 
                # Counter
                if timer.hasCounter():
                        default = timer.matchCount
                else:
                        default = 0
-               self.counter = ConfigNumber(default = default)
-               self.counterLeft = ConfigNumber(default = timer.matchLeft)
+               self.counter = NoSave(ConfigNumber(default = default))
+               self.counterLeft = NoSave(ConfigNumber(default = timer.matchLeft))
+               default = timer.getCounterFormatString()
                selection = [("", _("Never")), ("%m", _("Monthly")), ("%U", _("Weekly (Sunday)")), ("%W", _("Weekly (Monday)"))]
-               if timer.getCounterFormatString() not in ["", "%m", "%U", "%W"]:
-                       selection.append((timer.getCounterFormatString(), _("Custom (%s)") % (timer.getCounterFormatString())))
-               self.counterFormatString = ConfigSelection(selection, default = timer.getCounterFormatString())
+               if default not in ('', '%m', '%U', '%W'):
+                       selection.append((default, _("Custom (%s)") % (default)))
+               self.counterFormatString = NoSave(ConfigSelection(selection, default = default))
 
                # Avoid Duplicate Description
-               self.avoidDuplicateDescription = ConfigSelection([
+               self.avoidDuplicateDescription = NoSave(ConfigSelection([
                                ("0", _("No")),
                                ("1", _("On same service")),
                                ("2", _("On any service")),
                        ],
                        default = str(timer.getAvoidDuplicateDescription())
-               )
+               ))
 
                # Custom Location
                if timer.hasDestination():
@@ -260,24 +302,24 @@ class AutoTimerEditorBase:
                else:
                        default = False
 
-               self.useDestination = ConfigYesNo(default = default)
+               self.useDestination = NoSave(ConfigYesNo(default = default))
 
                default = timer.destination or Directories.resolveFilename(Directories.SCOPE_HDD)
                choices = config.movielist.videodirs.value
 
                if default not in choices:
                        choices.append(default)
-               self.destination = ConfigSelection(default = default, choices = choices)
+               self.destination = NoSave(ConfigSelection(default = default, choices = choices))
 
                # Tags
                self.timerentry_tags = timer.tags
-               self.tags = ConfigSelection(choices = [len(self.timerentry_tags) == 0 and _("None") or ' '.join(self.timerentry_tags)])
+               self.tags = NoSave(ConfigSelection(choices = [len(self.timerentry_tags) == 0 and _("None") or ' '.join(self.timerentry_tags)]))
 
        def pathSelected(self, res):
                if res is not None:
-                       if res not in self.destination.choices:
-                               self.destination.choices.append(res)
-                               self.destination.description[res] = res
+                       # I'm pretty sure this will always fail
+                       if config.movielist.videodirs.value != self.destination.choices:
+                                       self.destination.setChoices(config.movielist.videodirs.value, default = res)
                        self.destination.value = res
 
        def chooseDestination(self):
@@ -308,16 +350,18 @@ class AutoTimerEditorBase:
 class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase):
        """Edit AutoTimer"""
 
-       skin = """<screen name="AutoTimerEdit" title="Edit AutoTimer" position="75,155" size="565,280">
-               <widget name="config" position="5,5" size="555,225" scrollbarMode="showOnDemand" />
-               <ePixmap position="0,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
-               <ePixmap position="140,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
-               <ePixmap position="280,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
-               <ePixmap position="420,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
-               <widget name="key_red" position="0,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
-               <widget name="key_green" position="140,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
-               <widget name="key_yellow" position="280,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
-               <widget name="key_blue" position="420,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+       skin = """<screen name="AutoTimerEditor" title="Edit AutoTimer" position="center,center" size="565,350">
+               <ePixmap position="0,5" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
+               <ePixmap position="140,5" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
+               <ePixmap position="280,5" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
+               <ePixmap position="420,5" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
+               <widget source="key_red" render="Label" position="0,5" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+               <widget source="key_green" render="Label" position="140,5" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+               <widget source="key_yellow" render="Label" position="280,5" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+               <widget source="key_blue" render="Label" position="420,5" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+               <widget name="config" position="5,50" size="555,225" scrollbarMode="showOnDemand" />
+               <ePixmap pixmap="skin_default/div-h.png" position="0,275" zPosition="1" size="565,2" />
+               <widget source="help" render="Label" position="5,280" size="555,63" font="Regular;21" />
        </screen>"""
 
        def __init__(self, session, timer, editingDefaults = False):
@@ -339,14 +383,19 @@ class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase):
                self.useDestination.addNotifier(self.reloadList, initial_call = False)
 
                self.refresh()
+               self.initHelpTexts()
 
-               ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
+               # XXX: no help for numericaltextinput since it is shown on top of our help
+               ConfigListScreen.__init__(self, self.list, on_change = self.changed)
+               self["config"].onSelectionChanged.append(self.updateHelp)
 
                # Initialize Buttons
-               self["key_red"] = Button(_("Cancel"))
-               self["key_green"] = Button(_("OK"))
-               self["key_yellow"] = Button()
-               self["key_blue"] = Button()
+               self["key_red"] = StaticText(_("Cancel"))
+               self["key_green"] = StaticText(_("OK"))
+               self["key_yellow"] = StaticText()
+               self["key_blue"] = StaticText()
+
+               self["help"] = StaticText()
 
                # Set Button texts
                self.renameServiceButton()
@@ -373,21 +422,26 @@ class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase):
 
        def renameFilterButton(self):
                if self.filterSet:
-                       self["key_yellow"].setText(_("Edit Filters"))
+                       self["key_yellow"].text = _("edit filters")
                else:
-                       self["key_yellow"].setText(_("Add Filters"))
+                       self["key_yellow"].text = _("add filters")
 
        def renameServiceButton(self):
                if self.serviceRestriction:
-                       self["key_blue"].setText(_("Edit Services"))
+                       self["key_blue"].text = _("edit services")
                else:
-                       self["key_blue"].setText(_("Add Services"))
+                       self["key_blue"].text = _("add services")
+
+       def updateHelp(self):
+               cur = self["config"].getCurrent()
+               if cur:
+                       self["help"].text = self.helpDict[cur[1]]
 
        def changed(self):
                for x in self.onChangedEntry:
                        try:
                                x()
-                       except:
+                       except Exception:
                                pass
 
        def getCurrentEntry(self):
@@ -399,72 +453,109 @@ class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase):
        def createSummary(self):
                return SetupSummary
 
+       def initHelpTexts(self):
+               self.helpDict = {
+                       self.enabled: _("Set this NO to disable this AutoTimer."),
+                       self.name: _("This is a name you can give the AutoTimer. It will be shown in the Overview and the Preview."),
+                       self.match: _("This is what will be looked for in event titles. Note that looking for e.g. german umlauts can be tricky as you have to know the encoding the channel uses."),
+                       self.encoding: _("Encoding the channel uses for it's EPG data. You only need to change this if you're searching for special characters like the german umlauts."),
+                       self.searchType: _("Select \"exact match\" to enforce \"Match title\" to match exactly or \"partial match\" if you only want to search for a part of the event title."),
+                       self.searchCase: _("Select whether or not you want to enforce case correctness."),
+                       self.justplay: _("Add zap timer instead of record timer?"),
+                       self.overrideAlternatives: _("With this option enabled the channel to record on can be changed to a alternative service it is restricted to."),
+                       self.timespan: _("Should this AutoTimer be restricted to a timespan?"),
+                       self.timespanbegin: _("Lower bound of timespan. Nothing before this time will be matched. Offsets are not taken into account!"),
+                       self.timespanend: _("Upper bound of timespan. Nothing after this time will be matched. Offsets are not taken into account!"),
+                       self.offset: _("Change default recording offset?"),
+                       self.offsetbegin: _("Time in minutes to prepend to recording."),
+                       self.offsetend: _("Time in minutes to append to recording."),
+                       self.duration: _("Should this AutoTimer only match up to a certain event duration?"),
+                       self.durationlength: _("Maximum event duration to match. If an event is longer than this ammount of time (without offset) it won't be matched."),
+                       self.afterevent: _("Power state to change to after recordings. Select \"standard\" to not change the default behavior of enigma2 or values changed by yourself."),
+                       self.afterevent_timespan: _("Restrict \"after event\" to a certain timespan?"),
+                       self.afterevent_timespanbegin: _("Lower bound of timespan."),
+                       self.afterevent_timespanend: _("Upper bound of timespan."),
+                       self.counter: _("With this option you can restrict the AutoTimer to a certain ammount of scheduled recordings. Set this to 0 to disable this functionality."),
+                       self.counterLeft: _("Number of scheduled recordings left."),
+                       self.counterFormatString: _("The counter can automatically be reset to the limit at certain intervals."),
+                       self.avoidDuplicateDescription: _("When this option is enabled the AutoTimer won't match events where another timer with the same description already exists in the timer list."),
+                       self.useDestination: _("Should timers created by this AutoTimer be recorded to a custom location?"),
+                       self.destination: _("Select the location to save the recording to."),
+                       self.tags: _("Tags the Timer/Recording will have."),
+               }
+
        def refresh(self):
                # First three entries are only showed when not editing defaults
-               self.list = []
+               list = []
                if not self.editingDefaults:
-                       self.list.extend([
+                       list.extend((
                                getConfigListEntry(_("Enabled"), self.enabled),
                                getConfigListEntry(_("Description"), self.name),
-                               getConfigListEntry(_("Match Title"), self.match),
-                       ])
-
-               self.list.extend([
-                       getConfigListEntry(_("Timer Type"), self.justplay),
-                       getConfigListEntry(_("Only match during Timespan"), self.timespan)
-               ])
+                               getConfigListEntry(_("Match title"), self.match),
+                       ))
+
+               list.extend((
+                       getConfigListEntry(_("EPG encoding"), self.encoding),
+                       getConfigListEntry(_("Search type"), self.searchType),
+                       getConfigListEntry(_("Search strictness"), self.searchCase),
+                       getConfigListEntry(_("Timer type"), self.justplay),
+                       getConfigListEntry(_("Override found with alternative service"), self.overrideAlternatives),
+                       getConfigListEntry(_("Only match during timespan"), self.timespan)
+               ))
 
                # Only allow editing timespan when it's enabled
                if self.timespan.value:
-                       self.list.extend([
-                               getConfigListEntry(_("Begin of Timespan"), self.timespanbegin),
-                               getConfigListEntry(_("End of Timespan"), self.timespanend)
-                       ])
+                       list.extend((
+                               getConfigListEntry(_("Begin of timespan"), self.timespanbegin),
+                               getConfigListEntry(_("End of timespan"), self.timespanend)
+                       ))
 
-               self.list.append(getConfigListEntry(_("Custom offset"), self.offset))
+               list.append(getConfigListEntry(_("Custom offset"), self.offset))
 
                # Only allow editing offsets when it's enabled
                if self.offset.value:
-                       self.list.extend([
+                       list.extend((
                                getConfigListEntry(_("Offset before recording (in m)"), self.offsetbegin),
                                getConfigListEntry(_("Offset after recording (in m)"), self.offsetend)
-                       ])
+                       ))
 
-               self.list.append(getConfigListEntry(_("Set maximum Duration"), self.duration))
+               list.append(getConfigListEntry(_("Set maximum duration"), self.duration))
 
                # Only allow editing maxduration when it's enabled
                if self.duration.value:
-                       self.list.append(getConfigListEntry(_("Maximum Duration (in m)"), self.durationlength))
+                       list.append(getConfigListEntry(_("Maximum duration (in m)"), self.durationlength))
 
-               self.list.append(getConfigListEntry(_("After event"), self.afterevent))
+               list.append(getConfigListEntry(_("After event"), self.afterevent))
 
                # Only allow setting afterevent timespan when afterevent is active
                if self.afterevent.value != "default":
-                       self.list.append(getConfigListEntry(_("Execute after Event during Timespan"), self.afterevent_timespan))
+                       list.append(getConfigListEntry(_("Execute \"after event\" during timespan"), self.afterevent_timespan))
 
                        # Only allow editing timespan when it's enabled
                        if self.afterevent_timespan.value:
-                               self.list.extend([
-                                       getConfigListEntry(_("Begin of after Event Timespan"), self.afterevent_timespanbegin),
-                                       getConfigListEntry(_("End of after Event Timespan"), self.afterevent_timespanend)
-                               ])
+                               list.extend((
+                                       getConfigListEntry(_("Begin of \"after event\" timespan"), self.afterevent_timespanbegin),
+                                       getConfigListEntry(_("End of \"after event\" timespan"), self.afterevent_timespanend)
+                               ))
 
-               self.list.append(getConfigListEntry(_("Record a maximum of x times"), self.counter))
+               list.append(getConfigListEntry(_("Record a maximum of x times"), self.counter))
 
                # Only allow setting matchLeft when counting hits
                if self.counter.value:
                        if not self.editingDefaults:
-                               self.list.append(getConfigListEntry(_("Ammount of recordings left"), self.counterLeft))
-                       self.list.append(getConfigListEntry(_("Reset Count"), self.counterFormatString))
+                               list.append(getConfigListEntry(_("Ammount of recordings left"), self.counterLeft))
+                       list.append(getConfigListEntry(_("Reset count"), self.counterFormatString))
 
-               self.list.append(getConfigListEntry(_("Require Description to be unique"), self.avoidDuplicateDescription))
+               list.append(getConfigListEntry(_("Require description to be unique"), self.avoidDuplicateDescription))
 
                # We always add this option though its expert only in enigma2
-               self.list.append(getConfigListEntry(_("Use a custom location"), self.useDestination))
+               list.append(getConfigListEntry(_("Use a custom location"), self.useDestination))
                if self.useDestination.value:
-                       self.list.append(getConfigListEntry(_("Custom Location"), self.destination))
+                       list.append(getConfigListEntry(_("Custom location"), self.destination))
+
+               list.append(getConfigListEntry(_("Tags"), self.tags))
 
-               self.list.append(getConfigListEntry(_("Tags"), self.tags))
+               self.list = list
 
        def reloadList(self, value):
                self.refresh()
@@ -502,6 +593,22 @@ class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase):
                        self.bouquets = ret[1][1]
                        self.renameServiceButton()
 
+       def keyLeft(self):
+               cur = self["config"].getCurrent()
+               cur = cur and cur[1]
+               if cur == self.tags:
+                       self.chooseTags()
+               else:
+                       ConfigListScreen.keyLeft(self)
+
+       def keyRight(self):
+               cur = self["config"].getCurrent()
+               cur = cur and cur[1]
+               if cur == self.tags:
+                       self.chooseTags()
+               else:
+                       ConfigListScreen.keyRight(self)
+
        def ok(self):
                cur = self["config"].getCurrent()
                cur = cur and cur[1]
@@ -563,6 +670,16 @@ class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase):
                # Name
                self.timer.name = self.name.value.strip() or self.timer.match
 
+               # Encoding
+               self.timer.encoding = self.encoding.value
+
+               # ...
+               self.timer.searchType = self.searchType.value
+               self.timer.searchCase = self.searchCase.value
+
+               # Alternatives
+               self.timer.overrideAlternatives = self.overrideAlternatives.value
+
                # Enabled
                self.timer.enabled = self.enabled.value
 
@@ -654,16 +771,16 @@ class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase):
 class AutoTimerFilterEditor(Screen, ConfigListScreen):
        """Edit AutoTimer Filter"""
 
-       skin = """<screen name="AutoFilterEditor" title="Edit AutoTimer Filters" position="75,150" size="565,245">
-               <widget name="config" position="5,5" size="555,200" scrollbarMode="showOnDemand" />
-               <ePixmap position="5,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
-               <ePixmap position="145,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
-               <ePixmap position="285,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
-               <ePixmap position="425,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
-               <widget name="key_red" position="5,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
-               <widget name="key_green" position="145,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
-               <widget name="key_yellow" position="285,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
-               <widget name="key_blue" position="425,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+       skin = """<screen name="AutoTimerFilterEditor" title="Edit AutoTimer Filters" position="center,center" size="565,280">
+               <ePixmap position="0,0" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
+               <ePixmap position="140,0" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
+               <ePixmap position="280,0" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
+               <ePixmap position="420,0" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
+               <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+               <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+               <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+               <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+               <widget name="config" position="5,45" size="555,225" scrollbarMode="showOnDemand" />
        </screen>"""
 
        def __init__(self, session, filterset, excludes, includes):
@@ -673,10 +790,15 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen):
                self.setup_title = _("AutoTimer Filters")
                self.onChangedEntry = []
 
-               self.typeSelection = ConfigSelection(choices = [("title", _("in Title")), ("short", _("in Shortdescription")), ("desc", _("in Description")), ("day", _("on Weekday"))])
+               self.typeSelection = NoSave(ConfigSelection(choices = [
+                       ("title", _("in Title")),
+                       ("short", _("in Shortdescription")),
+                       ("desc", _("in Description")),
+                       ("day", _("on Weekday"))]
+               ))
                self.typeSelection.addNotifier(self.refresh, initial_call = False)
 
-               self.enabled = ConfigEnableDisable(default = filterset)
+               self.enabled = NoSave(ConfigEnableDisable(default = filterset))
 
                self.excludes = excludes
                self.includes = includes
@@ -686,10 +808,10 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen):
                ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
 
                # Initialize Buttons
-               self["key_red"] = Button(_("Cancel"))
-               self["key_green"] = Button(_("Save"))
-               self["key_yellow"] = Button(_("delete"))
-               self["key_blue"] = Button(_("New"))
+               self["key_red"] = StaticText(_("Cancel"))
+               self["key_green"] = StaticText(_("Save"))
+               self["key_yellow"] = StaticText(_("delete"))
+               self["key_blue"] = StaticText(_("New"))
 
                # Define Actions
                self["actions"] = ActionMap(["SetupActions", "ColorActions"],
@@ -707,14 +829,14 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen):
                self.onLayoutFinish.append(self.setCustomTitle)
 
        def setCustomTitle(self):
-               self.setTitle(_("Edit AutoTimer Filters"))
+               self.setTitle(_("Edit AutoTimer filters"))
 
 
        def changed(self):
                for x in self.onChangedEntry:
                        try:
                                x()
-                       except:
+                       except Exception:
                                pass
 
        def getCurrentEntry(self):
@@ -760,12 +882,12 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen):
 
                        # Weekdays are presented as ConfigSelection
                        self.list.extend([
-                               getConfigListEntry(_("Exclude"), ConfigSelection(choices = weekdays, default = x))
+                               getConfigListEntry(_("Exclude"), NoSave(ConfigSelection(choices = weekdays, default = x)))
                                        for x in self.excludes[3]
                        ])
                        self.lenExcludes = len(self.list)
                        self.list.extend([
-                               getConfigListEntry(_("Include"), ConfigSelection(choices = weekdays, default = x))
+                               getConfigListEntry(_("Include"), NoSave(ConfigSelection(choices = weekdays, default = x)))
                                        for x in self.includes[3]
                        ])
                        return
@@ -777,12 +899,12 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen):
                        self.idx = 2
 
                self.list.extend([
-                       getConfigListEntry(_("Exclude"), ExtendedConfigText(default = x, fixed_size = False))
+                       getConfigListEntry(_("Exclude"), NoSave(ExtendedConfigText(default = x, fixed_size = False)))
                                for x in self.excludes[self.idx]
                ])
                self.lenExcludes = len(self.list)
                self.list.extend([
-                       getConfigListEntry(_("Include"), ExtendedConfigText(default = x, fixed_size = False))
+                       getConfigListEntry(_("Include"), NoSave(ExtendedConfigText(default = x, fixed_size = False)))
                                for x in self.includes[self.idx]
                ])
 
@@ -820,9 +942,9 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen):
                                text = ret[0]
 
                        if self.typeSelection.value == "day":
-                               entry = getConfigListEntry(text, ConfigSelection(choices = weekdays))
+                               entry = getConfigListEntry(text, NoSave(ConfigSelection(choices = weekdays)))
                        else:
-                               entry = getConfigListEntry(text, ExtendedConfigText(fixed_size = False))
+                               entry = getConfigListEntry(text, NoSave(ExtendedConfigText(fixed_size = False)))
 
                        list.insert(pos, entry)
                        self["config"].setList(list)
@@ -853,16 +975,16 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen):
 class AutoTimerServiceEditor(Screen, ConfigListScreen):
        """Edit allowed Services of a AutoTimer"""
 
-       skin = """<screen name="AutoTimerServiceEditor" title="Edit AutoTimer Services" position="75,150" size="565,245">
-               <widget name="config" position="5,5" size="555,200" scrollbarMode="showOnDemand" />
-               <ePixmap position="5,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
-               <ePixmap position="145,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
-               <ePixmap position="285,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
-               <ePixmap position="425,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
-               <widget name="key_red" position="5,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
-               <widget name="key_green" position="145,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
-               <widget name="key_yellow" position="285,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
-               <widget name="key_blue" position="425,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+       skin = """<screen name="AutoTimerServiceEditor" title="Edit AutoTimer Services" position="center,center" size="565,280">
+               <ePixmap position="0,0" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
+               <ePixmap position="140,0" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
+               <ePixmap position="280,0" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
+               <ePixmap position="420,0" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
+               <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+               <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+               <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+               <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+               <widget name="config" position="5,45" size="555,225" scrollbarMode="showOnDemand" />
        </screen>"""
 
        def __init__(self, session, servicerestriction, servicelist, bouquetlist):
@@ -877,8 +999,11 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen):
                        bouquetlist[:]
                )
 
-               self.enabled = ConfigEnableDisable(default = servicerestriction)
-               self.typeSelection = ConfigSelection(choices = [("channels", _("Channels")), ("bouquets", _("Bouquets"))])
+               self.enabled = NoSave(ConfigEnableDisable(default = servicerestriction))
+               self.typeSelection = NoSave(ConfigSelection(choices = [
+                       ("channels", _("Channels")),
+                       ("bouquets", _("Bouquets"))]
+               ))
                self.typeSelection.addNotifier(self.refresh, initial_call = False)
 
                self.reloadList()
@@ -886,10 +1011,10 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen):
                ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
 
                # Initialize Buttons
-               self["key_red"] = Button(_("Cancel"))
-               self["key_green"] = Button(_("OK"))
-               self["key_yellow"] = Button(_("delete"))
-               self["key_blue"] = Button(_("New"))
+               self["key_red"] = StaticText(_("Cancel"))
+               self["key_green"] = StaticText(_("OK"))
+               self["key_yellow"] = StaticText(_("delete"))
+               self["key_blue"] = StaticText(_("New"))
 
                # Define Actions
                self["actions"] = ActionMap(["SetupActions", "ColorActions"],
@@ -907,11 +1032,11 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen):
                self.onLayoutFinish.append(self.setCustomTitle)
 
        def setCustomTitle(self):
-               self.setTitle(_("Edit AutoTimer Services"))
+               self.setTitle(_("Edit AutoTimer services"))
 
        def saveCurrent(self):
                del self.services[self.idx][:]
-               
+
                # Warning, accessing a ConfigListEntry directly might be considered evil!
 
                myl = self["config"].getList()[:]
@@ -931,14 +1056,14 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen):
                        getConfigListEntry(_("Enable Service Restriction"), self.enabled),
                        getConfigListEntry(_("Editing"), self.typeSelection)
                ]
-               
+
                if self.typeSelection.value == "channels":
                        self.idx = 0
                else: # self.typeSelection.value == "bouquets":
                        self.idx = 1
 
                self.list.extend([
-                       getConfigListEntry(_("Record on"), ConfigSelection(choices = [(str(x), ServiceReference(str(x)).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))]))
+                       getConfigListEntry(_("Record on"), NoSave(ConfigSelection(choices = [(str(x), ServiceReference(str(x)).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))])))
                                for x in self.services[self.idx]
                ])
 
@@ -946,7 +1071,7 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen):
                for x in self.onChangedEntry:
                        try:
                                x()
-                       except:
+                       except Exception:
                                pass
 
        def getCurrentEntry(self):
@@ -979,17 +1104,19 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen):
                        )
 
        def finishedServiceSelection(self, *args):
-               if len(args):
+               if args:
                        list = self["config"].getList()
                        sname = args[0].toString()
 
-                       if self.typeSelection.value == "channels":
-                               # strip all after last : when adding a channel
+                       if self.typeSelection.value == "channels" and not (args[0].flags & eServiceReference.isGroup):
+                               # strip all after last : when adding a (non alternative) channel
                                pos = sname.rfind(':')
                                if pos != -1:
+                                       if sname[pos-1] == ':':
+                                               pos -= 1
                                        sname = sname[:pos+1]
 
-                       list.append(getConfigListEntry(_("Record on"), ConfigSelection(choices = [(sname, ServiceReference(args[0]).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))])))
+                       list.append(getConfigListEntry(_("Record on"), NoSave(ConfigSelection(choices = [(sname, ServiceReference(args[0]).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))]))))
                        self["config"].setList(list)
 
        def cancel(self):
@@ -1014,11 +1141,42 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen):
                        self.services
                ))
 
+def addAutotimerFromSearchString(session, match):
+       from AutoTimerComponent import preferredAutoTimerComponent
+       from AutoTimerImporter import AutoTimerImporter
+       from plugin import autotimer
+
+       # Create instance if needed
+       if autotimer is None:
+               from AutoTimer import AutoTimer
+               autotimer = AutoTimer()
+               autotimer.readXml()
+
+       session.openWithCallback(
+               importerCallback,
+               AutoTimerImporter,
+               preferredAutoTimerComponent(
+                       autotimer.getUniqueId(),
+                       match,
+                       '',             # Match
+                       True    # Enabled
+               ),
+               match,          # Proposed Match
+               None,           # Proposed Begin
+               None,           # Proposed End
+               None,           # Proposed Disabled
+               None,           # Proposed ServiceReference
+               None,           # Proposed afterEvent
+               None,           # Proposed justplay
+               None,           # Proposed dirname, can we get anything useful here?
+               []                      # Proposed tags
+       )
+
 def addAutotimerFromEvent(session, evt = None, service = None):
-       from AutoTimerComponent import AutoTimerComponent
+       from AutoTimerComponent import preferredAutoTimerComponent
        from AutoTimerImporter import AutoTimerImporter
        from plugin import autotimer
-               
+
        # Create instance if needed
        if autotimer is None:
                from AutoTimer import AutoTimer
@@ -1030,12 +1188,16 @@ def addAutotimerFromEvent(session, evt = None, service = None):
        sref = None
        if service is not None:
                service = str(service)
-               # strip all after last :
-               pos = service.rfind(':')
-               if pos != -1:
-                       service = service[:pos+1]
-
-               sref = ServiceReference(service)
+               myref = eServiceReference(service)
+               if not (myref.flags & eServiceReference.isGroup):
+                       # strip all after last :
+                       pos = service.rfind(':')
+                       if pos != -1:
+                               if service[pos-1] == ':':
+                                       pos -= 1
+                               service = service[:pos+1]
+
+               sref = ServiceReference(myref)
        if evt:
                # timespan defaults to +- 1h
                begin = evt.getBeginTime()-3600
@@ -1048,28 +1210,28 @@ def addAutotimerFromEvent(session, evt = None, service = None):
        session.openWithCallback(
                importerCallback,
                AutoTimerImporter,
-               AutoTimerComponent(
-                       autotimer.getUniqueId(),                # Id
-                       name,                                                   # Name
-                       "",                                                             # Match
-                       True                                                    # Enabled
+               preferredAutoTimerComponent(
+                       autotimer.getUniqueId(),
+                       name,
+                       '',             # Match
+                       True    # Enabled
                ),
-               match,                     # Proposed Match
-               begin,                     # Proposed Begin
-               end,                       # Proposed End
-               None,                      # Proposed Disabled
-               sref,                      # Proposed ServiceReference
-               None,                  # Proposed afterEvent
-               None,                      # Proposed justplay
-               None,                      # Proposed dirname, can we get anything useful here?
-               []                 #
+               match,          # Proposed Match
+               begin,          # Proposed Begin
+               end,            # Proposed End
+               None,           # Proposed Disabled
+               sref,           # Proposed ServiceReference
+               None,           # Proposed afterEvent
+               None,           # Proposed justplay
+               None,           # Proposed dirname, can we get anything useful here?
+               []                      # Proposed tags
        )
 
-def addAutotimerFromService(session, service = None):  
-       from AutoTimerComponent import AutoTimerComponent
+def addAutotimerFromService(session, service = None):
+       from AutoTimerComponent import preferredAutoTimerComponent
        from AutoTimerImporter import AutoTimerImporter
        from plugin import autotimer
-               
+
        # Create instance if needed
        if autotimer is None:
                from AutoTimer import AutoTimer
@@ -1086,6 +1248,8 @@ def addAutotimerFromService(session, service = None):
                # strip all after last :
                pos = sref.rfind(':')
                if pos != -1:
+                       if sref[pos-1] == ':':
+                               pos -= 1
                        sref = sref[:pos+1]
 
                sref = ServiceReference(sref)
@@ -1108,27 +1272,27 @@ def addAutotimerFromService(session, service = None):
        session.openWithCallback(
                importerCallback,
                AutoTimerImporter,
-               AutoTimerComponent(
-                       autotimer.getUniqueId(),                # Id
-                       name,                                                   # Name
-                       "",                                                             # Match
-                       True                                                    # Enabled
+               preferredAutoTimerComponent(
+                       autotimer.getUniqueId(),
+                       name,
+                       '',             # Match
+                       True    # Enabled
                ),
-               match,                     # Proposed Match
-               begin,                     # Proposed Begin
-               end,                       # Proposed End
-               None,                      # Proposed Disabled
-               sref,                      # Proposed ServiceReference
-               None,                  # Proposed afterEvent
-               None,                      # Proposed justplay
-               path,                      # Proposed dirname
-               tags               # Proposed tags
+               match,          # Proposed Match
+               begin,          # Proposed Begin
+               end,            # Proposed End
+               None,           # Proposed Disabled
+               sref,           # Proposed ServiceReference
+               None,           # Proposed afterEvent
+               None,           # Proposed justplay
+               path,           # Proposed dirname
+               tags            # Proposed tags
        )
 
 def importerCallback(ret):
        if ret:
                ret, session = ret
-               
+
                session.openWithCallback(
                        editorCallback,
                        AutoTimerEditor,
@@ -1143,7 +1307,7 @@ def importerCallback(ret):
 def editorCallback(ret):
        if ret:
                from plugin import autotimer
-               
+
                # Create instance if needed (should have been created by addAutotimerFrom* above though)
                if autotimer is None:
                        from AutoTimer import AutoTimer