add timeroverlap detection made by adenin (thanks for the great work!)
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Sat, 18 Oct 2008 17:11:52 +0000 (17:11 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Sat, 18 Oct 2008 17:11:52 +0000 (17:11 +0000)
RecordTimer.py
data/skin_default.xml
lib/python/Components/TimerList.py
lib/python/Components/TimerSanityCheck.py
lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py
lib/python/Screens/EpgSelection.py
lib/python/Screens/EventView.py
lib/python/Screens/InfoBarGenerics.py
lib/python/Screens/TimerEdit.py
lib/python/Screens/TimerEntry.py

index f93872cd69c19c9e02bdad2ae3d3830c02d00097..397ff8a773952954ac9d1909c20c5e02899cb96f 100644 (file)
@@ -10,7 +10,7 @@ from enigma import eEPGCache, getBestPlayableServiceReference, \
        eServiceReference, iRecordableService, quitMainloop
 
 from Screens.MessageBox import MessageBox
-
+from Components.TimerSanityCheck import TimerSanityCheck
 import NavigationInstance
 
 import Screens.Standby
@@ -116,7 +116,8 @@ class RecordTimerEntry(timer.TimerEntry, object):
                self.afterEvent = afterEvent
                self.dirname = dirname
                self.dirnameHadToFallback = False
-               
+               self.autoincrease = False
+
                self.log_entries = []
                self.resetState()
        
@@ -418,8 +419,16 @@ class RecordTimer(timer.Timer):
                        return
 
                root = doc.childNodes[0]
+
+               # put out a message when at least one timer overlaps
+               checkit = True
                for timer in elementsWithTag(root.childNodes, "timer"):
-                       self.record(createTimer(timer))
+                       newTimer = createTimer(timer)
+                       if (self.record(newTimer, True, True) is not None) and (checkit == True):
+                               from Tools.Notifications import AddPopup
+                               from Screens.MessageBox import MessageBox
+                               AddPopup(_("Timer overlap in timers.xml detected!\nPlease recheck it!"), type = MessageBox.TYPE_ERROR, timeout = 0, id = "TimerLoadFailed")
+                               checkit = False # at moment it is enough when the message is displayed one time
 
        def saveTimer(self):
                #doc = xml.dom.minidom.Document()
@@ -521,12 +530,24 @@ class RecordTimer(timer.Timer):
                        return timer.begin
                return -1
 
-       def record(self, entry):
+       def record(self, entry, ignoreTSC=False, dosave=True):          #wird von loadTimer mit dosave=False aufgerufen
+               timersanitycheck = TimerSanityCheck(self.timer_list,entry)
+               if not timersanitycheck.check():
+                       if ignoreTSC != True:
+                               print "timer conflict detected!"
+                               print timersanitycheck.getSimulTimerList()
+                               return timersanitycheck.getSimulTimerList()
+                       else:
+                               print "ignore timer conflict"
+               elif timersanitycheck.doubleCheck():
+                       print "ignore double timer"
                entry.timeChanged()
                print "[Timer] Record " + str(entry)
                entry.Timer = self
                self.addTimerEntry(entry)
-               self.saveTimer()
+               if dosave:
+                       self.saveTimer()
+               return None
                
        def isInTimer(self, eventid, begin, duration, service):
                time_match = 0
index 600f8383ec9e94c78b78d782eaae325c45534ac2..b63394159d52323b72395adad4b95dcadb0e4f32 100644 (file)
@@ -994,18 +994,18 @@ self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y()))
                <widget name="logentry" position="0,300" size="560,130" font="Regular;20" />
        </screen>
        <!-- Timer sanity conflict -->
-       <screen name="TimerSanityConflict" position="70,95" size="600,430" title="Timer sanity error">
-               <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
-               <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
-               <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
-               <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
-               <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
-               <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
-               <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
-               <widget name="key_blue" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
-               <widget name="timer1" position="10,45" size="280,220" scrollbarMode="showOnDemand" />
-               <widget name="timer2" position="310,45" size="280,220" scrollbarMode="showOnDemand" />
-               <widget name="list" position="0,280" size="500,290" scrollbarMode="showOnDemand" />
+       <screen name="TimerSanityConflict" position="70,100" size="560,430" title="Timer sanity error">
+               <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
+               <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
+               <ePixmap pixmap="skin_default/buttons/yellow.png" position="0,120" zPosition="0" size="140,40" transparent="1" alphatest="on" />
+               <ePixmap pixmap="skin_default/buttons/blue.png" position="140,120" zPosition="0" size="140,40" transparent="1" alphatest="on" />
+               <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#9f1313" transparent="1" />
+               <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
+               <widget name="key_yellow" position="0,120" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#a08500" transparent="1" />
+               <widget name="key_blue" position="140,120" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#18188b" transparent="1" />
+               <widget name="timer1" position="0,45" size="560,75" scrollbarMode="showNever" />
+               <widget name="timer2" position="0,165" size="560,75" scrollbarMode="showNever" />
+               <widget name="list" position="0,260" size="560,144" scrollbarMode="showOnDemand" />
        </screen>
        <!-- Timer Selection -->
        <screen name="TimerSelection" position="90,95" size="560,430" title="Timer selection">
index 0912a4d0db0e6d36db79a1c2efa223a850b895ba..f84743749e79ef2167b42a35688d70eec65b20fa 100644 (file)
@@ -33,14 +33,14 @@ class TimerList(HTMLComponent, GUIComponent, object):
                                                count += 1
                                        flags = flags >> 1
                        if timer.justplay:
