/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/mainwindow.py
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/Thuban/UI/mainwindow.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 264 by jan, Fri Aug 16 17:06:38 2002 UTC revision 879 by jonathan, Fri May 9 16:33:10 2003 UTC
# Line 1  Line 1 
1  # Copyright (C) 2001, 2002 by Intevation GmbH  # Copyright (C) 2001, 2002, 2003 by Intevation GmbH
2  # Authors:  # Authors:
3  # Jan-Oliver Wagner <[email protected]>  # Jan-Oliver Wagner <[email protected]>
4  # Bernhard Herzog <[email protected]>  # Bernhard Herzog <[email protected]>
# Line 12  The main window Line 12  The main window
12    
13  __version__ = "$Revision$"  __version__ = "$Revision$"
14    
15    __ThubanVersion__ = "0.2" #"$THUBAN_0_2$"
16    #__BuildDate__ = "$Date$"
17    
18  import os  import os
19    
20  from wxPython.wx import *  from wxPython.wx import *
21    
22  import Thuban  import Thuban
23    from Thuban import _
24  from Thuban.Model.session import create_empty_session  from Thuban.Model.session import create_empty_session
25  from Thuban.Model.layer import Layer  from Thuban.Model.layer import Layer
26  from Thuban.Model.color import Color  from Thuban.Model.color import Color
# Line 26  import view Line 30  import view
30  import tree  import tree
31  import proj4dialog  import proj4dialog
32  import tableview, identifyview  import tableview, identifyview
33    from Thuban.UI.classifier import Classifier
34    import legend
35  from menu import Menu  from menu import Menu
36    
37  from context import Context  from context import Context
38  from command import registry, Command  from command import registry, Command, ToolCommand
39  from messages import SELECTED_SHAPE, VIEW_POSITION  from messages import LAYER_SELECTED, SHAPES_SELECTED, VIEW_POSITION
40    
41    from Thuban.UI.dock import DockFrame
42    from Thuban.UI.join import JoinDialog
43    
44    import resource
45    
46    import projdialog
47    
48    
 # the directory where the toolbar icons are stored  
 bitmapdir = os.path.join(Thuban.__path__[0], os.pardir, "Resources", "Bitmaps")  
 bitmapext = ".xpm"  
49    
50    class MainWindow(DockFrame):
51    
52  class MainWindow(wxFrame):      # Some messages that can be subscribed/unsubscribed directly through
53        # the MapCanvas come in fact from other objects. This is a map to
54        # map those messages to the names of the instance variables they
55        # actually come from. This delegation is implemented in the
56        # Subscribe and unsubscribed methods
57        delegated_messages = {LAYER_SELECTED: "canvas",
58                              SHAPES_SELECTED: "canvas"}
59    
60        # Methods delegated to some instance variables. The delegation is
61        # implemented in the __getattr__ method.
62        delegated_methods = {"SelectLayer": "canvas",
63                             "SelectShapes": "canvas",
64                             "SelectedShapes": "canvas",
65                             }
66    
67      def __init__(self, parent, ID, title, application, interactor,      def __init__(self, parent, ID, title, application, interactor,
68                   initial_message = None, size = wxSize(-1, -1)):                   initial_message = None, size = wxSize(-1, -1)):
69          wxFrame.__init__(self, parent, ID, title, wxDefaultPosition, size)          DockFrame.__init__(self, parent, ID, title, wxDefaultPosition, size)
70            #wxFrame.__init__(self, parent, ID, title, wxDefaultPosition, size)
71    
72          self.application = application          self.application = application
         self.interactor = interactor  
73    
74          self.CreateStatusBar()          self.CreateStatusBar()
75          if initial_message:          if initial_message:
# Line 63  class MainWindow(wxFrame): Line 87  class MainWindow(wxFrame):
87          # call Realize to make sure that the tools appear.          # call Realize to make sure that the tools appear.
88          toolbar.Realize()          toolbar.Realize()
89    
90    
91          # Create the map canvas          # Create the map canvas
92          canvas = view.MapCanvas(self, -1, interactor)          canvas = view.MapCanvas(self, -1)
93          canvas.Subscribe(VIEW_POSITION, self.view_position_changed)          canvas.Subscribe(VIEW_POSITION, self.view_position_changed)
94            canvas.Subscribe(SHAPES_SELECTED, self.identify_view_on_demand)
95          self.canvas = canvas          self.canvas = canvas
96    
97            self.SetMainWindow(self.canvas)
98    
99            self.SetAutoLayout(True)
100    
101          self.init_dialogs()          self.init_dialogs()
102    
103          interactor.Subscribe(SELECTED_SHAPE, self.identify_view_on_demand)          EVT_CLOSE(self, self._OnClose)
104    
105          EVT_CLOSE(self, self.OnClose)      def Subscribe(self, channel, *args):
106            """Subscribe a function to a message channel.
107    
108            If channel is one of the delegated messages call the appropriate
109            object's Subscribe method. Otherwise do nothing.
110            """
111            if channel in self.delegated_messages:
112                object = getattr(self, self.delegated_messages[channel])
113                object.Subscribe(channel, *args)
114            else:
115                print "Trying to subscribe to unsupported channel %s" % channel
116    
117        def Unsubscribe(self, channel, *args):
118            """Unsubscribe a function from a message channel.
119    
120            If channel is one of the delegated messages call the appropriate
121            object's Unsubscribe method. Otherwise do nothing.
122            """
123            if channel in self.delegated_messages:
124                object = getattr(self, self.delegated_messages[channel])
125                object.Unsubscribe(channel, *args)
126    
127        def __getattr__(self, attr):
128            """If attr is one of the delegated methods return that method
129    
130            Otherwise raise AttributeError.
131            """
132            if attr in self.delegated_methods:
133                return getattr(getattr(self, self.delegated_methods[attr]), attr)
134            raise AttributeError(attr)
135    
136      def init_ids(self):      def init_ids(self):
137          """Initialize the ids"""          """Initialize the ids"""
# Line 112  class MainWindow(wxFrame): Line 171  class MainWindow(wxFrame):
171          return menu_bar          return menu_bar
172    
173      def build_menu(self, menudesc):      def build_menu(self, menudesc):
174          """Build and return a wxMenu from a menudescription"""          """Return a wxMenu built from the menu description menudesc"""
175          wxmenu = wxMenu()          wxmenu = wxMenu()
176          last = None          last = None
177          for item in menudesc.items:          for item in menudesc.items:
             # here the items must all be Menu instances themselves  
