/[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 357 - (hide annotations)
Mon Dec 9 10:32:27 2002 UTC (22 years, 3 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/mainwindow.py
File MIME type: text/x-python
File size: 25855 byte(s)
(MainWindow.update_command_ui): If an
active tool's command turns insensitive, disable the tool.
(_tool_command): Use the new ToolCommand class

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