-                               res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, 400, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + ((" %s "+ _("(ZAP)")) % (FuzzyTime(timer.begin)[1]))))
+                               res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + ((" %s "+ _("(ZAP)")) % (FuzzyTime(timer.begin)[1]))))
                        else:
-                               res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, 400, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + ((" %s ... %s (%d " + _("mins") + ")") % (FuzzyTime(timer.begin)[1], FuzzyTime(timer.end)[1], (timer.end - timer.begin) / 60))))
+                               res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + ((" %s ... %s (%d " + _("mins") + ")") % (FuzzyTime(timer.begin)[1], FuzzyTime(timer.end)[1], (timer.end - timer.begin) / 60))))
                else:
                        if timer.justplay:
-                               res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, 400, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + (("%s, %s " + _("(ZAP)")) % (FuzzyTime(timer.begin)))))
+                               res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + (("%s, %s " + _("(ZAP)")) % (FuzzyTime(timer.begin)))))
                        else:
-                               res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, 400, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + (("%s, %s ... %s (%d " + _("mins") + ")") % (FuzzyTime(timer.begin) + FuzzyTime(timer.end)[1:] + ((timer.end - timer.begin) / 60,)))))
+                               res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + (("%s, %s ... %s (%d " + _("mins") + ")") % (FuzzyTime(timer.begin) + FuzzyTime(timer.end)[1:] + ((timer.end - timer.begin) / 60,)))))
 
                if not processed:
                        if timer.state == TimerEntry.StateWaiting:
@@ -52,6 +52,8 @@ class TimerList(HTMLComponent, GUIComponent, object):
                                        state = _("zapped")
                                else:
                                        state = _("recording...")
+                       elif timer.state == TimerEntry.StateEnded:
+                               state = _("done!")
                        else:
                                state = _("<unknown>")
                else:
@@ -60,7 +62,7 @@ class TimerList(HTMLComponent, GUIComponent, object):
                if timer.disabled:
                        state = _("disabled")
 
-               res.append((eListboxPythonMultiContent.TYPE_TEXT, width-240, 50, 240, 20, 1, RT_HALIGN_RIGHT|RT_VALIGN_CENTER, state))
+               res.append((eListboxPythonMultiContent.TYPE_TEXT, width-150, 50, 150, 20, 1, RT_HALIGN_RIGHT|RT_VALIGN_CENTER, state))
 
                if timer.disabled:
                        png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/redx.png"))
index 50daa2f1015780c3cd1efdf01cd429305e248bf5..d3857039cce00f03c6ce5ef082e24310177317a6 100644 (file)
+import string
+import NavigationInstance
 from time import localtime
+from Components.NimManager import nimmanager
+from ServiceReference import ServiceReference
+from enigma import iServiceInformation, eServiceCenter
 
 class TimerSanityCheck:
-       def __init__(self, timerlist, newtimer):
+       def __init__(self, timerlist, newtimer=None):
+               print "sanitycheck"
                self.timerlist = timerlist
                self.newtimer = newtimer
                self.simultimer = []
-                               
-       def check(self):
-               self.simultimer = [ self.newtimer ]
-               for timer in self.timerlist:
-                       if self.isSimultaneous(timer, self.newtimer):
-                               self.simultimer.append(timer)
-               
-               if len(self.simultimer) > 1:
-                       return self.checkRecordable(self.simultimer)
+               self.rep_eventlist = []
+               self.nrep_eventlist = []
+               self.bflag = -1
+               self.eflag = 1
+
+       def check(self, ext_timer=1):
+               print "check"
+               if ext_timer != 1:
+                       self.newtimer = ext_timer
+               if self.newtimer is None:
+                       self.simultimer = []
+               else:
+                       self.simultimer = [ self.newtimer ]
+               return self.checkTimerlist()
                
-               return True
 
        def getSimulTimerList(self):
                return self.simultimer
-       
-       def isSimultaneous(self, timer1, timer2):
-               # both timers are repeated
-               if (timer1.repeated & timer2.repeated):
-                       return self.timeEquals(timer1, timer2)
-
-               # one timer is repeated
-               if not timer1.repeated:
-                       tmp = timer1
-                       timer1 = timer2
-                       timer2 = tmp
-
-               if timer1.repeated:
-                       dow2 = (localtime(timer2.begin).tm_wday - 1) % 7
-                       
-                       if timer1.repeated & (2 ** dow2):
-                               return self.timeEquals(timer1, timer2)
-               else:
-                       if (timer1.begin <= timer2.begin < timer1.end) or (timer2.begin <= timer1.begin < timer2.end):
-                               return True
 
+       def doubleCheck(self):
+               if self.newtimer is not None and self.newtimer.service_ref.ref.valid():
+                       self.simultimer = [ self.newtimer ]
+                       for timer in self.timerlist:
+                               if (timer == self.newtimer):
+                                       return True
+                               else:
+                                       if timer.begin == self.newtimer.begin:
+                                               getUnsignedDataRef1 = timer.service_ref.ref.getUnsignedData
+                                               getUnsignedDataRef2 = self.newtimer.service_ref.ref.getUnsignedData
+                                               for x in range(1,5):
+                                                       if getUnsignedDataRef1(x) != getUnsignedDataRef2(x):
+                                                               break;
+                                               else:
+                                                       return True
                return False
 
