/[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 37 - (show annotations)
Thu Sep 6 17:16:54 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: 18847 byte(s)
	* Thuban/UI/mainwindow.py (MainWindow.current_layer):
	(MainWindow.has_selected_layer): Simply call the appropriate
	interactor method

	* Thuban/UI/mainwindow.py (MainWindow.__init__):
	(MainWindow.LayerShowTable):
	(MainWindow.identify_view_on_demand): Store the interactor in an
	instvar and use that reference instead of going through main.app

	* Thuban/UI/mainwindow.py (MainWindow.ShowSessionTree):
	* Thuban/UI/application.py (ThubanApplication.OnInit):
	* Thuban/UI/main.py (main): Create the session tree view in main
	with the new mainwindow method ShowSessionTree and not directly
	the application's OnInit method

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