/[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 321 - (hide annotations)
Fri Sep 13 14:21:48 2002 UTC (22 years, 5 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/mainwindow.py
File MIME type: text/x-python
File size: 25227 byte(s)
(MainWindow.view_position_changed)
(MainWindow.set_position_text): Put the code that puts the text
with the mouse position into the status bar into the new method
set_position_text so that it can overwritten in derived classes.

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 6 from command import registry, Command
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 222 event.Enable(command.Sensitive(context))
214     event.SetText(command.DynText(context))
215 bh 13 if command.IsCheckCommand():
216 bh 222 event.Check(command.Checked(context))
217 bh 6
218 bh 20 def RunMessageBox(self, title, text, flags = wxOK | wxICON_INFORMATION):
219 bh 181 """Run a modal message box with the given text, title and flags
220 bh 20 and return the result"""
221     dlg = wxMessageDialog(self, text, title, flags)
222 bh 316 dlg.CenterOnParent()
223 bh 20 result = dlg.ShowModal()
224     dlg.Destroy()
225     return result
226    
227 bh 31 def init_dialogs(self):
228     """Initialize the dialog handling"""
229     # The mainwindow maintains a dict mapping names to open
230     # non-modal dialogs. The dialogs are put into this dict when
231     # they're created and removed when they're closed
232     self.dialogs = {}
233    
234     def add_dialog(self, name, dialog):
235     if self.dialogs.has_key(name):
236     raise RuntimeError("The Dialog named %s is already open" % name)
237     self.dialogs[name] = dialog
238    
239     def dialog_open(self, name):
240     return self.dialogs.has_key(name)
241    
242     def remove_dialog(self, name):
243     del self.dialogs[name]
244    
245     def get_open_dialog(self, name):
246     return self.dialogs.get(name)
247    
248 bh 123 def view_position_changed(self):
249     pos = self.canvas.CurrentPosition()
250     if pos is not None:
251     text = "(%10.10g, %10.10g)" % pos
252     else:
253     text = ""
254 bh 321 self.set_position_text(text)
255    
256     def set_position_text(self, text):
257     """Set the statusbar text showing the current position.
258    
259     By default the text is shown in field 0 of the status bar.
260     Override this method in derived classes to put it into a
261     different field of the statusbar.
262     """
263 bh 123 self.SetStatusText(text)
264    
265 bh 58 def save_modified_session(self, can_veto = 1):
266     """If the current session has been modified, ask the user
267     whether to save it and do so if requested. Return the outcome of
268     the dialog (either wxID_OK, wxID_CANCEL or wxID_NO). If the
269     dialog wasn't run return wxID_NO.
270    
271     If the can_veto parameter is true (default) the dialog includes
272     a cancel button, otherwise not.
273     """
274 bh 227 if self.application.session.WasModified():
275 bh 58 flags = wxYES_NO | wxICON_QUESTION
276     if can_veto:
277     flags = flags | wxCANCEL
278     result = self.RunMessageBox("Exit",
279     ("The session has been modified."
280     " Do you want to save it?"),
281     flags)
282     if result == wxID_YES:
283     self.SaveSession()
284     else:
285     result = wxID_NO
286     return result
287    
288 bh 6 def NewSession(self):
289 bh 58 self.save_modified_session()
290 bh 227 self.application.SetSession(create_empty_session())
291 bh 6
292     def OpenSession(self):
293 bh 58 self.save_modified_session()
294 bh 6 dlg = wxFileDialog(self, "Select a session file", ".", "",
295 bh 130 "*.thuban", wxOPEN)
296 bh 6 if dlg.ShowModal() == wxID_OK:
297 bh 227 self.application.OpenSession(dlg.GetPath())
298 bh 6 dlg.Destroy()
299    
300     def SaveSession(self):
301 bh 227 if self.application.session.filename == None:
302 jan 102 self.SaveSessionAs()
303 bh 227 self.application.SaveSession()
304 bh 6
305     def SaveSessionAs(self):
306     dlg = wxFileDialog(self, "Enter a filename for session", ".", "",
307 bh 130 "*.thuban", wxOPEN)
308 bh 6 if dlg.ShowModal() == wxID_OK:
309 bh 227 self.application.session.SetFilename(dlg.GetPath())
310     self.application.SaveSession()
311 bh 6 dlg.Destroy()
312    
313     def Exit(self):
314     self.Close(false)
315    
316     def OnClose(self, event):
317 bh 58 result = self.save_modified_session(can_veto = event.CanVeto())
318     if result == wxID_CANCEL:
319 bh 6 event.Veto()
320     else:
321 bh 307 # FIXME: it would be better to tie the unsubscription to
322     # wx's destroy event, but that isn't implemented for wxGTK
323     # yet.
324     self.canvas.Unsubscribe(VIEW_POSITION, self.view_position_changed)
325 bh 6 self.Destroy()
326    
327     def SetMap(self, map):
328     self.canvas.SetMap(map)
329    
330 bh 310 def Map(self):
331     """Return the map displayed by this mainwindow"""
332     return self.canvas.Map()
333    
334 bh 37 def ShowSessionTree(self):
335     name = "session_tree"
336     dialog = self.get_open_dialog(name)
337     if dialog is None:
338 bh 227 dialog = tree.SessionTreeView(self, self.application, name)
339 bh 37 self.add_dialog(name, dialog)
340     dialog.Show(true)
341     else:
342     # FIXME: bring dialog to front here
343     pass
344    
345 bh 6 def About(self):
346 bh 20 self.RunMessageBox("About",
347     ("Thuban is a program for\n"
348     "exploring geographic data.\n"
349     "Copyright (C) 2001 Intevation GmbH.\n"
350     "Thuban is licensed under the GPL"),
351     wxOK | wxICON_INFORMATION)
352 bh 6
353     def AddLayer(self):
354 frank 119 dlg = wxFileDialog(self, "Select a data file", ".", "", "*.*",
355 bh 6 wxOPEN)
356     if dlg.ShowModal() == wxID_OK:
357     filename = dlg.GetPath()
358     title = os.path.splitext(os.path.basename(filename))[0]
359     layer = Layer(title, filename)
360 bh 18 map = self.canvas.Map()
361     has_layers = map.HasLayers()
362 bh 20 try:
363     map.AddLayer(layer)
364     except IOError:
365     # the layer couldn't be opened
366     self.RunMessageBox("Add Layer",
367     "Can't open the file '%s'." % filename)
368     else:
369     if not has_layers:
370     # if we're adding a layer to an empty map, for the
371     # new map to the window
372     self.canvas.FitMapToWindow()
373 bh 6 dlg.Destroy()
374    
375     def RemoveLayer(self):
376     layer = self.current_layer()
377     if layer is not None:
378     self.canvas.Map().RemoveLayer(layer)
379    
380 bh 299 def CanRemoveLayer(self):
381     """Return true if the currently selected layer can be deleted.
382    
383     If no layer is selected return false.
384    
385     The return value of this method determines whether the remove
386     layer command is sensitive in menu.
387     """
388     layer = self.current_layer()
389     if layer is not None:
390     return self.canvas.Map().CanRemoveLayer(layer)
391     return 0
392    
393 bh 6 def RaiseLayer(self):
394     layer = self.current_layer()
395     if layer is not None:
396     self.canvas.Map().RaiseLayer(layer)
397 bh 222
398 bh 6 def LowerLayer(self):
399     layer = self.current_layer()
400     if layer is not None:
401     self.canvas.Map().LowerLayer(layer)
402    
403     def current_layer(self):
404     """Return the currently selected layer.
405    
406     If no layer is selected, return None
407     """
408 bh 37 return self.interactor.SelectedLayer()
409 bh 6
410     def has_selected_layer(self):
411     """Return true if a layer is currently selected"""
412 bh 37 return self.interactor.HasSelectedLayer()
413 bh 6
414     def choose_color(self):
415     """Run the color selection dialog and return the selected color.
416    
417     If the user cancels, return None.
418     """
419     dlg = wxColourDialog(self)
420     color = None
421     if dlg.ShowModal() == wxID_OK:
422     data = dlg.GetColourData()
423     wxc = data.GetColour()
424     color = Color(wxc.Red() / 255.0,
425     wxc.Green() / 255.0,
426     wxc.Blue() / 255.0)
427     dlg.Destroy()
428     return color
429    
430     def LayerFillColor(self):
431     layer = self.current_layer()
432     if layer is not None:
433     color = self.choose_color()
434     if color is not None:
435     layer.SetFill(color)
436    
437     def LayerTransparentFill(self):
438     layer = self.current_layer()
439     if layer is not None:
440     layer.SetFill(None)
441    
442     def LayerOutlineColor(self):
443     layer = self.current_layer()
444     if layer is not None:
445     color = self.choose_color()
446     if color is not None:
447     layer.SetStroke(color)
448    
449     def LayerNoOutline(self):
450     layer = self.current_layer()
451     if layer is not None:
452     layer.SetStroke(None)
453    
454     def HideLayer(self):
455     layer = self.current_layer()
456     if layer is not None:
457     layer.SetVisible(0)
458    
459     def ShowLayer(self):
460     layer = self.current_layer()
461     if layer is not None:
462     layer.SetVisible(1)
463    
464     def LayerShowTable(self):
465     layer = self.current_layer()
466     if layer is not None:
467 bh 31 table = layer.table
468     name = "table_view" + str(id(table))
469     dialog = self.get_open_dialog(name)
470     if dialog is None:
471 bh 278 dialog = tableview.LayerTableFrame(self, self.interactor, name,
472     "Table: %s" % layer.Title(),
473     layer, table)
474 bh 31 self.add_dialog(name, dialog)
475     dialog.Show(true)
476     else:
477     # FIXME: bring dialog to front here
478     pass
479 bh 6
480     def Projection(self):
481     map = self.canvas.Map()
482     proj = map.projection
483     if proj is None:
484 jan 110 proj4Dlg = proj4dialog.Proj4Dialog(NULL, None, map.BoundingBox())
485 bh 6 else:
486 jan 110 proj4Dlg = proj4dialog.Proj4Dialog(NULL, map.projection.params,
487     map.BoundingBox())
488 bh 6 if proj4Dlg.ShowModal() == wxID_OK:
489     params = proj4Dlg.GetParams()
490     if params is not None:
491     proj = Projection(params)
492     else:
493     proj = None
494     map.SetProjection(proj)
495     proj4Dlg.Destroy()
496    
497     def ZoomInTool(self):
498     self.canvas.ZoomInTool()
499    
500     def ZoomOutTool(self):
501     self.canvas.ZoomOutTool()
502    
503     def PanTool(self):
504     self.canvas.PanTool()
505    
506     def IdentifyTool(self):
507     self.canvas.IdentifyTool()
508 bh 49 self.identify_view_on_demand(None, None)
509 bh 6
510     def LabelTool(self):
511     self.canvas.LabelTool()
512    
513     def FullExtent(self):
514     self.canvas.FitMapToWindow()
515    
516     def PrintMap(self):
517     self.canvas.Print()
518    
519 bh 31 def identify_view_on_demand(self, layer, shape):
520     name = "identify_view"
521     if self.canvas.CurrentTool() == "IdentifyTool":
522     if not self.dialog_open(name):
523 bh 37 dialog = identifyview.IdentifyView(self, self.interactor, name)
524 bh 31 self.add_dialog(name, dialog)
525     dialog.Show(true)
526     else:
527 bh 33 # FIXME: bring dialog to front?
528 bh 31 pass
529 bh 6
530     #
531     # Define all the commands available in the main window
532     #
533    
534    
535     # Helper functions to define common command implementations
536     def call_method(context, methodname, *args):
537 bh 222 """Call the mainwindow's method methodname with args *args"""
538     apply(getattr(context.mainwindow, methodname), args)
539 bh 6
540 jan 110 def _method_command(name, title, method, helptext = "",
541     icon = "", sensitive = None):
542 bh 222 """Add a command implemented by a method of the mainwindow object"""
543 bh 6 registry.Add(Command(name, title, call_method, args=(method,),
544 jan 110 helptext = helptext, icon = icon,
545     sensitive = sensitive))
546    
547 bh 270 def make_check_current_tool(toolname):
548     """Return a function that tests if the currently active tool is toolname
549    
550     The returned function can be called with the context and returns
551     true iff the currently active tool's name is toolname. It's directly
552     usable as the 'checked' callback of a command.
553     """
554     def check_current_tool(context, name=toolname):
555     return context.mainwindow.canvas.CurrentTool() == name
556     return check_current_tool
557    
558 bh 6 def _tool_command(name, title, method, toolname, helptext = "",
559 bh 310 icon = "", sensitive = None):
560 bh 6 """Add a tool command"""
561     registry.Add(Command(name, title, call_method, args=(method,),
562     helptext = helptext, icon = icon,
563 bh 310 checked = make_check_current_tool(toolname),
564     sensitive = sensitive))
565 bh 6
566     def _has_selected_layer(context):
567     """Return true if a layer is selected in the context"""
568 bh 222 return context.mainwindow.has_selected_layer()
569 bh 6
570 bh 299 def _can_remove_layer(context):
571     return context.mainwindow.CanRemoveLayer()
572    
573 jan 264 def _has_tree_window_shown(context):
574     """Return true if the tree window is shown"""
575     return context.mainwindow.get_open_dialog("session_tree") is None
576    
577 bh 310 def _has_visible_map(context):
578     """Return true iff theres a visible map in the mainwindow.
579    
580     A visible map is a map with at least one visible layer."""
581     map = context.mainwindow.Map()
582     if map is not None:
583     for layer in map.Layers():
584     if layer.Visible():
585     return 1
586     return 0
587    
588    
589 bh 6 # File menu
590     _method_command("new_session", "&New Session", "NewSession")
591     _method_command("open_session", "&Open Session", "OpenSession")
592     _method_command("save_session", "&Save Session", "SaveSession")
593     _method_command("save_session_as", "Save Session &As", "SaveSessionAs")
594 jan 264 _method_command("show_session_tree", "Show Session &Tree", "ShowSessionTree",
595     sensitive = _has_tree_window_shown)
596 bh 312 _method_command("exit", "E&xit", "Exit")
597 bh 6
598     # Help menu
599     _method_command("help_about", "&About", "About")
600    
601    
602     # Map menu
603     _method_command("map_projection", "Pro&jection", "Projection")
604    
605     _tool_command("map_zoom_in_tool", "&Zoom in", "ZoomInTool", "ZoomInTool",
606 bh 310 helptext = "Switch to map-mode 'zoom-in'", icon = "zoom_in",
607     sensitive = _has_visible_map)
608 bh 6 _tool_command("map_zoom_out_tool", "Zoom &out", "ZoomOutTool", "ZoomOutTool",
609 bh 310 helptext = "Switch to map-mode 'zoom-out'", icon = "zoom_out",
610     sensitive = _has_visible_map)
611 bh 6 _tool_command("map_pan_tool", "&Pan", "PanTool", "PanTool",
612 bh 310 helptext = "Switch to map-mode 'pan'", icon = "pan",
613     sensitive = _has_visible_map)
614 bh 6 _tool_command("map_identify_tool", "&Identify", "IdentifyTool", "IdentifyTool",
615 bh 310 helptext = "Switch to map-mode 'identify'", icon = "identify",
616     sensitive = _has_visible_map)
617 bh 6 _tool_command("map_label_tool", "&Label", "LabelTool", "LabelTool",
618 bh 310 helptext = "Add/Remove labels", icon = "label",
619     sensitive = _has_visible_map)
620 jan 110 _method_command("map_full_extent", "&Full extent", "FullExtent",
621 bh 310 helptext = "Full Extent", icon = "fullextent",
622     sensitive = _has_visible_map)
623 bh 6 _method_command("map_print", "Prin&t", "PrintMap", helptext = "Print the map")
624    
625     # Layer menu
626 bh 84 _method_command("layer_add", "&Add Layer", "AddLayer",
627 bh 6 helptext = "Add a new layer to active map")
628 bh 84 _method_command("layer_remove", "&Remove Layer", "RemoveLayer",
629 bh 6 helptext = "Remove selected layer(s)",
630 bh 299 sensitive = _can_remove_layer)
631 bh 6 _method_command("layer_fill_color", "&Fill Color", "LayerFillColor",
632     helptext = "Set the fill color of selected layer(s)",
633     sensitive = _has_selected_layer)
634     _method_command("layer_transparent_fill", "&Transparent Fill",
635     "LayerTransparentFill",
636     helptext = "Do not fill the selected layer(s)",
637     sensitive = _has_selected_layer)
638 bh 185 _method_command("layer_outline_color", "&Outline Color", "LayerOutlineColor",
639 bh 6 helptext = "Set the outline color of selected layer(s)",
640     sensitive = _has_selected_layer)
641     _method_command("layer_no_outline", "&No Outline", "LayerNoOutline",
642     helptext = "Do not draw the outline of the selected layer(s)",
643     sensitive = _has_selected_layer)
644     _method_command("layer_raise", "&Raise", "RaiseLayer",
645     helptext = "Raise selected layer(s)",
646     sensitive = _has_selected_layer)
647     _method_command("layer_lower", "&Lower", "LowerLayer",
648     helptext = "Lower selected layer(s)",
649     sensitive = _has_selected_layer)
650     _method_command("layer_show", "&Show", "ShowLayer",
651     helptext = "Make selected layer(s) visible",
652     sensitive = _has_selected_layer)
653     _method_command("layer_hide", "&Hide", "HideLayer",
654     helptext = "Make selected layer(s) unvisible",
655     sensitive = _has_selected_layer)
656     _method_command("layer_show_table", "Show Ta&ble", "LayerShowTable",
657     helptext = "Show the selected layer's table",
658     sensitive = _has_selected_layer)
659 bh 188
660    
661     # the menu structure
662     main_menu = Menu("<main>", "<main>",
663     [Menu("file", "&File",
664     ["new_session", "open_session", None,
665     "save_session", "save_session_as", None,
666     "show_session_tree", None,
667     "exit"]),
668     Menu("map", "&Map",
669     ["layer_add", "layer_remove",
670     None,
671     "map_projection",
672     None,
673     "map_zoom_in_tool", "map_zoom_out_tool",
674     "map_pan_tool", "map_identify_tool", "map_label_tool",
675     None,
676     "map_full_extent",
677     None,
678     "map_print"]),
679     Menu("layer", "&Layer",
680     ["layer_fill_color", "layer_transparent_fill",
681     "layer_outline_color", "layer_no_outline",
682     None,
683     "layer_raise", "layer_lower",
684     None,
685     "layer_show", "layer_hide",
686     None,
687     "layer_show_table"]),
688     Menu("help", "&Help",
689     ["help_about"])])
690 bh 191
691     # the main toolbar
692    
693     main_toolbar = Menu("<toolbar>", "<toolbar>",
694     ["map_zoom_in_tool", "map_zoom_out_tool", "map_pan_tool",
695     "map_identify_tool", "map_label_tool", "map_full_extent"])

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26