-       def timeEquals(self, timer1, timer2):
-               ltb1 = localtime(timer1.begin)
-               ltb2 = localtime(timer2.begin)
-                               
-               begin1 = ltb1.tm_hour * 3600 + ltb1.tm_min * 60 + ltb1.tm_sec
-               begin2 = ltb2.tm_hour * 3600 + ltb2.tm_min * 60 + ltb2.tm_sec
-               
-               end1 = begin1 + timer1.end - timer1.begin
-               end2 = begin2 + timer2.end - timer2.begin
-               
-               return (begin1 <= begin2 < end1) or (begin2 <= begin1 < end2)
-       
-       def checkRecordable(self, timerlist):
-               # TODO: Add code here
-               return True
\ No newline at end of file
+       def checkTimerlist(self, ext_timer=1):
+               #with special service for external plugins
+               # Entries in eventlist
+               # timeindex
+               # index -1 for the new Timer, 0..n index of the existing timers
+               # BeginEndFlag -1 for begin, +1 for end
+               # count of running timers
+
+               print "checkTimerlist"
+# create a list with all start and end times
+# split it into recurring and singleshot timers
+
+##################################################################################
+# process the new timer
+               self.rep_eventlist = []
+               self.nrep_eventlist = []
+               if ext_timer != 1:
+                       self.newtimer = ext_timer
+               if (self.newtimer is not None) and (not self.newtimer.disabled):
+                       if not self.newtimer.service_ref.ref.valid():
+                               return False
+                       rflags = self.newtimer.repeated
+                       rflags = ((rflags & 0x7F)>> 3)|((rflags & 0x07)<<4)
+                       if rflags:
+                               begin = self.newtimer.begin % 86400 # map to first day
+                               while rflags: # then arrange on the week
+                                       if rflags & 1:
+                                               self.rep_eventlist.append((begin, -1))
+                                       begin += 86400
+                                       rflags >>= 1
+                       else:
+                               self.nrep_eventlist.extend([(self.newtimer.begin,-1,self.bflag),(self.newtimer.end,-1,self.eflag)])
+
+##################################################################################
+# now process existing timers
+               idx = 0
+               for timer in self.timerlist:
+                       if (timer != self.newtimer) and (not timer.disabled):
+                               if timer.repeated:
+                                       rflags = timer.repeated
+                                       rflags = ((rflags & 0x7F)>> 3)|((rflags & 0x07)<<4)
+                                       begin = timer.begin % 86400 # map all to first day
+                                       while rflags:
+                                               if rflags & 1:
+                                                       self.rep_eventlist.append((begin, idx))
+                                               begin += 86400
+                                               rflags >>= 1
+                               else:
+                                       self.nrep_eventlist.extend([(timer.begin,idx,self.bflag),(timer.end,idx,self.eflag)])
+                       idx += 1
+
+################################################################################
+# journalize timer repeations
+               if len(self.nrep_eventlist):
+                       interval_begin = min(self.nrep_eventlist)[0]
+                       interval_end = max(self.nrep_eventlist)[0]
+                       offset_0 = interval_begin - (interval_begin % 604800)
+                       weeks = (interval_end - offset_0) / 604800
+                       if ((interval_end - offset_0) % 604800):
+                               weeks += 1
+                       for cnt in range(weeks):
+                               for event in self.rep_eventlist:
+                                       if event[1] == -1: # -1 is the identifier of the changed timer
+                                               event_begin = self.newtimer.begin
+                                               event_end = self.newtimer.end
+                                       else:
+                                               event_begin = self.timerlist[event[1]].begin
+                                               event_end = self.timerlist[event[1]].end
+                                       new_event_begin = event[0] + offset_0 + (cnt * 604800)
+                                       # summertime correction
+                                       new_lth = localtime(new_event_begin).tm_hour
+                                       new_event_begin += 3600 * (localtime(event_begin).tm_hour - new_lth)
+                                       new_event_end = new_event_begin + (event_end - event_begin)
+                                       if event[1] == -1:
+                                               if new_event_begin >= self.newtimer.begin: # is the soap already running?
+                                                       self.nrep_eventlist.extend([(new_event_begin, event[1], self.bflag),(new_event_end, event[1], self.eflag)])
+                                       else:
+                                               if new_event_begin >= self.timerlist[event[1]].begin: # is the soap already running?
+                                                       self.nrep_eventlist.extend([(new_event_begin, event[1], self.bflag),(new_event_end, event[1], self.eflag)])
+               else:
+                       offset_0 = 345600 # the Epoch begins on Thursday
+                       weeks = 2 # test two weeks to take care of Sunday-Monday transitions
+                       for cnt in range(weeks):
+                               for event in self.rep_eventlist:
+                                       if event[1] == -1: # -1 is the identifier of the changed timer
+                                               event_begin = self.newtimer.begin
+                                               event_end = self.newtimer.end
+                                       else:
+                                               event_begin = self.timerlist[event[1]].begin
+                                               event_end = self.timerlist[event[1]].end
+                                       new_event_begin = event[0] + offset_0 + (cnt * 604800)
+                                       new_event_end = new_event_begin + (event_end - event_begin)
+                                       self.nrep_eventlist.extend([(new_event_begin, event[1], self.bflag),(new_event_end, event[1], self.eflag)])
+
+################################################################################
+# order list chronological
+               self.nrep_eventlist.sort()
+
+##################################################################################
+# detect overlapping timers and overlapping times
+               fakeRecList = []
+               ConflictTimer = None
+               ConflictTunerType = None
+               ConflictSlot = None
+               newTimerTunerType = None
+               newTimerTunerSlot = None
+               cnt = 0
+               idx = 0
+               overlaplist = []
+               for event in self.nrep_eventlist:
+                       cnt -= event[2]
+                       if event[1] == -1: # new timer
+                               timer = self.newtimer
+                       else:
+                               timer = self.timerlist[event[1]]
+                       if event[2] == self.bflag:
+                               fakeRecService = NavigationInstance.instance.recordService(timer.service_ref)
+                               feinfo = fakeRecService.frontendInfo().getFrontendData()
+                               tunerType = feinfo.get("tuner_type")
+                               tunerSlot = feinfo.get("tuner_number")
+                               if event[1] == -1: # new timer
+                                       newTimerTunerType = tunerType
+                                       newTimerTunerSlot = tunerSlot
+                               fakeRecResult = fakeRecService.start(True)
+                               overlaplist.append((fakeRecResult, timer, tunerType, tunerSlot))
+                               fakeRecList.append((timer, fakeRecService))
+                               if fakeRecResult:
+                                       if ConflictTimer is None: # just take care of the first conflict
+                                               ConflictTimer = timer
+                                               ConflictTunerType = tunerType
+                                               ConflictSlot = tunerSlot
+                       elif event[2] == self.eflag:
+                               for fakeRec in fakeRecList:
+                                       if timer == fakeRec[0]:
+                                               NavigationInstance.instance.stopRecordService(fakeRec[1])
+                                               fakeRecList.remove(fakeRec)
+                               if overlaplist.count(timer):
+                                       overlaplist.remove(timer)
+                       else:
+                               print "Bug: unknown flag!"
+                       self.nrep_eventlist[idx] = (event[0],event[1],event[2],cnt,overlaplist[:]) # insert a duplicate into current overlaplist
+                       idx += 1
+
+               for fakeRec in fakeRecList:
+                       NavigationInstance.instance.stopRecordService(fakeRec[1])
+
+               if ConflictTimer is None: # no conflict found :)
+                       return True
+
+##################################################################################
+# we have detected a conflict, now we must figure out the involved timers
+
+               if self.newtimer is not None: # new timer?
+                       if self.newtimer is not ConflictTimer: # the new timer is not the conflicting timer?
+                               for event in self.nrep_eventlist:
+                                       if len(event[4]) > 1: # entry in overlaplist of this event??
+                                               kt = False
+                                               nt = False
+                                               for entry in event[4]:
+                                                       if entry[1] is ConflictTimer:
+                                                               kt = True
+                                                       if entry[1] is self.newtimer:
+                                                               nt = True
+                                               if nt and kt:
+                                                       ConflictTimer = self.newtimer
+                                                       ConflictTunerType = newTimerTunerType
+                                                       ConflictSlot = newTimerTunerSlot
+                                                       break
+
+               self.simultimer = [ ConflictTimer ]
+               for event in self.nrep_eventlist:
+                       if len(event[4]) > 1: # entry in overlaplist of this event??
+                               for entry in event[4]:
+                                       if entry[1] is ConflictTimer:
+                                               break
+                               else:
+                                       continue
+                               for entry in event[4]:
+                                       if not self.simultimer.count(entry[1]) and (entry[2] == ConflictTunerType or entry[3] == ConflictTunerSlot):
+                                               self.simultimer.append(entry[1])
+
+               if len(self.simultimer) < 2:
+                       print "Bug: unknown Conflict!"
+
+               return False # conflict detected!
index 036cb7a6fd7a88f50abbd8761ba63fd32de9fe6e..1af90f1350423d8342c4ae6ceb9b30b4868b1f25 100644 (file)
@@ -8,11 +8,13 @@ from Components.GUIComponent import GUIComponent
 from Components.EpgList import Rect
 from Components.Sources.Event import Event
 from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest
