add possibility to choose record location on timer creation and choose
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Thu, 26 Jun 2008 18:31:21 +0000 (18:31 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Thu, 26 Jun 2008 18:31:21 +0000 (18:31 +0000)
record location in movieplayer (only in expert user level)

14 files changed:
Navigation.py
RecordTimer.py
data/skin_default.xml
lib/python/Components/FileList.py
lib/python/Components/config.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/LocationBox.py
lib/python/Screens/MovieSelection.py
lib/python/Screens/TimerEdit.py
lib/python/Screens/TimerEntry.py
lib/python/Tools/Directories.py

index b4110f4949ea0a658a1be7b2aeca6f7c275f6959..eb1a2b14585c3e7ca09deb40c89758c6c248c99e 100644 (file)
@@ -103,13 +103,6 @@ class Navigation:
        def pause(self, p):
                return self.pnav and self.pnav.pause(p)
 
-       def recordWithTimer(self, ref, begin, end, name, description, eit):
-               if isinstance(ref, eServiceReference):
-                       ref = ServiceReference.ServiceReference(ref)
-               entry = RecordTimer.RecordTimerEntry(ref, begin, end, name, description, eit)
-               self.RecordTimer.record(entry)
-               return entry
-       
        def shutdown(self):
                self.RecordTimer.shutdown()
                self.ServiceHandler = None
index dde6c4ccb1a7dfb3f74dd5ac1ad8b2be2c25fdda..147a38fc6510660b340719e9d5fa2c74d6a6d407 100644 (file)
@@ -115,6 +115,7 @@ class RecordTimerEntry(timer.TimerEntry, object):
                self.justplay = justplay
                self.afterEvent = afterEvent
                self.dirname = dirname
+               self.dirnameHadToFallback = False
                
                self.log_entries = []
                self.resetState()
@@ -136,7 +137,11 @@ class RecordTimerEntry(timer.TimerEntry, object):
                if self.name:
                        filename += " - " + self.name
 
-               self.Filename = Directories.getRecordingFilename(filename, self.dirname)
+               if self.dirname and not Directories.pathExists(self.dirname):
+                       self.dirnameHadToFallback = True
+                       self.Filename = Directories.getRecordingFilename(filename, None)
+               else:
+                       self.Filename = Directories.getRecordingFilename(filename, self.dirname)
                self.log(0, "Filename calculated as: '%s'" % self.Filename)
                #begin_date + " - " + service_name + description)
 
@@ -323,8 +328,12 @@ class RecordTimerEntry(timer.TimerEntry, object):
                        # that in our state, with also keeping the possibility to re-try.
                        # TODO: this has to be done.
                elif event == iRecordableService.evStart:
+                       text = _("A record has been started:\n%s") % self.name
+                       if self.dirnameHadToFallback:
+                               text = '\n'.join([text, _("Please note that the previously selected media could not be accessed and therefore the default directory is being used instead.")])
+
                        # maybe this should be configurable?
-                       Notifications.AddPopup(text = _("A record has been started:\n%s") % self.name, type = MessageBox.TYPE_INFO, timeout = 3)
+                       Notifications.AddPopup(text = text, type = MessageBox.TYPE_INFO, timeout = 3)
 
        # we have record_service as property to automatically subscribe to record service events
        def setRecordService(self, service):
@@ -355,11 +364,10 @@ def createTimer(xml):
        else:
                eit = None
        if xml.hasAttribute("location") and xml.getAttribute("location") != "None":
-               location = str(xml.getAttribute("location")).encode("utf-8")
+               location = xml.getAttribute("location").encode("utf-8")
        else:
                location = None
 
-
        name = xml.getAttribute("name").encode("utf-8")
        #filename = xml.getAttribute("filename").encode("utf-8")
        entry = RecordTimerEntry(serviceref, begin, end, name, description, eit, disabled, justplay, afterevent, dirname = location)
index a2bf0b695ec4e07d8ea440a2699e763bda22942d..f3ffc2deab0a4c539eb25b27f118a73512897485 100644 (file)
@@ -393,16 +393,20 @@ self.instance.move(ePoint((720-wsizex)/2, (576-wsizey)/(count &gt; 7 and 2 or 3)
                </widget>
        </screen>
        <!-- Location Box -->
-       <screen name="LocationBox" position="90,95" zPosition="3" size="560,430" title="Select Location">
-               <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
-               <widget name="green" 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_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="text" position="10,45" size="270,22" font="Regular;22" />
-               <widget name="target" position="280,45" size="270,22" font="Regular;22" halign="right" />
-               <widget name="filelist" position="10,80" size="540,347" scrollbarMode="showOnDemand" />
+       <screen name="LocationBox" position="100,75" size="540,460" >
+               <widget name="text" position="0,2" size="540,22" font="Regular;22" />
+               <widget name="target" position="0,23" size="540,22" valign="center" font="Regular;22" />
+               <widget name="filelist" position="0,55" zPosition="1" size="540,210" scrollbarMode="showOnDemand" selectionDisabled="1" />
+               <widget name="textbook" position="0,272" size="540,22" font="Regular;22" />
+               <widget name="booklist" position="5,302" zPosition="2" size="535,100" scrollbarMode="showOnDemand" />
+               <widget name="red" position="0,415" zPosition="1" size="135,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
+               <widget name="key_red" position="0,415" zPosition="2" size="135,40" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />       
+               <widget name="green" position="135,415" zPosition="1" size="135,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
+               <widget name="key_green" position="135,415" zPosition="2" size="135,40" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
+               <widget name="yellow" position="270,415" zPosition="1" size="135,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
+               <widget name="key_yellow" position="270,415" zPosition="2" size="135,40" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
+               <widget name="blue" position="405,415" zPosition="1" size="135,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
+               <widget name="key_blue" position="405,415" zPosition="2" size="135,40" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />                    
        </screen>
        <!-- Mediaplayer -->
        <screen name="MediaPlayer" position="70,70" size="580,475" title="MediaPlayer">
@@ -934,11 +938,10 @@ self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y()))
        <screen name="TimerEntry" position="90,95" size="560,430" title="Timer entry">
                <widget name="cancel" pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
                <widget name="ok" pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
-               <widget name="location" pixmap="skin_default/buttons/yellow.png" position="280,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="canceltext" position="0,0" zPosition="2" size="140,40" halign="center" valign="center" font="Regular;21" backgroundColor="#9f1313" transparent="1" />
                <widget name="oktext" position="140,0" zPosition="2" size="140,40" halign="center" valign="center" font="Regular;21" backgroundColor="#1f771f" transparent="1" />
-               <widget name="locationtext" position="280,0" zPosition="2" size="140,40" halign="center" valign="center" font="Regular;21" backgroundColor="#a08500" transparent="1" />
                <widget name="config" position="10,45" size="540,385" scrollbarMode="showOnDemand" />
        </screen>
        <!-- Timer log -->
index fcd1555f083fdd4cb7706dfc30b3a4d61500e5ae..5824747d0a95f571f67c009e78a2629b7f161f4e 100644 (file)
@@ -42,23 +42,52 @@ def FileEntryComponent(name, absolute = None, isDir = False):
        return res
 
 class FileList(MenuList):
-       def __init__(self, directory, showDirectories = True, showFiles = True, matchingPattern = None, useServiceRef = False, isTop = False, enableWrapAround = False, additionalExtensions = None):
+       def __init__(self, directory, showDirectories = True, showFiles = True, showMountpoints = True, matchingPattern = None, useServiceRef = False, inhibitDirs = False, inhibitMounts = False, enableWrapAround = False, additionalExtensions = None):
                MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
                self.additional_extensions = additionalExtensions
-               self.mount_point = None
+               self.mountpoints = []
                self.current_directory = None
+               self.current_mountpoint = None
                self.useServiceRef = useServiceRef
                self.showDirectories = showDirectories
+               self.showMountpoints = showMountpoints
                self.showFiles = showFiles
-               self.isTop = isTop
                # example: matching .nfi and .ts files: "^.*\.(nfi|ts)"
                self.matchingPattern = matchingPattern
-               self.changeDir(directory)
+               self.inhibitDirs = inhibitDirs or []
+               self.inhibitMounts = inhibitMounts or []
 
+               self.refreshMountpoints()
+               self.changeDir(directory)
                self.l.setFont(0, gFont("Regular", 18))
                self.l.setItemHeight(23)
                self.serviceHandler = eServiceCenter.getInstance()
 
+       def refreshMountpoints(self):
+               self.mountpoints = [os_path.join(p.mountpoint, "") for p in harddiskmanager.getMountedPartitions()]
+               self.mountpoints.sort(reverse = True)
+
+       def getMountpoint(self, file):
+               file = os_path.join(os_path.realpath(file), "")
+               for m in self.mountpoints:
+                       if file.startswith(m):
+                               return m
+               return False
+
+       def getMountpointLink(self, file):
+               if os_path.realpath(file) == file:
+                       return self.getMountpoint(file)
+               else:
+                       if file[-1] == "/":
+                               file = file[:-1]
+                       mp = self.getMountpoint(file)
+                       last = file
+                       file = os_path.dirname(file)
+                       while last != "/" and mp == self.getMountpoint(file):
+                               last = file
+                               file = os_path.dirname(file)
+                       return os_path.join(last, "")
+
        def getSelection(self):
                if self.l.getCurrentSelection() is None:
                        return None
@@ -74,36 +103,33 @@ class FileList(MenuList):
        def getFileList(self):
                return self.list
 
+       def inParentDirs(self, dir, parents):
+               dir = os_path.realpath(dir)
+               for p in parents:
+                       if dir.startswith(p):
+                               return True
+               return False
+
        def changeDir(self, directory, select = None):
                self.list = []
 
+               if directory and not os_path.isdir(directory):
+                       directory = None
                # if we are just entering from the list of mount points:
                if self.current_directory is None:
-                       if directory is None:
-                               self.mount_point = None
+                       if directory and self.showMountpoints:
+                               self.current_mountpoint = self.getMountpointLink(directory)
                        else:
-                               # Sort Mountpoints by length (longest first)
-                               sortedp = harddiskmanager.getMountedPartitions()
-                               sortedp.sort(key=lambda p: 0 - len(p.mountpoint))
-
-                               # Search for the longest matching mp (should at least match /)
-                               for p in sortedp:
-                                       if directory.startswith(p.mountpoint):
-                                               self.mount_point = p.mountpoint
-                                               if p.mountpoint != "/":
-                                                       self.mount_point += "/"
-                                               break
+                               self.current_mountpoint = None
                self.current_directory = directory
                directories = []
                files = []
 
-               if directory is None: # present available mountpoints
-                       print "listing partitions:"
+               if directory is None and self.showMountpoints: # present available mountpoints
                        for p in harddiskmanager.getMountedPartitions():
-                               if p.mountpoint == "/":
-                                       self.list.append(FileEntryComponent(name = p.description, absolute = p.mountpoint, isDir = True))
-                               else:
-                                       self.list.append(FileEntryComponent(name = p.description, absolute = p.mountpoint + "/", isDir = True))
+                               path = os_path.join(p.mountpoint,"")
+                               if not self.inhibitMounts or ((not path in self.inhibitMounts) and (not self.inParentDirs(path, self.inhibitDirs))):
+                                       self.list.append(FileEntryComponent(name = p.description, absolute = path, isDir = True))
                        files = [ ]
                        directories = [ ]
                elif self.useServiceRef:
@@ -122,7 +148,6 @@ class FileList(MenuList):
                                        directories.append(s.getPath())
                                else:
                                        files.append(s)
-                               print s.getName(), s.flags
                        directories.sort()
                        files.sort()
                else:
@@ -135,16 +160,17 @@ class FileList(MenuList):
                                                directories.append(directory + x + "/")
                                                files.remove(x)
 
-               if directory is not None and self.showDirectories and not self.isTop:
-                       if directory == self.mount_point:
-                               self.list.append(FileEntryComponent(name = ".. (" +_("List of Storage Devices") + ")", absolute = None, isDir = True))
-                       else:
-                               self.list.append(FileEntryComponent(name = "..", absolute = '/'.join(directory.split('/')[:-2]) + '/', isDir = True))
+               if directory is not None and self.showDirectories:
+                       if directory == self.current_mountpoint and self.showMountpoints:
+                               self.list.append(FileEntryComponent(name = "<" +_("List of Storage Devices") + ">", absolute = None, isDir = True))
+                       elif (directory != "/") and not (self.inhibitMounts and self.getMountpoint(directory) in self.inhibitMounts):
+                               self.list.append(FileEntryComponent(name = "<" +_("Parent Directory") + ">", absolute = '/'.join(directory.split('/')[:-2]) + '/', isDir = True))
 
                if self.showDirectories:
                        for x in directories:
-                               name = x.split('/')[-2]
-                               self.list.append(FileEntryComponent(name = name, absolute = x, isDir = True))
+                               if not (self.inhibitMounts and self.getMountpoint(x) in self.inhibitMounts) and not self.inParentDirs(x, self.inhibitDirs):
+                                       name = x.split('/')[-2]
+                                       self.list.append(FileEntryComponent(name = name, absolute = x, isDir = True))
 
                if self.showFiles:
                        for x in files:
@@ -155,10 +181,7 @@ class FileList(MenuList):
                                        path = directory + x
                                        name = x
 
-                               if self.matchingPattern is not None:
-                                       if re.compile(self.matchingPattern).search(path):
-                                               self.list.append(FileEntryComponent(name = name, absolute = x , isDir = False))
-                               else:
+                               if (self.matchingPattern is None) or re.compile(self.matchingPattern).search(path):
                                        self.list.append(FileEntryComponent(name = name, absolute = x , isDir = False))
 
                self.l.setList(self.list)
@@ -215,5 +238,6 @@ class FileList(MenuList):
                self.changeDir(self.current_directory, self.getFilename())
 
        def partitionListChanged(self, action, device):
+               self.refreshMountpoints()
                if self.current_directory is None:
                        self.refresh()
index b0f5fe6d9ed13de26096777b25ad61bae5414b15..529b602078a42c443c9dd7d9cb4a3d54fa5ab0c5 100644 (file)
@@ -2,8 +2,9 @@ import time
 from enigma import getPrevAsciiCode
 from Tools.NumericalTextInput import NumericalTextInput
 from Tools.Directories import resolveFilename, SCOPE_CONFIG
+from Components.Harddisk import harddiskmanager
 import copy
-
+import os
 
 # ConfigElement, the base class of all ConfigElements.
 
@@ -845,6 +846,237 @@ class ConfigSatlist(ConfigSelection):
        
        orbital_position = property(getOrbitalPosition)
 
+class ConfigSet(ConfigElement):
+       def __init__(self, choices, default = []):
+               ConfigElement.__init__(self)
+               self.choices = []
+               self.description = {}
+               if isinstance(choices, list):
+                       choices.sort()
+                       for x in choices:
+                               if isinstance(x, tuple):
+                                       self.choices.append(x[0])
+                                       self.description[x[0]] = str(x[1])
+                               else:
+                                       self.choices.append(x)
+                                       self.description[x] = str(x)
+               else:
+                       assert False, "ConfigSet choices must be a list!"
+               if len(self.choices) == 0:
+                       self.choices = [""]
+                       self.description[""] = ""
+               if default is None:
+                       default = []
+               self.pos = -1
+               default.sort()
+               self.default = default
+               self.value = default+[]
+
+       def toggleChoice(self, choice):
+               if choice in self.value:
+                       self.value.remove(choice)
+               else:
+                       self.value.append(choice)
+                       self.value.sort()
+
+       def handleKey(self, key):
+               if key in KEY_NUMBERS + [KEY_DELETE, KEY_BACKSPACE]:
+                       if self.pos != -1:
+                               self.toggleChoice(self.choices[self.pos])
+               elif key == KEY_LEFT:
+                       self.pos -= 1
+                       if self.pos < -1:
+                           self.pos = len(self.choices)-1
+               elif key == KEY_RIGHT:
+                       self.pos += 1
+                       if self.pos >= len(self.choices):
+                           self.pos = -1
+               elif key in [KEY_HOME, KEY_END]:
+                       self.pos = -1
+
+       def genString(self, lst):
+               res = ""
+               for x in lst:
+                       res += self.description[x]+" "
+               return res
+
+       def getText(self):
+               return self.genString(self.value)
+
+       def getMulti(self, selected):
+               if not selected or self.pos == -1:
+                       return ("text", self.genString(self.value))
+               else:
+                       tmp = self.value+[]
+                       ch = self.choices[self.pos]
+                       mem = ch in self.value
+                       if not mem:
+                               tmp.append(ch)
+                               tmp.sort()
+                       ind = tmp.index(ch)
+                       val1 = self.genString(tmp[:ind])
+                       val2 = " "+self.genString(tmp[ind+1:])
+                       if mem:
+                               chstr = " "+self.description[ch]+" "
+                       else:
+                               chstr = "("+self.description[ch]+")"
+                       return ("mtext", val1+chstr+val2, range(len(val1),len(val1)+len(chstr)))
+
+       def onDeselect(self, session):
+               self.pos = -1
+               self.changed()
+               
+       def tostring(self, value):
+               return str(value)
+
+       def fromstring(self, val):
+               return eval(val)
+
+class ConfigLocations(ConfigElement):
+       def __init__(self, default = [], visible_width = False):
+               ConfigElement.__init__(self)
+               self.pos = -1
+               self.default = default
+               self.locations = []
+               self.mountpoints = []
+               harddiskmanager.on_partition_list_change.append(self.mountpointsChanged)
+
+       def setValue(self, value):
+               loc = [x[0] for x in self.locations if x[3]]
+               add = [x for x in value if not x in loc]
+               diff = add + [x for x in loc if not x in value]
+               self.locations = [x for x in self.locations if not x[0] in diff] + [[x, self.getMountpoint(x), True, True] for x in add]
+               self.locations.sort(key = lambda x: x[0])
+               self.changed()
+
+       def getValue(self):
+               self.checkChangedMountpoints()
+               for x in self.locations:
+                       x[3] = x[2]
+               return [x[0] for x in self.locations if x[3]]
+       
+       value = property(getValue, setValue)
+
+       def tostring(self, value):
+               return str(value)
+
+       def fromstring(self, val):
+               return eval(val)
+
+       def load(self):
+               if self.saved_value is None:
+                       tmp = self.default
+               else:
+                       tmp = self.fromstring(self.saved_value)
+               self.locations = [[x, None, False, False] for x in tmp]
+               self.refreshMountpoints()
+               for x in self.locations:
+                       if os.path.exists(x[0]):
+                               x[1] = self.getMountpoint(x[0])
+                               x[2] = True
+
+       def save(self):
+               if self.save_disabled or self.locations == []:
+                       self.saved_value = None
+               else:
+                       self.saved_value = self.tostring([x[0] for x in self.locations])
+
+       def isChanged(self):
+               if self.saved_value is None and self.locations == []:
+                       return False
+               return self.tostring([x[0] for x in self.locations]) != self.saved_value
+
+       def mountpointsChanged(self, action, dev):
+               print "Mounts changed: ", action, dev
+               mp = dev.mountpoint+"/"
+               if action == "add":
+                       self.addedMount(mp)
+               elif action == "remove":
+                       self.removedMount(mp)
+               self.refreshMountpoints()
+
+       def addedMount(self, mp):
+               for x in self.locations:
+                       if x[1] == mp:
+                               x[2] = True
+                       elif x[1] == None and os.path.exists(x[0]):
+                               x[1] = self.getMountpoint(x[0])
+                               x[2] = True
+
+       def removedMount(self, mp):
+               for x in self.locations:
+                       if x[1] == mp:
+                               x[2] = False
+               
+       def refreshMountpoints(self):
+               self.mountpoints = [p.mountpoint + "/" for p in harddiskmanager.getMountedPartitions() if p.mountpoint != "/"]
+               self.mountpoints.sort(key = lambda x: -len(x))
+
+       def checkChangedMountpoints(self):
+               oldmounts = self.mountpoints
+               self.refreshMountpoints()
+               if oldmounts == self.mountpoints:
+                       return
+               for x in oldmounts:
+                       if not x in self.mountpoints:
+                               self.removedMount(x)
+               for x in self.mountpoints:
+                       if not x in oldmounts:
+                               self.addedMount(x)
+
+       def getMountpoint(self, file):
+               file = os.path.realpath(file)+"/"
+               for m in self.mountpoints:
+                       if file.startswith(m):
+                               return m
+               return None
+
+       def handleKey(self, key):
+               if key == KEY_LEFT:
+                       self.pos -= 1
+                       if self.pos < -1:
+                           self.pos = len(self.value)-1
+               elif key == KEY_RIGHT:
+                       self.pos += 1
+                       if self.pos >= len(self.value):
+                           self.pos = -1
+               elif key in [KEY_HOME, KEY_END]:
+                       self.pos = -1
+
+       def getText(self):
+               return " ".join(self.value)
+
+       def getMulti(self, selected):
+               if not selected:
+                       valstr = " ".join(self.value)
+                       if self.visible_width and len(valstr) > self.visible_width:
+                               return ("text", valstr[0:self.visible_width])
+                       else:
+                               return ("text", valstr)
+               else:
+                       i = 0
+                       valstr = ""
+                       ind1 = 0
+                       ind2 = 0
+                       for val in self.value:
+                               if i == self.pos:
+                                       ind1 = len(valstr)
+                               valstr += str(val)+" "
+                               if i == self.pos:
+                                       ind2 = len(valstr)
+                               i += 1
+                       if self.visible_width and len(valstr) > self.visible_width:
+                               if ind1+1 < self.visible_width/2:
+                                       off = 0
+                               else:
+                                       off = min(ind1+1-self.visible_width/2, len(valstr)-self.visible_width)
+                               return ("mtext", valstr[off:off+self.visible_width], range(ind1-off,ind2-off))
+                       else:
+                               return ("mtext", valstr, range(ind1,ind2))
+
+       def onDeselect(self, session):
+               self.pos = -1
+               
 # nothing.
 class ConfigNothing(ConfigSelection):
        def __init__(self):
@@ -1023,93 +1255,6 @@ class ConfigSubsection(object):
        def dict(self):
                return self.content.items
 
-class ConfigSet(ConfigElement):
-       def __init__(self, choices, default = []):
-               ConfigElement.__init__(self)
-               self.choices = []
-               self.description = {}
-               if isinstance(choices, list):
-                       choices.sort()
-                       for x in choices:
-                               if isinstance(x, tuple):
-                                       self.choices.append(x[0])
-                                       self.description[x[0]] = str(x[1])
-                               else:
-                                       self.choices.append(x)
-                                       self.description[x] = str(x)
-               else:
-                       assert False, "ConfigSet choices must be a list!"
-               if len(self.choices) == 0:
-                       self.choices = [""]
-                       self.description[""] = ""
-               if default is None:
-                       default = []
-               self.pos = -1
-               default.sort()
-               self.default = default
-               self.value = default+[]
-
-       def toggleChoice(self, choice):
-               if choice in self.value:
-                       self.value.remove(choice)
-               else:
-                       self.value.append(choice)
-                       self.value.sort()
-
-       def handleKey(self, key):
-               if key in KEY_NUMBERS + [KEY_DELETE, KEY_BACKSPACE]:
-                       if self.pos != -1:
-                               self.toggleChoice(self.choices[self.pos])
-               elif key == KEY_LEFT:
-                       self.pos -= 1
-                       if self.pos < -1:
-                           self.pos = len(self.choices)-1
-               elif key == KEY_RIGHT:
-                       self.pos += 1
-                       if self.pos >= len(self.choices):
-                           self.pos = -1
-               elif key in [KEY_HOME, KEY_END]:
-                       self.pos = -1
-
-       def genString(self, lst):
-               res = ""
-               for x in lst:
-                       res += self.description[x]+" "
-               return res
-
-       def getText(self):
-               return self.genString(self.value)
-
-       def getMulti(self, selected):
-               if not selected or self.pos == -1:
-                       return ("text", self.genString(self.value))
-               else:
-                       tmp = self.value+[]
-                       ch = self.choices[self.pos]
-                       mem = ch in self.value
-                       if not mem:
-                               tmp.append(ch)
-                               tmp.sort()
-                       ind = tmp.index(ch)
-                       val1 = self.genString(tmp[:ind])
-                       val2 = " "+self.genString(tmp[ind+1:])
-                       if mem:
-                               chstr = " "+self.description[ch]+" "
-                       else:
-                               chstr = "("+self.description[ch]+")"
-                       return ("mtext", val1+chstr+val2, range(len(val1),len(val1)+len(chstr)))
-
-       def onDeselect(self, session):
-               self.pos = -1
-               self.changed()
-               
-       def tostring(self, value):
-               return str(value)
-
-       def fromstring(self, val):
-               return eval(val)
-
-
 # the root config object, which also can "pickle" (=serialize)
 # down the whole config tree.
 #
index 18247bbbdfba04ed2a31209adf31edcb007b8454..036cb7a6fd7a88f50abbd8761ba63fd32de9fe6e 100644 (file)
@@ -498,7 +498,7 @@ class GraphMultiEPG(Screen):
                serviceref = cur[1]
                if event is None:
                        return
-               newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, *parseEvent(event))
+               newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, dirname = config.movielist.last_timer_videodir.value, *parseEvent(event))
                self.session.openWithCallback(self.timerEditFinished, TimerEntry, newEntry)
 
        def timerEditFinished(self, answer):
