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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1704 - (show annotations)
Wed Sep 3 07:02:36 2003 UTC (21 years, 6 months ago) by jan
Original Path: trunk/thuban/Thuban/UI/application.py
File MIME type: text/x-python
File size: 10290 byte(s)
(ThubanApplication.ShowExceptionDialog): Made strings available to
translations. Exchanged the simple
ScrolledMessageDialog by the new ExceptionDialog.

1 # Copyright (C) 2001, 2002, 2003 by Intevation GmbH
2 # Authors:
3 # Jan-Oliver Wagner <[email protected]>
4 # Bernhard Herzog <[email protected]>
5 #
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 import sys, os
16 import os.path
17
18 import traceback
19
20 from wxPython.wx import *
21
22 from Thuban.Lib.connector import Publisher
23 from Thuban.Lib.fileutil import get_application_dir
24
25 from Thuban import _
26 from Thuban.Model.session import create_empty_session
27 from Thuban.Model.save import save_session
28 from Thuban.Model.load import load_session, LoadCancelled
29 from Thuban.Model.messages import MAPS_CHANGED
30 from Thuban.Model.layer import RasterLayer
31 import Thuban.Model.resource
32
33 import view
34 import tree
35 import mainwindow
36 import dbdialog
37 import exceptiondialog
38
39 from messages import SESSION_REPLACED
40
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 references to the main window and the session.
50 """
51
52 def OnInit(self):
53 sys.excepthook = self.ShowExceptionDialog
54 self.splash = self.splash_screen()
55 if self.splash is not None:
56 self.splash.Show()
57 self.read_startup_files()
58 self.top = self.CreateMainWindow()
59 self.SetTopWindow(self.top)
60 if self.splash is None:
61 self.ShowMainWindow()
62 self.session = None
63 self.create_session()
64 return True
65
66 def OnExit(self):
67 """Clean up code.
68
69 Extend this in derived classes if needed.
70 """
71 self.session.Destroy()
72 self.session = None
73 Publisher.Destroy(self)
74
75 def read_startup_files(self):
76 """Read the startup files."""
77 # for now the startup file is ~/.thuban/thubanstart.py
78 dir = get_application_dir()
79 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 sys.stderr.write(_("Cannot import the thubanstart"
90 " module\n"))
91 traceback.print_exc(None, sys.stderr)
92 else:
93 # There's no thubanstart module.
94 sys.stderr.write(_("No thubanstart module available\n"))
95 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 sys.stderr.write(_("Cannot import the thubanstart module\n"))
102 traceback.print_exc(None, sys.stderr)
103 else:
104 # There's no .thuban directory
105 sys.stderr.write(_("No ~/.thuban directory\n"))
106
107 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 self.top.Show(True)
132
133 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 msg = (_("This is the wxPython-based Graphical User Interface"
141 " for exploring geographic data"))
142 return mainwindow.MainWindow(NULL, -1, "Thuban", self, None,
143 initial_message = msg,
144 size = (600, 400))
145
146 def Session(self):
147 """Return the application's session object"""
148 return self.session
149
150 def SetSession(self, session):
151 """Make session the new session.
152
153 Issue SESSION_REPLACED after self.session has become the new
154 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 """
158 oldsession = self.session
159 self.session = session
160 self.subscribe_session(self.session)
161 self.issue(SESSION_REPLACED)
162 self.maps_changed()
163 if oldsession is not None:
164 self.unsubscribe_session(oldsession)
165 oldsession.Destroy()
166
167 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 def create_session(self):
184 """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 self.SetSession(create_empty_session())
192
193 def OpenSession(self, filename, db_connection_callback = None):
194 """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 if db_connection_callback is None:
200 db_connection_callback = self.run_db_param_dialog
201 try:
202 session = load_session(filename,
203 db_connection_callback=db_connection_callback)
204 except LoadCancelled:
205 return
206 session.SetFilename(filename)
207 session.UnsetModified()
208 self.SetSession(session)
209
210 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 msg = _("The current session contains Image layers,\n"
215 "but the GDAL library is not available to "
216 "draw them.")
217 dlg = wx.wxMessageDialog(None,
218 msg,
219 _("Library not available"),
220 wx.wxOK | wx.wxICON_INFORMATION)
221 print msg
222 dlg.ShowModal()
223 dlg.Destroy()
224 break
225
226 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 def SaveSession(self):
234 save_session(self.session, self.session.filename)
235
236 def maps_changed(self, *args):
237 if self.session.HasMaps():
238 self.top.SetMap(self.session.Maps()[0])
239 else:
240 self.top.SetMap(None)
241
242 in_exception_dialog = 0 # flag: are we already inside the exception dialog?
243
244 def ShowExceptionDialog(self, exc_type, exc_value, exc_traceback):
245 """Show a message box with information about an exception.
246
247 The parameters are the usual values describing an exception in
248 Python, the exception type, the value and the traceback.
249
250 This method can be used as a value for the sys.excepthook.
251 """
252
253 if self.in_exception_dialog:
254 return
255 self.in_exception_dialog = 1
256 while wxIsBusy():
257 wxEndBusyCursor() # reset the mouse cursor
258
259 try:
260 lines = traceback.format_exception(exc_type, exc_value,
261 exc_traceback)
262 message = _("An unhandled exception occurred:\n%s\n") % exc_value+\
263 _("(please report to") +\
264 " http://thuban.intevation.org/bugtracker.html)"\
265 "\n\n\n"+\
266 "".join(lines)
267 print message
268
269 # We don't use an explicit parent here because this method might
270 # be called in circumstances where the main window doesn't exist
271 # anymore.
272 exceptiondialog.run_exception_dialog(None, message)
273
274 finally:
275 self.in_exception_dialog = 0
276 # delete the last exception info that python keeps in
277 # sys.last_* because especially last_traceback keeps
278 # indirect references to all objects bound to local
279 # variables and this might prevent some object from being
280 # collected early enough.
281 sys.last_type = sys.last_value = sys.last_traceback = None
282

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26