+from Components.TimerList import TimerList
 from Screens.Screen import Screen
 from Screens.EventView import EventViewSimple
 from Screens.TimeDateInput import TimeDateInput
 from Screens.TimerEntry import TimerEntry
 from Screens.EpgSelection import EPGSelection
+from Screens.TimerEdit import TimerSanityConflict
 from Tools.Directories import resolveFilename, SCOPE_SKIN_IMAGE
 from RecordTimer import RecordTimerEntry, parseEvent
 from ServiceReference import ServiceReference
@@ -498,14 +500,26 @@ class GraphMultiEPG(Screen):
                serviceref = cur[1]
                if event is None:
                        return
-               newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, dirname = config.movielist.last_timer_videodir.value, *parseEvent(event))
-               self.session.openWithCallback(self.timerEditFinished, TimerEntry, newEntry)
+               newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, *parseEvent(event))
+               self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
 
-       def timerEditFinished(self, answer):
+       def finishedAdd(self, answer):
+               print "finished add"
                if answer[0]:
-                       self.session.nav.RecordTimer.record(answer[1])
+                       entry = answer[1]
+                       simulTimerList = self.session.nav.RecordTimer.record(entry)
+                       if simulTimerList is not None:
+                               if (len(simulTimerList) == 2) and (simulTimerList[1].dontSave) and (simulTimerList[1].autoincrease):
+                                       simulTimerList[1].end = entry.begin - 30
+                                       self.session.nav.RecordTimer.timeChanged(simulTimerList[1])
+                                       self.session.nav.RecordTimer.record(entry)
+                               else:
+                                       self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
                else:
-                       print "Timeredit aborted"
+                       print "Timeredit aborted"               
+       
+       def finishSanityCorrection(self, answer):
+               self.finishedAdd(answer)
 
        def onSelectionChanged(self):
                evt = self["list"].getCurrent()
