/[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 704 - (hide annotations)
Tue Apr 22 16:55:50 2003 UTC (21 years, 10 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/mainwindow.py
File MIME type: text/x-python
File size: 29737 byte(s)
Remove some unused imports and global
constants

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