/[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 1566 - (hide 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 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 jonathan 1390 from wxPython.lib.dialogs import wxScrolledMessageDialog
22 bh 6
23     from Thuban.Lib.connector import Publisher
24 frank 1150 from Thuban.Lib.fileutil import get_application_dir
25 bh 6
26 jan 374 from Thuban import _
27 bh 6 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 bh 242 from Thuban.Model.messages import MAPS_CHANGED
31 jonathan 1162 from Thuban.Model.layer import RasterLayer
32     import Thuban.Model.resource
33 bh 6
34     import view
35     import tree
36 bh 215 import mainwindow
37 bh 6
38 jonathan 503 from messages import SESSION_REPLACED
39 bh 6
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 bh 535 references to the main window and the session.
49 bh 6 """
50    
51     def OnInit(self):
52 jonathan 1518 sys.excepthook = self.ShowExceptionDialog
53 bh 401 self.splash = self.splash_screen()
54     if self.splash is not None:
55     self.splash.Show()
56 bh 189 self.read_startup_files()
57 bh 401 self.top = self.CreateMainWindow()
58     self.SetTopWindow(self.top)
59     if self.splash is None:
60     self.ShowMainWindow()
61 bh 6 self.session = None
62     self.create_session()
63 jonathan 518 return True
64 bh 6
65 bh 251 def OnExit(self):
66     """Clean up code.
67    
68     Extend this in derived classes if needed.
69     """
70     self.session.Destroy()
71 bh 765 self.session = None
72 bh 251 Publisher.Destroy(self)
73    
74 bh 189 def read_startup_files(self):
75     """Read the startup files."""
76     # for now the startup file is ~/.thuban/thubanstart.py
77 frank 1150 dir = get_application_dir()
78 bh 189 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 jan 374 sys.stderr.write(_("Cannot import the thubanstart"
89 bh 671 " module\n"))
90 bh 189 traceback.print_exc(None, sys.stderr)
91     else:
92     # There's no thubanstart module.
93 jan 374 sys.stderr.write(_("No thubanstart module available\n"))
94 bh 189 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 jan 374 sys.stderr.write(_("Cannot import the thubanstart module\n"))
101 bh 189 traceback.print_exc(None, sys.stderr)
102     else:
103     # There's no .thuban directory
104 jan 374 sys.stderr.write(_("No ~/.thuban directory\n"))
105 bh 189
106 bh 401 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 jonathan 518 self.top.Show(True)
131 bh 535
132 bh 235 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 jan 374 msg = (_("This is the wxPython-based Graphical User Interface"
140     " for exploring geographic data"))
141 bh 535 return mainwindow.MainWindow(NULL, -1, "Thuban", self, None,
142 jonathan 934 initial_message = msg,
143     size = (600, 400))
144 bh 235
145 bh 219 def Session(self):
146     """Return the application's session object"""
147     return self.session
148    
149 bh 6 def SetSession(self, session):
150 bh 219 """Make session the new session.
151    
152 jonathan 503 Issue SESSION_REPLACED after self.session has become the new
153 bh 242 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 bh 219 """
157 bh 6 oldsession = self.session
158     self.session = session
159 bh 242 self.subscribe_session(self.session)
160 jonathan 503 self.issue(SESSION_REPLACED)
161 bh 242 self.maps_changed()
162 bh 6 if oldsession is not None:
163 bh 242 self.unsubscribe_session(oldsession)
164 bh 6 oldsession.Destroy()
165    
166 bh 242 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 bh 6 def create_session(self):
183 bh 242 """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 bh 6 self.SetSession(create_empty_session())
191    
192     def OpenSession(self, filename):
193 bh 592 """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 bh 6 session = load_session(filename)
199     session.SetFilename(filename)
200     session.UnsetModified()
201     self.SetSession(session)
202    
203 jonathan 1162 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 bh 1566 msg = _("The current session contains Image layers,\n"
208     "but the GDAL library is not available to "
209 jonathan 1162 "draw them.")
210 bh 1566 dlg = wx.wxMessageDialog(None,
211     msg,
212 jonathan 1162 _("Library not available"),
213     wx.wxOK | wx.wxICON_INFORMATION)
214     print msg
215     dlg.ShowModal()
216     dlg.Destroy()
217     break
218    
219 bh 6 def SaveSession(self):
220     save_session(self.session, self.session.filename)
221    
222 bh 242 def maps_changed(self, *args):
223 bh 6 if self.session.HasMaps():
224     self.top.SetMap(self.session.Maps()[0])
225     else:
226     self.top.SetMap(None)
227 jonathan 1390
228 jonathan 1518 in_exception_dialog = 0 # flag: are we already inside the exception dialog?
229 jonathan 1390
230 jonathan 1518 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 jonathan 1390
239 jonathan 1518 if self.in_exception_dialog:
240     return
241     self.in_exception_dialog = 1
242     while wxIsBusy():
243     wxEndBusyCursor() # reset the mouse cursor
244 jonathan 1390
245 jonathan 1518 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 jonathan 1390
255 jonathan 1518 # 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 jonathan 1390
263 jonathan 1518 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 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