/[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 622 - (show annotations)
Mon Apr 7 10:54:32 2003 UTC (21 years, 11 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/mainwindow.py
File MIME type: text/x-python
File size: 31146 byte(s)
(MainWindow.ShowSessionTree): Removed in
favor of ToggleSessionTree
(MainWindow.ToggleSessionTree): New method to toggle visibility of
the session tree.
(MainWindow.SessionTreeShown): New method to return whether the
session tree is currently shown.
(MainWindow.ToggleLegend): New method to toggle visibility of the
legend
(MainWindow.ShowLegend): Implement in terms of ToggleLegend and
LegendShown
(MainWindow.LegendShown): New method to return whether the legend
is currently shown.
(_method_command): Add checked parameter so we can define check
menu items
(_has_tree_window_shown, _has_legend_shown): Use the appropriate
mainwindow methods.
(show_session_tree, show_legend commands): Removed.
(toggle_session_tree, toggle_legend commands): New commands to
toggle the visibility of the dialogs

1 # Copyright (C) 2001, 2002, 2003 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 __ThubanVersion__ = "0.2" #"$THUBAN_0_2$"
16 #__BuildDate__ = "$Date$"
17
18 import os
19
20 from wxPython.wx import *
21
22 import Thuban
23 from Thuban import _
24 from Thuban.Model.session import create_empty_session
25 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 import classifier
34 import legend
35 from menu import Menu
36
37 from context import Context
38 from command import registry, Command, ToolCommand
39 from messages import LAYER_SELECTED, SHAPES_SELECTED, VIEW_POSITION, DOCKABLE_DOCKED, DOCKABLE_UNDOCKED, DOCKABLE_CLOSED
40
41 from Thuban.UI.dock import DockableWindow, DockFrame, DockPanel
42
43
44 # 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 ID_WINDOW_LEGEND = 4001
49 ID_WINDOW_CANVAS = 4002
50
51
52 class MainWindow(DockFrame):
53
54 # 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 def __init__(self, parent, ID, title, application, interactor,
69 initial_message = None, size = wxSize(-1, -1)):
70 DockFrame.__init__(self, parent, ID, title, wxDefaultPosition, size)
71 #wxFrame.__init__(self, parent, ID, title, wxDefaultPosition, size)
72
73 self.application = application
74
75 self.CreateStatusBar()
76 if initial_message:
77 self.SetStatusText(initial_message)
78
79 self.identify_view = None
80
81 self.init_ids()
82
83 # creat the menubar from the main_menu description
84 self.SetMenuBar(self.build_menu_bar(main_menu))
85
86 # Similarly, create the toolbar from main_toolbar
87 toolbar = self.build_toolbar(main_toolbar)
88 # call Realize to make sure that the tools appear.
89 toolbar.Realize()
90
91
92 # Create the map canvas
93 canvas = view.MapCanvas(self, -1)
94 canvas.Subscribe(VIEW_POSITION, self.view_position_changed)
95 canvas.Subscribe(SHAPES_SELECTED, self.identify_view_on_demand)
96 self.canvas = canvas
97
98 self.SetMainWindow(self.canvas)
99
100 self.SetAutoLayout(True)
101
102 self.init_dialogs()
103
104 EVT_CLOSE(self, self._OnClose)
105
106 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 def init_ids(self):
138 """Initialize the ids"""
139 self.current_id = 6000
140 self.id_to_name = {}
141 self.name_to_id = {}
142 self.events_bound = {}
143
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
156 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 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 """Return a wxMenu built from the menu description menudesc"""
176 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 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 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 self.bind_command_events(command, ID)
230 else:
231 print _("Unknown command %s") % name
232
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 self.bind_command_events(command, ID)
252 else:
253 print _("Unknown command %s") % name
254
255 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 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 command.Execute(self.Context())
265 else:
266 print _("Unknown command ID %d") % event.GetId()
267
268 def update_command_ui(self, event):
269 #print "update_command_ui", self.id_to_name[event.GetId()]
270 context = self.Context()
271 command = registry.Command(self.id_to_name[event.GetId()])
272 if command is not None:
273 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 event.SetText(command.DynText(context))
284 if command.IsCheckCommand():
285 event.Check(command.Checked(context))
286
287 def RunMessageBox(self, title, text, flags = wxOK | wxICON_INFORMATION):
288 """Run a modal message box with the given text, title and flags
289 and return the result"""
290 dlg = wxMessageDialog(self, text, title, flags)
291 dlg.CenterOnParent()
292 result = dlg.ShowModal()
293 dlg.Destroy()
294 return result
295
296 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 raise RuntimeError(_("The Dialog named %s is already open") % name)
306 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 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 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 self.SetStatusText(text)
333
334 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 if self.application.session.WasModified():
344 flags = wxYES_NO | wxICON_QUESTION
345 if can_veto:
346 flags = flags | wxCANCEL
347 result = self.RunMessageBox(_("Exit"),
348 _("The session has been modified."
349 " 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 def prepare_new_session(self):
358 for d in self.dialogs.values():
359 if not isinstance(d, tree.SessionTreeView):
360 d.Close()
361
362 def NewSession(self):
363 self.save_modified_session()
364 self.prepare_new_session()
365 self.application.SetSession(create_empty_session())
366
367 def OpenSession(self):
368 self.save_modified_session()
369 dlg = wxFileDialog(self, _("Open Session"), ".", "", "*.thuban", wxOPEN)
370 if dlg.ShowModal() == wxID_OK:
371 self.prepare_new_session()
372 self.application.OpenSession(dlg.GetPath())
373 dlg.Destroy()
374
375 def SaveSession(self):
376 if self.application.session.filename == None:
377 self.SaveSessionAs()
378 else:
379 self.application.SaveSession()
380
381 def SaveSessionAs(self):
382 dlg = wxFileDialog(self, _("Save Session As"), ".", "",
383 "*.thuban", wxOPEN)
384 if dlg.ShowModal() == wxID_OK:
385 self.application.session.SetFilename(dlg.GetPath())
386 self.application.SaveSession()
387 dlg.Destroy()
388
389 def Exit(self):
390 self.Close(False)
391
392 def _OnClose(self, event):
393 result = self.save_modified_session(can_veto = event.CanVeto())
394 if result == wxID_CANCEL:
395 event.Veto()
396 else:
397 # 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 DockFrame._OnClose(self, event)
402 self.Destroy()
403
404 def SetMap(self, map):
405 self.canvas.SetMap(map)
406 #self.legendPanel.SetMap(map)
407
408 def Map(self):
409 """Return the map displayed by this mainwindow"""
410
411 # sanity check
412 #assert(self.canvas.Map() is self.legendPanel.GetMap())
413
414 return self.canvas.Map()
415
416 def ToggleSessionTree(self):
417 """If the session tree is shown close it otherwise create a new tree"""
418 name = "session_tree"
419 dialog = self.get_open_dialog(name)
420 if dialog is None:
421 dialog = tree.SessionTreeView(self, self.application, name)
422 self.add_dialog(name, dialog)
423 dialog.Show(True)
424 else:
425 dialog.Close()
426
427 def SessionTreeShown(self):
428 """Return true iff the session tree is currently shown"""
429 return self.get_open_dialog("session_tree") is not None
430
431 def About(self):
432 self.RunMessageBox(_("About"),
433 _("Thuban v%s\n"
434 #"Build Date: %s\n"
435 "\n"
436 "Thuban is a program for\n"
437 "exploring geographic data.\n"
438 "Copyright (C) 2001-2003 Intevation GmbH.\n"
439 "Thuban is licensed under the GNU GPL"
440 % __ThubanVersion__), #__BuildDate__)),
441 wxOK | wxICON_INFORMATION)
442
443 def AddLayer(self):
444 dlg = wxFileDialog(self, _("Select a data file"), ".", "", "*.*",
445 wxOPEN)
446 if dlg.ShowModal() == wxID_OK:
447 filename = dlg.GetPath()
448 title = os.path.splitext(os.path.basename(filename))[0]
449 layer = Layer(title, filename)
450 map = self.canvas.Map()
451 has_layers = map.HasLayers()
452 try:
453 map.AddLayer(layer)
454 except IOError:
455 # the layer couldn't be opened
456 self.RunMessageBox(_("Add Layer"),
457 _("Can't open the file '%s'.") % filename)
458 else:
459 if not has_layers:
460 # if we're adding a layer to an empty map, fit the
461 # new map to the window
462 self.canvas.FitMapToWindow()
463 dlg.Destroy()
464
465 def RemoveLayer(self):
466 layer = self.current_layer()
467 if layer is not None:
468 self.canvas.Map().RemoveLayer(layer)
469
470 def CanRemoveLayer(self):
471 """Return true if the currently selected layer can be deleted.
472
473 If no layer is selected return False.
474
475 The return value of this method determines whether the remove
476 layer command is sensitive in menu.
477 """
478 layer = self.current_layer()
479 if layer is not None:
480 return self.canvas.Map().CanRemoveLayer(layer)
481 return False
482
483 def RaiseLayer(self):
484 layer = self.current_layer()
485 if layer is not None:
486 self.canvas.Map().RaiseLayer(layer)
487
488 def LowerLayer(self):
489 layer = self.current_layer()
490 if layer is not None:
491 self.canvas.Map().LowerLayer(layer)
492
493 def current_layer(self):
494 """Return the currently selected layer.
495
496 If no layer is selected, return None
497 """
498 return self.canvas.SelectedLayer()
499
500 def has_selected_layer(self):
501 """Return true if a layer is currently selected"""
502 return self.canvas.HasSelectedLayer()
503
504 def choose_color(self):
505 """Run the color selection dialog and return the selected color.
506
507 If the user cancels, return None.
508 """
509 dlg = wxColourDialog(self)
510 color = None
511 if dlg.ShowModal() == wxID_OK:
512 data = dlg.GetColourData()
513 wxc = data.GetColour()
514 color = Color(wxc.Red() / 255.0,
515 wxc.Green() / 255.0,
516 wxc.Blue() / 255.0)
517 dlg.Destroy()
518 return color
519
520 def LayerFillColor(self):
521 layer = self.current_layer()
522 if layer is not None:
523 color = self.choose_color()
524 if color is not None:
525 layer.GetClassification().SetDefaultFill(color)
526
527 def LayerTransparentFill(self):
528 layer = self.current_layer()
529 if layer is not None:
530 layer.GetClassification().SetDefaultFill(Color.Transparent)
531
532 def LayerOutlineColor(self):
533 layer = self.current_layer()
534 if layer is not None:
535 color = self.choose_color()
536 if color is not None:
537 layer.GetClassification().SetDefaultLineColor(color)
538
539 def LayerNoOutline(self):
540 layer = self.current_layer()
541 if layer is not None:
542 layer.GetClassification().SetDefaultLineColor(Color.Transparent)
543
544 def HideLayer(self):
545 layer = self.current_layer()
546 if layer is not None:
547 layer.SetVisible(0)
548
549 def ShowLayer(self):
550 layer = self.current_layer()
551 if layer is not None:
552 layer.SetVisible(1)
553
554 def LayerShowTable(self):
555 layer = self.current_layer()
556 if layer is not None:
557 table = layer.table
558 name = "table_view" + str(id(table))
559 dialog = self.get_open_dialog(name)
560 if dialog is None:
561 dialog = tableview.LayerTableFrame(self, name,
562 _("Table: %s") % layer.Title(),
563 layer, table)
564 self.add_dialog(name, dialog)
565 dialog.Show(true)
566 else:
567 # FIXME: bring dialog to front here
568 pass
569
570 def Projection(self):
571 map = self.canvas.Map()
572 proj = map.projection
573 if proj is None:
574 proj4Dlg = proj4dialog.Proj4Dialog(NULL, None, map.BoundingBox())
575 else:
576 proj4Dlg = proj4dialog.Proj4Dialog(NULL, map.projection.params,
577 map.BoundingBox())
578 if proj4Dlg.ShowModal() == wxID_OK:
579 params = proj4Dlg.GetParams()
580 if params is not None:
581 proj = Projection(params)
582 else:
583 proj = None
584 map.SetProjection(proj)
585 proj4Dlg.Destroy()
586
587 def Classify(self):
588
589 #
590 # the menu option for this should only be available if there
591 # is a current layer, so we don't need to check if the
592 # current layer is None
593 #
594
595 layer = self.current_layer()
596 self.OpenClassifier(layer)
597
598 def OpenClassifier(self, layer, group = None):
599 name = "classifier" + str(id(layer))
600 dialog = self.get_open_dialog(name)
601
602 if dialog is None:
603 dialog = classifier.Classifier(self, name, layer, group)
604 self.add_dialog(name, dialog)
605 dialog.Show()
606 dialog.Raise()
607
608
609 def ShowLegend(self):
610 if not self.LegendShown():
611 self.ToggleLegend()
612
613 def ToggleLegend(self):
614 """Show the legend if it's not shown otherwise hide it again"""
615 name = "legend"
616 dialog = self.FindRegisteredDock(name)
617
618 if dialog is None:
619 title = "Legend: %s" % self.Map().Title()
620 dialog = self.CreateDock(name, -1, title, wxLAYOUT_LEFT)
621 legend.LegendPanel(dialog, None, self)
622 dialog.Dock()
623 dialog.GetPanel().SetMap(self.Map())
624 dialog.Show()
625 else:
626 dialog.Show(not dialog.IsShown())
627
628 def LegendShown(self):
629 """Return true iff the legend is currently open"""
630 dialog = self.FindRegisteredDock("legend")
631 return dialog is not None and dialog.IsShown()
632
633 def ZoomInTool(self):
634 self.canvas.ZoomInTool()
635
636 def ZoomOutTool(self):
637 self.canvas.ZoomOutTool()
638
639 def PanTool(self):
640 self.canvas.PanTool()
641
642 def IdentifyTool(self):
643 self.canvas.IdentifyTool()
644 self.identify_view_on_demand(None, None)
645
646 def LabelTool(self):
647 self.canvas.LabelTool()
648
649 def FullExtent(self):
650 self.canvas.FitMapToWindow()
651
652 def PrintMap(self):
653 self.canvas.Print()
654
655 def identify_view_on_demand(self, layer, shapes):
656 name = "identify_view"
657 if self.canvas.CurrentTool() == "IdentifyTool":
658 if not self.dialog_open(name):
659 dialog = identifyview.IdentifyView(self, name)
660 self.add_dialog(name, dialog)
661 dialog.Show(True)
662 else:
663 # FIXME: bring dialog to front?
664 pass
665
666 #
667 # Define all the commands available in the main window
668 #
669
670
671 # Helper functions to define common command implementations
672 def call_method(context, methodname, *args):
673 """Call the mainwindow's method methodname with args *args"""
674 apply(getattr(context.mainwindow, methodname), args)
675
676 def _method_command(name, title, method, helptext = "",
677 icon = "", sensitive = None, checked = None):
678 """Add a command implemented by a method of the mainwindow object"""
679 registry.Add(Command(name, title, call_method, args=(method,),
680 helptext = helptext, icon = icon,
681 sensitive = sensitive, checked = checked))
682
683 def make_check_current_tool(toolname):
684 """Return a function that tests if the currently active tool is toolname
685
686 The returned function can be called with the context and returns
687 true iff the currently active tool's name is toolname. It's directly
688 usable as the 'checked' callback of a command.
689 """
690 def check_current_tool(context, name=toolname):
691 return context.mainwindow.canvas.CurrentTool() == name
692 return check_current_tool
693
694 def _tool_command(name, title, method, toolname, helptext = "",
695 icon = "", sensitive = None):
696 """Add a tool command"""
697 registry.Add(ToolCommand(name, title, call_method, args=(method,),
698 helptext = helptext, icon = icon,
699 checked = make_check_current_tool(toolname),
700 sensitive = sensitive))
701
702 def _has_selected_layer(context):
703 """Return true if a layer is selected in the context"""
704 return context.mainwindow.has_selected_layer()
705
706 def _can_remove_layer(context):
707 return context.mainwindow.CanRemoveLayer()
708
709 def _has_tree_window_shown(context):
710 """Return true if the tree window is shown"""
711 return context.mainwindow.SessionTreeShown()
712
713 def _has_visible_map(context):
714 """Return true iff theres a visible map in the mainwindow.
715
716 A visible map is a map with at least one visible layer."""
717 map = context.mainwindow.Map()
718 if map is not None:
719 for layer in map.Layers():
720 if layer.Visible():
721 return 1
722 return 0
723
724 def _has_legend_shown(context):
725 """Return true if the legend window is shown"""
726 return context.mainwindow.LegendShown()
727
728
729 # File menu
730 _method_command("new_session", _("&New Session"), "NewSession")
731 _method_command("open_session", _("&Open Session"), "OpenSession")
732 _method_command("save_session", _("&Save Session"), "SaveSession")
733 _method_command("save_session_as", _("Save Session &As"), "SaveSessionAs")
734 _method_command("toggle_session_tree", _("Session &Tree"), "ToggleSessionTree",
735 checked = _has_tree_window_shown)
736 _method_command("toggle_legend", _("Legend"), "ToggleLegend",
737 checked = _has_legend_shown)
738 _method_command("exit", _("E&xit"), "Exit")
739
740 # Help menu
741 _method_command("help_about", _("&About"), "About")
742
743
744 # Map menu
745 _method_command("map_projection", _("Pro&jection"), "Projection")
746
747 _tool_command("map_zoom_in_tool", _("&Zoom in"), "ZoomInTool", "ZoomInTool",
748 helptext = _("Switch to map-mode 'zoom-in'"), icon = "zoom_in",
749 sensitive = _has_visible_map)
750 _tool_command("map_zoom_out_tool", _("Zoom &out"), "ZoomOutTool", "ZoomOutTool",
751 helptext = _("Switch to map-mode 'zoom-out'"), icon = "zoom_out",
752 sensitive = _has_visible_map)
753 _tool_command("map_pan_tool", _("&Pan"), "PanTool", "PanTool",
754 helptext = _("Switch to map-mode 'pan'"), icon = "pan",
755 sensitive = _has_visible_map)
756 _tool_command("map_identify_tool", _("&Identify"), "IdentifyTool",
757 "IdentifyTool",
758 helptext = _("Switch to map-mode 'identify'"), icon = "identify",
759 sensitive = _has_visible_map)
760 _tool_command("map_label_tool", _("&Label"), "LabelTool", "LabelTool",
761 helptext = _("Add/Remove labels"), icon = "label",
762 sensitive = _has_visible_map)
763 _method_command("map_full_extent", _("&Full extent"), "FullExtent",
764 helptext = _("Full Extent"), icon = "fullextent",
765 sensitive = _has_visible_map)
766 _method_command("map_print", _("Prin&t"), "PrintMap",
767 helptext = _("Print the map"))
768
769 # Layer menu
770 _method_command("layer_add", _("&Add Layer"), "AddLayer",
771 helptext = _("Add a new layer to active map"))
772 _method_command("layer_remove", _("&Remove Layer"), "RemoveLayer",
773 helptext = _("Remove selected layer(s)"),
774 sensitive = _can_remove_layer)
775 _method_command("layer_fill_color", _("&Fill Color"), "LayerFillColor",
776 helptext = _("Set the fill color of selected layer(s)"),
777 sensitive = _has_selected_layer)
778 _method_command("layer_transparent_fill", _("&Transparent Fill"),
779 "LayerTransparentFill",
780 helptext = _("Do not fill the selected layer(s)"),
781 sensitive = _has_selected_layer)
782 _method_command("layer_outline_color", _("&Outline Color"), "LayerOutlineColor",
783 helptext = _("Set the outline color of selected layer(s)"),
784 sensitive = _has_selected_layer)
785 _method_command("layer_no_outline", _("&No Outline"), "LayerNoOutline",
786 helptext= _("Do not draw the outline of the selected layer(s)"),
787 sensitive = _has_selected_layer)
788 _method_command("layer_raise", _("&Raise"), "RaiseLayer",
789 helptext = _("Raise selected layer(s)"),
790 sensitive = _has_selected_layer)
791 _method_command("layer_lower", _("&Lower"), "LowerLayer",
792 helptext = _("Lower selected layer(s)"),
793 sensitive = _has_selected_layer)
794 _method_command("layer_show", _("&Show"), "ShowLayer",
795 helptext = _("Make selected layer(s) visible"),
796 sensitive = _has_selected_layer)
797 _method_command("layer_hide", _("&Hide"), "HideLayer",
798 helptext = _("Make selected layer(s) unvisible"),
799 sensitive = _has_selected_layer)
800 _method_command("layer_show_table", _("Show Ta&ble"), "LayerShowTable",
801 helptext = _("Show the selected layer's table"),
802 sensitive = _has_selected_layer)
803 _method_command("layer_classifier", _("Classify"), "Classify",
804 sensitive = _has_selected_layer)
805
806 # the menu structure
807 main_menu = Menu("<main>", "<main>",
808 [Menu("file", _("&File"),
809 ["new_session", "open_session", None,
810 "save_session", "save_session_as", None,
811 "toggle_session_tree",
812 "toggle_legend", None,
813 "exit"]),
814 Menu("map", _("&Map"),
815 ["layer_add", "layer_remove",
816 None,
817 "map_projection",
818 None,
819 "map_zoom_in_tool", "map_zoom_out_tool",
820 "map_pan_tool", "map_identify_tool", "map_label_tool",
821 None,
822 "map_full_extent",
823 None,
824 "map_print"]),
825 Menu("layer", _("&Layer"),
826 ["layer_fill_color", "layer_transparent_fill",
827 "layer_outline_color", "layer_no_outline",
828 None,
829 "layer_raise", "layer_lower",
830 None,
831 "layer_show", "layer_hide",
832 None,
833 "layer_show_table",
834 None,
835 "layer_classifier"]),
836 Menu("help", _("&Help"),
837 ["help_about"])])
838
839 # the main toolbar
840
841 main_toolbar = Menu("<toolbar>", "<toolbar>",
842 ["map_zoom_in_tool", "map_zoom_out_tool", "map_pan_tool",
843 "map_full_extent", None,
844 "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