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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 20 - (show annotations)
Tue Sep 4 16:44:31 2001 UTC (23 years, 6 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/mainwindow.py
File MIME type: text/x-python
File size: 17058 byte(s)
	* Thuban/UI/mainwindow.py (MainWindow.RunMessageBox): New method
	that runs a modal message box
	(MainWindow.OnClose): Use the new method
	(MainWindow.RemoveLayer): Just do nothing in case no layer is
	selected. The command should be grayed out anyway, so there's no
	need to pop up a message box.
	(MainWindow.AddLayer): Pop up a message box with an error message
	if the shape file can't be opened

1 # Copyright (C) 2001 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 The main window
11 """
12
13 __version__ = "$Revision$"
14
15 import sys, os
16
17 from wxPython.wx import *
18
19 import Thuban
20 from Thuban.Model.session import Session
21 from Thuban.Model.map import Map
22 from Thuban.Model.layer import Layer
23 from Thuban.Model.color import Color
24 from Thuban.Model.proj import Projection
25
26 import view
27 import tree
28 import proj4dialog
29 import tableview, identifyview
30
31 import main
32 from command import registry, Command
33
34
35 # the directory where the toolbar icons are stored
36 bitmapdir = os.path.join(Thuban.__path__[0], os.pardir, "Resources", "Bitmaps")
37 bitmapext = ".xpm"
38
39
40 class MainWindow(wxFrame):
41
42 def __init__(self, parent, ID):
43 wxFrame.__init__(self, parent, ID, 'Thuban',
44 wxDefaultPosition, wxSize(400, 300))
45
46 self.CreateStatusBar()
47 self.SetStatusText("This is the wxPython-based "
48 "Graphical User Interface for exploring geographic data")
49
50 self.identify_view = None
51
52 self.init_ids()
53
54 menuBar = wxMenuBar()
55
56 menu = wxMenu()
57 menuBar.Append(menu, "&File");
58 for name in ["new_session", "open_session", None,
59 "save_session", "save_session_as", None,
60 "exit"]:
61 self.add_menu_command(menu, name)
62
63 menu = wxMenu()
64 menuBar.Append(menu, "&Map");
65 for name in ["map_projection",
66 None,
67 "map_zoom_in_tool", "map_zoom_out_tool", "map_pan_tool",
68 "map_identify_tool", "map_label_tool",
69 None,
70 "map_full_extent",
71 None,
72 "map_print"]:
73 self.add_menu_command(menu, name)
74
75 menu = wxMenu()
76 menuBar.Append(menu, "&Layer");
77 for name in ["layer_add", "layer_remove",
78 None,
79 "layer_fill_color", "layer_transparent_fill",
80 "layer_ourline_color", "layer_no_outline",
81 None,
82 "layer_raise", "layer_lower",
83 None,
84 "layer_show", "layer_hide",
85 None,
86 "layer_show_table"]:
87 self.add_menu_command(menu, name)
88
89 menu = wxMenu()
90 menuBar.Append(menu, "&Help");
91 self.add_menu_command(menu, "help_about")
92
93 self.SetMenuBar(menuBar)
94
95 # toolbar
96 toolbar = self.CreateToolBar(wxTB_3DBUTTONS)
97 for name in ["map_zoom_in_tool", "map_zoom_out_tool", "map_pan_tool",
98 "map_identify_tool", "map_label_tool"]:
99 self.add_toolbar_command(toolbar, name)
100 # call Realize to make sure that the tools appear.
101 toolbar.Realize()
102
103 # Create the map canvas
104 canvas = view.MapCanvas(self, -1)
105 self.canvas = canvas
106
107 EVT_CLOSE(self, self.OnClose)
108
109 def init_ids(self):
110 """Initialize the ids"""
111 self.current_id = 6000
112 self.id_to_name = {}
113 self.name_to_id = {}
114
115 def get_id(self, name):
116 """Return the wxWindows id for the command named name.
117
118 Create a new one if there isn't one yet"""
119 ID = self.name_to_id.get(name)
120 if ID is None:
121 ID = self.current_id
122 self.current_id = self.current_id + 1
123 self.name_to_id[name] = ID
124 self.id_to_name[ID] = name
125 return ID
126
127 def add_menu_command(self, menu, name):
128 """Add the command with name name to the menu menu.
129
130 If name is None, add a separator.
131 """
132 if name is None:
133 menu.AppendSeparator()
134 else:
135 command = registry.Command(name)
136 if command is not None:
137 ID = self.get_id(name)
138 menu.Append(ID, command.Title(), command.HelpText(),
139 command.IsCheckCommand())
140 EVT_MENU(self, ID, self.invoke_command)
141 if command.IsDynamic():
142 EVT_UPDATE_UI(self, ID, self.update_command_ui)
143 else:
144 print "Unknown command %s" % name
145
146 def add_toolbar_command(self, toolbar, name):
147 """Add the command with name name to the toolbar toolbar.
148
149 If name is None, add a separator.
150 """
151 # Assume that all toolbar commands are also menu commmands so
152 # that we don't have to add the event handlers here
153 if name is None:
154 toolbar.AddSeparator()
155 else:
156 command = registry.Command(name)
157 if command is not None:
158 ID = self.get_id(name)
159 filename = os.path.join(bitmapdir, command.Icon()) + bitmapext
160 bitmap = wxBitmap(filename, wxBITMAP_TYPE_XPM)
161 toolbar.AddTool(ID, bitmap,
162 shortHelpString = command.HelpText(),
163 isToggle = command.IsCheckCommand())
164 else:
165 print "Unknown command %s" % name
166
167 def invoke_command(self, event):
168 name = self.id_to_name.get(event.GetId())
169 if name is not None:
170 command = registry.Command(name)
171 command.Execute(self)
172 else:
173 print "Unknown command ID %d" % event.GetId()
174
175 def update_command_ui(self, event):
176 #print "update_command_ui", self.id_to_name[event.GetId()]
177 command = registry.Command(self.id_to_name[event.GetId()])
178 if command is not None:
179 event.Enable(command.Sensitive(self))
180 event.SetText(command.DynText(self))
181 if command.IsCheckCommand():
182 event.Check(command.Checked(self))
183
184 def RunMessageBox(self, title, text, flags = wxOK | wxICON_INFORMATION):
185 """Run a modla message box with the given text, title and flags
186 and return the result"""
187 dlg = wxMessageDialog(self, text, title, flags)
188 result = dlg.ShowModal()
189 dlg.Destroy()
190 return result
191
192 def NewSession(self):
193 session = Session("")
194 session.AddMap(Map(""))
195 main.app.SetSession(session)
196
197 def OpenSession(self):
198 dlg = wxFileDialog(self, "Select a session file", ".", "",
199 "*.session", wxOPEN)
200 if dlg.ShowModal() == wxID_OK:
201 main.app.OpenSession(dlg.GetPath())
202 dlg.Destroy()
203
204 def SaveSession(self):
205 main.app.SaveSession()
206
207 def SaveSessionAs(self):
208 dlg = wxFileDialog(self, "Enter a filename for session", ".", "",
209 "*.session", wxOPEN)
210 if dlg.ShowModal() == wxID_OK:
211 main.app.session.SetFilename(dlg.GetPath())
212 main.app.SaveSession()
213 dlg.Destroy()
214
215 def Exit(self):
216 self.Close(false)
217
218 def OnClose(self, event):
219 veto = 0
220 if main.app.session.WasModified():
221 flags = wxYES_NO | wxICON_QUESTION
222 if event.CanVeto():
223 flags = flags | wxCANCEL
224 result = self.RunMessageBox("Exit",
225 ("The session has been modified."
226 " Do you want to save it?"),
227 flags)
228 if result == wxID_YES:
229 self.SaveSession()
230 elif result == wxID_CANCEL:
231 veto = 1
232
233 if veto:
234 event.Veto()
235 else:
236 self.Destroy()
237
238 def SetMap(self, map):
239 self.canvas.SetMap(map)
240
241 def About(self):
242 self.RunMessageBox("About",
243 ("Thuban is a program for\n"
244 "exploring geographic data.\n"
245 "Copyright (C) 2001 Intevation GmbH.\n"
246 "Thuban is licensed under the GPL"),
247 wxOK | wxICON_INFORMATION)
248
249 def AddLayer(self):
250 dlg = wxFileDialog(self, "Select a session file", ".", "", "*.*",
251 wxOPEN)
252 if dlg.ShowModal() == wxID_OK:
253 filename = dlg.GetPath()
254 title = os.path.splitext(os.path.basename(filename))[0]
255 layer = Layer(title, filename)
256 map = self.canvas.Map()
257 has_layers = map.HasLayers()
258 try:
259 map.AddLayer(layer)
260 except IOError:
261 # the layer couldn't be opened
262 self.RunMessageBox("Add Layer",
263 "Can't open the file '%s'." % filename)
264 else:
265 if not has_layers:
266 # if we're adding a layer to an empty map, for the
267 # new map to the window
268 self.canvas.FitMapToWindow()
269 dlg.Destroy()
270
271 def RemoveLayer(self):
272 layer = self.current_layer()
273 if layer is not None:
274 self.canvas.Map().RemoveLayer(layer)
275
276 def RaiseLayer(self):
277 layer = self.current_layer()
278 if layer is not None:
279 self.canvas.Map().RaiseLayer(layer)
280
281 def LowerLayer(self):
282 layer = self.current_layer()
283 if layer is not None:
284 self.canvas.Map().LowerLayer(layer)
285
286 def current_layer(self):
287 """Return the currently selected layer.
288
289 If no layer is selected, return None
290 """
291 tree = main.app.tree.tree
292 layer = tree.GetPyData(tree.GetSelection())
293 if isinstance(layer, Layer):
294 return layer
295 return None
296
297 def has_selected_layer(self):
298 """Return true if a layer is currently selected"""
299 tree = main.app.tree.tree
300 layer = tree.GetPyData(tree.GetSelection())
301 return isinstance(layer, Layer)
302
303 def choose_color(self):
304 """Run the color selection dialog and return the selected color.
305
306 If the user cancels, return None.
307 """
308 dlg = wxColourDialog(self)
309 color = None
310 if dlg.ShowModal() == wxID_OK:
311 data = dlg.GetColourData()
312 wxc = data.GetColour()
313 color = Color(wxc.Red() / 255.0,
314 wxc.Green() / 255.0,
315 wxc.Blue() / 255.0)
316 dlg.Destroy()
317 return color
318
319 def LayerFillColor(self):
320 layer = self.current_layer()
321 if layer is not None:
322 color = self.choose_color()
323 if color is not None:
324 layer.SetFill(color)
325
326 def LayerTransparentFill(self):
327 layer = self.current_layer()
328 if layer is not None:
329 layer.SetFill(None)
330
331 def LayerOutlineColor(self):
332 layer = self.current_layer()
333 if layer is not None:
334 color = self.choose_color()
335 if color is not None:
336 layer.SetStroke(color)
337
338 def LayerNoOutline(self):
339 layer = self.current_layer()
340 if layer is not None:
341 layer.SetStroke(None)
342
343 def HideLayer(self):
344 layer = self.current_layer()
345 if layer is not None:
346 layer.SetVisible(0)
347
348 def ShowLayer(self):
349 layer = self.current_layer()
350 if layer is not None:
351 layer.SetVisible(1)
352
353 def LayerShowTable(self):
354 layer = self.current_layer()
355 if layer is not None:
356 tv = tableview.TableFrame(self, layer.table)
357 tv.Show(true)
358
359 def Projection(self):
360 map = self.canvas.Map()
361 proj = map.projection
362 if proj is None:
363 proj4Dlg = proj4dialog.Proj4Dialog(NULL, None)
364 else:
365 proj4Dlg = proj4dialog.Proj4Dialog(NULL, map.projection.params)
366 if proj4Dlg.ShowModal() == wxID_OK:
367 params = proj4Dlg.GetParams()
368 if params is not None:
369 proj = Projection(params)
370 else:
371 proj = None
372 map.SetProjection(proj)
373 proj4Dlg.Destroy()
374
375 def ZoomInTool(self):
376 self.canvas.ZoomInTool()
377
378 def ZoomOutTool(self):
379 self.canvas.ZoomOutTool()
380
381 def PanTool(self):
382 self.canvas.PanTool()
383
384 def IdentifyTool(self):
385 if self.identify_view is None:
386 self.identify_view = identifyview.IdentifyView(self, main.app)
387 self.identify_view.Show(true)
388 self.canvas.IdentifyTool()
389
390 def LabelTool(self):
391 self.canvas.LabelTool()
392
393 def FullExtent(self):
394 self.canvas.FitMapToWindow()
395
396 def PrintMap(self):
397 self.canvas.Print()
398
399
400 #
401 # Define all the commands available in the main window
402 #
403
404
405 # Helper functions to define common command implementations
406 def call_method(context, methodname, *args):
407 """Call the context's method methodname with args *args"""
408 apply(getattr(context, methodname), args)
409
410 def _method_command(name, title, method, helptext = "", sensitive = None):
411 """Add a command implemented by a method of the context object"""
412 registry.Add(Command(name, title, call_method, args=(method,),
413 helptext = helptext, sensitive = sensitive))
414 def _tool_command(name, title, method, toolname, helptext = "",
415 icon = ""):
416 """Add a tool command"""
417 def check_current_tool(context, name=toolname):
418 return context.canvas.CurrentTool() == name
419 registry.Add(Command(name, title, call_method, args=(method,),
420 helptext = helptext, icon = icon,
421 checked = check_current_tool))
422
423 def _has_selected_layer(context):
424 """Return true if a layer is selected in the context"""
425 return context.has_selected_layer()
426
427 # File menu
428 _method_command("new_session", "&New Session", "NewSession")
429 _method_command("open_session", "&Open Session", "OpenSession")
430 _method_command("save_session", "&Save Session", "SaveSession")
431 _method_command("save_session_as", "Save Session &As", "SaveSessionAs")
432 _method_command("exit", "&Exit", "Exit")
433
434 # Help menu
435 _method_command("help_about", "&About", "About")
436
437
438 # Map menu
439 _method_command("map_projection", "Pro&jection", "Projection")
440
441 _tool_command("map_zoom_in_tool", "&Zoom in", "ZoomInTool", "ZoomInTool",
442 helptext = "Switch to map-mode 'zoom-in'", icon = "zoom_in")
443 _tool_command("map_zoom_out_tool", "Zoom &out", "ZoomOutTool", "ZoomOutTool",
444 helptext = "Switch to map-mode 'zoom-out'", icon = "zoom_out")
445 _tool_command("map_pan_tool", "&Pan", "PanTool", "PanTool",
446 helptext = "Switch to map-mode 'pan'", icon = "pan")
447 _tool_command("map_identify_tool", "&Identify", "IdentifyTool", "IdentifyTool",
448 helptext = "Switch to map-mode 'identify'", icon = "identify")
449 _tool_command("map_label_tool", "&Label", "LabelTool", "LabelTool",
450 helptext = "Add/Remove labels", icon = "label")
451 _method_command("map_full_extent", "&Full extent", "FullExtent")
452 _method_command("map_print", "Prin&t", "PrintMap", helptext = "Print the map")
453
454 # Layer menu
455 _method_command("layer_add", "&Add", "AddLayer",
456 helptext = "Add a new layer to active map")
457 _method_command("layer_remove", "&Remove", "RemoveLayer",
458 helptext = "Remove selected layer(s)",
459 sensitive = _has_selected_layer)
460 _method_command("layer_fill_color", "&Fill Color", "LayerFillColor",
461 helptext = "Set the fill color of selected layer(s)",
462 sensitive = _has_selected_layer)
463 _method_command("layer_transparent_fill", "&Transparent Fill",
464 "LayerTransparentFill",
465 helptext = "Do not fill the selected layer(s)",
466 sensitive = _has_selected_layer)
467 _method_command("layer_ourline_color", "&Outline Color", "LayerOutlineColor",
468 helptext = "Set the outline color of selected layer(s)",
469 sensitive = _has_selected_layer)
470 _method_command("layer_no_outline", "&No Outline", "LayerNoOutline",
471 helptext = "Do not draw the outline of the selected layer(s)",
472 sensitive = _has_selected_layer)
473 _method_command("layer_raise", "&Raise", "RaiseLayer",
474 helptext = "Raise selected layer(s)",
475 sensitive = _has_selected_layer)
476 _method_command("layer_lower", "&Lower", "LowerLayer",
477 helptext = "Lower selected layer(s)",
478 sensitive = _has_selected_layer)
479 _method_command("layer_show", "&Show", "ShowLayer",
480 helptext = "Make selected layer(s) visible",
481 sensitive = _has_selected_layer)
482 _method_command("layer_hide", "&Hide", "HideLayer",
483 helptext = "Make selected layer(s) unvisible",
484 sensitive = _has_selected_layer)
485 _method_command("layer_show_table", "Show Ta&ble", "LayerShowTable",
486 helptext = "Show the selected layer's table",
487 sensitive = _has_selected_layer)

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26