/[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 653 - (hide annotations)
Fri Apr 11 14:28:29 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: 30017 byte(s)
Added new menu item and associated code to open a dialog to rename the map.
(MainWindow): Use new resource class to import bitmaps.

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