1 | # coding: utf-8 |
---|
2 | |
---|
3 | import pychan |
---|
4 | import pychan.widgets as widgets |
---|
5 | import sys |
---|
6 | |
---|
7 | def u2s(string): |
---|
8 | return string.encode(sys.getfilesystemencoding()) |
---|
9 | |
---|
10 | class FileBrowser(object): |
---|
11 | """ |
---|
12 | FileBrowser displays directory and file listings from the vfs. |
---|
13 | The fileSelected parameter is a callback invoked when a file selection has been made; its |
---|
14 | signature must be fileSelected(path,filename). If selectdir is set, fileSelected's |
---|
15 | filename parameter should be optional. |
---|
16 | The savefile option provides a box for supplying a new filename that doesn't exist yet. |
---|
17 | The selectdir option allows directories to be selected as well as files. |
---|
18 | """ |
---|
19 | def __init__(self, engine, fileSelected, savefile=False, selectdir=False, extensions=('xml',), guixmlpath="gui/filebrowser.xml"): |
---|
20 | self.engine = engine |
---|
21 | self.fileSelected = fileSelected |
---|
22 | |
---|
23 | self._widget = None |
---|
24 | self.savefile = savefile |
---|
25 | self.selectdir = selectdir |
---|
26 | |
---|
27 | self.guixmlpath = guixmlpath |
---|
28 | |
---|
29 | self.extensions = extensions |
---|
30 | self.path = './saves/' |
---|
31 | self.dir_list = [] |
---|
32 | self.file_list = [] |
---|
33 | |
---|
34 | def showBrowser(self): |
---|
35 | if self._widget: |
---|
36 | self._widget.show() |
---|
37 | return |
---|
38 | self._widget = pychan.loadXML(self.guixmlpath) |
---|
39 | self._widget.mapEvents({ |
---|
40 | 'dirList' : self._setDirectory, |
---|
41 | 'selectButton' : self._selectFile, |
---|
42 | 'closeButton' : self._widget.hide |
---|
43 | }) |
---|
44 | self._setDirectory() |
---|
45 | if self.savefile: |
---|
46 | self._file_entry = widgets.TextField(name='saveField', text=u'') |
---|
47 | self._widget.findChild(name="fileColumn").addChild(self._file_entry) |
---|
48 | self._widget.show() |
---|
49 | |
---|
50 | def _setDirectory(self): |
---|
51 | selection = self._widget.collectData('dirList') |
---|
52 | if not (selection < 0): |
---|
53 | new_dir = u2s(self.dir_list[selection]) |
---|
54 | lst = self.path.split('/') |
---|
55 | if new_dir == '..' and lst[-1] != '..' and lst[-1] != '.': |
---|
56 | lst.pop() |
---|
57 | else: |
---|
58 | lst.append(new_dir) |
---|
59 | self.path = '/'.join(lst) |
---|
60 | |
---|
61 | def decodeList(list): |
---|
62 | fs_encoding = sys.getfilesystemencoding() |
---|
63 | if fs_encoding is None: fs_encoding = "ascii" |
---|
64 | |
---|
65 | newList = [] |
---|
66 | for i in list: |
---|
67 | try: newList.append(unicode(i, fs_encoding)) |
---|
68 | except: |
---|
69 | newList.append(unicode(i, fs_encoding, 'replace')) |
---|
70 | print "WARNING: Could not decode item:", i |
---|
71 | return newList |
---|
72 | |
---|
73 | |
---|
74 | |
---|
75 | self.dir_list = [] |
---|
76 | self.file_list = [] |
---|
77 | |
---|
78 | dir_list = ('..',) + filter(lambda d: not d.startswith('.'), self.engine.getVFS().listDirectories(self.path)) |
---|
79 | file_list = filter(lambda f: f.split('.')[-1] in self.extensions, self.engine.getVFS().listFiles(self.path)) |
---|
80 | |
---|
81 | self.dir_list = decodeList(dir_list) |
---|
82 | self.file_list = decodeList(file_list) |
---|
83 | self._widget.distributeInitialData({ |
---|
84 | 'dirList' : self.dir_list, |
---|
85 | 'fileList' : self.file_list |
---|
86 | }) |
---|
87 | |
---|
88 | def _selectFile(self): |
---|
89 | self._widget.hide() |
---|
90 | selection = self._widget.collectData('fileList') |
---|
91 | data = self._widget.collectData('saveField') |
---|
92 | |
---|
93 | if self.savefile: |
---|
94 | if data: |
---|
95 | if (data.split('.')[1] == 'dat'): |
---|
96 | self.fileSelected(self.path, u2s(self._widget.collectData('saveField'))) |
---|
97 | else: |
---|
98 | self._warningMessage() |
---|
99 | return |
---|
100 | |
---|
101 | |
---|
102 | if selection >= 0 and selection < len(self.file_list): |
---|
103 | self.fileSelected(self.path, u2s(self.file_list[selection])) |
---|
104 | return |
---|
105 | |
---|
106 | if self.selectdir: |
---|
107 | self.fileSelected(self.path) |
---|
108 | return |
---|
109 | |
---|
110 | print 'FileBrowser: error, no selection.' |
---|
111 | |
---|
112 | def _warningMessage(self): |
---|
113 | window = widgets.Window(title="Warning") |
---|
114 | text = "Please save the file as a .dat" |
---|
115 | label = widgets.Label(text=text) |
---|
116 | ok_button = widgets.Button(name="ok_button", text="Ok") |
---|
117 | window.addChildren([label, ok_button]) |
---|
118 | window.mapEvents({'ok_button':window.hide}) |
---|
119 | window.show() |
---|