/[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 316 - (hide annotations)
Thu Sep 12 18:46:01 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: 24899 byte(s)
(MainWindow.RunMessageBox): Center the
message box on the main window.

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