178              if item is None:              if item is None:
179                  # a separator. Only add one if the last item was not a                  # a separator. Only add one if the last item was not a
180                  # separator                  # separator
# Line 169  class MainWindow(wxFrame): Line 227  class MainWindow(wxFrame):
227                              command.IsCheckCommand())                              command.IsCheckCommand())
228                  self.bind_command_events(command, ID)                  self.bind_command_events(command, ID)
229              else:              else:
230                  print "Unknown command %s" % name                  print _("Unknown command %s") % name
231    
232      def add_toolbar_command(self, toolbar, name):      def add_toolbar_command(self, toolbar, name):
233          """Add the command with name name to the toolbar toolbar.          """Add the command with name name to the toolbar toolbar.
# Line 184  class MainWindow(wxFrame): Line 242  class MainWindow(wxFrame):
242              command = registry.Command(name)              command = registry.Command(name)
243              if command is not None:              if command is not None:
244                  ID = self.get_id(name)                  ID = self.get_id(name)
245                  filename = os.path.join(bitmapdir, command.Icon()) + bitmapext                  bitmap = resource.GetBitmapResource(command.Icon(),
246                  bitmap = wxBitmap(filename, wxBITMAP_TYPE_XPM)                                                      wxBITMAP_TYPE_XPM)
247                  toolbar.AddTool(ID, bitmap,                  toolbar.AddTool(ID, bitmap,
248                                  shortHelpString = command.HelpText(),                                  shortHelpString = command.HelpText(),
249                                  isToggle = command.IsCheckCommand())                                  isToggle = command.IsCheckCommand())
250                  self.bind_command_events(command, ID)                  self.bind_command_events(command, ID)
251              else:              else:
252                  print "Unknown command %s" % name                  print _("Unknown command %s") % name
253    
254        def Context(self):
255            """Return the context object for a command invoked from this window
256            """
257            return Context(self.application, self.application.Session(), self)
258    
259      def invoke_command(self, event):      def invoke_command(self, event):
260          name = self.id_to_name.get(event.GetId())          name = self.id_to_name.get(event.GetId())
261          if name is not None:          if name is not None:
262              command = registry.Command(name)              command = registry.Command(name)
263              context = Context(self.application, self.application.Session(),              command.Execute(self.Context())
                               self)  
             command.Execute(context)  
