/[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 1566 - (show annotations)
Fri Aug 8 13:01:30 2003 UTC (21 years, 7 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/application.py
File MIME type: text/x-python
File size: 9828 byte(s)
Make sure translated strings are recognized as one string literal.

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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26