Mercurial > urwid-satext
annotate urwid_satext/files_management.py @ 30:1aeb3540aa49
files reorganisation after project separation. new README, and COPYING files
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 28 Dec 2010 11:53:18 +0100 |
parents | frontends/primitivus/files_management.py@fcc20ac7b68a |
children | 818393067e54 |
rev | line source |
---|---|
21 | 1 #!/usr/bin/python |
2 # -*- coding: utf-8 -*- | |
3 | |
4 """ | |
5 Primitivus: a SAT frontend | |
6 Copyright (C) 2009, 2010 Jérôme Poisson (goffi@goffi.org) | |
7 | |
8 This program is free software: you can redistribute it and/or modify | |
9 it under the terms of the GNU General Public License as published by | |
10 the Free Software Foundation, either version 3 of the License, or | |
11 (at your option) any later version. | |
12 | |
13 This program is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 GNU General Public License for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20 """ | |
21 | |
22 import urwid | |
30
1aeb3540aa49
files reorganisation after project separation. new README, and COPYING files
Goffi <goffi@goffi.org>
parents:
26
diff
changeset
|
23 import sat_widgets |
21 | 24 import os, os.path |
25 from xml.dom import minidom | |
26 from logging import debug, info, error | |
23 | 27 from time import time |
21 | 28 |
30
1aeb3540aa49
files reorganisation after project separation. new README, and COPYING files
Goffi <goffi@goffi.org>
parents:
26
diff
changeset
|
29 class PathEdit(sat_widgets.AdvancedEdit): |
23 | 30 """AdvancedEdit with manage file paths""" |
21 | 31 |
32 def keypress(self, size, key): | |
23 | 33 if key == '~' and self.edit_pos==0: |
34 expanded = os.path.expanduser('~') | |
35 self.set_edit_text(os.path.normpath(expanded+'/'+self.edit_text)) | |
36 self.set_edit_pos(len(expanded)+1) | |
37 elif key == 'ctrl w': | |
21 | 38 if self.edit_pos<2: |
39 return | |
40 before = self.edit_text[:self.edit_pos] | |
41 pos = (before[:-1] if before.endswith('/') else before).rfind("/")+1 | |
42 self.set_edit_text(before[:pos] + self.edit_text[self.edit_pos:]) | |
43 self.set_edit_pos(pos) | |
44 return | |
45 else: | |
46 return super(PathEdit, self).keypress(size, key) | |
47 | |
23 | 48 class FilesViewer(urwid.WidgetWrap): |
49 """List specialised for files""" | |
50 | |
51 def __init__(self, onPreviousDir, onDirClick, onFileClick): | |
52 self.path='' | |
53 self.key_cache = '' | |
54 self.key_time = time() | |
55 self.onPreviousDir = onPreviousDir | |
56 self.onDirClick = onDirClick | |
57 self.onFileClick = onFileClick | |
58 self.files_list = urwid.SimpleListWalker([]) | |
59 self.show_hidden = True | |
60 listbox = urwid.ListBox(self.files_list) | |
61 urwid.WidgetWrap.__init__(self, listbox) | |
62 | |
63 def keypress(self, size, key): | |
64 if key=='meta h': | |
65 #(un)hide hidden files | |
66 self.show_hidden = not self.show_hidden | |
67 self.showDirectory(self.path) | |
68 if key=='meta d': | |
69 #jump to directories | |
70 if self.files_list: | |
71 self._w.set_focus(0) | |
72 elif key=='meta f': | |
73 for idx in range(len(self.files_list)): | |
74 if isinstance(self.files_list[idx].base_widget,urwid.Divider): | |
75 if idx<len(self.files_list)-1: | |
76 self._w.set_focus(idx+1) | |
77 break | |
78 elif len(key) == 1: | |
79 if time() - self.key_time > 2: | |
80 self.key_cache=key | |
81 else: | |
82 self.key_cache+=key | |
83 self.key_time = time() | |
84 for idx in range(len(self.files_list)): | |
30
1aeb3540aa49
files reorganisation after project separation. new README, and COPYING files
Goffi <goffi@goffi.org>
parents:
26
diff
changeset
|
85 if isinstance(self.files_list[idx],sat_widgets.ClickableText) and self.files_list[idx].get_text().lower().startswith(self.key_cache.lower()): |
23 | 86 self._w.set_focus(idx) |
87 break | |
88 else: | |
89 return self._w.keypress(size, key) | |
90 | |
91 def showDirectory(self, path): | |
92 self.path = path | |
93 del self.files_list[:] | |
94 directories = [] | |
95 files = [] | |
96 try: | |
97 for filename in os.listdir(path): | |
98 fullpath = os.path.join(path,filename) | |
99 if os.path.isdir(fullpath): | |
100 directories.append(filename) | |
101 else: | |
102 files.append(filename) | |
103 except OSError: | |
104 self.files_list.append(urwid.Text(("warning",_("Impossible to list directory")),'center')) | |
105 directories.sort() | |
106 files.sort() | |
107 if os.path.abspath(path)!='/' and os.path.abspath(path) != '//': | |
30
1aeb3540aa49
files reorganisation after project separation. new README, and COPYING files
Goffi <goffi@goffi.org>
parents:
26
diff
changeset
|
108 previous_wid = sat_widgets.ClickableText(('directory','..')) |
23 | 109 urwid.connect_signal(previous_wid,'click',self.onPreviousDir) |
110 self.files_list.append(previous_wid) | |
111 for directory in directories: | |
112 if directory.startswith('.') and not self.show_hidden: | |
113 continue | |
30
1aeb3540aa49
files reorganisation after project separation. new README, and COPYING files
Goffi <goffi@goffi.org>
parents:
26
diff
changeset
|
114 dir_wid = sat_widgets.ClickableText(('directory',directory)) |
23 | 115 urwid.connect_signal(dir_wid,'click',self.onDirClick) |
116 self.files_list.append(dir_wid) | |
117 self.files_list.append(urwid.AttrMap(urwid.Divider('-'),'separator')) | |
118 for filename in files: | |
119 if filename.startswith('.') and not self.show_hidden: | |
120 continue | |
30
1aeb3540aa49
files reorganisation after project separation. new README, and COPYING files
Goffi <goffi@goffi.org>
parents:
26
diff
changeset
|
121 file_wid = sat_widgets.ClickableText(filename) |
23 | 122 urwid.connect_signal(file_wid,'click',self.onFileClick) |
123 self.files_list.append(file_wid) | |
124 | |
125 | |
126 | |
21 | 127 class FileDialog(urwid.WidgetWrap): |
128 | |
23 | 129 def __init__(self, ok_cb, cancel_cb, title=_("Please select a file"), style=[]): |
130 """Create file dialog | |
131 @param title: title of the window/popup | |
132 @param style: NOT USED YET #FIXME | |
133 """ | |
134 self.ok_cb = ok_cb | |
21 | 135 self.__home_path = os.path.expanduser('~') |
23 | 136 self.path_wid = PathEdit(_('Path: ')) |
137 self.path_wid.setCompletionMethod(self._directory_completion) | |
21 | 138 urwid.connect_signal(self.path_wid, 'change', self.onPathChange) |
139 header = urwid.Pile([self.path_wid, urwid.Divider(u'─')]) | |
140 bookm_list = urwid.SimpleListWalker([]) | |
141 self.bookmarks = list(self.getBookmarks()) | |
142 self.bookmarks.sort() | |
143 for bookmark in self.bookmarks: | |
144 if bookmark.startswith(self.__home_path): | |
145 bookmark="~"+bookmark[len(self.__home_path):] | |
30
1aeb3540aa49
files reorganisation after project separation. new README, and COPYING files
Goffi <goffi@goffi.org>
parents:
26
diff
changeset
|
146 book_wid = sat_widgets.ClickableText(bookmark) |
21 | 147 urwid.connect_signal(book_wid, 'click', self.onBookmarkSelected) |
148 bookm_list.append(book_wid) | |
149 bookm_wid = urwid.Frame(urwid.ListBox(bookm_list), urwid.AttrMap(urwid.Text(_('Bookmarks'),'center'),'title')) | |
23 | 150 self.files_wid = FilesViewer(self.onPreviousDir, self.onDirClick, self.onFileClick) |
21 | 151 center_row = urwid.Columns([('weight',2,bookm_wid), |
30
1aeb3540aa49
files reorganisation after project separation. new README, and COPYING files
Goffi <goffi@goffi.org>
parents:
26
diff
changeset
|
152 ('weight',8,sat_widgets.VerticalSeparator(self.files_wid))]) |
23 | 153 |
154 buttons = [] | |
30
1aeb3540aa49
files reorganisation after project separation. new README, and COPYING files
Goffi <goffi@goffi.org>
parents:
26
diff
changeset
|
155 buttons.append(sat_widgets.CustomButton(_('Cancel'),cancel_cb)) |
23 | 156 max_len = max([button.getSize() for button in buttons]) |
157 buttons_wid = urwid.GridFlow(buttons,max_len,1,0,'center') | |
30
1aeb3540aa49
files reorganisation after project separation. new README, and COPYING files
Goffi <goffi@goffi.org>
parents:
26
diff
changeset
|
158 main_frame = sat_widgets.FocusFrame(center_row, header, buttons_wid) |
1aeb3540aa49
files reorganisation after project separation. new README, and COPYING files
Goffi <goffi@goffi.org>
parents:
26
diff
changeset
|
159 decorated = sat_widgets.LabelLine(main_frame, sat_widgets.SurroundedText(title)) |
21 | 160 urwid.WidgetWrap.__init__(self, decorated) |
23 | 161 self.path_wid.set_edit_text(os.getcwdu()) |
162 | |
163 def _directory_completion(self, path, completion_data): | |
164 path=os.path.abspath(path) | |
165 if not os.path.isdir(path): | |
166 head,dir_start = os.path.split(path) | |
167 else: | |
168 head=path | |
169 dir_start='' | |
170 try: | |
171 filenames = os.listdir(head) | |
172 filenames.sort() | |
173 try: | |
174 start_idx=filenames.index(completion_data['last_dir'])+1 | |
175 if start_idx == len(filenames): | |
176 start_idx = 0 | |
177 except (KeyError,ValueError): | |
178 start_idx = 0 | |
179 for idx in range(start_idx,len(filenames)) + range(0,start_idx): | |
180 full_path = os.path.join(head,filenames[idx]) | |
181 if filenames[idx].lower().startswith(dir_start.lower()) and os.path.isdir(full_path): | |
182 completion_data['last_dir'] = filenames[idx] | |
183 return full_path | |
184 except OSError: | |
185 pass | |
186 return path | |
21 | 187 |
188 def getBookmarks(self): | |
23 | 189 gtk_bookm = os.path.expanduser("~/.gtk-bookmarks") |
190 kde_bookm = os.path.expanduser("~/.kde/share/apps/kfileplaces/bookmarks.xml") | |
21 | 191 bookmarks = set() |
192 try: | |
23 | 193 with open(gtk_bookm) as gtk_fd: |
194 for bm in gtk_fd.readlines(): | |
21 | 195 if bm.startswith("file:///"): |
196 bookmarks.add(bm[7:].replace('\n','')) | |
197 except IOError: | |
23 | 198 info(_('No GTK bookmarks file found')) |
21 | 199 pass |
200 | |
201 try: | |
202 dom = minidom.parse(kde_bookm) | |
23 | 203 for elem in dom.getElementsByTagName('bookmark'): |
21 | 204 bm = elem.getAttribute("href") |
205 if bm.startswith("file:///"): | |
206 bookmarks.add(bm[7:]) | |
207 except IOError: | |
208 info(_('No KDE bookmarks file found')) | |
209 pass | |
210 | |
211 return bookmarks | |
212 | |
213 def onBookmarkSelected(self, button): | |
214 self.path_wid.set_edit_text(os.path.expanduser(button.get_text())) | |
215 | |
23 | 216 def onPathChange(self, edit, path): |
217 if os.path.isdir(path): | |
218 self.files_wid.showDirectory(path) | |
219 | |
220 def onPreviousDir(self, wid): | |
221 path = os.path.abspath(self.path_wid.get_edit_text()) | |
222 if not os.path.isdir(path): | |
223 path = dirname(path) | |
224 self.path_wid.set_edit_text(os.path.split(path)[0]) | |
225 | |
226 def onDirClick(self, wid): | |
227 path = os.path.abspath(self.path_wid.get_edit_text()) | |
228 if not os.path.isdir(path): | |
229 path = dirname(path) | |
230 self.path_wid.set_edit_text(os.path.join(path,wid.get_text())) | |
231 | |
232 def onFileClick(self, wid): | |
233 self.ok_cb(os.path.abspath(os.path.join(self.files_wid.path,wid.get_text()))) |