cleanup
[vuplus_dvbapp-plugin] / autotimer / src / AutoTimerEditor.py
index 807f319..611650c 100644 (file)
@@ -1,7 +1,12 @@
+# -*- coding: UTF-8 -*-
+# for localized messages
+from . import _
+
 # GUI (Screens)
 from Screens.Screen import Screen
 from Components.ConfigList import ConfigListScreen
 from Screens.ChannelSelection import SimpleChannelSelection
+from Screens.EpgSelection import EPGSelection
 from Screens.MessageBox import MessageBox
 from Screens.ChoiceBox import ChoiceBox
 
@@ -14,7 +19,8 @@ from Components.Button import Button
 
 # Configuration
 from Components.config import getConfigListEntry, ConfigEnableDisable, \
-       ConfigYesNo, ConfigText, ConfigClock, ConfigInteger, ConfigSelection
+       ConfigYesNo, ConfigText, ConfigClock, ConfigNumber, ConfigSelection, \
+       config, NoSave
 
 # Timer
 from RecordTimer import AFTEREVENT
@@ -25,6 +31,15 @@ from time import localtime, mktime
 # Show ServiceName instead of ServiceReference
 from ServiceReference import ServiceReference
 
+# addAutotimerFromService, AutoTimerChannelSelection
+from enigma import eServiceCenter, eServiceReference, iServiceInformation
+
+# Default Record Directory
+from Tools import Directories
+
+# Tags
+from Screens.MovieSelection import getPreferredTagEditor
+
 weekdays = [
        ("0", _("Monday")),
        ("1", _("Tuesday")),
@@ -37,12 +52,26 @@ weekdays = [
        ("weekday", _("Weekday"))
 ]
 
+class ExtendedConfigText(ConfigText):
+       def __init__(self, default = "", fixed_size = True, visible_width = False):
+               ConfigText.__init__(self, default = default, fixed_size = fixed_size, visible_width = visible_width)
+
+               # Workaround some characters currently not "typeable" using NumericalTextInput
+               mapping = self.mapping
+               if mapping:
+                       if "&" not in mapping[0]:
+                               mapping[0] += "&"
+                       if ";" not in mapping[0]:
+                               mapping[0] += ";"
+                       if "%" not in mapping[0]:
+                               mapping[0] += "%"
+
 class SimpleBouquetSelection(SimpleChannelSelection):
        def __init__(self, session, title):
                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)
@@ -51,135 +80,111 @@ class SimpleBouquetSelection(SimpleChannelSelection):
                        # Asking the user if this is what he wants might be better though
                        self.close(self.servicePath[-1])
 