index a2c31d266b08265a26c3692eac877b4972a08447..edad3596ab24e2241ce1a15d54b13da86ff8360e 100644 (file)
@@ -184,7 +184,7 @@ class EPGSelection(Screen):
                serviceref = cur[1]
                if event is None:
                        return
-               newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, *parseEvent(event))
+               newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, dirname = config.movielist.last_timer_videodir.value, *parseEvent(event))
                self.session.openWithCallback(self.timerEditFinished, TimerEntry, newEntry)
 
        def timerEditFinished(self, answer):
index 1bb3d0b16adb184d78f5a71dcbc719f5c9f030a6..964973d381143fe3e53de1ee255c01044b71b51e 100644 (file)
@@ -7,6 +7,7 @@ from enigma import eEPGCache, eTimer, eServiceReference
 from RecordTimer import RecordTimerEntry, parseEvent
 from TimerEntry import TimerEntry
 from time import localtime
+from Components.config import config
 
 class EventViewBase:
        def __init__(self, Event, Ref, callback=None, similarEPGCB=None):
@@ -58,7 +59,7 @@ class EventViewBase:
 
        def timerAdd(self):
                if not self.isRecording:
-                       newEntry = RecordTimerEntry(self.currentService, checkOldTimers = True, *parseEvent(self.event))
+                       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):
index 6ece278425f30c32dd6f52844fd34f7414dc716a..e7f71daf7766c5ee1f572e5dea7e36e3e7ef9c0f 100644 (file)
@@ -1356,7 +1356,7 @@ class InfoBarPiP:
                elif "stop" == use:
                        self.showPiP()
 
