Mercurial > urwid-satext
view urwid_satext/files_management.py @ 105:20be00928875
Lower default setuptools version
From 0d607b6ed49eab758fd9b272e148f032e65fb2e2 Mon Sep 17 00:00:00 2001
python-setuptools 5.7 is not yet in Debian, so we need to set the
default version to 5.5 (the current version in sid) to avoid the newer
version to be downloaded from pypi.
author | Matteo Cypriani <mcy@lm7.fr> |
---|---|
date | Tue, 09 Sep 2014 22:09:51 -0400 |
parents | 900014ae36b8 |
children | 5bb3b7e25bf6 |
line wrap: on
line source
#!/usr/bin/python # -*- coding: utf-8 -*- # Urwid SàT extensions # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Jérôme Poisson (goffi@goffi.org) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import urwid import sat_widgets import os, os.path from xml.dom import minidom from logging import debug, info, error from time import time from .keys import action_key_map as a_key import gettext gettext.install('urwid_satext', unicode=True) class PathEdit(sat_widgets.AdvancedEdit): """AdvancedEdit with manage file paths""" def keypress(self, size, key): if key == '~' and self.edit_pos==0: expanded = os.path.expanduser('~') self.set_edit_text(os.path.normpath(expanded+'/'+self.edit_text)) self.set_edit_pos(len(expanded)+1) elif key == a_key['EDIT_DELETE_LAST_WORD']: if self.edit_pos<2: return before = self.edit_text[:self.edit_pos] pos = (before[:-1] if before.endswith('/') else before).rfind("/")+1 self.set_edit_text(before[:pos] + self.edit_text[self.edit_pos:]) self.set_edit_pos(pos) return else: return super(PathEdit, self).keypress(size, key) class FilesViewer(urwid.WidgetWrap): """List specialised for files""" def __init__(self, onPreviousDir, onDirClick, onFileClick = None): self.path='' self.key_cache = '' self.key_time = time() self.onPreviousDir = onPreviousDir self.onDirClick = onDirClick self.onFileClick = onFileClick self.files_list = urwid.SimpleListWalker([]) self.show_hidden = True listbox = urwid.ListBox(self.files_list) urwid.WidgetWrap.__init__(self, listbox) def keypress(self, size, key): if key==a_key['FILES_HIDDEN_HIDE']: #(un)hide hidden files self.show_hidden = not self.show_hidden self.showDirectory(self.path) elif key==a_key['FILES_JUMP_DIRECTORIES']: #jump to directories if self.files_list: self._w.set_focus(0) elif key==a_key['FILES_JUMP_FILES']: for idx in range(len(self.files_list)): if isinstance(self.files_list[idx].base_widget,urwid.Divider): if idx<len(self.files_list)-1: self._w.set_focus(idx+1) break elif len(key) == 1: if time() - self.key_time > 2: self.key_cache=key else: self.key_cache+=key self.key_time = time() for idx in range(len(self.files_list)): if isinstance(self.files_list[idx],sat_widgets.ClickableText) and self.files_list[idx].get_text().lower().startswith(self.key_cache.lower()): self._w.set_focus(idx) break else: return self._w.keypress(size, key) def showDirectory(self, path): path = path.encode('utf-8') self.path = path del self.files_list[:] directories = [] files = [] try: for filename in os.listdir(path): fullpath = os.path.join(path,filename) if os.path.isdir(fullpath): directories.append(filename) else: files.append(filename) except OSError: self.files_list.append(urwid.Text(("warning",_("Impossible to list directory")),'center')) directories.sort() files.sort() if os.path.abspath(path)!='/' and os.path.abspath(path) != '//': previous_wid = sat_widgets.ClickableText(('directory','..')) urwid.connect_signal(previous_wid,'click',self.onPreviousDir) self.files_list.append(previous_wid) for directory in directories: if directory.startswith('.') and not self.show_hidden: continue dir_wid = sat_widgets.ClickableText(('directory',directory)) urwid.connect_signal(dir_wid,'click',self.onDirClick) self.files_list.append(dir_wid) self.files_list.append(urwid.AttrMap(urwid.Divider('-'),'separator')) for filename in files: if filename.startswith('.') and not self.show_hidden: continue file_wid = sat_widgets.ClickableText(filename) if self.onFileClick: urwid.connect_signal(file_wid,'click',self.onFileClick) self.files_list.append(file_wid) class FileDialog(urwid.WidgetWrap): def __init__(self, ok_cb, cancel_cb, title=_("Please select a file"), style=[]): """Create file dialog @param title: title of the window/popup @param style: list of string: - 'dir' if a dir path must be selected """ self.ok_cb = ok_cb self._type = 'dir' if 'dir' in style else 'normal' self.__home_path = os.path.expanduser('~') self.path_wid = PathEdit(_('Path: ')) self.path_wid.setCompletionMethod(self._directory_completion) urwid.connect_signal(self.path_wid, 'change', self.onPathChange) header = urwid.Pile([self.path_wid, urwid.Divider(u'─')]) bookm_list = urwid.SimpleListWalker([]) self.bookmarks = list(self.getBookmarks()) self.bookmarks.sort() for bookmark in self.bookmarks: if bookmark.startswith(self.__home_path): bookmark="~"+bookmark[len(self.__home_path):] book_wid = sat_widgets.ClickableText(bookmark) urwid.connect_signal(book_wid, 'click', self.onBookmarkSelected) bookm_list.append(book_wid) bookm_wid = urwid.Frame(urwid.ListBox(bookm_list), urwid.AttrMap(urwid.Text(_('Bookmarks'),'center'),'title')) self.files_wid = FilesViewer(self.onPreviousDir, self.onDirClick, self.onFileClick if self._type == 'normal' else None) center_row = urwid.Columns([('weight',2,bookm_wid), ('weight',8,sat_widgets.VerticalSeparator(self.files_wid))]) buttons = [] if self._type == 'dir': buttons.append(sat_widgets.CustomButton(_('Ok'), self._validateDir)) buttons.append(sat_widgets.CustomButton(_('Cancel'),cancel_cb)) max_len = max([button.getSize() for button in buttons]) buttons_wid = urwid.GridFlow(buttons,max_len,1,0,'center') main_frame = sat_widgets.FocusFrame(center_row, header, buttons_wid) decorated = sat_widgets.LabelLine(main_frame, sat_widgets.SurroundedText(title)) urwid.WidgetWrap.__init__(self, decorated) self.path_wid.set_edit_text(os.getcwdu()) def _validateDir(self, wid): """ call ok callback if current path is a dir """ path = os.path.abspath(self.path_wid.get_edit_text()) if os.path.isdir(path): self.ok_cb(path) def _directory_completion(self, path, completion_data): path=os.path.abspath(path) if not os.path.isdir(path): head,dir_start = os.path.split(path) else: head=path dir_start='' try: filenames = os.listdir(head) filenames.sort() try: start_idx=filenames.index(completion_data['last_dir'])+1 if start_idx == len(filenames): start_idx = 0 except (KeyError,ValueError): start_idx = 0 for idx in range(start_idx,len(filenames)) + range(0,start_idx): full_path = os.path.join(head,filenames[idx]) if filenames[idx].lower().startswith(dir_start.lower()) and os.path.isdir(full_path): completion_data['last_dir'] = filenames[idx] return full_path except OSError: pass return path def getBookmarks(self): gtk_bookm = os.path.expanduser("~/.gtk-bookmarks") kde_bookm = os.path.expanduser("~/.kde/share/apps/kfileplaces/bookmarks.xml") bookmarks = set() try: with open(gtk_bookm) as gtk_fd: for bm in gtk_fd.readlines(): if bm.startswith("file:///"): bookmarks.add(bm[7:].replace('\n','')) except IOError: info(_('No GTK bookmarks file found')) pass try: dom = minidom.parse(kde_bookm) for elem in dom.getElementsByTagName('bookmark'): bm = elem.getAttribute("href") if bm.startswith("file:///"): bookmarks.add(bm[7:]) except IOError: info(_('No KDE bookmarks file found')) pass return bookmarks def onBookmarkSelected(self, button): self.path_wid.set_edit_text(os.path.expanduser(button.get_text())) def onPathChange(self, edit, path): if os.path.isdir(path): self.files_wid.showDirectory(path) def onPreviousDir(self, wid): path = os.path.abspath(self.path_wid.get_edit_text()) if not os.path.isdir(path): path = os.path.dirname(path) self.path_wid.set_edit_text(os.path.split(path)[0]) def onDirClick(self, wid): path = os.path.abspath(self.path_wid.get_edit_text()) if not os.path.isdir(path): path = os.path.dirname(path) self.path_wid.set_edit_text(os.path.join(path,wid.get_text())) def onFileClick(self, wid): self.ok_cb(os.path.abspath(os.path.join(self.files_wid.path,wid.get_text())))