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

Revision 810, 5.9 KB checked in by aspidites, 8 years ago (diff)

Patch by Aspidites

  • Removed SystemDataDirectory? and UserDataDirectory?
    • it is the the settings module's job to keep track of this sort of thing, not fife or PARPG's
    • consequently, setting.py's command line interface became simple
    • this will also prevent those "I generated a settings file but PARPG doesnt run" complaints
    • I think I'm going to have some helper methods to generate platform-specific paths at run-time
  • User data directory is now properly created
  • added platform_paths(system) which returns the platform-specific paths for the given system
  • if no system is given, it gives the paths for the system that the script was run on
  • changed logic of settings.py so that it is not required to pass a path.
  • not passing a path invokes paltform_paths
  • 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 os
19import logging
20
21logger = logging.getLogger('filebrowser')
22
23def u2s(string):
24    # TODO: cryptic function name
25    return string.encode(sys.getfilesystemencoding())
26
27class FileBrowser(object):
28    """FileBrowser displays directory and file listings from the vfs.
29       The file_selected parameter is a callback invoked when a file selection
30       has been made; its signature must be file_selected(path,filename). If
31       select_dir is set, file_selected's filename parameter should be optional.
32       The save_file option provides a box for supplying a new filename that
33       doesn't exist yet. The select_dir option allows directories to be
34       selected as well as files."""
35    def __init__(self, engine, settings, file_selected, gui_xml_path,
36                 close_callback=None, save_file=False, select_dir=False, 
37                 extensions=('.dat',)):
38        self.engine = engine
39        self.settings = settings
40        print self.settings.parpg.SavesDirectory
41        self.file_selected = file_selected
42
43        self._widget = None
44        self.save_file = save_file
45        self.select_dir = select_dir
46        self.close_callback = close_callback
47        self.gui_xml_path = gui_xml_path
48       
49        self.extensions = extensions
50        self.path = os.path.join(self.settings.paths['user'],
51                                 self.settings.parpg.SavesDirectory)
52        self.dir_list = []
53        self.file_list = []
54       
55    def close(self):
56        """Closes the browser"""       
57        self._widget.hide()
58        if self.close_callback:
59            self.close_callback()
60   
61    def showBrowser(self):
62        """Shows the file dialog browser"""
63        if self._widget:
64            self._widget.show()
65            return
66        self._widget = pychan.loadXML(self.gui_xml_path)
67        self._widget.mapEvents({
68            'dirList'       : self._setDirectory,
69            'selectButton'  : self._selectFile,
70            'closeButton'   : self.close
71        })
72        self._setDirectory()
73        if self.save_file:
74            self._file_entry = widgets.TextField(name='saveField', text=u'')   
75            self._widget.findChild(name="fileColumn").\
76                addChild(self._file_entry)
77        self._widget.show()
78
79    def _setDirectory(self):
80        """Directory change callback."""
81        selection = self._widget.collectData('dirList')
82        if not (selection < 0):
83            new_dir = u2s(self.dir_list[selection])
84            lst = self.path.split('/')
85            if new_dir == '..' and lst[-1] != '..' and lst[-1] != '.':
86                lst.pop()
87            else:
88                lst.append(new_dir)
89            self.path = '/'.join(lst)
90           
91        def decodeList(list):
92            fs_encoding = sys.getfilesystemencoding()
93            if fs_encoding is None: fs_encoding = "ascii"
94       
95            new_list = []
96            for i in list:
97                try:
98                    new_list.append(unicode(i, fs_encoding))
99                except:
100                    new_list.append(unicode(i, fs_encoding, 'replace'))
101                    logger.debug("WARNING: Could not decode item:\n"
102                                        "{0}".format(i))
103            return new_list
104           
105       
106
107        self.dir_list = []
108        self.file_list = []
109       
110        dir_list = ('..',) + filter(lambda d: not d.startswith('.'), \
111                                    self.engine.getVFS().\
112                                    listDirectories(self.path))
113        file_list = filter(lambda f: f.split('.')[-1] in self.extensions, \
114                           self.engine.getVFS().listFiles(self.path))
115               
116        self.dir_list = decodeList(dir_list)
117        self.file_list = decodeList(file_list)
118        self._widget.distributeInitialData({
119            'dirList'  : self.dir_list,
120            'fileList' : self.file_list
121        })
122
123    def _selectFile(self):
124        """ File selection callback. """
125        self._widget.hide()
126        selection = self._widget.collectData('fileList')
127
128        if self.save_file:
129            data = self._widget.collectData('saveField')
130            if data:
131                if (data.endswith(".dat")):
132                    self.file_selected(self.path, \
133                                u2s(self._widget.collectData('saveField')))
134                else:
135                    self.file_selected(self.path, 
136                                       u2s(self._widget.collectData('saveField')) + '.dat')
137                return
138           
139
140        if selection >= 0 and selection < len(self.file_list):
141            self.file_selected(self.path, u2s(self.file_list[selection]))
142            return
143       
144        if self.select_dir:
145            self.file_selected(self.path)
146            return
147
148        logger.error('no selection')
149
150    def _warningMessage(self):
151        """Shows the warning message dialog when a file with a
152           faulty extension was selected."""
153        window = widgets.Window(title="Warning")
154        text = "Please save the file as a .dat"
155        label = widgets.Label(text=text)
156        ok_button = widgets.Button(name="ok_button", text="Ok")
157        window.addChildren([label, ok_button])
158        window.mapEvents({'ok_button':window.hide})
159        window.show()
Note: See TracBrowser for help on using the repository browser.