/[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 33 - (show annotations)
Thu Sep 6 15:31: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: 18717 byte(s)
	* Thuban/UI/mainwindow.py (MainWindow.LayerShowTable): Pass the
	layer to the tableview dialog.

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