index edad3596ab24e2241ce1a15d54b13da86ff8360e..6740bfb6d6ea0da297f3834d5556708e9149c18a 100644 (file)
@@ -5,6 +5,7 @@ from Components.Pixmap import Pixmap
 from Components.Label import Label
 from Components.EpgList import EPGList, EPG_TYPE_SINGLE, EPG_TYPE_SIMILAR, EPG_TYPE_MULTI
 from Components.ActionMap import ActionMap
+from Screens.TimerEdit import TimerSanityConflict
 from Screens.EventView import EventViewSimple
 from TimeDateInput import TimeDateInput
 from enigma import eServiceReference
@@ -184,14 +185,26 @@ class EPGSelection(Screen):
                serviceref = cur[1]
                if event is None:
                        return
-               newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, dirname = config.movielist.last_timer_videodir.value, *parseEvent(event))
-               self.session.openWithCallback(self.timerEditFinished, TimerEntry, newEntry)
+               newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, *parseEvent(event))
+               self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
 
-       def timerEditFinished(self, answer):
+       def finishedAdd(self, answer):
+               print "finished add"
                if answer[0]:
-                       self.session.nav.RecordTimer.record(answer[1])
+                       entry = answer[1]
+                       simulTimerList = self.session.nav.RecordTimer.record(entry)
+                       if simulTimerList is not None:
+                               if (len(simulTimerList) == 2) and (simulTimerList[1].dontSave) and (simulTimerList[1].autoincrease):
+                                       simulTimerList[1].end = entry.begin - 30
+                                       self.session.nav.RecordTimer.timeChanged(simulTimerList[1])
+                                       self.session.nav.RecordTimer.record(entry)
+                               else:
+                                       self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
                else:
-                       print "Timeredit aborted"       
+                       print "Timeredit aborted"               
+       
+       def finishSanityCorrection(self, answer):
+               self.finishedAdd(answer)
 
        def moveUp(self):
                self["list"].moveUp()
index 964973d381143fe3e53de1ee255c01044b71b51e..5d50d9bcb5aa60d85978bfe821edb32a8f3a5c11 100644 (file)
@@ -1,8 +1,10 @@
 from Screen import Screen
+from Screens.TimerEdit import TimerSanityConflict
 from Components.ActionMap import ActionMap
 from Components.Button import Button
 from Components.Label import Label
 from Components.ScrollLabel import ScrollLabel
+from Components.TimerList import TimerList
 from enigma import eEPGCache, eTimer, eServiceReference
 from RecordTimer import RecordTimerEntry, parseEvent
 from TimerEntry import TimerEntry
@@ -59,14 +61,26 @@ class EventViewBase:
 
        def timerAdd(self):
                if not self.isRecording:
-                       newEntry = RecordTimerEntry(self.currentService, checkOldTimers = True, dirname = config.movielist.last_timer_videodir.value, *parseEvent(self.event))
-                       self.session.openWithCallback(self.timerEditFinished, TimerEntry, newEntry)
-
-       def timerEditFinished(self, answer):
-               if (answer[0]):
-                       self.session.nav.RecordTimer.record(answer[1])
+                       newEntry = RecordTimerEntry(self.currentService, checkOldTimers = True, *parseEvent(self.event))
+                       self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
+
+       def finishedAdd(self, answer):
+               print "finished add"
+               if answer[0]:
+                       entry = answer[1]
+                       simulTimerList = self.session.nav.RecordTimer.record(entry)
+                       if simulTimerList is not None:
+                               if (len(simulTimerList) == 2) and (simulTimerList[1].dontSave) and (simulTimerList[1].autoincrease):
+                                       simulTimerList[1].end = entry.begin - 30
+                                       self.session.nav.RecordTimer.timeChanged(simulTimerList[1])
+                                       self.session.nav.RecordTimer.record(entry)
+                               else:
+                                       self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
                else:
-                       print "Timeredit aborted"
+                       print "Timeredit aborted"               
+
+       def finishSanityCorrection(self, answer):
+               self.finishedAdd(answer)
 
        def setService(self, service):
                self.currentService=service
index 1156e139943ce2092e36abf12658a170a4ddf44d..5ff227da2d9ba2ca7fa0fc740c63555da88c8274 100644 (file)
@@ -38,6 +38,8 @@ from time import time, localtime, strftime
 from os import stat as os_stat
 from bisect import insort
 
+from RecordTimer import RecordTimerEntry, RecordTimer
+
 # hack alert!
 from Menu import MainMenu, mdom
 
@@ -1411,7 +1413,7 @@ class InfoBarInstantRecord:
                        pass
 
                begin = time()
-               end = time() + 3600 * 10
+               end = time() + 3600 * 24 * 365 * 1 # 1 year
                name = "instant record"
                description = ""
                eventid = None
@@ -1427,14 +1429,23 @@ class InfoBarInstantRecord:
                        if limitEvent:
                                self.session.open(MessageBox, _("No event info found, recording indefinitely."), MessageBox.TYPE_INFO)
 
-               # TODO: needed?
                if isinstance(serviceref, eServiceReference):
                        serviceref = ServiceReference(serviceref)
 
                recording = RecordTimerEntry(serviceref, begin, end, name, description, eventid, dirname = config.movielist.last_videodir.value)
                recording.dontSave = True
-
-               self.session.nav.RecordTimer.record(recording)
+               recording.autoincrease = True
+
+               simulTimerList = self.session.nav.RecordTimer.record(recording)
+               if simulTimerList is not None:
+                       print "timer conflict detected!"
+                       if (len(simulTimerList) > 1):
+                               print "tsc_list > 1"
+                               recording.end = simulTimerList[1].begin - 30
+                               self.session.nav.RecordTimer.record(recording)
+                               print "new endtime applied"
+                       else:
+                               print "conflict with only one timer? ! ?"
                self.recording.append(recording)
 
        def isInstantRecordRunning(self):