-from RecordTimer import parseEvent
+from RecordTimer import parseEvent, RecordTimerEntry
 
 class InfoBarInstantRecord:
        """Instant Record - handles the instantRecord action in order to
@@ -1406,10 +1406,14 @@ class InfoBarInstantRecord:
                        if limitEvent:
                                self.session.open(MessageBox, _("No event info found, recording indefinitely."), MessageBox.TYPE_INFO)
 
-               data = (begin, end, name, description, eventid)
+               # TODO: needed?
+               if isinstance(serviceref, eServiceReference):
+                       serviceref = ServiceReference(serviceref)
 
-               recording = self.session.nav.recordWithTimer(serviceref, *data)
+               recording = RecordTimerEntry(serviceref, begin, end, name, description, eventid, dirname = config.movielist.last_videodir.value)
                recording.dontSave = True
+
+               self.session.nav.RecordTimer.record(recording)
                self.recording.append(recording)
 
        def isInstantRecordRunning(self):
index de7923e43c315f329f61a8bc5c92d7fced6084cb..132f14014f2cb901e2f4e61bcd64fd27c9b5bb0d 100644 (file)
@@ -6,40 +6,54 @@
 from Screens.Screen import Screen
 from Screens.MessageBox import MessageBox
 from Screens.InputBox import InputBox
+from Screens.HelpMenu import HelpableScreen
+from Screens.ChoiceBox import ChoiceBox
 
 # Generic
 from Tools.BoundFunction import boundFunction
+from Tools.Directories import *
+from Components.config import config, configfile, ConfigSubList, ConfigSubsection, \
+               ConfigText, ConfigNumber, ConfigBoolean
+import os
 
 # Quickselect
 from Tools.NumericalTextInput import NumericalTextInput
 
 # GUI (Components)
-from Components.ActionMap import NumberActionMap
+from Components.ActionMap import NumberActionMap, HelpableActionMap
 from Components.Label import Label
 from Components.Pixmap import Pixmap
 from Components.Button import Button
 from Components.FileList import FileList
+from Components.MenuList import MenuList
 
 # Timer
 from enigma import eTimer
 
-class LocationBox(Screen, NumericalTextInput):
+class LocationBox(Screen, NumericalTextInput, HelpableScreen):
        """Simple Class similar to MessageBox / ChoiceBox but used to choose a folder/pathname combination"""
 
-       skin = """<screen name="LocationBox" position="100,130" size="540,340" >
+       skin = """<screen name="LocationBox" position="100,75" size="540,460" >
                        <widget name="text" position="0,2" size="540,22" font="Regular;22" />
-                       <widget name="filelist" position="0,25" size="540,235" />
-                       <widget name="target" position="0,260" size="540,40" valign="center" font="Regular;22" />
-                       <widget name="yellow" position="260,300" zPosition="1" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
-                       <widget name="key_yellow" position="260,300" zPosition="2" size="140,40" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
-                       <widget name="green" position="400,300" zPosition="1" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
-                       <widget name="key_green" position="400,300" zPosition="2" size="140,40" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
+                       <widget name="target" position="0,23" size="540,22" valign="center" font="Regular;22" />
+                       <widget name="filelist" position="0,55" zPosition="1" size="540,210" scrollbarMode="showOnDemand" selectionDisabled="1" />
+                       <widget name="textbook" position="0,272" size="540,22" font="Regular;22" />
+                       <widget name="booklist" position="5,302" zPosition="2" size="535,100" scrollbarMode="showOnDemand" />
+                       <widget name="red" position="0,415" zPosition="1" size="135,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
+                       <widget name="key_red" position="0,415" zPosition="2" size="135,40" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />   
+                       <widget name="green" position="135,415" zPosition="1" size="135,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
+                       <widget name="key_green" position="135,415" zPosition="2" size="135,40" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
+                       <widget name="yellow" position="270,415" zPosition="1" size="135,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
+                       <widget name="key_yellow" position="270,415" zPosition="2" size="135,40" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
+                       <widget name="blue" position="405,415" zPosition="1" size="135,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
+                       <widget name="key_blue" position="405,415" zPosition="2" size="135,40" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />            
                </screen>"""
 