-class AutoTimerEditor(Screen, ConfigListScreen):
-       """Edit AutoTimer"""
+class AutoTimerChannelSelection(SimpleChannelSelection):
+       def __init__(self, session, autotimer):
+               SimpleChannelSelection.__init__(self, session, _("Channel Selection"))
+               self.skinName = "SimpleChannelSelection"
+               self.autotimer = 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/key-red.png" transparent="1" alphatest="on" />
-               <ePixmap position="140,235" zPosition="4" size="140,40" pixmap="skin_default/key-green.png" transparent="1" alphatest="on" />
-               <ePixmap position="280,235" zPosition="4" size="140,40" pixmap="skin_default/key-yellow.png" transparent="1" alphatest="on" />
-               <ePixmap position="420,235" zPosition="4" size="140,40" pixmap="skin_default/key-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" />
-       </screen>"""
+               self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
+                       {
+                               "showEPGList": self.channelSelected
+                       }
+               )
 
-       def __init__(self, session, timer):
-               Screen.__init__(self, session)
+       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)
+               self.skinName = "EPGSelection"
+
+       def infoKeyPressed(self):
+               self.timerAdd()
+
+       def timerAdd(self):
+               cur = self["list"].getCurrent()
+               evt = cur[0]
+               sref = cur[1]
+               if not evt:
+                       return
+
+               addAutotimerFromEvent(self.session, evt = evt, service = sref)
+
+       def onSelectionChanged(self):
+               pass
 
+class AutoTimerEditorBase:
+       """ Base Class for all Editors """
+       def __init__(self, timer, editingDefaults = False):
                # Keep Timer
                self.timer = timer
-
-               # Summary
-               self.setup_title = "AutoTimer Editor"
-               self.onChangedEntry = []
+               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.getServices()
-               self.bouquets = timer.getBouquets()
-               if len(self.services) or len(self.bouquets):
+               self.services = timer.services
+               self.bouquets = timer.bouquets
+               if self.services or self.bouquets:
                        self.serviceRestriction = True
                else:
                        self.serviceRestriction = False
 
                self.createSetup(timer)
 
-               # We might need to change shown items, so add some notifiers
-               self.timespan.addNotifier(self.reloadList, initial_call = False)
-               self.offset.addNotifier(self.reloadList, initial_call = False)
-               self.duration.addNotifier(self.reloadList, initial_call = False)
-               self.afterevent.addNotifier(self.reloadList, initial_call = False)
-               self.afterevent_timespan.addNotifier(self.reloadList, initial_call = False)
-               self.counter.addNotifier(self.reloadList, initial_call = False)
-
-               self.refresh()
-
-               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()
-               self["key_blue"] = Button()
-
-               # Set Button texts
-               self.renameServiceButton()
-               self.renameFilterButton()
-
-               # Define Actions
-               self["actions"] = ActionMap(["SetupActions", "ColorActions"],
-                       {
-                               "cancel": self.cancel,
-                               "save": self.maybeSave,
-                               "ok": self.ok,
-                               "yellow": self.editFilter,
-                               "blue": self.editServices
-                       }, -2
-               )
-
-               # Trigger change
-               self.changed()
-
-       def renameFilterButton(self):
-               if self.filterSet:
-                       self["key_yellow"].setText(_("Edit Filters"))
-               else:
-                       self["key_yellow"].setText(_("Add Filters"))
-
-       def renameServiceButton(self):
-               if self.serviceRestriction:
-                       self["key_blue"].setText(_("Edit Services"))
-               else:
-                       self["key_blue"].setText(_("Add Services"))
-
-       def changed(self):
-               for x in self.onChangedEntry:
-                       try:
-                               x()
-                       except:
-                               pass
-
-       def getCurrentEntry(self):
-               return self["config"].getCurrent()[0]
-
-       def getCurrentValue(self):
-               return str(self["config"].getCurrent()[1].getText())
-
-       def createSummary(self):
-               return SetupSummary
-
        def createSetup(self, timer):
                # Name
-               self.name = ConfigText(default = timer.name, fixed_size = False)
+               self.name = NoSave(ExtendedConfigText(default = timer.name, fixed_size = False))
 
                # Match
-               self.match = ConfigText(default = timer.match, fixed_size = False)
+               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()]
@@ -199,9 +204,9 @@ class AutoTimerEditor(Screen, ConfigListScreen):
                        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
 
@@ -214,16 +219,26 @@ class AutoTimerEditor(Screen, ConfigListScreen):
                        default = False
                        begin = 5
                        end = 5
-               self.offset = ConfigEnableDisable(default = default)
-               self.offsetbegin = ConfigInteger(default = begin, limits = (0, 180))
-               self.offsetend = ConfigInteger(default = end, limits = (0, 180))
+               self.offset = NoSave(ConfigEnableDisable(default = default))
+               self.offsetbegin = NoSave(ConfigNumber(default = begin))
+               self.offsetend = NoSave(ConfigNumber(default = end))
 
                # AfterEvent
                if timer.hasAfterEvent():
-                       afterevent = { None: "default", AFTEREVENT.NONE: "nothing", AFTEREVENT.DEEPSTANDBY: "deepstandby", AFTEREVENT.STANDBY: "standby"}[timer.afterevent[0][0]]
+                       default = {
+                               None: "default",
+                               AFTEREVENT.NONE: "nothing",
+                               AFTEREVENT.DEEPSTANDBY: "deepstandby",
+                               AFTEREVENT.STANDBY: "standby",
+                               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"))], 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:
@@ -242,12 +257,12 @@ class AutoTimerEditor(Screen, ConfigListScreen):
                        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():
@@ -256,85 +271,248 @@ class AutoTimerEditor(Screen, ConfigListScreen):
                else:
                        default = False
                        duration =70
-               self.duration = ConfigEnableDisable(default = default)
-               self.durationlength = ConfigInteger(default = duration, limits = (0, 600))
+               self.duration = NoSave(ConfigEnableDisable(default = default))
+               self.durationlength = NoSave(ConfigNumber(default = duration))
 
                # Counter
                if timer.hasCounter():
                        default = timer.matchCount
                else:
                        default = 0
-               self.counter = ConfigInteger(default = default, limits = (0, 50))
-               self.counterLeft = ConfigInteger(default = timer.matchLeft, limits = (0, 50))
+               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 = ConfigEnableDisable(default = timer.getAvoidDuplicateDescription())
+               self.avoidDuplicateDescription = NoSave(ConfigSelection([
+                               ("0", _("No")),
+                               ("1", _("On same service")),
+                               ("2", _("On any service")),
+                       ],
+                       default = str(timer.getAvoidDuplicateDescription())
+               ))
 
                # Custom Location
-               self.destination = ConfigSelection(choices = [timer.destination or "/hdd/movie"])
+               if timer.hasDestination():
+                       default = True
+               else:
+                       default = False
+
+               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 = NoSave(ConfigSelection(default = default, choices = choices))
+
+               # Tags
+               self.timerentry_tags = timer.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:
+                       # 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):
+               from Screens.LocationBox import MovieLocationBox
+
+               self.session.openWithCallback(
+                       self.pathSelected,
+                       MovieLocationBox,
+                       _("Choose target folder"),
+                       self.destination.value,
+                       minFree = 100 # Same requirement as in Screens.TimerEntry
+               )
+
+       def tagEditFinished(self, ret):
+               if ret is not None:
+                       self.timerentry_tags = ret
+                       self.tags.setChoices([len(ret) == 0 and _("None") or ' '.join(ret)])
+
+       def chooseTags(self):
+               preferredTagEditor = getPreferredTagEditor()
+               if preferredTagEditor:
+                       self.session.openWithCallback(
+                               self.tagEditFinished,
+                               preferredTagEditor,
+                               self.timerentry_tags
+                       )
+
+class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase):
+       """Edit AutoTimer"""
+
+       skin = """<screen name="AutoTimerEditor" 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" />
+       </screen>"""
+
+       def __init__(self, session, timer, editingDefaults = False):
+               Screen.__init__(self, session)
+
+               AutoTimerEditorBase.__init__(self, timer, editingDefaults)
+
+               # Summary
+               self.setup_title = _("AutoTimer Editor")
+               self.onChangedEntry = []
+
+               # We might need to change shown items, so add some notifiers
+               self.timespan.addNotifier(self.reloadList, initial_call = False)
+               self.offset.addNotifier(self.reloadList, initial_call = False)
+               self.duration.addNotifier(self.reloadList, initial_call = False)
+               self.afterevent.addNotifier(self.reloadList, initial_call = False)
+               self.afterevent_timespan.addNotifier(self.reloadList, initial_call = False)
+               self.counter.addNotifier(self.reloadList, initial_call = False)
+               self.useDestination.addNotifier(self.reloadList, initial_call = False)
+
+               self.refresh()
+
+               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()
+               self["key_blue"] = Button()
+
+               # Set Button texts
+               self.renameServiceButton()
+               self.renameFilterButton()
+
+               # Define Actions
+               self["actions"] = ActionMap(["SetupActions", "ColorActions"],
+                       {
+                               "cancel": self.cancel,
+                               "save": self.maybeSave,
+                               "ok": self.ok,
+                               "yellow": self.editFilter,
+                               "blue": self.editServices
+                       }, -2
+               )
+
+               # Trigger change
+               self.changed()
+
+               self.onLayoutFinish.append(self.setCustomTitle)
+
+       def setCustomTitle(self):
+               self.setTitle(_("Edit AutoTimer"))
+
+       def renameFilterButton(self):
+               if self.filterSet:
+                       self["key_yellow"].setText(_("Edit Filters"))
+               else:
+                       self["key_yellow"].setText(_("Add Filters"))
+
+       def renameServiceButton(self):
+               if self.serviceRestriction:
+                       self["key_blue"].setText(_("Edit Services"))
+               else:
+                       self["key_blue"].setText(_("Add Services"))
+
+       def changed(self):
+               for x in self.onChangedEntry:
+                       try:
+                               x()
+                       except Exception:
+                               pass
+
+       def getCurrentEntry(self):
+               return self["config"].getCurrent()[0]
+
+       def getCurrentValue(self):
+               return str(self["config"].getCurrent()[1].getText())
+
+       def createSummary(self):
+               return SetupSummary
 
        def refresh(self):
-               # First four entries are always shown
-               self.list = [
-                       getConfigListEntry(_("Enabled"), self.enabled),
-                       getConfigListEntry(_("Description"), self.name),
-                       getConfigListEntry(_("Match Title"), self.match),
+               # First three entries are only showed when not editing defaults
+               list = []
+               if not self.editingDefaults:
+                       list.extend((
+                               getConfigListEntry(_("Enabled"), self.enabled),
+                               getConfigListEntry(_("Description"), self.name),
+                               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([
+                       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.extend([
-                               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([
+                               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:
-                       self.list.append(getConfigListEntry(_("Ammount of recordings left"), self.counterLeft))
-                       self.list.append(getConfigListEntry(_("Reset Count"), self.counterFormatString))
+                       if not self.editingDefaults:
+                               list.append(getConfigListEntry(_("Ammount of recordings left"), self.counterLeft))
+                       list.append(getConfigListEntry(_("Reset Count"), self.counterFormatString))
+
+               list.append(getConfigListEntry(_("Require Description to be unique"), self.avoidDuplicateDescription))
 
-               self.list.append(getConfigListEntry(_("Require Description to be unique"), self.avoidDuplicateDescription))
+               # We always add this option though its expert only in enigma2
+               list.append(getConfigListEntry(_("Use a custom location"), self.useDestination))
+               if self.useDestination.value:
+                       list.append(getConfigListEntry(_("Custom Location"), self.destination))
 
-               # We always add this option though its actually expert only
-               self.list.append(getConfigListEntry(_("Custom Location"), self.destination))
+               list.append(getConfigListEntry(_("Tags"), self.tags))
+
+               self.list = list
 
        def reloadList(self, value):
                self.refresh()
@@ -372,25 +550,31 @@ class AutoTimerEditor(Screen, ConfigListScreen):
                        self.bouquets = ret[1][1]
                        self.renameServiceButton()
 
-       def ok(self):
+       def keyLeft(self):
                cur = self["config"].getCurrent()
                cur = cur and cur[1]
-               if cur == self.destination:
-                       from Screens.LocationBox import LocationBox
+               if cur == self.tags:
+                       self.chooseTags()
+               else:
+                       ConfigListScreen.keyLeft(self)
 
-                       self.session.openWithCallback(
-                               self.pathSelected,
-                               LocationBox,
-                               text = _("Choose target folder"),
-                               filename = "",
-                               currDir = self.destination.value
-                       )
+       def keyRight(self):
+               cur = self["config"].getCurrent()
+               cur = cur and cur[1]
+               if cur == self.tags:
+                       self.chooseTags()
+               else:
+                       ConfigListScreen.keyRight(self)
 
-       def pathSelected(self, res):
-               if res is not None:
-                       self.destination.choices.append(res)
-                       self.destination.description[res] = res
-                       self.destination.value = res
+       def ok(self):
+               cur = self["config"].getCurrent()
+               cur = cur and cur[1]
+               if cur == self.destination:
+                       self.chooseDestination()
+               elif cur == self.tags:
+                       self.chooseTags()
+               else:
+                       ConfigListScreen.keyOK(self)
 
        def cancel(self):
                if self["config"].isChanged():
@@ -407,8 +591,19 @@ class AutoTimerEditor(Screen, ConfigListScreen):
                        self.close(None)
 
        def maybeSave(self):
+               if self.editingDefaults:
+                       self.save()
+                       return
+               # Check if any match is set
+               if not self.match.value.strip():
+                       self.session.open(
+                                       MessageBox,
+                                       _("The match attribute is mandatory."),
+                                       type = MessageBox.TYPE_ERROR,
+                                       timeout = 5
+                       )
                # Check if we have a trailing whitespace
-               if self.match.value[-1:] == " ":
+               elif self.match.value[-1:] == " ":
                        self.session.openWithCallback(
                                self.saveCallback,
                                MessageBox,
@@ -430,7 +625,17 @@ class AutoTimerEditor(Screen, ConfigListScreen):
                self.timer.match = self.match.value
 
                # Name
-               self.timer.name = self.name.value or self.timer.match
+               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
@@ -464,7 +669,12 @@ class AutoTimerEditor(Screen, ConfigListScreen):
                if self.afterevent.value == "default":
                        self.timer.afterevent = []
                else:
-                       afterevent = {"nothing": AFTEREVENT.NONE, "deepstandby": AFTEREVENT.DEEPSTANDBY, "standby": AFTEREVENT.STANDBY}[self.afterevent.value]
+                       afterevent = {
+                               "nothing": AFTEREVENT.NONE,
+                               "deepstandby": AFTEREVENT.DEEPSTANDBY,
+                               "standby": AFTEREVENT.STANDBY,
+                               "auto": AFTEREVENT.AUTO
+                       }[self.afterevent.value]
                        # AfterEvent Timespan
                        if self.afterevent_timespan.value:
                                start = self.afterevent_timespanbegin.value
@@ -503,8 +713,14 @@ class AutoTimerEditor(Screen, ConfigListScreen):
                        self.timer.matchLeft = 0
                        self.timer.matchFormatString = ''
 
-               self.timer.avoidDuplicateDescription = self.avoidDuplicateDescription.value
-               self.timer.destination = self.destination.value
+               self.timer.avoidDuplicateDescription = int(self.avoidDuplicateDescription.value)
+
+               if self.useDestination.value:
+                       self.timer.destination = self.destination.value
+               else:
+                       self.timer.destination = None
+
+               self.timer.tags = self.timerentry_tags
 
                # Close
                self.close(self.timer)
@@ -512,12 +728,12 @@ class AutoTimerEditor(Screen, ConfigListScreen):
 class AutoTimerFilterEditor(Screen, ConfigListScreen):
        """Edit AutoTimer Filter"""
 
-       skin = """<screen name="AutoFilterEditor" title="Edit AutoTimer Filters" position="75,150" size="565,245">
+       skin = """<screen name="AutoTimerFilterEditor" 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/key-red.png" transparent="1" alphatest="on" />
-               <ePixmap position="145,205" zPosition="4" size="140,40" pixmap="skin_default/key-green.png" transparent="1" alphatest="on" />
-               <ePixmap position="285,205" zPosition="4" size="140,40" pixmap="skin_default/key-yellow.png" transparent="1" alphatest="on" />
-               <ePixmap position="425,205" zPosition="4" size="140,40" pixmap="skin_default/key-blue.png" transparent="1" alphatest="on" />
+               <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" />
@@ -528,13 +744,18 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen):
                Screen.__init__(self, session)
 
                # Summary
-               self.setup_title = "AutoTimer Filters"
+               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
@@ -562,11 +783,17 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen):
                # Trigger change
                self.changed()
 
+               self.onLayoutFinish.append(self.setCustomTitle)
+
+       def setCustomTitle(self):
+               self.setTitle(_("Edit AutoTimer Filters"))
+
+
        def changed(self):
                for x in self.onChangedEntry:
                        try:
                                x()
-                       except:
+                       except Exception:
                                pass
 
        def getCurrentEntry(self):
@@ -585,7 +812,7 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen):
                # Warning, accessing a ConfigListEntry directly might be considered evil!
 
                idx = -1
-               for item in self["config"].getList():
+               for item in self["config"].getList()[:]:
                        idx += 1
                        # Skip empty entries (and those which are no filters)
                        if item[1].value == "" or idx < 2:
@@ -595,7 +822,7 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen):
                        else:
                                self.includes[self.idx].append(item[1].value.encode("UTF-8"))
 
-       def refresh(self, value):
+       def refresh(self, *args, **kwargs):
                self.saveCurrent()
 
                self.reloadList()
@@ -612,12 +839,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
@@ -629,12 +856,12 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen):
                        self.idx = 2
 
                self.list.extend([
-                       getConfigListEntry(_("Exclude"), ConfigText(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"), ConfigText(default = x, fixed_size = False))
+                       getConfigListEntry(_("Include"), NoSave(ExtendedConfigText(default = x, fixed_size = False)))
                                for x in self.includes[self.idx]
                ])
 
@@ -672,9 +899,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, ConfigText(fixed_size = False))
+                               entry = getConfigListEntry(text, NoSave(ExtendedConfigText(fixed_size = False)))
 
                        list.insert(pos, entry)
                        self["config"].setList(list)
@@ -694,7 +921,7 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen):
                        self.close(None)
 
        def save(self):
-               self.saveCurrent()
+               self.refresh()
 
                self.close((
                        self.enabled.value,
@@ -707,10 +934,10 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen):
 
        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/key-red.png" transparent="1" alphatest="on" />
-               <ePixmap position="145,205" zPosition="4" size="140,40" pixmap="skin_default/key-green.png" transparent="1" alphatest="on" />
-               <ePixmap position="285,205" zPosition="4" size="140,40" pixmap="skin_default/key-yellow.png" transparent="1" alphatest="on" />
-               <ePixmap position="425,205" zPosition="4" size="140,40" pixmap="skin_default/key-blue.png" transparent="1" alphatest="on" />
+               <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" />
@@ -721,7 +948,7 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen):
                Screen.__init__(self, session)
 
                # Summary
-               self.setup_title = "AutoTimer Services"
+               self.setup_title = _("AutoTimer Services")
                self.onChangedEntry = []
 
                self.services = (
@@ -729,8 +956,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()
@@ -756,19 +986,23 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen):
                # Trigger change
                self.changed()
 
-       
+               self.onLayoutFinish.append(self.setCustomTitle)
+
+       def setCustomTitle(self):
+               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()
+               myl = self["config"].getList()[:]
                myl.pop(0) # Enabled
                myl.pop(0) # Type
                for item in myl:
                        self.services[self.idx].append(item[1].value)
 
-       def refresh(self, value):
+       def refresh(self, *args, **kwargs):
                self.saveCurrent()
 
                self.reloadList()
@@ -779,14 +1013,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]
                ])
 
@@ -794,7 +1028,7 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen):
                for x in self.onChangedEntry:
                        try:
                                x()
-                       except:
+                       except Exception:
                                pass
 
        def getCurrentEntry(self):
@@ -827,17 +1061,17 @@ 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:
                                        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):
@@ -855,60 +1089,188 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen):
                        self.close(None)
 
        def save(self):
-               self.saveCurrent()
+               self.refresh()
 
                self.close((
                        self.enabled.value,
                        self.services
                ))
 
+def addAutotimerFromSearchString(session, match):
+       from AutoTimerComponent import AutoTimerComponent
+       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,
+               AutoTimerComponent(
+                       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 AutoTimerImporter import AutoTimerImporter
+       from plugin import autotimer
+
+       # Create instance if needed
+       if autotimer is None:
+               from AutoTimer import AutoTimer
+               autotimer = AutoTimer()
+               autotimer.readXml()
 
-       name = evt and evt.getEventName() or "New AutoTimer"
        match = evt and evt.getEventName() or ""
-       servicelist = []
+       name = match or "New AutoTimer"
+       sref = None
        if service is not None:
                service = str(service)
+               myref = eServiceReference(service)
+               if not (myref.flags & eServiceReference.isGroup):
+                       # strip all after last :
+                       pos = service.rfind(':')
+                       if pos != -1:
+                               service = service[:pos+1]
+
+               sref = ServiceReference(myref)
+       if evt:
+               # timespan defaults to +- 1h
+               begin = evt.getBeginTime()-3600
+               end = begin + evt.getDuration()+7200
+       else:
+               begin = end = 0
+
+       # XXX: we might want to make sure that we actually collected any data because the importer does not do so :-)
+
+       session.openWithCallback(
+               importerCallback,
+               AutoTimerImporter,
+               AutoTimerComponent(
+                       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?
+               []                      # Proposed tags
+       )
+
+def addAutotimerFromService(session, service = None):
+       from AutoTimerComponent import AutoTimerComponent
+       from AutoTimerImporter import AutoTimerImporter
+       from plugin import autotimer
+
+       # Create instance if needed
+       if autotimer is None:
+               from AutoTimer import AutoTimer
+               autotimer = AutoTimer()
+               autotimer.readXml()
+
+       serviceHandler = eServiceCenter.getInstance()
+       info = serviceHandler.info(service)
+
+       match = info and info.getName(service) or ""
+       name = match or "New AutoTimer"
+       sref = info and info.getInfoString(service, iServiceInformation.sServiceref)
+       if sref:
                # strip all after last :
-               pos = service.rfind(':')
+               pos = sref.rfind(':')
                if pos != -1:
-                       service = service[:pos+1]
+                       sref = sref[:pos+1]
 
-               servicelist.append(service)
-       if evt:
-               begin = evt.getBeginTime()
-               end = begin + evt.getDuration()
-               timetuple = (begin-3600, end+3600) # timespan defaults to +- 1h
+               sref = ServiceReference(sref)
+       if info:
+               begin = info.getInfo(service, iServiceInformation.sTimeCreate)
+               end = begin + info.getLength(service)
        else:
-               timetuple = None
+               begin = end = 0
+
+       from os.path import dirname
+       path = dirname(service.getPath())
+       if not path == '/':
+               path += '/'
+
+       tags = info.getInfoString(service, iServiceInformation.sTags)
+       tags = tags and tags.split(' ') or []
+
+       # XXX: we might want to make sure that we actually collected any data because the importer does not do so :-)
 
        session.openWithCallback(
-               addCallback,
-               AutoTimerEditor,
+               importerCallback,
+               AutoTimerImporter,
                AutoTimerComponent(
-                       self.autotimer.getUniqueId(),   # Id
-                       name,                                                   # Name
-                       match,                                                  # Match
-                       True,                                                   # Enabled
-                       timespan = timetuple,
-                       services = servicelist
-               )
+                       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
        )
 
-def addCallback(ret):
+def importerCallback(ret):
+       if ret:
+               ret, session = ret
+
+               session.openWithCallback(
+                       editorCallback,
+                       AutoTimerEditor,
+                       ret
+               )
+       else:
+               # Remove instance if not running in background
+               if not config.plugins.autotimer.autopoll.value:
+                       from plugin import autotimer
+                       autotimer = None
+
+def editorCallback(ret):
        if ret:
                from plugin import autotimer
-               
-               # Create instance if needed
+
+               # Create instance if needed (should have been created by addAutotimerFrom* above though)
                if autotimer is None:
                        from AutoTimer import AutoTimer
                        autotimer = AutoTimer()
+                       autotimer.readXml()
 
                autotimer.add(ret)
-               
-               # Remove instance if not running in background
-               if not config.plugins.autotimer.autopoll.value:
-                       # Save xml
-                       autotimer.writeXml()
-                       autotimer = None
\ No newline at end of file
+
+               # Save modified xml
+               autotimer.writeXml()
+
+       # Remove instance if not running in background
+       if not config.plugins.autotimer.autopoll.value:
+               autotimer = None
+