source: trunk/game/scripts/filebrowser.py @ 303

Revision 303, 5.0 KB checked in by eliedebrauwer, 10 years ago (diff)

Ticket #110: Patch by Elie De Brauwer. removed parpgfilebrowser, filebrowser seems to have the required logic already on board, also added licensing information and some formatting to filebrowser.py fix. fixes[s:trac, t:110]

  • Property svn:eol-style set to native
Line 
1#!/usr/bin/python
2
3#   This program is free software: you can redistribute it and/or modify
4#   it under the terms of the GNU General Public License as published by
5#   the Free Software Foundation, either version 3 of the License, or
6#   (at your option) any later version.
7
8#   This program is distributed in the hope that it will be useful,
9#   but WITHOUT ANY WARRANTY; without even the implied warranty of
10#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11#   GNU General Public License for more details.
12
13#   You should have received a copy of the GNU General Public License
14#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16import pychan
17import pychan.widgets as widgets
18import sys
19
20def u2s(string):
21    return string.encode(sys.getfilesystemencoding())
22
23class FileBrowser(object):
24    """
25    FileBrowser displays directory and file listings from the vfs.
26    The fileSelected parameter is a callback invoked when a file selection has been made; its
27    signature must be fileSelected(path,filename). If selectdir is set, fileSelected's
28    filename parameter should be optional.
29    The savefile option provides a box for supplying a new filename that doesn't exist yet.
30    The selectdir option allows directories to be selected as well as files.
31    """
32    def __init__(self, engine, fileSelected, savefile=False, selectdir=False, extensions=('.dat',), guixmlpath="gui/filebrowser.xml"):
33        self.engine = engine
34        self.fileSelected = fileSelected
35
36        self._widget = None
37        self.savefile = savefile
38        self.selectdir = selectdir
39       
40        self.guixmlpath = guixmlpath
41
42        self.extensions = extensions
43        self.path = './saves/'
44        self.dir_list = []
45        self.file_list = []
46
47    def showBrowser(self):
48        """ Shows the file dialog browser """
49        if self._widget:
50            self._widget.show()
51            return
52        self._widget = pychan.loadXML(self.guixmlpath)
53        self._widget.mapEvents({
54            'dirList'       : self._setDirectory,
55            'selectButton'  : self._selectFile,
56            'closeButton'   : self._widget.hide
57        })
58        self._setDirectory()
59        if self.savefile:
60            self._file_entry = widgets.TextField(name='saveField', text=u'')   
61            self._widget.findChild(name="fileColumn").addChild(self._file_entry)
62        self._widget.show()
63
64    def _setDirectory(self):
65        """ Directory change callback. """
66        selection = self._widget.collectData('dirList')
67        if not (selection < 0):
68            new_dir = u2s(self.dir_list[selection])
69            lst = self.path.split('/')
70            if new_dir == '..' and lst[-1] != '..' and lst[-1] != '.':
71                lst.pop()
72            else:
73                lst.append(new_dir)
74            self.path = '/'.join(lst)
75           
76        def decodeList(list):
77            fs_encoding = sys.getfilesystemencoding()
78            if fs_encoding is None: fs_encoding = "ascii"
79       
80            newList = []
81            for i in list:
82                try: newList.append(unicode(i, fs_encoding))
83                except:
84                    newList.append(unicode(i, fs_encoding, 'replace'))
85                    print "WARNING: Could not decode item:", i
86            return newList
87           
88       
89
90        self.dir_list = []
91        self.file_list = []
92       
93        dir_list = ('..',) + filter(lambda d: not d.startswith('.'), self.engine.getVFS().listDirectories(self.path))
94        file_list = filter(lambda f: f.split('.')[-1] in self.extensions, self.engine.getVFS().listFiles(self.path))
95               
96        self.dir_list = decodeList(dir_list)
97        self.file_list = decodeList(file_list)
98        self._widget.distributeInitialData({
99            'dirList'  : self.dir_list,
100            'fileList' : self.file_list
101        })
102
103    def _selectFile(self):
104        """ File selection callback. """
105        self._widget.hide()
106        selection = self._widget.collectData('fileList')
107        data = self._widget.collectData('saveField')
108
109        if self.savefile:
110            if data:
111                if (data.split('.')[1] == 'dat'):
112                    self.fileSelected(self.path, u2s(self._widget.collectData('saveField')))
113                else:
114                    self._warningMessage()
115                return
116           
117
118        if selection >= 0 and selection < len(self.file_list):
119            self.fileSelected(self.path, u2s(self.file_list[selection]))
120            return
121       
122        if self.selectdir:
123            self.fileSelected(self.path)
124            return
125
126        print 'FileBrowser: error, no selection.'
127
128    def _warningMessage(self):
129        """ Shows the warning message dialog when a file with a
130        faulty extension was selected. """
131        window = widgets.Window(title="Warning")
132        text = "Please save the file as a .dat"
133        label = widgets.Label(text=text)
134        ok_button = widgets.Button(name="ok_button", text="Ok")
135        window.addChildren([label, ok_button])
136        window.mapEvents({'ok_button':window.hide})
137        window.show()
Note: See TracBrowser for help on using the repository browser.