/[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 550 - (hide annotations)
Thu Mar 20 09:45:19 2003 UTC (21 years, 11 months ago) by jonathan
Original Path: trunk/thuban/Thuban/UI/mainwindow.py
File MIME type: text/x-python
File size: 29818 byte(s)
New code to open the legend.

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