-       def __init__(self, session, text = "", filename = "", currDir = None, windowTitle = _("Select Location"), minFree = None):
+       def __init__(self, session, text = "", filename = "", currDir = None, bookmarks = None, userMode = False, windowTitle = _("Select Location"), minFree = None, autoAdd = False, editDir = False, inhibitDirs = [], inhibitMounts = []):
                # Init parents
                Screen.__init__(self, session)
                NumericalTextInput.__init__(self, handleTimeout = False)
+               HelpableScreen.__init__(self)
 
                # Set useable chars
                self.setUseableChars(u'1234567890abcdefghijklmnopqrstuvwxyz')
@@ -55,50 +69,84 @@ class LocationBox(Screen, NumericalTextInput):
 
                # Set Text
                self["text"] = Label(text)
+               self["textbook"] = Label(_("Bookmarks"))
 
                # Save parameters locally
                self.text = text
                self.filename = filename
                self.minFree = minFree
+               self.realBookmarks = bookmarks
+               self.bookmarks = bookmarks and bookmarks.value[:] or []
+               self.userMode = userMode
+               self.autoAdd = autoAdd
+               self.editDir = editDir
+               self.inhibitDirs = inhibitDirs
 
                # Initialize FileList
-               self["filelist"] = FileList(currDir, showDirectories = True, showFiles = False)
+               self["filelist"] = FileList(currDir, showDirectories = True, showFiles = False, inhibitMounts = inhibitMounts, inhibitDirs = inhibitDirs)
+
+               # Initialize BookList
+               self["booklist"] = MenuList(self.bookmarks)
 
                # Buttons
-               self["key_green"] = Button(_("Confirm"))
+               self["key_green"] = Button(_("OK"))
                self["key_yellow"] = Button(_("Rename"))
