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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 49 - (hide annotations)
Mon Sep 10 16:03:59 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: 18896 byte(s)
(MainWindow.IdentifyTool): Popup the identify view immediately

1 bh 6 # 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 bh 31 from messages import SELECTED_SHAPE
34 bh 6
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 bh 24 def __init__(self, parent, ID, interactor):
44 bh 6 wxFrame.__init__(self, parent, ID, 'Thuban',
45     wxDefaultPosition, wxSize(400, 300))
46    
47 bh 37 self.interactor = interactor
48    
49 bh 6 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 bh 13 # call Realize to make sure that the tools appear.
104     toolbar.Realize()
105 bh 6
106     # Create the map canvas
107 bh 24 canvas = view.MapCanvas(self, -1, interactor)
108 bh 6 self.canvas = canvas
109    
110 bh 31 self.init_dialogs()
111    
112     interactor.Subscribe(SELECTED_SHAPE, self.identify_view_on_demand)
113    
114 bh 6 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 bh 13 if command.IsCheckCommand():
189     event.Check(command.Checked(self))
190 bh 6
191 bh 20 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 bh 31 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 bh 6 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 bh 20 result = self.RunMessageBox("Exit",
253     ("The session has been modified."
254     " Do you want to save it?"),
255     flags)
256 bh 6 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 bh 37 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 bh 6 def About(self):
281 bh 20 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 bh 6
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 bh 18 map = self.canvas.Map()
296     has_layers = map.HasLayers()
297 bh 20 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 bh 6 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 bh 37 return self.interactor.SelectedLayer()
331 bh 6
332     def has_selected_layer(self):
333     """Return true if a layer is currently selected"""
334 bh 37 return self.interactor.HasSelectedLayer()
335 bh 6
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 bh 31 table = layer.table
390     name = "table_view" + str(id(table))
391     dialog = self.get_open_dialog(name)
392     if dialog is None:
393 bh 37 dialog = tableview.TableFrame(self, self.interactor, name,
394 bh 31 "Table: %s" % layer.Title(),
395 bh 33 layer, table)
396 bh 31 self.add_dialog(name, dialog)
397     dialog.Show(true)
398     else:
399     # FIXME: bring dialog to front here
400     pass
401 bh 6
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 bh 49 self.identify_view_on_demand(None, None)
430 bh 6
431     def LabelTool(self):
432     self.canvas.LabelTool()
433    
434     def FullExtent(self):
435     self.canvas.FitMapToWindow()
436    
437     def PrintMap(self):
438     self.canvas.Print()
439    
440 bh 31 def identify_view_on_demand(self, layer, shape):
441     name = "identify_view"
442     if self.canvas.CurrentTool() == "IdentifyTool":
443     if not self.dialog_open(name):
444 bh 37 dialog = identifyview.IdentifyView(self, self.interactor, name)
445 bh 31 self.add_dialog(name, dialog)
446     dialog.Show(true)
447     else:
448 bh 33 # FIXME: bring dialog to front?
449 bh 31 pass
450 bh 6
451     #
452     # Define all the commands available in the main window
453     #
454    
455    
456     # Helper functions to define common command implementations
457     def call_method(context, methodname, *args):
458     """Call the context's method methodname with args *args"""
459     apply(getattr(context, methodname), args)
460    
461     def _method_command(name, title, method, helptext = "", sensitive = None):
462     """Add a command implemented by a method of the context object"""
463     registry.Add(Command(name, title, call_method, args=(method,),
464     helptext = helptext, sensitive = sensitive))
465     def _tool_command(name, title, method, toolname, helptext = "",
466     icon = ""):
467     """Add a tool command"""
468     def check_current_tool(context, name=toolname):
469     return context.canvas.CurrentTool() == name
470     registry.Add(Command(name, title, call_method, args=(method,),
471     helptext = helptext, icon = icon,
472     checked = check_current_tool))
473    
474     def _has_selected_layer(context):
475     """Return true if a layer is selected in the context"""
476     return context.has_selected_layer()
477    
478     # File menu
479     _method_command("new_session", "&New Session", "NewSession")
480     _method_command("open_session", "&Open Session", "OpenSession")
481     _method_command("save_session", "&Save Session", "SaveSession")
482     _method_command("save_session_as", "Save Session &As", "SaveSessionAs")
483     _method_command("exit", "&Exit", "Exit")
484    
485     # Help menu
486     _method_command("help_about", "&About", "About")
487    
488    
489     # Map menu
490     _method_command("map_projection", "Pro&jection", "Projection")
491    
492     _tool_command("map_zoom_in_tool", "&Zoom in", "ZoomInTool", "ZoomInTool",
493     helptext = "Switch to map-mode 'zoom-in'", icon = "zoom_in")
494     _tool_command("map_zoom_out_tool", "Zoom &out", "ZoomOutTool", "ZoomOutTool",
495     helptext = "Switch to map-mode 'zoom-out'", icon = "zoom_out")
496     _tool_command("map_pan_tool", "&Pan", "PanTool", "PanTool",
497     helptext = "Switch to map-mode 'pan'", icon = "pan")
498     _tool_command("map_identify_tool", "&Identify", "IdentifyTool", "IdentifyTool",
499     helptext = "Switch to map-mode 'identify'", icon = "identify")
500     _tool_command("map_label_tool", "&Label", "LabelTool", "LabelTool",
501     helptext = "Add/Remove labels", icon = "label")
502     _method_command("map_full_extent", "&Full extent", "FullExtent")
503     _method_command("map_print", "Prin&t", "PrintMap", helptext = "Print the map")
504    
505     # Layer menu
506     _method_command("layer_add", "&Add", "AddLayer",
507     helptext = "Add a new layer to active map")
508     _method_command("layer_remove", "&Remove", "RemoveLayer",
509     helptext = "Remove selected layer(s)",
510     sensitive = _has_selected_layer)
511     _method_command("layer_fill_color", "&Fill Color", "LayerFillColor",
512     helptext = "Set the fill color of selected layer(s)",
513     sensitive = _has_selected_layer)
514     _method_command("layer_transparent_fill", "&Transparent Fill",
515     "LayerTransparentFill",
516     helptext = "Do not fill the selected layer(s)",
517     sensitive = _has_selected_layer)
518     _method_command("layer_ourline_color", "&Outline Color", "LayerOutlineColor",
519     helptext = "Set the outline color of selected layer(s)",
520     sensitive = _has_selected_layer)
521     _method_command("layer_no_outline", "&No Outline", "LayerNoOutline",
522     helptext = "Do not draw the outline of the selected layer(s)",
523     sensitive = _has_selected_layer)
524     _method_command("layer_raise", "&Raise", "RaiseLayer",
525     helptext = "Raise selected layer(s)",
526     sensitive = _has_selected_layer)
527     _method_command("layer_lower", "&Lower", "LowerLayer",
528     helptext = "Lower selected layer(s)",
529     sensitive = _has_selected_layer)
530     _method_command("layer_show", "&Show", "ShowLayer",
531     helptext = "Make selected layer(s) visible",
532     sensitive = _has_selected_layer)
533     _method_command("layer_hide", "&Hide", "HideLayer",
534     helptext = "Make selected layer(s) unvisible",
535     sensitive = _has_selected_layer)
536     _method_command("layer_show_table", "Show Ta&ble", "LayerShowTable",
537     helptext = "Show the selected layer's table",
538     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