/[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 653 - (show annotations)
Fri Apr 11 14:28:29 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: 30017 byte(s)
Added new menu item and associated code to open a dialog to rename the map.
(MainWindow): Use new resource class to import bitmaps.

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