/[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 640 - (hide annotations)
Thu Apr 10 14:36:08 2003 UTC (21 years, 11 months ago) by jonathan
Original Path: trunk/thuban/Thuban/UI/mainwindow.py
File MIME type: text/x-python
File size: 29411 byte(s)
MainWindow.OpenClassifier renamed to
MainWindow.OpenLayerProperties. MainWindow.LayerEditProperties
renamed to MainWindow.LayerEditProperties.
(MainWindow.ToggleLegend): Don't include map name in legend title.
(MainWindow.SetMap): Added the map name to the window title.
(MainWindow.LayerFillColor, MainWindow.LayerTransparentFill,
        MainWindow.LayerOutlineColor, MainWindow.LayerNoOutline): Removed.
        Functionality is found in the layer properties dialog.

1 bh 535 # Copyright (C) 2001, 2002, 2003 by Intevation GmbH
2 bh 6 # 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 jonathan 517 __ThubanVersion__ = "0.2" #"$THUBAN_0_2$"
16     #__BuildDate__ = "$Date$"
17    
18 bh 188 import os
19 bh 6
20     from wxPython.wx import *
21    
22     import Thuban
23 jan 374 from Thuban import _
24 bh 188 from Thuban.Model.session import create_empty_session
25 bh 6 from Thuban.Model.layer import Layer
26     from Thuban.Model.color import Color
27     from Thuban.Model.proj import Projection
28    
29     import view
30     import tree
31     import proj4dialog
32     import tableview, identifyview
33 jonathan 633 from Thuban.UI.classifier import Classifier
34 jonathan 550 import legend
35 bh 188 from menu import Menu
36 bh 6
37 bh 222 from context import Context
38 bh 357 from command import registry, Command, ToolCommand
39 jonathan 563 from messages import LAYER_SELECTED, SHAPES_SELECTED, VIEW_POSITION, DOCKABLE_DOCKED, DOCKABLE_UNDOCKED, DOCKABLE_CLOSED
40 bh 6
41 jonathan 573 from Thuban.UI.dock import DockableWindow, DockFrame, DockPanel
42 bh 6
43 jonathan 563
44 bh 6 # the directory where the toolbar icons are stored
45     bitmapdir = os.path.join(Thuban.__path__[0], os.pardir, "Resources", "Bitmaps")
46     bitmapext = ".xpm"
47    
48 jonathan 563 ID_WINDOW_LEGEND = 4001
49     ID_WINDOW_CANVAS = 4002
50 bh 6
51 jonathan 563
52 jonathan 573 class MainWindow(DockFrame):
53 bh 6
54 bh 535 # Some messages that can be subscribed/unsubscribed directly through
55     # the MapCanvas come in fact from other objects. This is a map to
56     # map those messages to the names of the instance variables they
57     # actually come from. This delegation is implemented in the
58     # Subscribe and unsubscribed methods
59     delegated_messages = {LAYER_SELECTED: "canvas",
60     SHAPES_SELECTED: "canvas"}
61    
62     # Methods delegated to some instance variables. The delegation is
63     # implemented in the __getattr__ method.
64     delegated_methods = {"SelectLayer": "canvas",
65     "SelectShapes": "canvas",
66     }
67    
68 bh 235 def __init__(self, parent, ID, title, application, interactor,
69 bh 238 initial_message = None, size = wxSize(-1, -1)):
70 jonathan 573 DockFrame.__init__(self, parent, ID, title, wxDefaultPosition, size)
71     #wxFrame.__init__(self, parent, ID, title, wxDefaultPosition, size)
72 bh 6
73 bh 227 self.application = application
74 bh 37
75 bh 6 self.CreateStatusBar()
76 bh 235 if initial_message:
77     self.SetStatusText(initial_message)
78 bh 6
79     self.identify_view = None
80    
81     self.init_ids()
82    
83 bh 191 # creat the menubar from the main_menu description
84 bh 188 self.SetMenuBar(self.build_menu_bar(main_menu))
85 bh 6
86 bh 191 # Similarly, create the toolbar from main_toolbar
87     toolbar = self.build_toolbar(main_toolbar)
88 bh 13 # call Realize to make sure that the tools appear.
89     toolbar.Realize()
90 bh 6
91 jonathan 563
92 bh 6 # Create the map canvas
93 bh 535 canvas = view.MapCanvas(self, -1)
94 bh 123 canvas.Subscribe(VIEW_POSITION, self.view_position_changed)
95 bh 535 canvas.Subscribe(SHAPES_SELECTED, self.identify_view_on_demand)
96 bh 6 self.canvas = canvas
97    
98 jonathan 573 self.SetMainWindow(self.canvas)
99    
100 jonathan 563 self.SetAutoLayout(True)
101    
102 bh 31 self.init_dialogs()
103    
104 jonathan 580 EVT_CLOSE(self, self._OnClose)
105 bh 6
106 bh 535 def Subscribe(self, channel, *args):
107     """Subscribe a function to a message channel.
108    
109     If channel is one of the delegated messages call the appropriate
110     object's Subscribe method. Otherwise do nothing.
111     """
112     if channel in self.delegated_messages:
113     object = getattr(self, self.delegated_messages[channel])
114     object.Subscribe(channel, *args)
115     else:
116     print "Trying to subscribe to unsupported channel %s" % channel
117    
118     def Unsubscribe(self, channel, *args):
119     """Unsubscribe a function from a message channel.
120    
121     If channel is one of the delegated messages call the appropriate
122     object's Unsubscribe method. Otherwise do nothing.
123     """
124     if channel in self.delegated_messages:
125     object = getattr(self, self.delegated_messages[channel])
126     object.Unsubscribe(channel, *args)
127    
128     def __getattr__(self, attr):
129     """If attr is one of the delegated methods return that method
130    
131     Otherwise raise AttributeError.
132     """
133     if attr in self.delegated_methods:
134     return getattr(getattr(self, self.delegated_methods[attr]), attr)
135     raise AttributeError(attr)
136    
137 bh 6 def init_ids(self):
138     """Initialize the ids"""
139     self.current_id = 6000
140     self.id_to_name = {}
141     self.name_to_id = {}
142 bh 193 self.events_bound = {}
143 bh 6
144     def get_id(self, name):
145     """Return the wxWindows id for the command named name.
146    
147     Create a new one if there isn't one yet"""
148     ID = self.name_to_id.get(name)
149     if ID is None:
150     ID = self.current_id
151     self.current_id = self.current_id + 1
152     self.name_to_id[name] = ID
153     self.id_to_name[ID] = name
154     return ID
155 bh 188
156 bh 193 def bind_command_events(self, command, ID):
157     """Bind the necessary events for the given command and ID"""
158     if not self.events_bound.has_key(ID):
159     # the events haven't been bound yet
160     EVT_MENU(self, ID, self.invoke_command)
161     if command.IsDynamic():
162     EVT_UPDATE_UI(self, ID, self.update_command_ui)
163    
164 bh 188 def build_menu_bar(self, menudesc):
165     """Build and return the menu bar from the menu description"""
166     menu_bar = wxMenuBar()
167    
168     for item in menudesc.items:
169     # here the items must all be Menu instances themselves
170     menu_bar.Append(self.build_menu(item), item.title)
171    
172     return menu_bar
173    
174     def build_menu(self, menudesc):
175 bh 314 """Return a wxMenu built from the menu description menudesc"""
176 bh 188 wxmenu = wxMenu()
177     last = None
178     for item in menudesc.items:
179     if item is None:
180     # a separator. Only add one if the last item was not a
181     # separator
182     if last is not None:
183     wxmenu.AppendSeparator()
184     elif isinstance(item, Menu):
185     # a submenu
186     wxmenu.AppendMenu(wxNewId(), item.title, self.build_menu(item))
187     else:
188     # must the name the name of a command
189     self.add_menu_command(wxmenu, item)
190     last = item
191     return wxmenu
192    
193 bh 191 def build_toolbar(self, toolbardesc):
194     """Build and return the main toolbar window from a toolbar description
195    
196     The parameter should be an instance of the Menu class but it
197     should not contain submenus.
198     """
199     toolbar = self.CreateToolBar(wxTB_3DBUTTONS)
200    
201     # set the size of the tools' bitmaps. Not needed on wxGTK, but
202     # on Windows, although it doesn't work very well there. It seems
203     # that only 16x16 icons are really supported on windows.
204     # We probably shouldn't hardwire the bitmap size here.
205     toolbar.SetToolBitmapSize(wxSize(24, 24))
206    
207     for item in toolbardesc.items:
208     if item is None:
209     toolbar.AddSeparator()
210     else:
211     # assume it's a string.
212     self.add_toolbar_command(toolbar, item)
213    
214     return toolbar
215    
216 bh 6 def add_menu_command(self, menu, name):
217     """Add the command with name name to the menu menu.
218    
219     If name is None, add a separator.
220     """
221     if name is None:
222     menu.AppendSeparator()
223     else:
224     command = registry.Command(name)
225     if command is not None:
226     ID = self.get_id(name)
227     menu.Append(ID, command.Title(), command.HelpText(),
228     command.IsCheckCommand())
229 bh 193 self.bind_command_events(command, ID)
230 bh 6 else:
231 jan 374 print _("Unknown command %s") % name
232 bh 6
233     def add_toolbar_command(self, toolbar, name):
234     """Add the command with name name to the toolbar toolbar.
235    
236     If name is None, add a separator.
237     """
238     # Assume that all toolbar commands are also menu commmands so
239     # that we don't have to add the event handlers here
240     if name is None:
241     toolbar.AddSeparator()
242     else:
243     command = registry.Command(name)
244     if command is not None:
245     ID = self.get_id(name)
246     filename = os.path.join(bitmapdir, command.Icon()) + bitmapext
247     bitmap = wxBitmap(filename, wxBITMAP_TYPE_XPM)
248     toolbar.AddTool(ID, bitmap,
249     shortHelpString = command.HelpText(),
250     isToggle = command.IsCheckCommand())
251 bh 193 self.bind_command_events(command, ID)
252 bh 6 else:
253 jan 374 print _("Unknown command %s") % name
254 bh 6
255 bh 281 def Context(self):
256     """Return the context object for a command invoked from this window
257     """
258     return Context(self.application, self.application.Session(), self)
259    
260 bh 6 def invoke_command(self, event):
261     name = self.id_to_name.get(event.GetId())
262     if name is not None:
263     command = registry.Command(name)
264 bh 281 command.Execute(self.Context())
265 bh 6 else:
266 jan 374 print _("Unknown command ID %d") % event.GetId()
267 bh 6
268     def update_command_ui(self, event):
269     #print "update_command_ui", self.id_to_name[event.GetId()]
270 bh 281 context = self.Context()
271 bh 6 command = registry.Command(self.id_to_name[event.GetId()])
272     if command is not None:
273 bh 357 sensitive = command.Sensitive(context)
274     event.Enable(sensitive)
275     if command.IsTool() and not sensitive and command.Checked(context):
276     # When a checked tool command is disabled deselect all
277     # tools. Otherwise the tool would remain active but it
278     # might lead to errors if the tools stays active. This
279     # problem occurred in GREAT-ER and this fixes it, but
280     # it's not clear to me whether this is really the best
281     # way to do it (BH, 20021206).
282     self.canvas.SelectTool(None)
283 bh 222 event.SetText(command.DynText(context))
284 bh 13 if command.IsCheckCommand():
285 bh 357 event.Check(command.Checked(context))
286 bh 6
287 bh 20 def RunMessageBox(self, title, text, flags = wxOK | wxICON_INFORMATION):
288 bh 181 """Run a modal message box with the given text, title and flags
289 bh 20 and return the result"""
290     dlg = wxMessageDialog(self, text, title, flags)
291 bh 316 dlg.CenterOnParent()
292 bh 20 result = dlg.ShowModal()
293     dlg.Destroy()
294     return result
295    
296 bh 31 def init_dialogs(self):
297     """Initialize the dialog handling"""
298     # The mainwindow maintains a dict mapping names to open
299     # non-modal dialogs. The dialogs are put into this dict when
300     # they're created and removed when they're closed
301     self.dialogs = {}
302    
303     def add_dialog(self, name, dialog):
304     if self.dialogs.has_key(name):
305 jan 374 raise RuntimeError(_("The Dialog named %s is already open") % name)
306 bh 31 self.dialogs[name] = dialog
307    
308     def dialog_open(self, name):
309     return self.dialogs.has_key(name)
310    
311     def remove_dialog(self, name):
312     del self.dialogs[name]
313    
314     def get_open_dialog(self, name):
315     return self.dialogs.get(name)
316    
317 bh 123 def view_position_changed(self):
318     pos = self.canvas.CurrentPosition()
319     if pos is not None:
320     text = "(%10.10g, %10.10g)" % pos
321     else:
322     text = ""
323 bh 321 self.set_position_text(text)
324    
325     def set_position_text(self, text):
326     """Set the statusbar text showing the current position.
327    
328     By default the text is shown in field 0 of the status bar.
329     Override this method in derived classes to put it into a
330     different field of the statusbar.
331     """
332 bh 123 self.SetStatusText(text)
333    
334 bh 58 def save_modified_session(self, can_veto = 1):
335     """If the current session has been modified, ask the user
336     whether to save it and do so if requested. Return the outcome of
337     the dialog (either wxID_OK, wxID_CANCEL or wxID_NO). If the
338     dialog wasn't run return wxID_NO.
339    
340     If the can_veto parameter is true (default) the dialog includes
341     a cancel button, otherwise not.
342     """
343 bh 227 if self.application.session.WasModified():
344 bh 58 flags = wxYES_NO | wxICON_QUESTION
345     if can_veto:
346     flags = flags | wxCANCEL
347 jan 374 result = self.RunMessageBox(_("Exit"),
348     _("The session has been modified."
349 bh 58 " Do you want to save it?"),
350     flags)
351     if result == wxID_YES:
352     self.SaveSession()
353     else:
354     result = wxID_NO
355     return result
356    
357 jonathan 487 def prepare_new_session(self):
358     for d in self.dialogs.values():
359     if not isinstance(d, tree.SessionTreeView):
360 jonathan 502 d.Close()
361 jonathan 487
362 bh 6 def NewSession(self):
363 bh 58 self.save_modified_session()
364 jonathan 487 self.prepare_new_session()
365 bh 227 self.application.SetSession(create_empty_session())
366 bh 6
367     def OpenSession(self):
368 bh 58 self.save_modified_session()
369 jonathan 487 dlg = wxFileDialog(self, _("Open Session"), ".", "", "*.thuban", wxOPEN)
370 bh 6 if dlg.ShowModal() == wxID_OK:
371 jonathan 487 self.prepare_new_session()
372 bh 227 self.application.OpenSession(dlg.GetPath())
373 bh 6 dlg.Destroy()
374    
375     def SaveSession(self):
376 bh 227 if self.application.session.filename == None:
377 jan 102 self.SaveSessionAs()
378 jonathan 487 else:
379     self.application.SaveSession()
380 bh 6
381     def SaveSessionAs(self):
382 jonathan 431 dlg = wxFileDialog(self, _("Save Session As"), ".", "",
383 bh 130 "*.thuban", wxOPEN)
384 bh 6 if dlg.ShowModal() == wxID_OK:
385 bh 227 self.application.session.SetFilename(dlg.GetPath())
386     self.application.SaveSession()
387 bh 6 dlg.Destroy()
388    
389     def Exit(self):
390 jonathan 621 self.Close(False)
391 bh 6
392 jonathan 580 def _OnClose(self, event):
393 bh 58 result = self.save_modified_session(can_veto = event.CanVeto())
394     if result == wxID_CANCEL:
395 bh 6 event.Veto()
396     else:
397 bh 307 # FIXME: it would be better to tie the unsubscription to
398     # wx's destroy event, but that isn't implemented for wxGTK
399     # yet.
400     self.canvas.Unsubscribe(VIEW_POSITION, self.view_position_changed)
401 jonathan 580 DockFrame._OnClose(self, event)
402 bh 6 self.Destroy()
403    
404     def SetMap(self, map):
405     self.canvas.SetMap(map)
406 jonathan 640 self.SetTitle("Thuban - " + map.Title())
407 jonathan 563 #self.legendPanel.SetMap(map)
408 bh 6
409 bh 310 def Map(self):
410     """Return the map displayed by this mainwindow"""
411 jonathan 563
412     # sanity check
413     #assert(self.canvas.Map() is self.legendPanel.GetMap())
414    
415 bh 310 return self.canvas.Map()
416    
417 bh 622 def ToggleSessionTree(self):
418     """If the session tree is shown close it otherwise create a new tree"""
419 bh 37 name = "session_tree"
420     dialog = self.get_open_dialog(name)
421     if dialog is None:
422 bh 227 dialog = tree.SessionTreeView(self, self.application, name)
423 bh 37 self.add_dialog(name, dialog)
424 jonathan 512 dialog.Show(True)
425 bh 37 else:
426 bh 622 dialog.Close()
427 bh 37
428 bh 622 def SessionTreeShown(self):
429     """Return true iff the session tree is currently shown"""
430     return self.get_open_dialog("session_tree") is not None
431 jonathan 517
432 bh 6 def About(self):
433 jan 374 self.RunMessageBox(_("About"),
434 jonathan 517 _("Thuban v%s\n"
435     #"Build Date: %s\n"
436     "\n"
437     "Thuban is a program for\n"
438 bh 20 "exploring geographic data.\n"
439 jan 374 "Copyright (C) 2001-2003 Intevation GmbH.\n"
440 jonathan 517 "Thuban is licensed under the GNU GPL"
441     % __ThubanVersion__), #__BuildDate__)),
442 bh 20 wxOK | wxICON_INFORMATION)
443 bh 6
444     def AddLayer(self):
445 jan 374 dlg = wxFileDialog(self, _("Select a data file"), ".", "", "*.*",
446 bh 6 wxOPEN)
447     if dlg.ShowModal() == wxID_OK:
448     filename = dlg.GetPath()
449     title = os.path.splitext(os.path.basename(filename))[0]
450     layer = Layer(title, filename)
451 bh 18 map = self.canvas.Map()
452     has_layers = map.HasLayers()
453 bh 20 try:
454     map.AddLayer(layer)
455     except IOError:
456     # the layer couldn't be opened
457 jan 374 self.RunMessageBox(_("Add Layer"),
458     _("Can't open the file '%s'.") % filename)
459 bh 20 else:
460     if not has_layers:
461 bh 535 # if we're adding a layer to an empty map, fit the
462 bh 20 # new map to the window
463     self.canvas.FitMapToWindow()
464 bh 6 dlg.Destroy()
465    
466     def RemoveLayer(self):
467     layer = self.current_layer()
468     if layer is not None:
469     self.canvas.Map().RemoveLayer(layer)
470    
471 bh 299 def CanRemoveLayer(self):
472     """Return true if the currently selected layer can be deleted.
473    
474 jonathan 621 If no layer is selected return False.
475 bh 299
476     The return value of this method determines whether the remove
477     layer command is sensitive in menu.
478     """
479     layer = self.current_layer()
480     if layer is not None:
481     return self.canvas.Map().CanRemoveLayer(layer)
482 jonathan 621 return False
483 bh 299
484 bh 6 def RaiseLayer(self):
485     layer = self.current_layer()
486     if layer is not None:
487     self.canvas.Map().RaiseLayer(layer)
488 bh 222
489 bh 6 def LowerLayer(self):
490     layer = self.current_layer()
491     if layer is not None:
492     self.canvas.Map().LowerLayer(layer)
493    
494     def current_layer(self):
495     """Return the currently selected layer.
496    
497     If no layer is selected, return None
498     """
499 bh 535 return self.canvas.SelectedLayer()
500 bh 6
501     def has_selected_layer(self):
502     """Return true if a layer is currently selected"""
503 bh 535 return self.canvas.HasSelectedLayer()
504 bh 6
505     def choose_color(self):
506     """Run the color selection dialog and return the selected color.
507    
508     If the user cancels, return None.
509     """
510     dlg = wxColourDialog(self)
511     color = None
512     if dlg.ShowModal() == wxID_OK:
513     data = dlg.GetColourData()
514     wxc = data.GetColour()
515     color = Color(wxc.Red() / 255.0,
516     wxc.Green() / 255.0,
517     wxc.Blue() / 255.0)
518     dlg.Destroy()
519     return color
520    
521     def HideLayer(self):
522     layer = self.current_layer()
523     if layer is not None:
524     layer.SetVisible(0)
525    
526     def ShowLayer(self):
527     layer = self.current_layer()
528     if layer is not None:
529     layer.SetVisible(1)
530    
531     def LayerShowTable(self):
532     layer = self.current_layer()
533     if layer is not None:
534 bh 31 table = layer.table
535     name = "table_view" + str(id(table))
536     dialog = self.get_open_dialog(name)
537     if dialog is None:
538 bh 535 dialog = tableview.LayerTableFrame(self, name,
539     _("Table: %s") % layer.Title(),
540 bh 278 layer, table)
541 bh 31 self.add_dialog(name, dialog)
542     dialog.Show(true)
543     else:
544     # FIXME: bring dialog to front here
545     pass
546 bh 6
547     def Projection(self):
548     map = self.canvas.Map()
549     proj = map.projection
550     if proj is None:
551 jan 110 proj4Dlg = proj4dialog.Proj4Dialog(NULL, None, map.BoundingBox())
552 bh 6 else:
553 jan 110 proj4Dlg = proj4dialog.Proj4Dialog(NULL, map.projection.params,
554     map.BoundingBox())
555 bh 6 if proj4Dlg.ShowModal() == wxID_OK:
556     params = proj4Dlg.GetParams()
557     if params is not None:
558     proj = Projection(params)
559     else:
560     proj = None
561     map.SetProjection(proj)
562     proj4Dlg.Destroy()
563    
564 jonathan 640 def LayerEditProperties(self):
565 jonathan 363
566 jonathan 487 #
567     # the menu option for this should only be available if there
568     # is a current layer, so we don't need to check if the
569     # current layer is None
570     #
571    
572     layer = self.current_layer()
573 jonathan 640 self.OpenLayerProperties(layer)
574 jonathan 550
575 jonathan 640 def OpenLayerProperties(self, layer, group = None):
576     name = "layer_properties" + str(id(layer))
577 jonathan 487 dialog = self.get_open_dialog(name)
578    
579     if dialog is None:
580 jonathan 633 dialog = Classifier(self, name, layer, group)
581 jonathan 487 self.add_dialog(name, dialog)
582     dialog.Show()
583 jonathan 573 dialog.Raise()
584 jonathan 487
585 jonathan 550
586 jonathan 621 def ShowLegend(self):
587 bh 622 if not self.LegendShown():
588     self.ToggleLegend()
589    
590     def ToggleLegend(self):
591     """Show the legend if it's not shown otherwise hide it again"""
592 jonathan 550 name = "legend"
593 jonathan 573 dialog = self.FindRegisteredDock(name)
594 jonathan 550
595     if dialog is None:
596 jonathan 640 dialog = self.CreateDock(name, -1, _("Legend"), wxLAYOUT_LEFT)
597 jonathan 573 legend.LegendPanel(dialog, None, self)
598 jonathan 580 dialog.Dock()
599 bh 622 dialog.GetPanel().SetMap(self.Map())
600     dialog.Show()
601     else:
602     dialog.Show(not dialog.IsShown())
603 jonathan 563
604 bh 622 def LegendShown(self):
605     """Return true iff the legend is currently open"""
606     dialog = self.FindRegisteredDock("legend")
607     return dialog is not None and dialog.IsShown()
608 jonathan 563
609 bh 6 def ZoomInTool(self):
610     self.canvas.ZoomInTool()
611    
612     def ZoomOutTool(self):
613     self.canvas.ZoomOutTool()
614    
615     def PanTool(self):
616     self.canvas.PanTool()
617    
618     def IdentifyTool(self):
619     self.canvas.IdentifyTool()
620 bh 49 self.identify_view_on_demand(None, None)
621 bh 6
622     def LabelTool(self):
623     self.canvas.LabelTool()
624    
625     def FullExtent(self):
626     self.canvas.FitMapToWindow()
627    
628     def PrintMap(self):
629     self.canvas.Print()
630    
631 bh 535 def identify_view_on_demand(self, layer, shapes):
632 bh 31 name = "identify_view"
633     if self.canvas.CurrentTool() == "IdentifyTool":
634     if not self.dialog_open(name):
635 bh 535 dialog = identifyview.IdentifyView(self, name)
636 bh 31 self.add_dialog(name, dialog)
637 jonathan 563 dialog.Show(True)
638 bh 31 else:
639 bh 33 # FIXME: bring dialog to front?
640 bh 31 pass
641 bh 6
642     #
643     # Define all the commands available in the main window
644     #
645    
646    
647     # Helper functions to define common command implementations
648     def call_method(context, methodname, *args):
649 bh 222 """Call the mainwindow's method methodname with args *args"""
650     apply(getattr(context.mainwindow, methodname), args)
651 bh 6
652 jan 110 def _method_command(name, title, method, helptext = "",
653 bh 622 icon = "", sensitive = None, checked = None):
654 bh 222 """Add a command implemented by a method of the mainwindow object"""
655 bh 6 registry.Add(Command(name, title, call_method, args=(method,),
656 jan 110 helptext = helptext, icon = icon,
657 bh 622 sensitive = sensitive, checked = checked))
658 jan 110
659 bh 270 def make_check_current_tool(toolname):
660     """Return a function that tests if the currently active tool is toolname
661    
662     The returned function can be called with the context and returns
663     true iff the currently active tool's name is toolname. It's directly
664     usable as the 'checked' callback of a command.
665     """
666     def check_current_tool(context, name=toolname):
667     return context.mainwindow.canvas.CurrentTool() == name
668     return check_current_tool
669    
670 bh 6 def _tool_command(name, title, method, toolname, helptext = "",
671 bh 310 icon = "", sensitive = None):
672 bh 6 """Add a tool command"""
673 bh 357 registry.Add(ToolCommand(name, title, call_method, args=(method,),
674     helptext = helptext, icon = icon,
675     checked = make_check_current_tool(toolname),
676     sensitive = sensitive))
677 bh 6
678     def _has_selected_layer(context):
679     """Return true if a layer is selected in the context"""
680 bh 222 return context.mainwindow.has_selected_layer()
681 bh 6
682 bh 299 def _can_remove_layer(context):
683     return context.mainwindow.CanRemoveLayer()
684    
685 jan 264 def _has_tree_window_shown(context):
686     """Return true if the tree window is shown"""
687 bh 622 return context.mainwindow.SessionTreeShown()
688 jan 264
689 bh 310 def _has_visible_map(context):
690     """Return true iff theres a visible map in the mainwindow.
691    
692     A visible map is a map with at least one visible layer."""
693     map = context.mainwindow.Map()
694     if map is not None:
695     for layer in map.Layers():
696     if layer.Visible():
697     return 1
698     return 0
699    
700 jonathan 550 def _has_legend_shown(context):
701     """Return true if the legend window is shown"""
702 bh 622 return context.mainwindow.LegendShown()
703 bh 310
704 jonathan 550
705 bh 6 # File menu
706 jan 374 _method_command("new_session", _("&New Session"), "NewSession")
707     _method_command("open_session", _("&Open Session"), "OpenSession")
708     _method_command("save_session", _("&Save Session"), "SaveSession")
709     _method_command("save_session_as", _("Save Session &As"), "SaveSessionAs")
710 bh 622 _method_command("toggle_session_tree", _("Session &Tree"), "ToggleSessionTree",
711     checked = _has_tree_window_shown)
712     _method_command("toggle_legend", _("Legend"), "ToggleLegend",
713     checked = _has_legend_shown)
714 jan 374 _method_command("exit", _("E&xit"), "Exit")
715 bh 6
716     # Help menu
717 jan 374 _method_command("help_about", _("&About"), "About")
718 bh 6
719    
720     # Map menu
721 jan 374 _method_command("map_projection", _("Pro&jection"), "Projection")
722 bh 6
723 jan 374 _tool_command("map_zoom_in_tool", _("&Zoom in"), "ZoomInTool", "ZoomInTool",
724     helptext = _("Switch to map-mode 'zoom-in'"), icon = "zoom_in",
725 bh 310 sensitive = _has_visible_map)
726 jan 374 _tool_command("map_zoom_out_tool", _("Zoom &out"), "ZoomOutTool", "ZoomOutTool",
727     helptext = _("Switch to map-mode 'zoom-out'"), icon = "zoom_out",
728 bh 310 sensitive = _has_visible_map)
729 jan 374 _tool_command("map_pan_tool", _("&Pan"), "PanTool", "PanTool",
730     helptext = _("Switch to map-mode 'pan'"), icon = "pan",
731 bh 310 sensitive = _has_visible_map)
732 jan 374 _tool_command("map_identify_tool", _("&Identify"), "IdentifyTool",
733     "IdentifyTool",
734     helptext = _("Switch to map-mode 'identify'"), icon = "identify",
735 bh 310 sensitive = _has_visible_map)
736 jan 374 _tool_command("map_label_tool", _("&Label"), "LabelTool", "LabelTool",
737     helptext = _("Add/Remove labels"), icon = "label",
738 bh 310 sensitive = _has_visible_map)
739 jan 374 _method_command("map_full_extent", _("&Full extent"), "FullExtent",
740     helptext = _("Full Extent"), icon = "fullextent",
741 bh 310 sensitive = _has_visible_map)
742 jan 374 _method_command("map_print", _("Prin&t"), "PrintMap",
743     helptext = _("Print the map"))
744 bh 6
745     # Layer menu
746 jan 374 _method_command("layer_add", _("&Add Layer"), "AddLayer",
747     helptext = _("Add a new layer to active map"))
748     _method_command("layer_remove", _("&Remove Layer"), "RemoveLayer",
749     helptext = _("Remove selected layer(s)"),
750 bh 299 sensitive = _can_remove_layer)
751 jan 374 _method_command("layer_raise", _("&Raise"), "RaiseLayer",
752     helptext = _("Raise selected layer(s)"),
753 bh 6 sensitive = _has_selected_layer)
754 jan 374 _method_command("layer_lower", _("&Lower"), "LowerLayer",
755     helptext = _("Lower selected layer(s)"),
756 bh 6 sensitive = _has_selected_layer)
757 jan 374 _method_command("layer_show", _("&Show"), "ShowLayer",
758     helptext = _("Make selected layer(s) visible"),
759 bh 6 sensitive = _has_selected_layer)
760 jan 374 _method_command("layer_hide", _("&Hide"), "HideLayer",
761     helptext = _("Make selected layer(s) unvisible"),
762 bh 6 sensitive = _has_selected_layer)
763 jan 374 _method_command("layer_show_table", _("Show Ta&ble"), "LayerShowTable",
764     helptext = _("Show the selected layer's table"),
765 bh 6 sensitive = _has_selected_layer)
766 jonathan 640 _method_command("layer_properties", _("Properties"), "LayerEditProperties",
767 jonathan 363 sensitive = _has_selected_layer)
768 bh 188
769     # the menu structure
770     main_menu = Menu("<main>", "<main>",
771 jan 374 [Menu("file", _("&File"),
772 bh 188 ["new_session", "open_session", None,
773     "save_session", "save_session_as", None,
774 bh 624 "toggle_session_tree", None,
775 bh 188 "exit"]),
776 jan 374 Menu("map", _("&Map"),
777 bh 188 ["layer_add", "layer_remove",
778     None,
779     "map_projection",
780     None,
781     "map_zoom_in_tool", "map_zoom_out_tool",
782     "map_pan_tool", "map_identify_tool", "map_label_tool",
783     None,
784     "map_full_extent",
785     None,
786 bh 624 "toggle_legend",
787     None,
788 bh 188 "map_print"]),
789 jan 374 Menu("layer", _("&Layer"),
790 jonathan 640 ["layer_raise", "layer_lower",
791 bh 188 None,
792     "layer_show", "layer_hide",
793     None,
794 jonathan 363 "layer_show_table",
795     None,
796 jonathan 640 "layer_properties"]),
797 jan 374 Menu("help", _("&Help"),
798 bh 188 ["help_about"])])
799 bh 191
800     # the main toolbar
801    
802     main_toolbar = Menu("<toolbar>", "<toolbar>",
803 frank 351 ["map_zoom_in_tool", "map_zoom_out_tool", "map_pan_tool",
804     "map_full_extent", None,
805     "map_identify_tool", "map_label_tool"])

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26