/[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 227 by bh, Thu Jul 18 16:27:11 2002 UTC revision 363 by jonathan, Mon Jan 27 11:40:13 2003 UTC
# Line 26  import view Line 26  import view
26  import tree  import tree
27  import proj4dialog  import proj4dialog
28  import tableview, identifyview  import tableview, identifyview
29    import classifier
30  from menu import Menu  from menu import Menu
31    
32  from context import Context  from context import Context
33  from command import registry, Command  from command import registry, Command, ToolCommand
34  from messages import SELECTED_SHAPE, VIEW_POSITION  from messages import SELECTED_SHAPE, VIEW_POSITION
35    
36    
# Line 40  bitmapext = ".xpm" Line 41  bitmapext = ".xpm"
41    
42  class MainWindow(wxFrame):  class MainWindow(wxFrame):
43    
44      def __init__(self, parent, ID, application, interactor):      def __init__(self, parent, ID, title, application, interactor,
45          wxFrame.__init__(self, parent, ID, 'Thuban',                   initial_message = None, size = wxSize(-1, -1)):
46                           wxDefaultPosition, wxSize(400, 300))          wxFrame.__init__(self, parent, ID, title, wxDefaultPosition, size)
47    
48          self.application = application          self.application = application
49          self.interactor = interactor          self.interactor = interactor
50    
51          self.CreateStatusBar()          self.CreateStatusBar()
52          self.SetStatusText("This is the wxPython-based "          if initial_message:
53                        "Graphical User Interface for exploring geographic data")              self.SetStatusText(initial_message)
54    
55          self.identify_view = None          self.identify_view = None
56    
# Line 112  class MainWindow(wxFrame): Line 113  class MainWindow(wxFrame):
113          return menu_bar          return menu_bar
114    
115      def build_menu(self, menudesc):      def build_menu(self, menudesc):
116          """Build and return a wxMenu from a menudescription"""          """Return a wxMenu built from the menu description menudesc"""
117          wxmenu = wxMenu()          wxmenu = wxMenu()
118          last = None          last = None
119          for item in menudesc.items:          for item in menudesc.items:
             # here the items must all be Menu instances themselves  
120              if item is None:              if item is None:
121                  # a separator. Only add one if the last item was not a                  # a separator. Only add one if the last item was not a
122                  # separator                  # separator
# Line 193  class MainWindow(wxFrame): Line 193  class MainWindow(wxFrame):
193              else:              else:
194                  print "Unknown command %s" % name                  print "Unknown command %s" % name
195    
196        def Context(self):
197            """Return the context object for a command invoked from this window
198            """
199            return Context(self.application, self.application.Session(), self)
200    
201      def invoke_command(self, event):      def invoke_command(self, event):
202          name = self.id_to_name.get(event.GetId())          name = self.id_to_name.get(event.GetId())
203          if name is not None:          if name is not None:
204              command = registry.Command(name)              command = registry.Command(name)
205              context = Context(self.application, self.application.Session(),              command.Execute(self.Context())
                               self)  
             command.Execute(context)  
206          else:          else:
207              print "Unknown command ID %d" % event.GetId()              print "Unknown command ID %d" % event.GetId()
208    
209      def update_command_ui(self, event):      def update_command_ui(self, event):
210          #print "update_command_ui", self.id_to_name[event.GetId()]          #print "update_command_ui", self.id_to_name[event.GetId()]
211          context = Context(self.application, self.application.Session(), self)          context = self.Context()
212          command = registry.Command(self.id_to_name[event.GetId()])          command = registry.Command(self.id_to_name[event.GetId()])
213          if command is not None:          if command is not None:
214              event.Enable(command.Sensitive(context))              sensitive = command.Sensitive(context)
215                event.Enable(sensitive)
216                if command.IsTool() and not sensitive and command.Checked(context):
217                    # When a checked tool command is disabled deselect all
218                    # tools. Otherwise the tool would remain active but it
219                    # might lead to errors if the tools stays active. This
220                    # problem occurred in GREAT-ER and this fixes it, but
221                    # it's not clear to me whether this is really the best
222                    # way to do it (BH, 20021206).
223                    self.canvas.SelectTool(None)
224              event.SetText(command.DynText(context))              event.SetText(command.DynText(context))
225              if command.IsCheckCommand():              if command.IsCheckCommand():
226                  event.Check(command.Checked(context))                      event.Check(command.Checked(context))
227    
228      def RunMessageBox(self, title, text, flags = wxOK | wxICON_INFORMATION):      def RunMessageBox(self, title, text, flags = wxOK | wxICON_INFORMATION):
229          """Run a modal message box with the given text, title and flags          """Run a modal message box with the given text, title and flags
230          and return the result"""          and return the result"""
231          dlg = wxMessageDialog(self, text, title, flags)          dlg = wxMessageDialog(self, text, title, flags)
232            dlg.CenterOnParent()
233          result = dlg.ShowModal()          result = dlg.ShowModal()
234          dlg.Destroy()          dlg.Destroy()
235          return result          return result
# Line 248  class MainWindow(wxFrame): Line 261  class MainWindow(wxFrame):
261              text = "(%10.10g, %10.10g)" % pos              text = "(%10.10g, %10.10g)" % pos
262          else:          else:
263              text = ""              text = ""
264            self.set_position_text(text)
265    
266        def set_position_text(self, text):
267            """Set the statusbar text showing the current position.
268    
269            By default the text is shown in field 0 of the status bar.
270            Override this method in derived classes to put it into a
271            different field of the statusbar.
272            """
273          self.SetStatusText(text)          self.SetStatusText(text)
274    
275      def save_modified_session(self, can_veto = 1):      def save_modified_session(self, can_veto = 1):
# Line 306  class MainWindow(wxFrame): Line 328  class MainWindow(wxFrame):
328          if result == wxID_CANCEL:          if result == wxID_CANCEL:
329              event.Veto()              event.Veto()
330          else:          else:
331                # FIXME: it would be better to tie the unsubscription to
332                # wx's destroy event, but that isn't implemented for wxGTK
333                # yet.
334                self.canvas.Unsubscribe(VIEW_POSITION, self.view_position_changed)
335              self.Destroy()              self.Destroy()
336    
337      def SetMap(self, map):      def SetMap(self, map):
338          self.canvas.SetMap(map)          self.canvas.SetMap(map)
339    
340        def Map(self):
341            """Return the map displayed by this mainwindow"""
342            return self.canvas.Map()
343    
344      def ShowSessionTree(self):      def ShowSessionTree(self):
345          name = "session_tree"          name = "session_tree"
346          dialog = self.get_open_dialog(name)          dialog = self.get_open_dialog(name)
# Line 326  class MainWindow(wxFrame): Line 356  class MainWindow(wxFrame):
356          self.RunMessageBox("About",          self.RunMessageBox("About",
357                             ("Thuban is a program for\n"                             ("Thuban is a program for\n"
358                              "exploring geographic data.\n"                              "exploring geographic data.\n"
359                              "Copyright (C) 2001 Intevation GmbH.\n"                              "Copyright (C) 2001, 2002 Intevation GmbH.\n"
360                              "Thuban is licensed under the GPL"),                              "Thuban is licensed under the GPL"),
361                             wxOK | wxICON_INFORMATION)                             wxOK | wxICON_INFORMATION)
362    
# Line 357  class MainWindow(wxFrame): Line 387  class MainWindow(wxFrame):
387          if layer is not None:          if layer is not None:
388              self.canvas.Map().RemoveLayer(layer)              self.canvas.Map().RemoveLayer(layer)
389    
390        def CanRemoveLayer(self):
391            """Return true if the currently selected layer can be deleted.
392    
393            If no layer is selected return false.
394    
395            The return value of this method determines whether the remove
396            layer command is sensitive in menu.
397            """
398            layer = self.current_layer()
399            if layer is not None:
400                return self.canvas.Map().CanRemoveLayer(layer)
401            return 0
402    
403      def RaiseLayer(self):      def RaiseLayer(self):
404          layer = self.current_layer()          layer = self.current_layer()
405          if layer is not None:          if layer is not None:
# Line 435  class MainWindow(wxFrame): Line 478  class MainWindow(wxFrame):
478              name = "table_view" + str(id(table))              name = "table_view" + str(id(table))
479              dialog = self.get_open_dialog(name)              dialog = self.get_open_dialog(name)
480              if dialog is None:              if dialog is None:
481                  dialog = tableview.TableFrame(self, self.interactor, name,                  dialog = tableview.LayerTableFrame(self, self.interactor, name,
482                                                "Table: %s" % layer.Title(),                                                     "Table: %s" % layer.Title(),
483                                                layer, table)                                                     layer, table)
484                  self.add_dialog(name, dialog)                  self.add_dialog(name, dialog)
485                  dialog.Show(true)                  dialog.Show(true)
486              else:              else:
# Line 461  class MainWindow(wxFrame): Line 504  class MainWindow(wxFrame):
504              map.SetProjection(proj)              map.SetProjection(proj)
505          proj4Dlg.Destroy()          proj4Dlg.Destroy()
506    
507        def Classify(self):
508            classifyDlg = classifier.Classifier(NULL, self.current_layer())
509    
510            classifyDlg.ShowModal()
511            classifyDlg.Destroy()
512    
513      def ZoomInTool(self):      def ZoomInTool(self):
514          self.canvas.ZoomInTool()          self.canvas.ZoomInTool()
515    
# Line 511  def _method_command(name, title, method, Line 560  def _method_command(name, title, method,
560                           helptext = helptext, icon = icon,                           helptext = helptext, icon = icon,
561                           sensitive = sensitive))                           sensitive = sensitive))
562    
563  def _tool_command(name, title, method, toolname, helptext = "",  def make_check_current_tool(toolname):
564                    icon = ""):      """Return a function that tests if the currently active tool is toolname
565      """Add a tool command"""  
566        The returned function can be called with the context and returns
567        true iff the currently active tool's name is toolname. It's directly
568        usable as the 'checked' callback of a command.
569        """
570      def check_current_tool(context, name=toolname):      def check_current_tool(context, name=toolname):
571          return context.mainwindow.canvas.CurrentTool() == name          return context.mainwindow.canvas.CurrentTool() == name
572      registry.Add(Command(name, title, call_method, args=(method,),      return check_current_tool
573                           helptext = helptext, icon = icon,  
574                           checked = check_current_tool))  def _tool_command(name, title, method, toolname, helptext = "",
575                      icon = "", sensitive = None):
576        """Add a tool command"""
577        registry.Add(ToolCommand(name, title, call_method, args=(method,),
578                                 helptext = helptext, icon = icon,
579                                 checked = make_check_current_tool(toolname),
580                                 sensitive = sensitive))
581    
582  def _has_selected_layer(context):  def _has_selected_layer(context):
583      """Return true if a layer is selected in the context"""      """Return true if a layer is selected in the context"""
584      return context.mainwindow.has_selected_layer()      return context.mainwindow.has_selected_layer()
585    
586    def _can_remove_layer(context):
587        return context.mainwindow.CanRemoveLayer()
588    
589    def _has_tree_window_shown(context):
590        """Return true if the tree window is shown"""
591        return context.mainwindow.get_open_dialog("session_tree") is None
592    
593    def _has_visible_map(context):
594        """Return true iff theres a visible map in the mainwindow.
595    
596        A visible map is a map with at least one visible layer."""
597        map = context.mainwindow.Map()
598        if map is not None:
599            for layer in map.Layers():
600                if layer.Visible():
601                    return 1
602        return 0
603    
604    
605  # File menu  # File menu
606  _method_command("new_session", "&New Session", "NewSession")  _method_command("new_session", "&New Session", "NewSession")
607  _method_command("open_session", "&Open Session", "OpenSession")  _method_command("open_session", "&Open Session", "OpenSession")
608  _method_command("save_session", "&Save Session", "SaveSession")  _method_command("save_session", "&Save Session", "SaveSession")
609  _method_command("save_session_as", "Save Session &As", "SaveSessionAs")  _method_command("save_session_as", "Save Session &As", "SaveSessionAs")
610  _method_command("show_session_tree", "Show Session &Tree", "ShowSessionTree")  _method_command("show_session_tree", "Show Session &Tree", "ShowSessionTree",
611  _method_command("exit", "&Exit", "Exit")                  sensitive = _has_tree_window_shown)
612    _method_command("exit", "E&xit", "Exit")
613    
614  # Help menu  # Help menu
615  _method_command("help_about", "&About", "About")  _method_command("help_about", "&About", "About")
# Line 539  _method_command("help_about", "&About", Line 618  _method_command("help_about", "&About",
618  # Map menu  # Map menu
619  _method_command("map_projection", "Pro&jection", "Projection")  _method_command("map_projection", "Pro&jection", "Projection")
620    
621    
622  _tool_command("map_zoom_in_tool", "&Zoom in", "ZoomInTool", "ZoomInTool",  _tool_command("map_zoom_in_tool", "&Zoom in", "ZoomInTool", "ZoomInTool",
623                helptext = "Switch to map-mode 'zoom-in'", icon = "zoom_in")                helptext = "Switch to map-mode 'zoom-in'", icon = "zoom_in",
624                  sensitive = _has_visible_map)
625  _tool_command("map_zoom_out_tool", "Zoom &out", "ZoomOutTool", "ZoomOutTool",  _tool_command("map_zoom_out_tool", "Zoom &out", "ZoomOutTool", "ZoomOutTool",
626                helptext = "Switch to map-mode 'zoom-out'", icon = "zoom_out")                helptext = "Switch to map-mode 'zoom-out'", icon = "zoom_out",
627                  sensitive = _has_visible_map)
628  _tool_command("map_pan_tool", "&Pan", "PanTool", "PanTool",  _tool_command("map_pan_tool", "&Pan", "PanTool", "PanTool",
629                helptext = "Switch to map-mode 'pan'", icon = "pan")                helptext = "Switch to map-mode 'pan'", icon = "pan",
630                  sensitive = _has_visible_map)
631  _tool_command("map_identify_tool", "&Identify", "IdentifyTool", "IdentifyTool",  _tool_command("map_identify_tool", "&Identify", "IdentifyTool", "IdentifyTool",
632                helptext = "Switch to map-mode 'identify'", icon = "identify")                helptext = "Switch to map-mode 'identify'", icon = "identify",
633                  sensitive = _has_visible_map)
634  _tool_command("map_label_tool", "&Label", "LabelTool", "LabelTool",  _tool_command("map_label_tool", "&Label", "LabelTool", "LabelTool",
635                helptext = "Add/Remove labels", icon = "label")                helptext = "Add/Remove labels", icon = "label",
636                  sensitive = _has_visible_map)
637  _method_command("map_full_extent", "&Full extent", "FullExtent",  _method_command("map_full_extent", "&Full extent", "FullExtent",
638                 helptext = "Full Extent", icon = "fullextent")                 helptext = "Full Extent", icon = "fullextent",
639                  sensitive = _has_visible_map)
640  _method_command("map_print", "Prin&t", "PrintMap", helptext = "Print the map")  _method_command("map_print", "Prin&t", "PrintMap", helptext = "Print the map")
641    
642  # Layer menu  # Layer menu
# Line 558  _method_command("layer_add", "&Add Layer Line 644  _method_command("layer_add", "&Add Layer
644                  helptext = "Add a new layer to active map")                  helptext = "Add a new layer to active map")
645  _method_command("layer_remove", "&Remove Layer", "RemoveLayer",  _method_command("layer_remove", "&Remove Layer", "RemoveLayer",
646                  helptext = "Remove selected layer(s)",                  helptext = "Remove selected layer(s)",
647                  sensitive = _has_selected_layer)                  sensitive = _can_remove_layer)
648  _method_command("layer_fill_color", "&Fill Color", "LayerFillColor",  _method_command("layer_fill_color", "&Fill Color", "LayerFillColor",
649                  helptext = "Set the fill color of selected layer(s)",                  helptext = "Set the fill color of selected layer(s)",
650                  sensitive = _has_selected_layer)                  sensitive = _has_selected_layer)
# Line 588  _method_command("layer_show_table", "Sho Line 674  _method_command("layer_show_table", "Sho
674                  helptext = "Show the selected layer's table",                  helptext = "Show the selected layer's table",
675                  sensitive = _has_selected_layer)                  sensitive = _has_selected_layer)
676    
677    _method_command("layer_classifier", "Classify", "Classify",
678                    sensitive = _has_selected_layer)
679    
680  # the menu structure  # the menu structure
681  main_menu = Menu("<main>", "<main>",  main_menu = Menu("<main>", "<main>",
# Line 615  main_menu = Menu("<main>", "<main>", Line 703  main_menu = Menu("<main>", "<main>",
703                          None,                          None,
704                          "layer_show", "layer_hide",                          "layer_show", "layer_hide",
705                          None,                          None,
706                          "layer_show_table"]),                          "layer_show_table",
707                            None,
708                            "layer_classifier"]),
709                    Menu("help", "&Help",                    Menu("help", "&Help",
710                         ["help_about"])])                         ["help_about"])])
711    
712  # the main toolbar  # the main toolbar
713    
714  main_toolbar = Menu("<toolbar>", "<toolbar>",  main_toolbar = Menu("<toolbar>", "<toolbar>",
715                      ["map_zoom_in_tool", "map_zoom_out_tool", "map_pan_tool",                      ["map_zoom_in_tool", "map_zoom_out_tool", "map_pan_tool",
716                       "map_identify_tool", "map_label_tool", "map_full_extent"])                       "map_full_extent", None,
717                         "map_identify_tool", "map_label_tool"])

Legend:
Removed from v.227  
changed lines
  Added in v.363

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26