/[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 314 - (hide annotations)
Wed Sep 11 15:18:09 2002 UTC (22 years, 6 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/mainwindow.py
File MIME type: text/x-python
File size: 24870 byte(s)
(MainWindow.build_menu): remove an incorrect comment.

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