@@ -1493,6 +1504,8 @@ class InfoBarInstantRecord:
                        if ret[0]:
                                localendtime = localtime(ret[1])
                                print "stopping recording at", strftime("%c", localendtime)
+                               if self.recording[self.selectedEntry].end != ret[1]:
+                                       recording.autoincrease = False
                                self.recording[self.selectedEntry].end = ret[1]
                                self.session.nav.RecordTimer.timeChanged(self.recording[self.selectedEntry])
 
@@ -1504,6 +1517,8 @@ class InfoBarInstantRecord:
        def inputCallback(self, value):
                if value is not None:
                        print "stopping recording after", int(value), "minutes."
+                       if int(value) != 0:
+                               recording.autoincrease = False
                        self.recording[self.selectedEntry].end = time() + 60 * int(value)
                        self.session.nav.RecordTimer.timeChanged(self.recording[self.selectedEntry])
 
index bdf3527dbbff0fd3f9592f935f07be79f810cf9b..996d7304a6f9fe93d3ffb10de428af587ab77152 100644 (file)
@@ -65,23 +65,31 @@ class TimerEditList(Screen):
                cur=self["timerlist"].getCurrent()
                if cur:
                        t = cur
-               
                        if t.disabled:
+                               print "try to enable timer"
                                t.enable()
-                               self.session.nav.RecordTimer.timeChanged(t)
-
+                               timersanitycheck = TimerSanityCheck(self.session.nav.RecordTimer.timer_list, cur)
+                               if not timersanitycheck.check():
+                                       t.disable()
+                                       print "Sanity check failed"
+                                       self.session.openWithCallback(self.finishedEdit, TimerSanityConflict, timersanitycheck.getSimulTimerList())
+                               else:
+                                       print "Sanity check passed"
+                                       if timersanitycheck.doubleCheck():
+                                               t.disable()
                        else:
-                               if t.isRunning() and t.repeated:
-                                       list = []
-                                       list.append((_("Stop current event but not coming events"), "stoponlycurrent"))
-                                       list.append((_("Stop current event and disable coming events"), "stopall"))
-                                       list.append((_("Don't stop current event but disable coming events"), "stoponlycoming"))
-                                       self.session.openWithCallback(boundFunction(self.runningEventCallback, t), ChoiceBox, title=_("Repeating event currently recording... What do you want to do?"), list = list)
+                               if t.isRunning():
+                                       if t.repeated:
+                                               list = []
+                                               list.append((_("Stop current event but not coming events"), "stoponlycurrent"))
+                                               list.append((_("Stop current event and disable coming events"), "stopall"))
+                                               list.append((_("Don't stop current event but disable coming events"), "stoponlycoming"))
+                                               self.session.openWithCallback(boundFunction(self.runningEventCallback, t), ChoiceBox, title=_("Repeating event currently recording... What do you want to do?"), list = list)
                                else:
                                        t.disable()
-                                       self.session.nav.RecordTimer.timeChanged(t)
-                       self.updateState()
+                       self.session.nav.RecordTimer.timeChanged(t)
                        self.refill()
+                       self.updateState()
 
        def runningEventCallback(self, t, result):
                if result is not None:
@@ -92,17 +100,47 @@ class TimerEditList(Screen):
                        if result[1] == "stoponlycoming" or result[1] == "stopall":
                                t.disable()
                        self.session.nav.RecordTimer.timeChanged(t)
-
-                       self.updateState()
                        self.refill()
+                       self.updateState()
                
        def updateState(self):
-               if len(self.list) > 0:
-                       if self["timerlist"].getCurrent().disabled:
+               cur = self["timerlist"].getCurrent()
+               if cur:
+                       if self["key_red"].getText()!=(_("Delete")):
+                               self["key_red"].setText(_("Delete"))
+                               self["key_red"].instance.invalidate()
+                       
+                       if cur.disabled and (self["key_yellow"].getText()!=(_("Enable"))):
                                self["key_yellow"].setText(_("Enable"))
-                       else:
+                               self["key_yellow"].instance.invalidate()
+                       elif cur.isRunning() and (self["key_yellow"].getText()!=(_(" "))):
+                               self["key_yellow"].setText(_(" "))
+                               self["key_yellow"].instance.invalidate()
+                       elif (not cur.isRunning()) and (not cur.disabled) and (self["key_yellow"].getText()!=(_("Disable"))):
                                self["key_yellow"].setText(_("Disable"))
-                       self["key_yellow"].instance.invalidate()
+                               self["key_yellow"].instance.invalidate()
+               else:
+                       if self["key_red"].getText()!=(_(" ")):
+                               self["key_red"].setText(_(" "))
+                               self["key_red"].instance.invalidate()
+                       if self["key_yellow"].getText()!=(_(" ")):
+                               self["key_yellow"].setText(_(" "))
+                               self["key_yellow"].instance.invalidate()
+               
+               showCleanup = True
+               for x in self.list:
+                       if (not x[0].disabled) and (x[1] == True):
+                               break
+               else:
+                       showCleanup = False
+               
+               if showCleanup and (self["key_blue"].getText()!=(_("Cleanup"))):
+                       self["key_blue"].setText(_("Cleanup"))
+                       self["key_blue"].instance.invalidate()
+               elif (not showCleanup) and (self["key_blue"].getText()!=(_(" "))):
+                       self["key_blue"].setText(_(" "))
+                       self["key_blue"].instance.invalidate()
+
 
        def fillTimerList(self):
                del self.list[:]
