X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/2a8ecd871020fdd668cf5500460e5a6e7851b4b0..92929c357751afc31f7f1acbe3e724bdf307cf23:/lib/python/Screens/LocationBox.py diff --git a/lib/python/Screens/LocationBox.py b/lib/python/Screens/LocationBox.py index de7923e4..e41601a9 100644 --- a/lib/python/Screens/LocationBox.py +++ b/lib/python/Screens/LocationBox.py @@ -6,40 +6,53 @@ 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 +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 = """ + skin = """ - - - - - - + + + + + + + + + + + + """ - 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 +68,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 +166,186 @@ 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 selectConfirmed(self, res): - if res: - self.close(''.join([self["filelist"].getCurrentDirectory(), self.filename])) + 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, ret): + if ret: + ret = ''.join([self.getPreferredFolder(), self.filename]) + if self.realBookmarks: + if self.autoAdd and not ret in self.bookmarks: + self.bookmarks.append(self.getPreferredFolder()) + self.bookmarks.sort() + + if self.bookmarks != self.realBookmarks.value: + self.realBookmarks.value = self.bookmarks + self.realBookmarks.save() + 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) @@ -182,13 +360,12 @@ class LocationBox(Screen, NumericalTextInput): type = MessageBox.TYPE_YESNO ) # No minimum free Space means we can safely close - else: + else: self.selectConfirmed(True) 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 +388,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 +497,7 @@ class LocationBox(Screen, NumericalTextInput): def __repr__(self): return str(type(self)) + "(" + self.text + ")" +class MovieLocationBox(LocationBox): + def __init__(self, session, text, dir, minFree = None): + inhibitDirs = ["/bin", "/boot", "/dev", "/etc", "/lib", "/proc", "/sbin", "/sys", "/usr", "/var"] + LocationBox.__init__(self, session, text = text, currDir = dir, bookmarks = config.movielist.videodirs, autoAdd = True, editDir = True, inhibitDirs = inhibitDirs, minFree = minFree)