+               self["key_blue"] = Button(_("Remove Bookmark"))
+               self["key_red"] = Button(_("Cancel"))
 
                # Background for Buttons
                self["green"] = Pixmap()
                self["yellow"] = Pixmap()
+               self["blue"] = Pixmap()
+               self["red"] = Pixmap()
 
                # Initialize Target
                self["target"] = Label()
 
+               if self.userMode:
+                       self.usermodeOn()
+
                # Custom Action Handler
-               class LocationBoxActionMap(NumberActionMap):
-                       def __init__(self, box, contexts = [ ], actions = { }, prio=0):                                                                                                                                                                                                                                    
-                               NumberActionMap.__init__(self, contexts, actions, prio)
-                               self.box = box
+               class LocationBoxActionMap(HelpableActionMap):
+                       def __init__(self, parent, context, actions = { }, prio=0):
+                               HelpableActionMap.__init__(self, parent, context, actions, prio)
+                               self.box = parent
 
                        def action(self, contexts, action):
                                # Reset Quickselect
                                self.box.timeout(force = True)
 
-                               return NumberActionMap.action(self, contexts, action)
+                               return HelpableActionMap.action(self, contexts, action)
 
                # Actions that will reset quickselect
-               self["actions"] = LocationBoxActionMap(self, ["WizardActions", "ColorActions"],
-               {
-                       "ok": self.ok,
-                       "back": self.cancel,
-                       "green": self.select,
-                       "yellow": self.changeName,
-                       "left": self.left,
-                       "right": self.right,
-                       "up": self.up,
-                       "down": self.down,
-               }, -2)
+               self["WizardActions"] = LocationBoxActionMap(self, "WizardActions",
+                       {
+                               "left": self.left,
+                               "right": self.right,
+                               "up": self.up,
+                               "down": self.down,
+                               "ok": (self.ok, _("select")),
+                               "back": (self.cancel, _("cancel")),
+                       }, -2)
+
+               self["ColorActions"] = LocationBoxActionMap(self, "ColorActions",
+                       {
+                               "red": self.cancel,
+                               "green": self.select,
+                               "yellow": self.changeName,
+                               "blue": self.addRemoveBookmark,
+                       }, -2)
+
+               self["EPGSelectActions"] = LocationBoxActionMap(self, "EPGSelectActions",
+                       {
+                               "prevBouquet": (self.switchToBookList, _("switch to bookmarks")),
+                               "nextBouquet": (self.switchToFileList, _("switch to filelist")),
+                       }, -2)
+
+               self["MenuActions"] = LocationBoxActionMap(self, "MenuActions",
+                       {
+                               "menu": (self.showMenu, _("menu")),
+                       }, -2)
 
                # Actions used by quickselect
                self["NumberActions"] = NumberActionMap(["NumberActions"],
@@ -119,55 +167,181 @@ class LocationBox(Screen, NumericalTextInput):
                self.onShown.extend([
                        boundFunction(self.setTitle, windowTitle),
                        self.updateTarget,
-                       self.showHideRename
+                       self.showHideRename,
                ])
+
+               self.onLayoutFinish.append(self.switchToFileListOnStart)
  
                # Make sure we remove our callback
                self.onClose.append(self.disableTimer)
 
+       def switchToFileListOnStart(self):
+               if self.realBookmarks and self.realBookmarks.value:
+                       self.currList = "booklist"
+                       currDir = self["filelist"].current_directory
+                       if currDir in self.bookmarks:
+                               self["booklist"].moveToIndex(self.bookmarks.index(currDir))
+               else:
+                       self.switchToFileList()
+
        def disableTimer(self):
                self.qs_timer.callback.remove(self.timeout)
 
        def showHideRename(self):
                # Don't allow renaming when filename is empty
                if self.filename == "":
-                       self["yellow"].hide()
                        self["key_yellow"].hide()
 
+       def switchToFileList(self):
+               if not self.userMode:
+                       self.currList = "filelist"
+                       self["filelist"].selectionEnabled(1)
+                       self["booklist"].selectionEnabled(0)
+                       self["key_blue"].text = _("Add Bookmark")
+                       self.updateTarget()
+
+       def switchToBookList(self):
+               self.currList = "booklist"
+               self["filelist"].selectionEnabled(0)
+               self["booklist"].selectionEnabled(1)
+               self["key_blue"].text = _("Remove Bookmark")
+               self.updateTarget()
+
+       def addRemoveBookmark(self):
+               if self.currList == "filelist":
+                       # add bookmark
+                       folder = self["filelist"].getSelection()[0]
+                       if folder is not None and not folder in self.bookmarks:
+                               self.bookmarks.append(folder)
+                               self.bookmarks.sort()
+                               self["booklist"].setList(self.bookmarks)
+               else:
+                       # remove bookmark
+                       if not self.userMode:
+                               name = self["booklist"].getCurrent()
+                               self.session.openWithCallback(
+                                       boundFunction(self.removeBookmark, name),
+                                       MessageBox,
+                                       _("Do you really want to remove your bookmark of %s?") % (name),
+                               )
+
+       def removeBookmark(self, name, ret):
+               if not ret:
+                       return
+               if name in self.bookmarks:
+                       self.bookmarks.remove(name)
+                       self["booklist"].setList(self.bookmarks)
+
+       def createDir(self):
+               if self["filelist"].current_directory != None:
+                       self.session.openWithCallback(
+                               self.createDirCallback,
+                               InputBox,
+                               title = _("Please enter name of the new directory"),
+                               text = ""
+                       )
+
+       def createDirCallback(self, res):
+               if res is not None and len(res):
+                       path = os.path.join(self["filelist"].current_directory, res)
+                       if not pathExists(path):
+                               if not createDir(path):
+                                       self.session.open(
+                                               MessageBox,
+                                               _("Creating directory %s failed.") % (path),
+                                               type = MessageBox.TYPE_ERROR,
+                                               timeout = 5
+                                       )
+                               self["filelist"].refresh()
+                       else:
+                               self.session.open(
+                                       MessageBox,
+                                       _("The path %s already exists.") % (path),
+                                       type = MessageBox.TYPE_ERROR,
+                                       timeout = 5
+                               )
+
+       def removeDir(self):
+               sel = self["filelist"].getSelection()
+               if sel and pathExists(sel[0]):
+                       self.session.openWithCallback(
+                               boundFunction(self.removeDirCallback, sel[0]),
+                               MessageBox,
+                               _("Do you really want to remove directory %s from the disk?") % (sel[0]),
+                               type = MessageBox.TYPE_YESNO
+                       )
+               else:
+                       self.session.open(
+                               MessageBox,
+                               _("Invalid directory selected: %s") % (sel[0]),
+                               type = MessageBox.TYPE_ERROR,
+                               timeout = 5
+                       )
+
+       def removeDirCallback(self, name, res):
+               if res:
+                       if not removeDir(name):
+                               self.session.open(
+                                       MessageBox,
+                                       _("Removing directory %s failed. (Maybe not empty.)") % (name),
+                                       type = MessageBox.TYPE_ERROR,
+                                       timeout = 5
+                               )
+                       else:
+                               self["filelist"].refresh()
+                               self.removeBookmark(name, True)
+
        def up(self):
-               self["filelist"].up()
+               self[self.currList].up()
+               self.updateTarget()
 
        def down(self):
-               self["filelist"].down()
+               self[self.currList].down()
+               self.updateTarget()
 
        def left(self):
-               self["filelist"].pageUp()
+               self[self.currList].pageUp()
+               self.updateTarget()
 
        def right(self):
-               self["filelist"].pageDown()
+               self[self.currList].pageDown()
+               self.updateTarget()
 
        def ok(self):
-               if self["filelist"].canDescent():
-                       self["filelist"].descent()
-                       self.updateTarget()
+               if self.currList == "filelist":
+                       if self["filelist"].canDescent():
+                               self["filelist"].descent()
+                               self.updateTarget()
+               else:
+                       self.select()
 
        def cancel(self):
                self.close(None)
 
+       def getPreferredFolder(self):
+               if self.currList == "filelist":
+                       # XXX: We might want to change this for parent folder...
+                       return self["filelist"].getSelection()[0]
+               else:
+                       return self["booklist"].getCurrent()
+
        def selectConfirmed(self, res):
-               if res: 
-                       self.close(''.join([self["filelist"].getCurrentDirectory(), self.filename]))
+               if res:
+                       ret = ''.join([self.getPreferredFolder(), self.filename])
+                       if self.realBookmarks and self.autoAdd and not ret in self.bookmarks:
+                               self.bookmarks.append(self.getPreferredFolder())
+                               self.bookmarks.sort()
+                       self.close(ret)
 
        def select(self):
+               currentFolder = self.getPreferredFolder()
                # Do nothing unless current Directory is valid
-               if self["filelist"].getCurrentDirectory() is not None:
+               if currentFolder is not None:
                        # Check if we need to have a minimum of free Space available
                        if self.minFree is not None:
                                # Try to read fs stats
                                try:
-                                       from os import statvfs
-
-                                       s = statvfs(self["filelist"].getCurrentDirectory())
+                                       s = os.statvfs(currentFolder)
                                        if (s.f_bavail * s.f_bsize) / 1000000 > self.minFree:
                                                # Automatically confirm if we have enough free disk Space available
                                                return self.selectConfirmed(True)
@@ -181,14 +355,19 @@ class LocationBox(Screen, NumericalTextInput):
                                        _("There might not be enough Space on the selected Partition.\nDo you really want to continue?"),
                                        type = MessageBox.TYPE_YESNO
                                )