@@ -131,6 +169,7 @@ class TimerEditList(Screen):
                if delete:
                        self.session.nav.RecordTimer.cleanup()
                        self.refill()
+                       self.updateState()
 
        def removeTimerQuestion(self):
                if not self["timerlist"].getCurrent():
@@ -146,7 +185,21 @@ class TimerEditList(Screen):
                        timer = cur
                        timer.afterEvent = AFTEREVENT.NONE
                        self.session.nav.RecordTimer.removeEntry(timer)
+                       if not timer.dontSave:
+                               for timer in self.session.nav.RecordTimer.timer_list:
+                                       if timer.dontSave and timer.autoincrease:
+                                               timer.end = timer.begin + (3600 * 24 * 356 * 1)
+                                               self.session.nav.RecordTimer.timeChanged(timer)
+                                               timersanitycheck = TimerSanityCheck(self.session.nav.RecordTimer.timer_list,timer)
+                                               if not timersanitycheck.check():
+                                                       tsc_list = timersanitycheck.getSimulTimerList()
+                                                       if len(tsc_list) > 1:
+                                                               timer.end = tsc_list[1].begin - 30
+                                                               self.session.nav.RecordTimer.timeChanged(timer)
+
                        self.refill()
+                       self.updateState()
+
        
        def refill(self):
                oldsize = len(self.list)
@@ -185,30 +238,42 @@ class TimerEditList(Screen):
                
                if answer[0]:
                        print "Edited timer"
-                       timersanitycheck = TimerSanityCheck(self.session.nav.RecordTimer.timer_list, answer[1])
+                       entry = answer[1]
+                       timersanitycheck = TimerSanityCheck(self.session.nav.RecordTimer.timer_list, entry)
                        if not timersanitycheck.check():
-                               print "Sanity check failed"
+                               simulTimerList = timersanitycheck.getSimulTimerList()
+                               if (len(simulTimerList) == 2) and (simulTimerList[1].dontSave) and (simulTimerList[1].autoincrease):
+                                       simulTimerList[1].end = entry.begin - 30
+                                       self.session.nav.RecordTimer.timeChanged(simulTimerList[1])
+                                       self.session.nav.RecordTimer.timeChanged(entry)
+                               else:
+                                       print "Sanity check failed"
+                                       self.session.openWithCallback(self.finishedEdit, TimerSanityConflict, timersanitycheck.getSimulTimerList())
                        else:
                                print "Sanity check passed"
-                       self.session.nav.RecordTimer.timeChanged(answer[1])
+                               if not timersanitycheck.doubleCheck():
+                                       self.session.nav.RecordTimer.timeChanged(entry)
                        self.fillTimerList()
+                       self.updateState()
                else:
                        print "Timeredit aborted"
 
        def finishedAdd(self, answer):
                print "finished add"
                if answer[0]:
-                       timersanitycheck = TimerSanityCheck(self.session.nav.RecordTimer.timer_list, answer[1])
-                       if not timersanitycheck.check():
-                               print "Sanity check failed"
-                               self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, timersanitycheck.getSimulTimerList())
-                       else:
-                               print "Sanity check passed"
-                               entry = answer[1]
-                               self.session.nav.RecordTimer.record(entry)
-                               self.fillTimerList()
+                       entry = answer[1]
+                       simulTimerList = self.session.nav.RecordTimer.record(entry)
+                       if simulTimerList is not None:
+                               if (len(simulTimerList) == 2) and (simulTimerList[1].dontSave) and (simulTimerList[1].autoincrease):
+                                       simulTimerList[1].end = entry.begin - 30
+                                       self.session.nav.RecordTimer.timeChanged(simulTimerList[1])
+                                       self.session.nav.RecordTimer.record(entry)
+                               else:
+                                       self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
+                       self.fillTimerList()
+                       self.updateState()
                else:
-                       print "Timeredit aborted"               
+                       print "Timeredit aborted"
 
        def finishSanityCorrection(self, answer):
                self.finishedAdd(answer)
@@ -219,47 +284,48 @@ class TimerEditList(Screen):
 
        def onStateChange(self, entry):
                self.refill()
+               self.updateState()
 
 class TimerSanityConflict(Screen):
        def __init__(self, session, timer):
                Screen.__init__(self, session)
                self.timer = timer
-               print "TimerSanityConflict", timer
+               print "TimerSanityConflict"
                        
                self["timer1"] = TimerList(self.getTimerList(timer[0]))
-               if len(timer) > 1:
-                       self["timer2"] = TimerList(self.getTimerList(timer[1]))
-               else:
-                       self["timer2"] = TimerList([])
-               
                self.list = []
+               self.list2 = []
                count = 0
                for x in timer:
                        if count != 0:
                                self.list.append((_("Conflicting timer") + " " + str(count), x))
+                               self.list2.append((timer[count], False))
                        count += 1
 
                self["list"] = MenuList(self.list)
+               self["timer2"] = TimerList(self.list2)
+               
                
                self["key_red"] = Button("Edit")
-               self["key_green"] = Button("Disable")
+               self["key_green"] = Button("")
                self["key_yellow"] = Button("Edit")