264          else:          else:
265              print "Unknown command ID %d" % event.GetId()              print _("Unknown command ID %d") % event.GetId()
266    
267      def update_command_ui(self, event):      def update_command_ui(self, event):
268          #print "update_command_ui", self.id_to_name[event.GetId()]          #print "update_command_ui", self.id_to_name[event.GetId()]
269          context = Context(self.application, self.application.Session(), self)          context = self.Context()
270          command = registry.Command(self.id_to_name[event.GetId()])          command = registry.Command(self.id_to_name[event.GetId()])
271          if command is not None:          if command is not None:
272              event.Enable(command.Sensitive(context))              sensitive = command.Sensitive(context)
273                event.Enable(sensitive)
274                if command.IsTool() and not sensitive and command.Checked(context):
275                    # When a checked tool command is disabled deselect all
276                    # tools. Otherwise the tool would remain active but it
277                    # might lead to errors if the tools stays active. This
278                    # problem occurred in GREAT-ER and this fixes it, but
279                    # it's not clear to me whether this is really the best
280                    # way to do it (BH, 20021206).
281                    self.canvas.SelectTool(None)
282              event.SetText(command.DynText(context))              event.SetText(command.DynText(context))
283              if command.IsCheckCommand():              if command.IsCheckCommand():
284                  event.Check(command.Checked(context))                      event.Check(command.Checked(context))
285    
286      def RunMessageBox(self, title, text, flags = wxOK | wxICON_INFORMATION):      def RunMessageBox(self, title, text, flags = wxOK | wxICON_INFORMATION):
287          """Run a modal message box with the given text, title and flags          """Run a modal message box with the given text, title and flags
288          and return the result"""          and return the result"""
289          dlg = wxMessageDialog(self, text, title, flags)          dlg = wxMessageDialog(self, text, title, flags)
290            dlg.CenterOnParent()
291          result = dlg.ShowModal()          result = dlg.ShowModal()
292          dlg.Destroy()          dlg.Destroy()
293          return result          return result
# Line 230  class MainWindow(wxFrame): Line 301  class MainWindow(wxFrame):
301    
302      def add_dialog(self, name, dialog):      def add_dialog(self, name, dialog):
303          if self.dialogs.has_key(name):          if self.dialogs.has_key(name):
304              raise RuntimeError("The Dialog named %s is already open" % name)              raise RuntimeError(_("The Dialog named %s is already open") % name)
305          self.dialogs[name] = dialog          self.dialogs[name] = dialog
306    
307      def dialog_open(self, name):      def dialog_open(self, name):
# Line 248  class MainWindow(wxFrame): Line 319  class MainWindow(wxFrame):
319              text = "(%10.10g, %10.10g)" % pos              text = "(%10.10g, %10.10g)" % pos
320          else:          else:
321              text = ""              text = ""
322            self.set_position_text(text)
323    
324        def set_position_text(self, text):
325            """Set the statusbar text showing the current position.
326    
327            By default the text is shown in field 0 of the status bar.
328            Override this method in derived classes to put it into a
329            different field of the statusbar.
330            """
331          self.SetStatusText(text)          self.SetStatusText(text)
332    
333      def save_modified_session(self, can_veto = 1):      def save_modified_session(self, can_veto = 1):
# Line 263  class MainWindow(wxFrame): Line 343  class MainWindow(wxFrame):
343              flags = wxYES_NO | wxICON_QUESTION              flags = wxYES_NO | wxICON_QUESTION
344              if can_veto:              if can_veto:
345                  flags = flags | wxCANCEL                  flags = flags | wxCANCEL
346              result = self.RunMessageBox("Exit",              result = self.RunMessageBox(_("Exit"),
347                                          ("The session has been modified."                                          _("The session has been modified."
348                                           " Do you want to save it?"),                                           " Do you want to save it?"),
349                                          flags)                                          flags)
350              if result == wxID_YES:              if result == wxID_YES:
# Line 273  class MainWindow(wxFrame): Line 353  class MainWindow(wxFrame):
353              result = wxID_NO              result = wxID_NO
354          return result          return result
355    
356        def prepare_new_session(self):
357            for d in self.dialogs.values():
358                if not isinstance(d, tree.SessionTreeView):
359                    d.Close()
360    
361      def NewSession(self):      def NewSession(self):
362          self.save_modified_session()          self.save_modified_session()
363            self.prepare_new_session()
364          self.application.SetSession(create_empty_session())          self.application.SetSession(create_empty_session())
365    
366      def OpenSession(self):      def OpenSession(self):
367          self.save_modified_session()          self.save_modified_session()
368          dlg = wxFileDialog(self, "Select a session file", ".", "",          dlg = wxFileDialog(self, _("Open Session"), ".", "",
369                             "*.thuban", wxOPEN)                             "Thuban Session File (*.thuban)|*.thuban", wxOPEN)
370          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
371                self.prepare_new_session()
372              self.application.OpenSession(dlg.GetPath())              self.application.OpenSession(dlg.GetPath())
373          dlg.Destroy()          dlg.Destroy()
374    
375      def SaveSession(self):      def SaveSession(self):
376          if self.application.session.filename == None:          if self.application.session.filename == None:
377              self.SaveSessionAs()              self.SaveSessionAs()
378          self.application.SaveSession()          else:
379                self.application.SaveSession()
380    
381      def SaveSessionAs(self):      def SaveSessionAs(self):
382          dlg = wxFileDialog(self, "Enter a filename for session", ".", "",          dlg = wxFileDialog(self, _("Save Session As"), ".", "",
383                             "*.thuban", wxOPEN)                             "Thuban Session File (*.thuban)|*.thuban",
384                               wxSAVE|wxOVERWRITE_PROMPT)
385          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
386              self.application.session.SetFilename(dlg.GetPath())              self.application.session.SetFilename(dlg.GetPath())
387              self.application.SaveSession()              self.application.SaveSession()
388          dlg.Destroy()          dlg.Destroy()
389    
390      def Exit(self):      def Exit(self):
391          self.Close(false)          self.Close(False)
392    
393      def OnClose(self, event):      def _OnClose(self, event):
394          result = self.save_modified_session(can_veto = event.CanVeto())          result = self.save_modified_session(can_veto = event.CanVeto())
395          if result == wxID_CANCEL:          if result == wxID_CANCEL:
396              event.Veto()              event.Veto()
397          else:          else:
398                # FIXME: it would be better to tie the unsubscription to
399                # wx's destroy event, but that isn't implemented for wxGTK
400                # yet.
401                self.canvas.Unsubscribe(VIEW_POSITION, self.view_position_changed)
402                DockFrame._OnClose(self, event)
403              self.Destroy()              self.Destroy()
404    
405      def SetMap(self, map):      def SetMap(self, map):
406          self.canvas.SetMap(map)          self.canvas.SetMap(map)
407            self.__SetTitle(map.Title())
408    
409            dialog = self.FindRegisteredDock("legend")
410            if dialog is not None:
411                dialog.GetPanel().SetMap(self.Map())
412    
413        def Map(self):
414            """Return the map displayed by this mainwindow"""
415    
416      def ShowSessionTree(self):          return self.canvas.Map()
417    
418        def ToggleSessionTree(self):
419            """If the session tree is shown close it otherwise create a new tree"""
420          name = "session_tree"          name = "session_tree"
421          dialog = self.get_open_dialog(name)          dialog = self.get_open_dialog(name)
422          if dialog is None:          if dialog is None:
423              dialog = tree.SessionTreeView(self, self.application, name)              dialog = tree.SessionTreeView(self, self.application, name)
424              self.add_dialog(name, dialog)              self.add_dialog(name, dialog)
425              dialog.Show(true)              dialog.Show(True)
426          else:          else:
427              # FIXME: bring dialog to front here              dialog.Close()
428              pass  
429        def SessionTreeShown(self):
430            """Return true iff the session tree is currently shown"""
431            return self.get_open_dialog("session_tree") is not None
432    
433      def About(self):      def About(self):
434          self.RunMessageBox("About",          self.RunMessageBox(_("About"),
435                             ("Thuban is a program for\n"                             _("Thuban v%s\n"
436                                #"Build Date: %s\n"
437                                "\n"
438                                "Thuban is a program for\n"
439                              "exploring geographic data.\n"                              "exploring geographic data.\n"
440                              "Copyright (C) 2001 Intevation GmbH.\n"                              "Copyright (C) 2001-2003 Intevation GmbH.\n"
441                              "Thuban is licensed under the GPL"),                              "Thuban is licensed under the GNU GPL"
442                               % __ThubanVersion__), #__BuildDate__)),
443                             wxOK | wxICON_INFORMATION)                             wxOK | wxICON_INFORMATION)
444    
445      def AddLayer(self):      def AddLayer(self):
446          dlg = wxFileDialog(self, "Select a data file", ".", "", "*.*",          dlg = wxFileDialog(self, _("Select a data file"), ".", "", "*.*",
447                             wxOPEN)                             wxOPEN)
448          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
449              filename = dlg.GetPath()              filename = dlg.GetPath()
450              title = os.path.splitext(os.path.basename(filename))[0]              title = os.path.splitext(os.path.basename(filename))[0]
451              layer = Layer(title, filename)              store = self.application.Session().OpenShapefile(filename)
452                layer = Layer(title, store)
453              map = self.canvas.Map()              map = self.canvas.Map()
454              has_layers = map.HasLayers()              has_layers = map.HasLayers()
455              try:              try:
456                  map.AddLayer(layer)                  map.AddLayer(layer)
457              except IOError:              except IOError:
458                  # the layer couldn't be opened                  # the layer couldn't be opened
459                  self.RunMessageBox("Add Layer",                  self.RunMessageBox(_("Add Layer"),
460                                     "Can't open the file '%s'." % filename)                                     _("Can't open the file '%s'.") % filename)
461              else:              else:
462                  if not has_layers:                  if not has_layers:
463                      # if we're adding a layer to an empty map, for the                      # if we're adding a layer to an empty map, fit the
464                      # new map to the window                      # new map to the window
465                      self.canvas.FitMapToWindow()                      self.canvas.FitMapToWindow()
466          dlg.Destroy()          dlg.Destroy()
# Line 357  class MainWindow(wxFrame): Line 470  class MainWindow(wxFrame):
470          if layer is not None:          if layer is not None:
471              self.canvas.Map().RemoveLayer(layer)              self.canvas.Map().RemoveLayer(layer)
472    
473        def CanRemoveLayer(self):
474            """Return true if the currently selected layer can be deleted.
475    
476            If no layer is selected return False.
477    
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            return False
485    
486      def RaiseLayer(self):      def RaiseLayer(self):
487          layer = self.current_layer()          layer = self.current_layer()
488          if layer is not None:          if layer is not None:
# Line 372  class MainWindow(wxFrame): Line 498  class MainWindow(wxFrame):
498    
499          If no layer is selected, return None          If no layer is selected, return None
500          """          """
501          return self.interactor.SelectedLayer()          return self.canvas.SelectedLayer()
502    
503      def has_selected_layer(self):      def has_selected_layer(self):
504          """Return true if a layer is currently selected"""          """Return true if a layer is currently selected"""
505          return self.interactor.HasSelectedLayer()          return self.canvas.HasSelectedLayer()
   
     def choose_color(self):  
         """Run the color selection dialog and return the selected color.  
   
         If the user cancels, return None.  
         """  
         dlg = wxColourDialog(self)  
         color = None  
         if dlg.ShowModal() == wxID_OK:  
             data = dlg.GetColourData()  
             wxc = data.GetColour()  
             color = Color(wxc.Red() / 255.0,  
                           wxc.Green() / 255.0,  
                           wxc.Blue() / 255.0)  
         dlg.Destroy()  
         return color  
   
     def LayerFillColor(self):  
         layer = self.current_layer()  
         if layer is not None:  
             color = self.choose_color()  
             if color is not None:  
                 layer.SetFill(color)  
506    
507      def LayerTransparentFill(self):      def has_selected_shapes(self):
508          layer = self.current_layer()          """Return true if a shape is currently selected"""
509          if layer is not None:          return self.canvas.HasSelectedShapes()
             layer.SetFill(None)  
   
     def LayerOutlineColor(self):  
         layer = self.current_layer()  
         if layer is not None:  
             color = self.choose_color()  
             if color is not None:  
                 layer.SetStroke(color)  
   
     def LayerNoOutline(self):  
         layer = self.current_layer()  
         if layer is not None:  
             layer.SetStroke(None)  
510    
511      def HideLayer(self):      def HideLayer(self):
512          layer = self.current_layer()          layer = self.current_layer()
# Line 435  class MainWindow(wxFrame): Line 525  class MainWindow(wxFrame):
525              name = "table_view" + str(id(table))              name = "table_view" + str(id(table))
526              dialog = self.get_open_dialog(name)              dialog = self.get_open_dialog(name)
527              if dialog is None:              if dialog is None:
528                  dialog = tableview.TableFrame(self, self.interactor, name,                  dialog = tableview.LayerTableFrame(self, name,
529                                                "Table: %s" % layer.Title(),                                                 _("Table: %s") % layer.Title(),
530                                                layer, table)                                                     layer, table)
531                  self.add_dialog(name, dialog)                  self.add_dialog(name, dialog)
532                  dialog.Show(true)                  dialog.Show(true)
533              else:              else:
534                  # FIXME: bring dialog to front here                  # FIXME: bring dialog to front here
535                  pass                  pass
536    
537      def Projection(self):      def MapProjection(self):
538          map = self.canvas.Map()  
539          proj = map.projection          name = "map_projection"
540          if proj is None:          dialog = self.get_open_dialog(name)
541              proj4Dlg = proj4dialog.Proj4Dialog(NULL, None, map.BoundingBox())  
542            if dialog is None:
543                map = self.canvas.Map()
544                dialog = projdialog.ProjFrame(self, name,
545                         _("Map Projection: %s") % map.Title(), map)
546                self.add_dialog(name, dialog)
547                dialog.Show()
548            dialog.Raise()
549    
550        def LayerProjection(self):
551    
552            layer = self.current_layer()
553    
554            name = "layer_projection" + str(id(layer))
555            dialog = self.get_open_dialog(name)
556    
557            if dialog is None:
558                map = self.canvas.Map()
559                dialog = projdialog.ProjFrame(self, name,
560                         _("Layer Projection: %s") % layer.Title(), layer)
561                self.add_dialog(name, dialog)
562                dialog.Show()
563            dialog.Raise()
564    
565        def LayerEditProperties(self):
566    
567            #
568            # the menu option for this should only be available if there
569            # is a current layer, so we don't need to check if the
570            # current layer is None
571            #
572    
573            layer = self.current_layer()
574            self.OpenLayerProperties(layer)
575    
576        def OpenLayerProperties(self, layer, group = None):
577            name = "layer_properties" + str(id(layer))
578            dialog = self.get_open_dialog(name)
579    
580            if dialog is None:
581                dialog = Classifier(self, name, layer, group)
582                self.add_dialog(name, dialog)
583                dialog.Show()
584            dialog.Raise()
585    
586        def LayerJoinTable(self):
587            print "LayerJoinTable"
588    
589        def LayerUnjoinTable(self):
590            print "LayerUnjoinTable"
591    
592        def ShowLegend(self):
593            if not self.LegendShown():
594                self.ToggleLegend()
595    
596        def ToggleLegend(self):
597            """Show the legend if it's not shown otherwise hide it again"""
598            name = "legend"
599            dialog = self.FindRegisteredDock(name)
600    
601            if dialog is None:
602                dialog = self.CreateDock(name, -1, _("Legend"), wxLAYOUT_LEFT)
603                legend.LegendPanel(dialog, None, self)
604                dialog.Dock()
605                dialog.GetPanel().SetMap(self.Map())
606                dialog.Show()
607          else:          else:
608              proj4Dlg = proj4dialog.Proj4Dialog(NULL, map.projection.params,              dialog.Show(not dialog.IsShown())
609                                                 map.BoundingBox())  
610          if proj4Dlg.ShowModal() == wxID_OK:      def LegendShown(self):
611              params = proj4Dlg.GetParams()          """Return true iff the legend is currently open"""
612              if params is not None:          dialog = self.FindRegisteredDock("legend")
613                  proj = Projection(params)          return dialog is not None and dialog.IsShown()
614              else:  
615                  proj = None      def TableOpen(self):
616              map.SetProjection(proj)          print "TableOpen"
617          proj4Dlg.Destroy()          dlg = wxFileDialog(self, _("Open Table"), ".", "",
618                               "DBF Files (*.dbf)|*.dbf|" +
619                               "CSV Files (*.csv)|*.csv|" +
620                               "All Files (*.*)|*.*",
621                               wxOPEN)
622            if dlg.ShowModal() == wxID_OK:
623                #self.application.session.OpenTable(dlg.GetPath())
624                pass
625    
626            dlg.Destroy()
627    
628        def TableClose(self):
629            print "TableClose"
630    
631        def TableShow(self):
632            print "TableShow"
633    
634        def TableHide(self):
635            print "TableHide"
636    
637        def TableJoin(self):
638            print "TableJoin"
639            dlg = JoinDialog(self, _("Join Tables"), self.application.session)
640            if dlg.ShowModal() == wxID_OK:
641                print "OK"
642    
643      def ZoomInTool(self):      def ZoomInTool(self):
644          self.canvas.ZoomInTool()          self.canvas.ZoomInTool()
# Line 480  class MainWindow(wxFrame): Line 659  class MainWindow(wxFrame):
659      def FullExtent(self):      def FullExtent(self):
660          self.canvas.FitMapToWindow()          self.canvas.FitMapToWindow()
661    
662        def FullLayerExtent(self):
663            self.canvas.FitLayerToWindow(self.current_layer())
664    
665        def FullSelectionExtent(self):
666            self.canvas.FitSelectedToWindow()
667    
668      def PrintMap(self):      def PrintMap(self):
669          self.canvas.Print()          self.canvas.Print()
670    
671      def identify_view_on_demand(self, layer, shape):      def RenameMap(self):
672            dlg = wxTextEntryDialog(self, "Map Title: ", "Rename Map",
673                                    self.Map().Title())
674            if dlg.ShowModal() == wxID_OK:
675                title = dlg.GetValue()
676                if title != "":
677                    self.Map().SetTitle(title)
678                    self.__SetTitle(title)
679    
680            dlg.Destroy()
681    
682        def identify_view_on_demand(self, layer, shapes):
683            """Subscribed to the canvas' SHAPES_SELECTED message
684    
685            If the current tool is the identify tool, at least one shape is
686            selected and the identify dialog is not shown, show the dialog.
687            """
688            # If the selection has become empty we don't need to do
689            # anything. Otherwise it could happen that the dialog was popped
690            # up when the selection became empty, e.g. when a new selection
691            # is opened while the identify tool is active and dialog had
692            # been closed
693            if not shapes:
694                return
695    
696          name = "identify_view"          name = "identify_view"
697          if self.canvas.CurrentTool() == "IdentifyTool":          if self.canvas.CurrentTool() == "IdentifyTool":
698              if not self.dialog_open(name):              if not self.dialog_open(name):
699                  dialog = identifyview.IdentifyView(self, self.interactor, name)                  dialog = identifyview.IdentifyView(self, name)
700                  self.add_dialog(name, dialog)                  self.add_dialog(name, dialog)
701                  dialog.Show(true)                  dialog.Show(True)
702              else:              else:
703                  # FIXME: bring dialog to front?                  # FIXME: bring dialog to front?
704                  pass                  pass
705    
706        def __SetTitle(self, title):
707            self.SetTitle("Thuban - " + title)
708    
709  #  #
710  # Define all the commands available in the main window  # Define all the commands available in the main window
711  #  #
# Line 505  def call_method(context, methodname, *ar Line 717  def call_method(context, methodname, *ar
717      apply(getattr(context.mainwindow, methodname), args)      apply(getattr(context.mainwindow, methodname), args)
718    
719  def _method_command(name, title, method, helptext = "",  def _method_command(name, title, method, helptext = "",
720                      icon = "", sensitive = None):                      icon = "", sensitive = None, checked = None):
721      """Add a command implemented by a method of the mainwindow object"""      """Add a command implemented by a method of the mainwindow object"""
722      registry.Add(Command(name, title, call_method, args=(method,),      registry.Add(Command(name, title, call_method, args=(method,),
723                           helptext = helptext, icon = icon,                           helptext = helptext, icon = icon,
724                           sensitive = sensitive))                           sensitive = sensitive, checked = checked))
725    
726  def _tool_command(name, title, method, toolname, helptext = "",  def make_check_current_tool(toolname):
727                    icon = ""):      """Return a function that tests if the currently active tool is toolname
728      """Add a tool command"""  
729        The returned function can be called with the context and returns
730        true iff the currently active tool's name is toolname. It's directly
731        usable as the 'checked' callback of a command.
732        """
733      def check_current_tool(context, name=toolname):      def check_current_tool(context, name=toolname):
734          return context.mainwindow.canvas.CurrentTool() == name          return context.mainwindow.canvas.CurrentTool() == name
735      registry.Add(Command(name, title, call_method, args=(method,),      return check_current_tool
736                           helptext = helptext, icon = icon,  
737                           checked = check_current_tool))  def _tool_command(name, title, method, toolname, helptext = "",
738                      icon = "", sensitive = None):
739        """Add a tool command"""
740        registry.Add(ToolCommand(name, title, call_method, args=(method,),
741                                 helptext = helptext, icon = icon,
742                                 checked = make_check_current_tool(toolname),
743                                 sensitive = sensitive))
744    
745  def _has_selected_layer(context):  def _has_selected_layer(context):
746      """Return true if a layer is selected in the context"""      """Return true if a layer is selected in the context"""
747      return context.mainwindow.has_selected_layer()      return context.mainwindow.has_selected_layer()
748    
749    def _has_selected_shapes(context):
750        """Return true if a layer is selected in the context"""
751        return context.mainwindow.has_selected_shapes()
752    
753    def _can_remove_layer(context):
754        return context.mainwindow.CanRemoveLayer()
755    
756  def _has_tree_window_shown(context):  def _has_tree_window_shown(context):
757      """Return true if the tree window is shown"""      """Return true if the tree window is shown"""
758      return context.mainwindow.get_open_dialog("session_tree") is None      return context.mainwindow.SessionTreeShown()
759    
760    def _has_visible_map(context):
761        """Return true iff theres a visible map in the mainwindow.
762    
763        A visible map is a map with at least one visible layer."""
764        map = context.mainwindow.Map()
765        if map is not None:
766            for layer in map.Layers():
767                if layer.Visible():
768                    return 1
769        return 0
770    
771    def _has_legend_shown(context):
772        """Return true if the legend window is shown"""
773        return context.mainwindow.LegendShown()
774    
775    
776  # File menu  # File menu
777  _method_command("new_session", "&New Session", "NewSession")  _method_command("new_session", _("&New Session"), "NewSession")
778  _method_command("open_session", "&Open Session", "OpenSession")  _method_command("open_session", _("&Open Session..."), "OpenSession")
779  _method_command("save_session", "&Save Session", "SaveSession")  _method_command("save_session", _("&Save Session"), "SaveSession")
780  _method_command("save_session_as", "Save Session &As", "SaveSessionAs")  _method_command("save_session_as", _("Save Session &As..."), "SaveSessionAs")
781  _method_command("show_session_tree", "Show Session &Tree", "ShowSessionTree",  _method_command("toggle_session_tree", _("Session &Tree"), "ToggleSessionTree",
782                  sensitive = _has_tree_window_shown)                  checked = _has_tree_window_shown)
783  _method_command("exit", "&Exit", "Exit")  _method_command("toggle_legend", _("Legend"), "ToggleLegend",
784                    checked = _has_legend_shown)
785    _method_command("exit", _("E&xit"), "Exit")
786    
787  # Help menu  # Help menu
788  _method_command("help_about", "&About", "About")  _method_command("help_about", _("&About..."), "About")
789    
790    
791  # Map menu  # Map menu
792  _method_command("map_projection", "Pro&jection", "Projection")  _method_command("map_projection", _("Pro&jection..."), "MapProjection")
793    
794  _tool_command("map_zoom_in_tool", "&Zoom in", "ZoomInTool", "ZoomInTool",  _tool_command("map_zoom_in_tool", _("&Zoom in"), "ZoomInTool", "ZoomInTool",
795                helptext = "Switch to map-mode 'zoom-in'", icon = "zoom_in")                helptext = _("Switch to map-mode 'zoom-in'"), icon = "zoom_in",
796  _tool_command("map_zoom_out_tool", "Zoom &out", "ZoomOutTool", "ZoomOutTool",                sensitive = _has_visible_map)
797                helptext = "Switch to map-mode 'zoom-out'", icon = "zoom_out")  _tool_command("map_zoom_out_tool", _("Zoom &out"), "ZoomOutTool", "ZoomOutTool",
798  _tool_command("map_pan_tool", "&Pan", "PanTool", "PanTool",                helptext = _("Switch to map-mode 'zoom-out'"), icon = "zoom_out",
799                helptext = "Switch to map-mode 'pan'", icon = "pan")                sensitive = _has_visible_map)
800  _tool_command("map_identify_tool", "&Identify", "IdentifyTool", "IdentifyTool",  _tool_command("map_pan_tool", _("&Pan"), "PanTool", "PanTool",
801                helptext = "Switch to map-mode 'identify'", icon = "identify")                helptext = _("Switch to map-mode 'pan'"), icon = "pan",
802  _tool_command("map_label_tool", "&Label", "LabelTool", "LabelTool",                sensitive = _has_visible_map)
803                helptext = "Add/Remove labels", icon = "label")  _tool_command("map_identify_tool", _("&Identify"), "IdentifyTool",
804  _method_command("map_full_extent", "&Full extent", "FullExtent",                "IdentifyTool",
805                 helptext = "Full Extent", icon = "fullextent")                helptext = _("Switch to map-mode 'identify'"), icon = "identify",
806  _method_command("map_print", "Prin&t", "PrintMap", helptext = "Print the map")                sensitive = _has_visible_map)
807    _tool_command("map_label_tool", _("&Label"), "LabelTool", "LabelTool",
808                  helptext = _("Add/Remove labels"), icon = "label",
809                  sensitive = _has_visible_map)
810    _method_command("map_full_extent", _("&Full extent"), "FullExtent",
811                   helptext = _("Full Extent"), icon = "fullextent",
812                  sensitive = _has_visible_map)
813    _method_command("layer_full_extent", _("&Full layer extent"), "FullLayerExtent",
814                   helptext = _("Full Layer Extent"), icon = "fulllayerextent",
815                  sensitive = _has_selected_layer)
816    _method_command("selected_full_extent", _("&Full selection extent"), "FullSelectionExtent",
817                   helptext = _("Full Selection Extent"), icon = "fullselextent",
818                  sensitive = _has_selected_shapes)
819    _method_command("map_print", _("Prin&t"), "PrintMap",
820                    helptext = _("Print the map"))
821    _method_command("map_rename", _("&Rename..."), "RenameMap",
822                    helptext = _("Rename the map"))
823    _method_command("layer_add", _("&Add Layer..."), "AddLayer",
824                    helptext = _("Add a new layer to active map"))
825    _method_command("layer_remove", _("&Remove Layer"), "RemoveLayer",
826                    helptext = _("Remove selected layer(s)"),
827                    sensitive = _can_remove_layer)
828    
829  # Layer menu  # Layer menu
830  _method_command("layer_add", "&Add Layer", "AddLayer",  _method_command("layer_projection", _("Pro&jection..."), "LayerProjection",
                 helptext = "Add a new layer to active map")  
 _method_command("layer_remove", "&Remove Layer", "RemoveLayer",  
                 helptext = "Remove selected layer(s)",  
831                  sensitive = _has_selected_layer)                  sensitive = _has_selected_layer)
832  _method_command("layer_fill_color", "&Fill Color", "LayerFillColor",  _method_command("layer_raise", _("&Raise"), "RaiseLayer",
833                  helptext = "Set the fill color of selected layer(s)",                  helptext = _("Raise selected layer(s)"),
834                  sensitive = _has_selected_layer)                  sensitive = _has_selected_layer)
835  _method_command("layer_transparent_fill", "&Transparent Fill",  _method_command("layer_lower", _("&Lower"), "LowerLayer",
836                  "LayerTransparentFill",                  helptext = _("Lower selected layer(s)"),
                 helptext = "Do not fill the selected layer(s)",  
837                  sensitive = _has_selected_layer)                  sensitive = _has_selected_layer)
838  _method_command("layer_outline_color", "&Outline Color", "LayerOutlineColor",  _method_command("layer_show", _("&Show"), "ShowLayer",
839                  helptext = "Set the outline color of selected layer(s)",                  helptext = _("Make selected layer(s) visible"),
840                  sensitive = _has_selected_layer)                  sensitive = _has_selected_layer)
841  _method_command("layer_no_outline", "&No Outline", "LayerNoOutline",  _method_command("layer_hide", _("&Hide"), "HideLayer",
842                  helptext = "Do not draw the outline of the selected layer(s)",                  helptext = _("Make selected layer(s) unvisible"),
843                  sensitive = _has_selected_layer)                  sensitive = _has_selected_layer)
844  _method_command("layer_raise", "&Raise", "RaiseLayer",  _method_command("layer_show_table", _("Show Ta&ble"), "LayerShowTable",
845                  helptext = "Raise selected layer(s)",                  helptext = _("Show the selected layer's table"),
846                  sensitive = _has_selected_layer)                  sensitive = _has_selected_layer)
847  _method_command("layer_lower", "&Lower", "LowerLayer",  _method_command("layer_properties", _("&Properties..."), "LayerEditProperties",
                 helptext = "Lower selected layer(s)",  
848                  sensitive = _has_selected_layer)                  sensitive = _has_selected_layer)
849  _method_command("layer_show", "&Show", "ShowLayer",  _method_command("layer_jointable", _("&Join Table..."), "LayerJoinTable",
                 helptext = "Make selected layer(s) visible",  
850                  sensitive = _has_selected_layer)                  sensitive = _has_selected_layer)
851  _method_command("layer_hide", "&Hide", "HideLayer",  _method_command("layer_unjointable", _("&Unjoin Table..."), "LayerUnjoinTable",
                 helptext = "Make selected layer(s) unvisible",  
                 sensitive = _has_selected_layer)  
 _method_command("layer_show_table", "Show Ta&ble", "LayerShowTable",  
                 helptext = "Show the selected layer's table",  
852                  sensitive = _has_selected_layer)                  sensitive = _has_selected_layer)
853    
854    # Table menu
855    _method_command("table_open", _("&Open..."), "TableOpen")
856    _method_command("table_close", _("&Close"), "TableClose")
857    _method_command("table_show", _("&Show"), "TableShow")
858    _method_command("table_hide", _("&Hide"), "TableHide")
859    _method_command("table_join", _("&Join..."), "TableJoin")
860    
861  # the menu structure  # the menu structure
862  main_menu = Menu("<main>", "<main>",  main_menu = Menu("<main>", "<main>",
863                   [Menu("file", "&File",                   [Menu("file", _("&File"),
864                         ["new_session", "open_session", None,                         ["new_session", "open_session", None,
865                          "save_session", "save_session_as", None,                          "save_session", "save_session_as", None,
866                          "show_session_tree", None,                          "toggle_session_tree", None,
867                          "exit"]),                          "exit"]),
868                    Menu("map", "&Map",                    Menu("map", _("&Map"),
869                         ["layer_add", "layer_remove",                         ["layer_add", "layer_remove", "map_rename",
870                          None,                          None,
871                          "map_projection",                          "map_projection",
872                          None,                          None,
873                          "map_zoom_in_tool", "map_zoom_out_tool",                          "map_zoom_in_tool", "map_zoom_out_tool",
874                          "map_pan_tool", "map_identify_tool", "map_label_tool",                          "map_pan_tool",
875                            "map_full_extent",
876                            "layer_full_extent",
877                            "selected_full_extent",
878                          None,                          None,
879                          "map_full_extent",                          "map_identify_tool", "map_label_tool",
880                          None,                          None,
881                          "map_print"]),                          "toggle_legend",
                   Menu("layer", "&Layer",  
                        ["layer_fill_color", "layer_transparent_fill",  
                         "layer_outline_color", "layer_no_outline",  
882                          None,                          None,
883                          "layer_raise", "layer_lower",                          "map_print"]),
884                      Menu("layer", _("&Layer"),
885                            ["layer_raise", "layer_lower",
886                          None,                          None,
887                          "layer_show", "layer_hide",                          "layer_show", "layer_hide",
888                          None,                          None,
889                          "layer_show_table"]),                          "layer_projection",
890                    Menu("help", "&Help",                          None,
891                            "layer_show_table",
892                            "layer_jointable",
893                            "layer_unjointable",
894                            None,
895                            "layer_properties"]),
896                      Menu("table", _("&Table"),
897                           ["table_open", "table_close",
898                           None,
899                           "table_show", "table_hide",
900                           None,
901                           "table_join"]),
902                      Menu("help", _("&Help"),
903                         ["help_about"])])                         ["help_about"])])
904    
905  # the main toolbar  # the main toolbar
906    
907  main_toolbar = Menu("<toolbar>", "<toolbar>",  main_toolbar = Menu("<toolbar>", "<toolbar>",
908                      ["map_zoom_in_tool", "map_zoom_out_tool", "map_pan_tool",                      ["map_zoom_in_tool", "map_zoom_out_tool", "map_pan_tool",
909                       "map_identify_tool", "map_label_tool", "map_full_extent"])                       "map_full_extent",
910                         "layer_full_extent",
911                         "selected_full_extent",
912                         None,
913                         "map_identify_tool", "map_label_tool"])

Legend:
Removed from v.264  
changed lines
  Added in v.879

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26