-                       # No minimum free Space means we can safely close
-                       else:   
+                               # No minimum free Space means we can safely close
+                       else:
                                self.selectConfirmed(True)
 
+       def close(self, ret):
+               if ret and self.realBookmarks and self.bookmarks != self.realBookmarks.value:
+                       self.realBookmarks.value = self.bookmarks
+                       self.realBookmarks.save()
+               Screen.close(self, ret)
+
        def changeName(self):
                if self.filename != "":
                        # TODO: Add Information that changing extension is bad? disallow?
-                       # TODO: decide if using an inputbox is ok - we could also keep this in here
                        self.session.openWithCallback(
                                self.nameChanged,
                                InputBox,
@@ -211,12 +390,42 @@ class LocationBox(Screen, NumericalTextInput):
 
        def updateTarget(self):
                # Write Combination of Folder & Filename when Folder is valid
-               if self["filelist"].getCurrentDirectory() is not None:
-                       self["target"].setText(''.join([self["filelist"].getCurrentDirectory(), self.filename]))
-               # Warning else
+               currFolder = self.getPreferredFolder()
+               if currFolder is not None:
+                       self["target"].setText(''.join([currFolder, self.filename]))
+               # Display a Warning otherwise
                else:
                        self["target"].setText(_("Invalid Location"))
 
+       def showMenu(self):
+               if not self.userMode and self.realBookmarks:
+                       menu = []
+                       if self.currList == "filelist":
+                               menu.append((_("switch to bookmarks"), self.switchToBookList))
+                               menu.append((_("add bookmark"), self.AddRemoveBookmark))
+                               if self.editDir:
+                                       menu.append((_("create directory"), self.createDir))
+                                       menu.append((_("remove directory"), self.removeDir))
+                       else:
+                               menu.append((_("switch to filelist"), self.switchToFileList))
+                               menu.append((_("remove bookmark"), self.AddRemoveBookmark))
+
+                       self.session.openWithCallback(
+                               self.menuCallback,
+                               ChoiceBox,
+                               title = "",
+                               list = menu
+                       )
+
+       def menuCallback(self, choice):
+               if choice:
+                       choice[1]()
+                       
+       def usermodeOn(self):
+               self.switchToBookList()
+               self["filelist"].hide()
+               self["key_blue"].hide()
+
        def keyNumberGlobal(self, number):
                # Cancel Timeout
                self.qs_timer.stop()
@@ -290,3 +499,9 @@ class LocationBox(Screen, NumericalTextInput):
        def __repr__(self):
                return str(type(self)) + "(" + self.text + ")"
 
+class MovieLocationBox(LocationBox):
+       def __init__(self, session, text, dir, minFree = None):
+               inhibitMounts = []
+               if config.usage.setup_level.index < 2: # -expert
+                       inhibitMounts.append("/")
+               LocationBox.__init__(self, session, text = text, currDir = dir, bookmarks = config.movielist.videodirs, autoAdd = True, editDir = True, inhibitMounts = inhibitMounts, minFree = minFree)
index a2ccb79a4b10b9c0a04e9a433a4a94a0b7f1b98b..c05f145f9d9e96dcd3bfcdd06ef9a2fe6c8a465c 100644 (file)
@@ -7,14 +7,14 @@ from Components.DiskInfo import DiskInfo
 from Components.Pixmap import Pixmap
 from Components.Label import Label
 from Components.PluginComponent import plugins
-from Components.config import config, ConfigSubsection, ConfigText, ConfigInteger, configfile
+from Components.config import config, ConfigSubsection, ConfigText, ConfigInteger, ConfigLocations
 from Components.Sources.ServiceEvent import ServiceEvent
 
 from Plugins.Plugin import PluginDescriptor
 
 from Screens.MessageBox import MessageBox
 from Screens.ChoiceBox import ChoiceBox
-from Screens.LocationBox import LocationBox
+from Screens.LocationBox import MovieLocationBox
 from Screens.HelpMenu import HelpableScreen
 
 from Tools.Directories import *
@@ -26,8 +26,9 @@ config.movielist = ConfigSubsection()
 config.movielist.moviesort = ConfigInteger(default=MovieList.SORT_RECORDED)
 config.movielist.listtype = ConfigInteger(default=MovieList.LISTTYPE_ORIGINAL)
 config.movielist.description = ConfigInteger(default=MovieList.HIDE_DESCRIPTION)
-# FIXME: see if this is always accessible by InfoBarGenerics
 config.movielist.last_videodir = ConfigText(default=resolveFilename(SCOPE_HDD))
+config.movielist.last_timer_videodir = ConfigText(default=resolveFilename(SCOPE_HDD))
+config.movielist.videodirs = ConfigLocations(default=[resolveFilename(SCOPE_HDD)])
 
 class MovieContextMenu(Screen):
        def __init__(self, session, csel, service):
@@ -69,7 +70,6 @@ class MovieContextMenu(Screen):
                self.close(False)
 
        def sortBy(self, newType):
-               self.csel.saveflag = True
                config.movielist.moviesort.value = newType
                self.csel.selectedmovie = self.csel.getCurrent()
                self.csel.setSortType(newType)
@@ -78,14 +78,12 @@ class MovieContextMenu(Screen):
                self.close()
 
        def listType(self, newType):
-               self.csel.saveflag = True
                config.movielist.listtype.value = newType
                self.csel.setListType(newType)
                self.csel.list.redrawList()
                self.close()
 
        def showDescription(self, newType):
-               self.csel.saveflag = True
                config.movielist.description.value = newType
                self.csel.setDescriptionState(newType)
                self.csel.updateDescription()
@@ -124,7 +122,8 @@ class MovieContextMenu(Screen):
                if result == False:
                        self.session.openWithCallback(self.close, MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
                else:
-                       list = self.csel["list"].removeService(self.service)
+                       self.csel["list"].removeService(self.service)
+                       self.csel["freeDiskSpace"].update()
                        self.close()
 
 class SelectionEventInfo:
@@ -148,13 +147,9 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
                Screen.__init__(self, session)
                HelpableScreen.__init__(self)
 
-               self.saveflag = False
-
                self.tags = [ ]
                self.selected_tags = None
 
-               self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + config.movielist.last_videodir.value)
-
                self.movemode = False
                self.bouquet_mark_edit = False
 
@@ -167,6 +162,11 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
                self["DescriptionBorder"] = Pixmap()
                self["DescriptionBorder"].hide()
 
+               if not pathExists(config.movielist.last_videodir.value):
+                       config.movielist.last_videodir.value = resolveFilename(SCOPE_HDD)
+                       config.movielist.last_videodir.save()
+               self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + config.movielist.last_videodir.value)
+
                self["list"] = MovieList(None,
                        config.movielist.listtype.value,
                        config.movielist.moviesort.value,
@@ -183,8 +183,7 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
                self["key_yellow"] = Button("")
                self["key_blue"] = Button("")
 
-               #self["freeDiskSpace"] = DiskInfo(resolveFilename(SCOPE_HDD), DiskInfo.FREE, update=False)
-               self["freeDiskSpace"] = self.diskinfo = DiskInfo(resolveFilename(SCOPE_HDD), DiskInfo.FREE, update=False)
+               self["freeDiskSpace"] = self.diskinfo = DiskInfo(config.movielist.last_videodir.value, DiskInfo.FREE, update=False)
 
                if config.usage.setup_level.index >= 2: # expert+
                        self["InfobarActions"] = HelpableActionMap(self, "InfobarActions", 
@@ -214,6 +213,7 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
                        })
 
                self.onShown.append(self.go)
+               self.onLayoutFinish.append(self.saveListsize)
                self.inited = False
 
        def updateDescription(self):
@@ -238,8 +238,8 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
                # this is of course not the right way to do this.
                        self.delayTimer.start(10, 1)
                        self.inited=True
-               # as this workaround is here anyways we can wait until the skin is initialized
-               # and afterwards read out the information we need to draw the dynamic style
+
+       def saveListsize(self):
                        listsize = self["list"].instance.size()
                        self.listWidth = listsize.width()
                        self.listHeight = listsize.height()
@@ -250,7 +250,6 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
                if self.selectedmovie is not None:
                        self.moveTo()
                self["waitingtext"].visible = False
-               self["freeDiskSpace"].update()
                self.updateTags()
 
        def moveTo(self):
@@ -275,12 +274,9 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
                self.close(None)
 
        def saveconfig(self):
-               if self.saveflag == True:
-                       config.movielist.moviesort.save()
-                       config.movielist.listtype.save()
-                       config.movielist.description.save()
-                       configfile.save()
-                       self.saveflag = False
+               config.movielist.moviesort.save()
+               config.movielist.listtype.save()
+               config.movielist.description.save()
 
        def getTagDescription(self, tag):
                # TODO: access the tag database
@@ -322,6 +318,12 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
                self["list"].setSortType(type)
 
        def reloadList(self):
+               if not pathExists(config.movielist.last_videodir.value):
+                       path = resolveFilename(SCOPE_HDD)
+                       config.movielist.last_videodir.value = path
+                       config.movielist.last_videodir.save()
+                       self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + path)
+                       self["freeDiskSpace"].path = path
                self["list"].reload(self.current_ref, self.selected_tags)
                title = _("Recorded files...")
                if self.selected_tags is not None:
@@ -329,21 +331,31 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
                if config.usage.setup_level.index >= 2: # expert+
                        title += "  " + config.movielist.last_videodir.value
                self.setTitle(title)
+               self["freeDiskSpace"].update()
 
        def doPathSelect(self):
                self.session.openWithCallback(
                        self.gotFilename,
-                       LocationBox,
+                       MovieLocationBox,
                        _("Please select the movie path..."),
-                       currDir = config.movielist.last_videodir.value
+                       config.movielist.last_videodir.value
                )
 
        def gotFilename(self, res):
                if res is not None and res is not config.movielist.last_videodir.value:
-                       config.movielist.last_videodir.value = res
-                       self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + res)
-                       self.reloadList()
-                       self.updateTags()
+                       if pathExists(res):
+                               config.movielist.last_videodir.value = res
+                               config.movielist.last_videodir.save()
+                               self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + res)
+                               self["freeDiskSpace"].path = res
+                               self.reloadList()
+                       else:
+                               self.session.open(
+                                       MessageBox,
+                                       _("Directory %s nonexistent.") % (res),
+                                       type = MessageBox.TYPE_ERROR,
+                                       timeout = 5
+                                       )
 
        def showAll(self):
                self.selected_tags = None
index 5a7109f2784346f35ac6c8fc72590f6ae6e7fbc3..bdf3527dbbff0fd3f9592f935f07be79f810cf9b 100644 (file)
@@ -1,5 +1,6 @@
 from Components.ActionMap import ActionMap
 from Components.Button import Button
+from Components.config import config
 from Components.MenuList import MenuList
 from Components.TimerList import TimerList
 from Components.TimerSanityCheck import TimerSanityCheck
@@ -174,7 +175,7 @@ class TimerEditList(Screen):
                else:
                        data = parseEvent(event, description = False)
 
-               self.addTimer(RecordTimerEntry(serviceref, checkOldTimers = True, *data))
+               self.addTimer(RecordTimerEntry(serviceref, checkOldTimers = True, dirname = config.movielist.last_timer_videodir.value, *data))
                
        def addTimer(self, timer):
                self.session.openWithCallback(self.finishedAdd, TimerEntry, timer)
index 6cbd18ecac1fbad09ca16571732bf17e6a7289dd..b490f6ddd37ad17e7fc1d0f9276c1770f9ecf4ea 100644 (file)
@@ -1,5 +1,4 @@
 from Screen import Screen
-from LocationBox import LocationBox
 import ChannelSelection
 from ServiceReference import ServiceReference
 from Components.config import config, ConfigSelection, ConfigText, ConfigSubList, ConfigDateTime, ConfigClock, ConfigYesNo, getConfigListEntry
@@ -9,9 +8,13 @@ from Components.MenuList import MenuList
 from Components.Button import Button
 from Components.Label import Label
 from Components.Pixmap import Pixmap
+from Components.SelectionList import SelectionList, SelectionEntryComponent
+from Components.MovieList import MovieList
+from Screens.LocationBox import MovieLocationBox
 from Screens.ChoiceBox import ChoiceBox
 from RecordTimer import AFTEREVENT
-from enigma import eEPGCache
+from Tools.Directories import resolveFilename, SCOPE_HDD
+from enigma import eEPGCache, eServiceReference
 import time
 import datetime
 
@@ -19,44 +22,34 @@ class TimerEntry(Screen, ConfigListScreen):
        def __init__(self, session, timer):
                Screen.__init__(self, session)
                self.timer = timer
-               
+
                self.entryStartDate = None
                self.entryEndDate = None
                self.entryService = None
-               
+
                self["oktext"] = Label(_("OK"))
                self["canceltext"] = Label(_("Cancel"))
-               self["locationtext"] = Label(_("Location"))
                self["ok"] = Pixmap()
                self["cancel"] = Pixmap()
-               self["location"] = Pixmap()
 
                self.createConfig()
 