-               self["key_blue"] = Button("Disable")
+               self["key_blue"] = Button("")
 
                self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "ShortcutActions", "TimerEditActions"], 
                        {
-                               "ok": self.close,
-                               #"cancel": self.leave,
+                               "ok": self.leave_ok,
+                               "cancel": self.leave_cancel,
                                "red": self.editTimer1,
-                               "green": self.disableTimer1,
-#                              "yellow": self.editTimer2,
-#                              "blue": self.disableTimer2,
+                               "green": self.toggleTimer1,
+                               "yellow": self.editTimer2,
+                               "blue": self.toggleTimer2,
                                #"log": self.showLog,
                                #"left": self.left,
                                #"right": self.right,
                                "up": self.up,
                                "down": self.down
                        }, -1)
+               self.onShown.append(self.updateState)
 
        def getTimerList(self, timer):
                return [(timer, False)]
@@ -267,17 +333,66 @@ class TimerSanityConflict(Screen):
        def editTimer1(self):
                self.session.openWithCallback(self.finishedEdit, TimerEntry, self["timer1"].getCurrent())
 
-       def disableTimer1(self):
-               self.timer[0].disabled = True
+       def toggleTimer1(self):
+               if self.timer[0].disabled:
+                       self.timer[0].disabled = False
+               else:
+                       if not self.timer[0].isRunning():
+                               self.timer[0].disabled = True
                self.finishedEdit((True, self.timer[0]))
+       
+       def editTimer2(self):
+               self.session.openWithCallback(self.finishedEdit, TimerEntry, self["timer2"].getCurrent())
 
+       def toggleTimer2(self):
+               x = self["list"].getSelectedIndex() + 1 # the first is the new timer so we do +1 here
+               if self.timer[x].disabled:
+                       self.timer[x].disabled = False
+               elif not self.timer[x].isRunning():
+                               self.timer[x].disabled = True
+               self.finishedEdit((True, self.timer[0]))
+       
        def finishedEdit(self, answer):
+               self.leave_ok()
+       
+       def leave_ok(self):
                self.close((True, self.timer[0]))
+       
+       def leave_cancel(self):
+               self.close((False, self.timer[0]))
 
        def up(self):
                self["list"].instance.moveSelection(self["list"].instance.moveUp)
-               self["timer2"].l.setList(self.getTimerList(self["list"].getCurrent()))
+               self["timer2"].moveToIndex(self["list"].getSelectedIndex())
                
        def down(self):
                self["list"].instance.moveSelection(self["list"].instance.moveDown)
-               self["timer2"].l.setList(self.getTimerList(self["list"].getCurrent()))
+               self["timer2"].moveToIndex(self["list"].getSelectedIndex())
+       
+       def updateState(self):
+               if self.timer[0] is not None:
+                       if self.timer[0].disabled and (self["key_green"].getText()!=(_("Enable"))):
+                               self["key_green"].setText(_("Enable"))
+                               self["key_green"].instance.invalidate()
+                       elif self.timer[0].isRunning() and (self["key_green"].getText()!= (_(" "))):
+                               self["key_green"].setText(_(" "))
+                               self["key_green"].instance.invalidate()
+                       elif (not self.timer[0].disabled)and(self["key_green"].getText()!= (_("Disable"))):
+                               self["key_green"].setText(_("Disable"))
+                               self["key_green"].instance.invalidate()
+               if (len(self.timer) >1 ):
+                       x = self["list"].getSelectedIndex()
+                       if self.timer[x] is not None:
+                               if self.timer[x].disabled and (self["key_blue"].getText()!=(_("Enable"))):
+                                       self["key_blue"].setText(_("Enable"))
+                                       self["key_blue"].instance.invalidate()
+                               elif self.timer[x].isRunning() and (self["key_blue"].getText()!=(_(" "))):
+                                       self["key_blue"].setText(_(" "))
+                                       self["key_blue"].instance.invalidate()
+                               elif (not self.timer[x].disabled)and(self["key_blue"].getText()!=(_("Disable"))):
+                                       self["key_blue"].setText(_("Disable"))
+                                       self["key_blue"].instance.invalidate()
+               else:
+#FIXME.... this doesnt hide the buttons self.... just the text
+                       self["key_blue"].hide
+                       self["key_yellow"].hide
index 31a65a3032f6a5c0536494f21cb455a37b49db8c..c4dfff7266044eebfd81508ea5c39dbf19236ae1 100644 (file)
@@ -302,9 +302,13 @@ class TimerEntry(Screen, ConfigListScreen):
                                        if self.timerentry_day[x].value:
                                                self.timer.setRepeated(x)
 
-                       self.timer.repeatedbegindate = self.buildRepeatedBegin(self.timerentry_repeatedbegindate.value, self.timerentry_starttime.value)
-                       self.timer.begin = self.getTimestamp(time(), self.timerentry_starttime.value)
-                       self.timer.end = self.getTimestamp(time(), self.timerentry_endtime.value)
+                       self.timer.repeatedbegindate = self.getTimestamp(self.timerentry_repeatedbegindate.value, self.timerentry_starttime.value)
+                       if self.timer.repeated:
+                               self.timer.begin = self.getTimestamp(self.timerentry_repeatedbegindate.value, self.timerentry_starttime.value)
+                               self.timer.end = self.getTimestamp(self.timerentry_repeatedbegindate.value, self.timerentry_endtime.value)
+                       else:
+                               self.timer.begin = self.getTimestamp(time.time(), self.timerentry_starttime.value)
+                               self.timer.end = self.getTimestamp(time.time(), self.timerentry_endtime.value)
 
                        # when a timer end is set before the start, add 1 day
                        if self.timer.end < self.timer.begin: