source: branches/active/character_customization/game/parpg/gui/filebrowser.py @ 797

Revision 797, 5.8 KB checked in by aspidites, 9 years ago (diff)

Patch by Aspidites:

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