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

Revision 736, 5.7 KB checked in by aspidites, 9 years ago (diff)

Patch by Aspidites:

  • renamed scripts package to parpg
  • renamed parpg module to application
  • removed packaging and other related files (kept locally for reference, will reintroduce similar scripts to resolve bug #275
  • updated all import statements to respect changes above
  • Property svn:eol-style set to native
Line 
1#!/usr/bin/env 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
16from fife.extensions import pychan
17from fife.extensions.pychan import widgets
18
19import sys
20
21def u2s(string):
22    # TODO: cryptic function name
23    return string.encode(sys.getfilesystemencoding())
24
25class FileBrowser(object):
26    """FileBrowser displays directory and file listings from the vfs.
27       The file_selected parameter is a callback invoked when a file selection
28       has been made; its signature must be file_selected(path,filename). If
29       select_dir is set, file_selected's filename parameter should be optional.
30       The save_file option provides a box for supplying a new filename that
31       doesn't exist yet. The select_dir option allows directories to be
32       selected as well as files."""
33    def __init__(self, engine, file_selected, close_callback = None, 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        self.close_callback = close_callback
43       
44        self.gui_xml_path = gui_xml_path
45
46        self.extensions = extensions
47        self.path = './saves/'
48        self.dir_list = []
49        self.file_list = []
50       
51    def close(self):
52        """Closes the browser"""       
53        self._widget.hide()
54        if self.close_callback:
55            self.close_callback()
56   
57    def showBrowser(self):
58        """Shows the file dialog browser"""
59        if self._widget:
60            self._widget.show()
61            return
62        self._widget = pychan.loadXML(self.gui_xml_path)
63        self._widget.mapEvents({
64            'dirList'       : self._setDirectory,
65            'selectButton'  : self._selectFile,
66            'closeButton'   : self.close
67        })
68        self._setDirectory()
69        if self.save_file:
70            self._file_entry = widgets.TextField(name='saveField', text=u'')   
71            self._widget.findChild(name="fileColumn").\
72                addChild(self._file_entry)
73        self._widget.show()
74
75    def _setDirectory(self):
76        """Directory change callback."""
77        selection = self._widget.collectData('dirList')
78        if not (selection < 0):
79            new_dir = u2s(self.dir_list[selection])
80            lst = self.path.split('/')
81            if new_dir == '..' and lst[-1] != '..' and lst[-1] != '.':
82                lst.pop()
83            else:
84                lst.append(new_dir)
85            self.path = '/'.join(lst)
86           
87        def decodeList(list):
88            fs_encoding = sys.getfilesystemencoding()
89            if fs_encoding is None: fs_encoding = "ascii"
90       
91            new_list = []
92            for i in list:
93                try:
94                    new_list.append(unicode(i, fs_encoding))
95                except:
96                    new_list.append(unicode(i, fs_encoding, 'replace'))
97                    print "WARNING: Could not decode item:", i
98            return new_list
99           
100       
101
102        self.dir_list = []
103        self.file_list = []
104       
105        dir_list = ('..',) + filter(lambda d: not d.startswith('.'), \
106                                    self.engine.getVFS().\
107                                    listDirectories(self.path))
108        file_list = filter(lambda f: f.split('.')[-1] in self.extensions, \
109                           self.engine.getVFS().listFiles(self.path))
110               
111        self.dir_list = decodeList(dir_list)
112        self.file_list = decodeList(file_list)
113        self._widget.distributeInitialData({
114            'dirList'  : self.dir_list,
115            'fileList' : self.file_list
116        })
117
118    def _selectFile(self):
119        """ File selection callback. """
120        self._widget.hide()
121        selection = self._widget.collectData('fileList')
122
123        if self.save_file:
124            data = self._widget.collectData('saveField')
125            if data:
126                if (data.endswith(".dat")):
127                    self.file_selected(self.path, \
128                                u2s(self._widget.collectData('saveField')))
129                else:
130                    self.file_selected(self.path, 
131                                       u2s(self._widget.collectData('saveField')) + '.dat')
132                return
133           
134
135        if selection >= 0 and selection < len(self.file_list):
136            self.file_selected(self.path, u2s(self.file_list[selection]))
137            return
138       
139        if self.select_dir:
140            self.file_selected(self.path)
141            return
142
143        print 'FileBrowser: error, no selection.'
144
145    def _warningMessage(self):
146        """Shows the warning message dialog when a file with a
147           faulty extension was selected."""
148        window = widgets.Window(title="Warning")
149        text = "Please save the file as a .dat"
150        label = widgets.Label(text=text)
151        ok_button = widgets.Button(name="ok_button", text="Ok")
152        window.addChildren([label, ok_button])
153        window.mapEvents({'ok_button':window.hide})
154        window.show()
Note: See TracBrowser for help on using the repository browser.