/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/application.py
ViewVC logotype

Annotation of /branches/WIP-pyshapelib-bramz/Thuban/UI/application.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2051 - (hide annotations)
Wed Jan 21 17:09:15 2004 UTC (21 years, 1 month ago) by frank
Original Path: trunk/thuban/Thuban/UI/application.py
File MIME type: text/x-python
File size: 11149 byte(s)
Make Thuban remember path selections (at least for one application run).

* Thuban/UI/application.py (Application.OnInit): Initialize path as a
	attribute of application object. Path is a dictionary of
	strings, currently with the items "data" and "projection".
	(Application.SetPath): New, stores path for the specified item.
	(Application.Path): New, return path for the specified item.

* Thuban/UI/mainwindow.py
	(MainWindow.OpenSession, MainWindow.SaveSessionAs,
	MainWindow.AddLayer, MainWindow.AddRasterLayer,
	MainWindow.TableOpen): Access "data" path information of the
	application.

* Thuban/UI/projdialog.py (ProjFrame._OnImport, ProjFrame._OnExport):
	Access "projection" path information of the application.

1 bh 401 # Copyright (C) 2001, 2002, 2003 by Intevation GmbH
2 bh 6 # Authors:
3     # Jan-Oliver Wagner <[email protected]>
4 bh 189 # Bernhard Herzog <[email protected]>
5 bh 6 #
6     # This program is free software under the GPL (>=v2)
7     # Read the file COPYING coming with Thuban for details.
8    
9     """
10     Thuban's application object.
11     """
12    
13     __version__ = "$Revision$"
14    
15 bh 189 import sys, os
16 frank 1133 import os.path
17    
18 bh 189 import traceback
19    
20 bh 6 from wxPython.wx import *
21    
22     from Thuban.Lib.connector import Publisher
23 frank 1150 from Thuban.Lib.fileutil import get_application_dir
24 bh 6
25 jan 374 from Thuban import _
26 bh 6 from Thuban.Model.session import create_empty_session
27     from Thuban.Model.save import save_session
28 bh 1650 from Thuban.Model.load import load_session, LoadCancelled
29 bh 242 from Thuban.Model.messages import MAPS_CHANGED
30 jonathan 1162 from Thuban.Model.layer import RasterLayer
31     import Thuban.Model.resource
32 bh 6
33     import view
34     import tree
35 bh 215 import mainwindow
36 bh 1654 import dbdialog
37 jan 1704 import exceptiondialog
38 bh 6
39 jonathan 503 from messages import SESSION_REPLACED
40 bh 6
41    
42     class ThubanApplication(wxApp, Publisher):
43    
44     """
45     Thuban's application class.
46    
47     All wxWindows programs have to have an instance of an application
48     class derived from wxApp. In Thuban the application class holds
49 bh 535 references to the main window and the session.
50 bh 6 """
51    
52     def OnInit(self):
53 jonathan 1518 sys.excepthook = self.ShowExceptionDialog
54 bh 401 self.splash = self.splash_screen()
55     if self.splash is not None:
56     self.splash.Show()
57 bh 189 self.read_startup_files()
58 bh 401 self.top = self.CreateMainWindow()
59     self.SetTopWindow(self.top)
60     if self.splash is None:
61     self.ShowMainWindow()
62 bh 6 self.session = None
63     self.create_session()
64 frank 2051 self.path={"data":".", "projection":"."}
65 jonathan 518 return True
66 bh 6
67 bh 251 def OnExit(self):
68     """Clean up code.
69    
70     Extend this in derived classes if needed.
71     """
72     self.session.Destroy()
73 bh 765 self.session = None
74 bh 251 Publisher.Destroy(self)
75    
76 bh 189 def read_startup_files(self):
77     """Read the startup files."""
78     # for now the startup file is ~/.thuban/thubanstart.py
79 frank 1150 dir = get_application_dir()
80 bh 189 if os.path.isdir(dir):
81     sys.path.append(dir)
82     try:
83     import thubanstart
84     except ImportError:
85     tb = sys.exc_info()[2]
86     try:
87     if tb.tb_next is not None:
88     # The ImportError exception was raised from
89     # inside the thubanstart module.
90 jan 374 sys.stderr.write(_("Cannot import the thubanstart"
91 bh 671 " module\n"))
92 bh 189 traceback.print_exc(None, sys.stderr)
93     else:
94     # There's no thubanstart module.
95 jan 374 sys.stderr.write(_("No thubanstart module available\n"))
96 bh 189 finally:
97     # make sure we delete the traceback object,
98     # otherwise there's be circular references involving
99     # the current stack frame
100     del tb
101     except:
102 jan 374 sys.stderr.write(_("Cannot import the thubanstart module\n"))
103 bh 189 traceback.print_exc(None, sys.stderr)
104     else:
105     # There's no .thuban directory
106 jan 374 sys.stderr.write(_("No ~/.thuban directory\n"))
107 bh 189
108 bh 401 def splash_screen(self):
109     """Create and return a splash screen.
110    
111     This method is called by OnInit to determine whether the
112     application should have a splashscreen. If the application
113     should display a splash screen override this method in a derived
114     class and have it create and return the wxSplashScreen instance.
115     The implementation of this method in the derived class should
116     also arranged for ShowMainWindow to be called.
117    
118     The default implementation simply returns None so that no splash
119     screen is shown and ShowMainWindow will be called automatically.
120     """
121     return None
122    
123     def ShowMainWindow(self):
124     """Show the main window
125    
126     Normally this method is automatically called by OnInit to show
127     the main window. However, if the splash_screen method has
128     returned a splashscreen it is expected that the derived class
129     also arranges for ShowMainWindow to be called at the appropriate
130     time.
131     """
132 jonathan 518 self.top.Show(True)
133 bh 535
134 bh 235 def CreateMainWindow(self):
135     """Create and return the main window for the application.
136    
137     Override this in subclasses to instantiate the Thuban mainwindow
138     with different parameters or to use a different class for the
139     main window.
140     """
141 jan 374 msg = (_("This is the wxPython-based Graphical User Interface"
142     " for exploring geographic data"))
143 bh 535 return mainwindow.MainWindow(NULL, -1, "Thuban", self, None,
144 jonathan 934 initial_message = msg,
145     size = (600, 400))
146 bh 235
147 bh 219 def Session(self):
148     """Return the application's session object"""
149     return self.session
150    
151 bh 6 def SetSession(self, session):
152 bh 219 """Make session the new session.
153    
154 jonathan 503 Issue SESSION_REPLACED after self.session has become the new
155 bh 242 session. After the session has been assigned call
156     self.subscribe_session() with the new session and
157     self.unsubscribe_session with the old one.
158 bh 219 """
159 bh 6 oldsession = self.session
160     self.session = session
161 bh 242 self.subscribe_session(self.session)
162 jonathan 503 self.issue(SESSION_REPLACED)
163 bh 242 self.maps_changed()
164 bh 6 if oldsession is not None:
165 bh 242 self.unsubscribe_session(oldsession)
166 bh 6 oldsession.Destroy()
167    
168 frank 2051 def SetPath(self, group, filename):
169     """Store the application's default path for file dialogs extracted
170     from a given filename.
171     """
172     self.path[group] = os.path.dirname( filename )
173    
174     def Path(self, group):
175     """Return the application's default path for file dialogs."""
176     return self.path[group]
177    
178 bh 242 def subscribe_session(self, session):
179     """Subscribe to some of the sessions channels.
180    
181     Extend this method in derived classes if you need additional
182     channels.
183     """
184     session.Subscribe(MAPS_CHANGED, self.maps_changed)
185    
186     def unsubscribe_session(self, session):
187     """Unsubscribe from the sessions channels.
188    
189     Extend this method in derived classes if you subscribed to
190     additional channels in subscribe_session().
191     """
192     session.Unsubscribe(MAPS_CHANGED, self.maps_changed)
193    
194 bh 6 def create_session(self):
195 bh 242 """Create a default session.
196    
197     Override this method in derived classes to instantiate the
198     session differently or to use a different session class. Don't
199     subscribe to channels here yet. Do that in the
200     subscribe_session() method.
201     """
202 bh 6 self.SetSession(create_empty_session())
203    
204 bh 1648 def OpenSession(self, filename, db_connection_callback = None):
205 bh 592 """Open the session in the file named filename"""
206     # Make sure we deal with an absolute pathname. Otherwise we can
207     # get problems when saving because the saving code expects an
208     # absolute directory name
209     filename = os.path.abspath(filename)
210 bh 1654 if db_connection_callback is None:
211     db_connection_callback = self.run_db_param_dialog
212 bh 1650 try:
213     session = load_session(filename,
214     db_connection_callback=db_connection_callback)
215     except LoadCancelled:
216     return
217 bh 6 session.SetFilename(filename)
218     session.UnsetModified()
219     self.SetSession(session)
220    
221 jonathan 1162 for map in session.Maps():
222     for layer in map.Layers():
223     if isinstance(layer, RasterLayer) \
224     and not Thuban.Model.resource.has_gdal_support():
225 bh 1566 msg = _("The current session contains Image layers,\n"
226     "but the GDAL library is not available to "
227 jonathan 1162 "draw them.")
228 bh 1566 dlg = wx.wxMessageDialog(None,
229     msg,
230 jonathan 1162 _("Library not available"),
231     wx.wxOK | wx.wxICON_INFORMATION)
232     print msg
233     dlg.ShowModal()
234     dlg.Destroy()
235     break
236    
237 bh 1654 def run_db_param_dialog(self, parameters, message):
238     """Implementation of the db_connection_callback for loading sessions"""
239     dlg = dbdialog.DBDialog(None, _("DB Connection Parameters"),
240     parameters, message)
241     return dlg.RunDialog()
242    
243    
244 bh 6 def SaveSession(self):
245     save_session(self.session, self.session.filename)
246    
247 bh 242 def maps_changed(self, *args):
248 bh 1776 """Subscribed to the session's MAPS_CHANGED messages.
249    
250     Set the toplevel window's map to the map in the session. This is
251     done by calling the window's SetMap method with the map as
252     argument. If the session doesn't have any maps None is used
253     instead.
254    
255     Currently Thuban can only really handle at most one map in a
256     sessions so the first map in the session's list of maps as
257     returned by the Maps method is used.
258     """
259 bh 6 if self.session.HasMaps():
260     self.top.SetMap(self.session.Maps()[0])
261     else:
262     self.top.SetMap(None)
263 jonathan 1390
264 jonathan 1518 in_exception_dialog = 0 # flag: are we already inside the exception dialog?
265 jonathan 1390
266 jonathan 1518 def ShowExceptionDialog(self, exc_type, exc_value, exc_traceback):
267     """Show a message box with information about an exception.
268    
269     The parameters are the usual values describing an exception in
270     Python, the exception type, the value and the traceback.
271    
272     This method can be used as a value for the sys.excepthook.
273     """
274 jonathan 1390
275 jonathan 1518 if self.in_exception_dialog:
276     return
277     self.in_exception_dialog = 1
278     while wxIsBusy():
279     wxEndBusyCursor() # reset the mouse cursor
280 jonathan 1390
281 jonathan 1518 try:
282     lines = traceback.format_exception(exc_type, exc_value,
283     exc_traceback)
284 bh 1874 message = _("An unhandled exception occurred:\n%s\n"
285     "(please report to"
286     " http://thuban.intevation.org/bugtracker.html)"
287     "\n\n%s") % (exc_value, "".join(lines))
288 jonathan 1518 print message
289 jonathan 1390
290 jonathan 1518 # We don't use an explicit parent here because this method might
291     # be called in circumstances where the main window doesn't exist
292     # anymore.
293 jan 1704 exceptiondialog.run_exception_dialog(None, message)
294 jonathan 1390
295 jonathan 1518 finally:
296     self.in_exception_dialog = 0
297     # delete the last exception info that python keeps in
298     # sys.last_* because especially last_traceback keeps
299     # indirect references to all objects bound to local
300     # variables and this might prevent some object from being
301     # collected early enough.
302     sys.last_type = sys.last_value = sys.last_traceback = None
303 jonathan 1390

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26