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

Revision 357, 5.4 KB checked in by bretzel_parpg, 10 years ago (diff)

Ticket #136. Fix by Bretzel.

  • Added a check to verify that the filename you enter to save your game ends with .dat.
  • If it does not it will be automatically added.
  • Left the warning function that is no longer in use in case we want to revert back.
  • 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 file_selected parameter is a callback invoked when a file selection
27    has been made; its signature must be file_selected(path,filename). If
28    select_dir is set, file_selected's filename parameter should be optional.
29    The save_file option provides a box for supplying a new filename that
30    doesn't exist yet. The select_dir option allows directories to be
31    selected as well as files.
32    """
33    def __init__(self, engine, file_selected, save_file=False, \
34                 select_dir=False, extensions=('.dat',), \
35                 gui_xml_path="gui/filebrowser.xml"):
36        self.engine = engine
37        self.file_selected = file_selected
38
39        self._widget = None
40        self.save_file = save_file
41        self.select_dir = select_dir
42       
43        self.gui_xml_path = gui_xml_path
44
45        self.extensions = extensions
46        self.path = './saves/'
47        self.dir_list = []
48        self.file_list = []
49
50    def showBrowser(self):
51        """ Shows the file dialog browser """
52        if self._widget:
53            self._widget.show()
54            return
55        self._widget = pychan.loadXML(self.gui_xml_path)
56        self._widget.mapEvents({
57            'dirList'       : self._setDirectory,
58            'selectButton'  : self._selectFile,
59            'closeButton'   : self._widget.hide
60        })
61        self._setDirectory()
62        if self.save_file:
63            self._file_entry = widgets.TextField(name='saveField', text=u'')   
64            self._widget.findChild(name="fileColumn").\
65                addChild(self._file_entry)
66        self._widget.show()
67
68    def _setDirectory(self):
69        """ Directory change callback. """
70        selection = self._widget.collectData('dirList')
71        if not (selection < 0):
72            new_dir = u2s(self.dir_list[selection])
73            lst = self.path.split('/')
74            if new_dir == '..' and lst[-1] != '..' and lst[-1] != '.':
75                lst.pop()
76            else:
77                lst.append(new_dir)
78            self.path = '/'.join(lst)
79           
80        def decodeList(list):
81            fs_encoding = sys.getfilesystemencoding()
82            if fs_encoding is None: fs_encoding = "ascii"
83       
84            new_list = []
85            for i in list:
86                try:
87                    new_list.append(unicode(i, fs_encoding))
88                except:
89                    new_list.append(unicode(i, fs_encoding, 'replace'))
90                    print "WARNING: Could not decode item:", i
91            return new_list
92           
93       
94
95        self.dir_list = []
96        self.file_list = []
97       
98        dir_list = ('..',) + filter(lambda d: not d.startswith('.'), \
99                                    self.engine.getVFS().\
100                                    listDirectories(self.path))
101        file_list = filter(lambda f: f.split('.')[-1] in self.extensions, \
102                           self.engine.getVFS().listFiles(self.path))
103               
104        self.dir_list = decodeList(dir_list)
105        self.file_list = decodeList(file_list)
106        self._widget.distributeInitialData({
107            'dirList'  : self.dir_list,
108            'fileList' : self.file_list
109        })
110
111    def _selectFile(self):
112        """ File selection callback. """
113        self._widget.hide()
114        selection = self._widget.collectData('fileList')
115
116        if self.save_file:
117            data = self._widget.collectData('saveField')
118            if data:
119                if (data.endswith(".dat")):
120                    self.file_selected(self.path, \
121                                u2s(self._widget.collectData('saveField')))
122                else:
123                    self.file_selected(self.path, 
124                                       u2s(self._widget.collectData('saveField')) + '.dat')
125                return
126           
127
128        if selection >= 0 and selection < len(self.file_list):
129            self.file_selected(self.path, u2s(self.file_list[selection]))
130            return
131       
132        if self.select_dir:
133            self.file_selected(self.path)
134            return
135
136        print 'FileBrowser: error, no selection.'
137
138    def _warningMessage(self):
139        """ Shows the warning message dialog when a file with a
140        faulty extension was selected. """
141        window = widgets.Window(title="Warning")
142        text = "Please save the file as a .dat"
143        label = widgets.Label(text=text)
144        ok_button = widgets.Button(name="ok_button", text="Ok")
145        window.addChildren([label, ok_button])
146        window.mapEvents({'ok_button':window.hide})
147        window.show()
Note: See TracBrowser for help on using the repository browser.