/[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 1874 - (hide annotations)
Mon Oct 27 17:36:49 2003 UTC (21 years, 4 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/application.py
File MIME type: text/x-python
File size: 10756 byte(s)
(ThubanApplication.ShowExceptionDialog): Handle translation of the
dialog message properly

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