-               self["actions"] = NumberActionMap(["SetupActions", "ColorActions"],
+               self["actions"] = NumberActionMap(["SetupActions"],
                {
                        "ok": self.keySelect,
                        "save": self.keyGo,
                        "cancel": self.keyCancel,
-                       "yellow": self.selectPath,
                }, -2)
 
                self.list = []
                ConfigListScreen.__init__(self, self.list, session = session)
                self.createSetup("config")
 
-               self.onLayoutFinish.append(self.handleLocation)
-
-       def handleLocation(self):
-               if config.usage.setup_level.index < 2: # -expert
-                       self["locationtext"].hide()
-                       self["location"].hide()
-
        def createConfig(self):
                        justplay = self.timer.justplay
-                               
+
                        afterevent = { AFTEREVENT.NONE: "nothing", AFTEREVENT.DEEPSTANDBY: "deepstandby", AFTEREVENT.STANDBY: "standby"}[self.timer.afterEvent]
-                       
+
                        weekday_table = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
 
                        # calculate default values
@@ -91,7 +84,7 @@ class TimerEntry(Screen, ConfigListScreen):
                                repeated = None
                                weekday = (int(time.strftime("%w", time.localtime(self.timer.begin))) - 1) % 7
                                day[weekday] = 1
-                       
+
                        self.timerentry_justplay = ConfigSelection(choices = [("zap", _("zap")), ("record", _("record"))], default = {0: "record", 1: "zap"}[justplay])
                        self.timerentry_afterevent = ConfigSelection(choices = [("nothing", _("do nothing")), ("standby", _("go to standby")), ("deepstandby", _("go to deep standby"))], default = afterevent)
                        self.timerentry_type = ConfigSelection(choices = [("once",_("once")), ("repeated", _("repeated"))], default = type)
@@ -106,7 +99,10 @@ class TimerEntry(Screen, ConfigListScreen):
                        self.timerentry_enddate = ConfigDateTime(default = self.timer.end, formatstring =  _("%d.%B %Y"), increment = 86400)
                        self.timerentry_endtime = ConfigClock(default = self.timer.end)
 
-                       self.timerentry_dirname = ConfigSelection(choices = [self.timer.dirname or "/hdd/movie/"])
+                       tmp = config.movielist.videodirs.value
+                       if self.timer.dirname and not self.timer.dirname in tmp:
+                               tmp.append(self.timer.dirname)
+                       self.timerentry_dirname = ConfigSelection(default = self.timer.dirname or resolveFilename(SCOPE_HDD), choices = tmp)
 
                        self.timerentry_repeatedbegindate = ConfigDateTime(default = self.timer.repeatedbegindate, formatstring = _("%d.%B %Y"), increment = 86400)
 
@@ -124,7 +120,7 @@ class TimerEntry(Screen, ConfigListScreen):
                                pass
                        self.timerentry_service_ref = self.timer.service_ref
                        self.timerentry_service = ConfigSelection([servicename])
-                       
+
                        self.timerentry_startdate.addNotifier(self.checkDate)
                        self.timerentry_enddate.addNotifier(self.checkDate)
 
@@ -191,7 +187,8 @@ class TimerEntry(Screen, ConfigListScreen):
 
                if self.timerentry_justplay.value != "zap":
                        if config.usage.setup_level.index >= 2: # expert+
-                               self.list.append(getConfigListEntry(_("Location"), self.timerentry_dirname))
+                               self.dirname = getConfigListEntry(_("Location"), self.timerentry_dirname)
+                               self.list.append(self.dirname)
                        self.list.append(getConfigListEntry(_("After event"), self.timerentry_afterevent))
 
                self.channelEntry = getConfigListEntry(_("Channel"), self.timerentry_service)
@@ -222,10 +219,23 @@ class TimerEntry(Screen, ConfigListScreen):
                else:
                        ConfigListScreen.keyRight(self)
                        self.newConfig()
-               
+
        def keySelect(self):
-               if self["config"].getCurrent() == self.channelEntry:
-                       self.session.openWithCallback(self.finishedChannelSelection, ChannelSelection.SimpleChannelSelection, _("Select channel to record from"))
+               cur = self["config"].getCurrent()
+               if cur == self.channelEntry:
+                       self.session.openWithCallback(
+                               self.finishedChannelSelection,
+                               ChannelSelection.SimpleChannelSelection,
+                               _("Select channel to record from")
+                       )
+               elif config.usage.setup_level.index >= 2 and cur == self.dirname:
+                       self.session.openWithCallback(
+                               self.pathSelected,
+                               MovieLocationBox,
+                               _("Choose target folder"),
+                               self.timerentry_dirname.value,
+                               minFree = 100 # We require at least 100MB free space
+                       )
                else:
                        self.keyGo()
 
@@ -248,13 +258,13 @@ class TimerEntry(Screen, ConfigListScreen):
        def getBeginEnd(self):
                enddate = self.timerentry_enddate.value
                endtime = self.timerentry_endtime.value
-               
+
                startdate = self.timerentry_startdate.value
                starttime = self.timerentry_starttime.value
-               
+
                begin = self.getTimestamp(startdate, starttime)
                end = self.getTimestamp(enddate, endtime)
-               
+
                # because of the dateChecks, startdate can't be < enddate.
                # however, the endtime can be less than the starttime.
                # in this case, add 1 day.
@@ -270,11 +280,9 @@ class TimerEntry(Screen, ConfigListScreen):
                self.timer.afterEvent = {"nothing": AFTEREVENT.NONE, "deepstandby": AFTEREVENT.DEEPSTANDBY, "standby": AFTEREVENT.STANDBY}[self.timerentry_afterevent.value]
                self.timer.service_ref = self.timerentry_service_ref
 
-               # TODO: fix that thing with none (this might as well just be ignored)
-               if self.timerentry_dirname.value == "/hdd/movie/":
-                       self.timer.dirname = None
-               else:
-                       self.timer.dirname = self.timerentry_dirname.value
+               self.timer.dirname = self.timerentry_dirname.value
+               config.movielist.last_timer_videodir.value = self.timer.dirname
+               config.movielist.last_timer_videodir.save()
 
                if self.timerentry_type.value == "once":
                        self.timer.begin, self.timer.end = self.getBeginEnd()
@@ -285,11 +293,11 @@ class TimerEntry(Screen, ConfigListScreen):
 
                        if self.timerentry_repeated.value == "weekly":
                                self.timer.setRepeated(self.timerentry_weekday.index)
-                               
+
                        if self.timerentry_repeated.value == "weekdays":
                                for x in range(0,5):
                                        self.timer.setRepeated(x)
-                               
+
                        if self.timerentry_repeated.value == "user":
                                for x in range(0,7):
                                        if self.timerentry_day[x].value:
@@ -298,7 +306,7 @@ class TimerEntry(Screen, ConfigListScreen):
                        self.timer.repeatedbegindate = self.buildRepeatedBegin(self.timerentry_repeatedbegindate.value, self.timerentry_starttime.value)
                        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:
                                self.timer.end += 86400
@@ -335,22 +343,10 @@ class TimerEntry(Screen, ConfigListScreen):
        def keyCancel(self):
                self.close((False,))
 
-       def selectPath(self):
-               if config.usage.setup_level.index < 2: #-expert
-                       return
-               self.session.openWithCallback(
-                       self.pathSelected,
-                       LocationBox,
-                       text = _("Choose target folder"),
-                       filename = "",
-                       currDir = None, # TODO: fix FileList to correctly determine mountpoint
-                       minFree = 100
-               )
-
        def pathSelected(self, res):
                if res is not None:
-                       self.timerentry_dirname.choices.append(res)
-                       self.timerentry_dirname.description[res] = res
+                       if config.movielist.videodirs.value != self.timerentry_dirname.choices:
+                               self.timerentry_dirname.setChoices(config.movielist.videodirs.value, default=res)
                        self.timerentry_dirname.value = res
 
 class TimerLog(Screen):
@@ -358,17 +354,17 @@ class TimerLog(Screen):
                Screen.__init__(self, session)
                self.timer = timer;
                self.log_entries = self.timer.log_entries[:]
-               
+
                self.fillLogList()
-               
+
                self["loglist"] = MenuList(self.list)
                self["logentry"] = Label()
-               
+
                self["key_red"] = Button(_("Delete entry"))
                self["key_green"] = Button()
                self["key_yellow"] = Button("")
                self["key_blue"] = Button(_("Clear log"))
-               
+
                self.onShown.append(self.updateText)
 
                self["actions"] = NumberActionMap(["OkCancelActions", "DirectionActions", "ColorActions"],
@@ -396,24 +392,24 @@ class TimerLog(Screen):
                self.list = [ ]
                for x in self.log_entries:
                        self.list.append((str(time.strftime("%Y-%m-%d %H-%M", time.localtime(x[0])) + " - " + x[2]), x))
-       
-       def clearLog(self):             
+
+       def clearLog(self):
                self.log_entries = []
                self.fillLogList()
                self["loglist"].l.setList(self.list)
                self.updateText()
-               
+
        def keyClose(self):
                if self.timer.log_entries != self.log_entries:
                        self.timer.log_entries = self.log_entries
                        self.close((True, self.timer))
                else:
                        self.close((False,))
-               
+
        def up(self):
                self["loglist"].instance.moveSelection(self["loglist"].instance.moveUp)
                self.updateText()
-               
+
        def down(self):
                self["loglist"].instance.moveSelection(self["loglist"].instance.moveDown)
                self.updateText()
@@ -421,7 +417,7 @@ class TimerLog(Screen):
        def left(self):
                self["loglist"].instance.moveSelection(self["loglist"].instance.pageUp)
                self.updateText()
-               
+
        def right(self):
                self["loglist"].instance.moveSelection(self["loglist"].instance.pageDown)
                self.updateText()
index 692a555051f017b2f69f68dee22ca8c2c7ebfebf..1e35722d06e758dfed114ef1ddc34ac38b0526c8 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-from os import path as os_path, mkdir, system, walk
+from os import path as os_path, mkdir, rmdir, system, walk
 from re import compile
 
 SCOPE_TRANSPONDERDATA = 0
@@ -121,6 +121,15 @@ def createDir(path):
                ret = 1
        return ret
 
+def removeDir(path):
+       try:
+               rmdir(path)
+       except:
+               ret = 0
+       else:
+               ret = 1
+       return ret
+
 def fileExists(f, mode='r'):
        try:
                file = open(f, mode)