/[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 6 by bh, Tue Aug 28 15:41:52 2001 UTC revision 181 by bh, Wed May 22 13:42:04 2002 UTC
# Line 1  Line 1 
1  # Copyright (C) 2001 by Intevation GmbH  # Copyright (C) 2001, 2002 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 17  import sys, os Line 17  import sys, os
17  from wxPython.wx import *  from wxPython.wx import *
18    
19  import Thuban  import Thuban
20  from Thuban.Model.session import Session  from Thuban.Model.session import Session, create_empty_session
21  from Thuban.Model.map import Map  from Thuban.Model.map import Map
22  from Thuban.Model.layer import Layer  from Thuban.Model.layer import Layer
23  from Thuban.Model.color import Color  from Thuban.Model.color import Color
# Line 30  import tableview, identifyview Line 30  import tableview, identifyview
30    
31  import main  import main
32  from command import registry, Command  from command import registry, Command
33    from messages import SELECTED_SHAPE, VIEW_POSITION
34    
35    
36  # the directory where the toolbar icons are stored  # the directory where the toolbar icons are stored
# Line 39  bitmapext = ".xpm" Line 40  bitmapext = ".xpm"
40    
41  class MainWindow(wxFrame):  class MainWindow(wxFrame):
42    
43      def __init__(self, parent, ID):      def __init__(self, parent, ID, interactor):
44          wxFrame.__init__(self, parent, ID, 'Thuban',          wxFrame.__init__(self, parent, ID, 'Thuban',
45                           wxDefaultPosition, wxSize(400, 300))                           wxDefaultPosition, wxSize(400, 300))
46    
47            self.interactor = interactor
48    
49          self.CreateStatusBar()          self.CreateStatusBar()
50          self.SetStatusText("This is the wxPython-based "          self.SetStatusText("This is the wxPython-based "
51                        "Graphical User Interface for exploring geographic data")                        "Graphical User Interface for exploring geographic data")
# Line 57  class MainWindow(wxFrame): Line 60  class MainWindow(wxFrame):
60          menuBar.Append(menu, "&File");          menuBar.Append(menu, "&File");
61          for name in ["new_session", "open_session", None,          for name in ["new_session", "open_session", None,
62                       "save_session", "save_session_as", None,                       "save_session", "save_session_as", None,
63                         "show_session_tree", None,
64                       "exit"]:                       "exit"]:
65              self.add_menu_command(menu, name)              self.add_menu_command(menu, name)
66    
67          menu = wxMenu()          menu = wxMenu()
68          menuBar.Append(menu, "&Map");          menuBar.Append(menu, "&Map");
69          for name in ["map_projection",          for name in ["layer_add", "layer_remove",
70                         None,
71                         "map_projection",
72                       None,                       None,
73                       "map_zoom_in_tool", "map_zoom_out_tool", "map_pan_tool",                       "map_zoom_in_tool", "map_zoom_out_tool", "map_pan_tool",
74                       "map_identify_tool", "map_label_tool",                       "map_identify_tool", "map_label_tool",
# Line 74  class MainWindow(wxFrame): Line 80  class MainWindow(wxFrame):
80    
81          menu = wxMenu()          menu = wxMenu()
82          menuBar.Append(menu, "&Layer");          menuBar.Append(menu, "&Layer");
83          for name in ["layer_add", "layer_remove",          for name in ["layer_fill_color", "layer_transparent_fill",
                      None,  
                      "layer_fill_color", "layer_transparent_fill",  
84                       "layer_ourline_color", "layer_no_outline",                       "layer_ourline_color", "layer_no_outline",
85                       None,                       None,
86                       "layer_raise", "layer_lower",                       "layer_raise", "layer_lower",
# Line 94  class MainWindow(wxFrame): Line 98  class MainWindow(wxFrame):
98    
99          # toolbar          # toolbar
100          toolbar = self.CreateToolBar(wxTB_3DBUTTONS)          toolbar = self.CreateToolBar(wxTB_3DBUTTONS)
101    
102            # set the size of the tools' bitmaps. Not needed on wxGTK, but
103            # on Windows. We probably shouldn't hardwire the bitmap size
104            # here
105            toolbar.SetToolBitmapSize(wxSize(24, 24))
106    
107          for name in ["map_zoom_in_tool", "map_zoom_out_tool", "map_pan_tool",          for name in ["map_zoom_in_tool", "map_zoom_out_tool", "map_pan_tool",
108                       "map_identify_tool", "map_label_tool"]:                       "map_identify_tool", "map_label_tool", "map_full_extent"]:
109              self.add_toolbar_command(toolbar, name)              self.add_toolbar_command(toolbar, name)
110            # call Realize to make sure that the tools appear.
111            toolbar.Realize()
112    
113          # Create the map canvas          # Create the map canvas
114          canvas = view.MapCanvas(self, -1)          canvas = view.MapCanvas(self, -1, interactor)
115            canvas.Subscribe(VIEW_POSITION, self.view_position_changed)
116          self.canvas = canvas          self.canvas = canvas
117    
118            self.init_dialogs()
119    
120            interactor.Subscribe(SELECTED_SHAPE, self.identify_view_on_demand)
121    
122          EVT_CLOSE(self, self.OnClose)          EVT_CLOSE(self, self.OnClose)
123    
124      def init_ids(self):      def init_ids(self):
# Line 175  class MainWindow(wxFrame): Line 192  class MainWindow(wxFrame):
192          command = registry.Command(self.id_to_name[event.GetId()])          command = registry.Command(self.id_to_name[event.GetId()])
193          if command is not None:          if command is not None:
194              event.Enable(command.Sensitive(self))              event.Enable(command.Sensitive(self))
             event.Check(command.Checked(self))  
195              event.SetText(command.DynText(self))              event.SetText(command.DynText(self))
196                if command.IsCheckCommand():
197                    event.Check(command.Checked(self))
198    
199        def RunMessageBox(self, title, text, flags = wxOK | wxICON_INFORMATION):
200            """Run a modal message box with the given text, title and flags
201            and return the result"""
202            dlg = wxMessageDialog(self, text, title, flags)
203            result = dlg.ShowModal()
204            dlg.Destroy()
205            return result
206    
207        def init_dialogs(self):
208            """Initialize the dialog handling"""
209            # The mainwindow maintains a dict mapping names to open
210            # non-modal dialogs. The dialogs are put into this dict when
211            # they're created and removed when they're closed
212            self.dialogs = {}
213    
214        def add_dialog(self, name, dialog):
215            if self.dialogs.has_key(name):
216                raise RuntimeError("The Dialog named %s is already open" % name)
217            self.dialogs[name] = dialog
218    
219        def dialog_open(self, name):
220            return self.dialogs.has_key(name)
221    
222        def remove_dialog(self, name):
223            del self.dialogs[name]
224    
225        def get_open_dialog(self, name):
226            return self.dialogs.get(name)
227    
228        def view_position_changed(self):
229            pos = self.canvas.CurrentPosition()
230            if pos is not None:
231                text = "(%10.10g, %10.10g)" % pos
232            else:
233                text = ""
234            self.SetStatusText(text)
235    
236        def save_modified_session(self, can_veto = 1):
237            """If the current session has been modified, ask the user
238            whether to save it and do so if requested. Return the outcome of
239            the dialog (either wxID_OK, wxID_CANCEL or wxID_NO). If the
240            dialog wasn't run return wxID_NO.
241    
242            If the can_veto parameter is true (default) the dialog includes
243            a cancel button, otherwise not.
244            """
245            if main.app.session.WasModified():
246                flags = wxYES_NO | wxICON_QUESTION
247                if can_veto:
248                    flags = flags | wxCANCEL
249                result = self.RunMessageBox("Exit",
250                                            ("The session has been modified."
251                                             " Do you want to save it?"),
252                                            flags)
253                if result == wxID_YES:
254                    self.SaveSession()
255            else:
256                result = wxID_NO
257            return result
258    
259      def NewSession(self):      def NewSession(self):
260          session = Session("")          self.save_modified_session()
261          session.AddMap(Map(""))          main.app.SetSession(create_empty_session())
         main.app.SetSession(session)  
262    
263      def OpenSession(self):      def OpenSession(self):
264            self.save_modified_session()
265          dlg = wxFileDialog(self, "Select a session file", ".", "",          dlg = wxFileDialog(self, "Select a session file", ".", "",
266                             "*.session", wxOPEN)                             "*.thuban", wxOPEN)
267          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
268              main.app.OpenSession(dlg.GetPath())              main.app.OpenSession(dlg.GetPath())
269          dlg.Destroy()          dlg.Destroy()
270    
271      def SaveSession(self):      def SaveSession(self):
272            if main.app.session.filename == None:
273                self.SaveSessionAs()
274          main.app.SaveSession()          main.app.SaveSession()
275    
276      def SaveSessionAs(self):      def SaveSessionAs(self):
277          dlg = wxFileDialog(self, "Enter a filename for session", ".", "",          dlg = wxFileDialog(self, "Enter a filename for session", ".", "",
278                             "*.session", wxOPEN)                             "*.thuban", wxOPEN)
279          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
280              main.app.session.SetFilename(dlg.GetPath())              main.app.session.SetFilename(dlg.GetPath())
281              main.app.SaveSession()              main.app.SaveSession()
# Line 205  class MainWindow(wxFrame): Line 285  class MainWindow(wxFrame):
285          self.Close(false)          self.Close(false)
286    
287      def OnClose(self, event):      def OnClose(self, event):
288          veto = 0          result = self.save_modified_session(can_veto = event.CanVeto())
289          if main.app.session.WasModified():          if result == wxID_CANCEL:
             flags = wxYES_NO | wxICON_QUESTION  
             if event.CanVeto():  
                 flags = flags | wxCANCEL  
             dlg = wxMessageDialog(self,  
                                   ("The session has been modified."  
                                    " Do you want to save it?"),  
                                   "Exit", flags)  
             result = dlg.ShowModal()  
             dlg.Destroy()  
             if result == wxID_YES:  
                 self.SaveSession()  
             elif result == wxID_CANCEL:  
                 veto = 1  
   
         if veto:  
290              event.Veto()              event.Veto()
291          else:          else:
292              self.Destroy()              self.Destroy()
# Line 229  class MainWindow(wxFrame): Line 294  class MainWindow(wxFrame):
294      def SetMap(self, map):      def SetMap(self, map):
295          self.canvas.SetMap(map)          self.canvas.SetMap(map)
296    
297        def ShowSessionTree(self):
298            name = "session_tree"
299            dialog = self.get_open_dialog(name)
300            if dialog is None:
301                dialog = tree.SessionTreeView(self, main.app, name)
302                self.add_dialog(name, dialog)
303                dialog.Show(true)
304            else:
305                # FIXME: bring dialog to front here
306                pass
307    
308      def About(self):      def About(self):
309          dlg = wxMessageDialog(self,          self.RunMessageBox("About",
310                                ("Thuban is a program for\n"                             ("Thuban is a program for\n"
311                                 "exploring geographic data.\n"                              "exploring geographic data.\n"
312                                 "Copyright (C) 2001 Intevation GmbH.\n"                              "Copyright (C) 2001 Intevation GmbH.\n"
313                                 "Thuban is licensed under the GPL"),                              "Thuban is licensed under the GPL"),
314                                "About", wxOK | wxICON_INFORMATION)                             wxOK | wxICON_INFORMATION)
         dlg.ShowModal()  
         dlg.Destroy()  
315    
316      def AddLayer(self):      def AddLayer(self):
317          dlg = wxFileDialog(self, "Select a session file", ".", "", "*.*",          dlg = wxFileDialog(self, "Select a data file", ".", "", "*.*",
318                             wxOPEN)                             wxOPEN)
319          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
320              filename = dlg.GetPath()              filename = dlg.GetPath()
321              title = os.path.splitext(os.path.basename(filename))[0]              title = os.path.splitext(os.path.basename(filename))[0]
322              layer = Layer(title, filename)              layer = Layer(title, filename)
323              self.canvas.Map().AddLayer(layer)              map = self.canvas.Map()
324                has_layers = map.HasLayers()
325                try:
326                    map.AddLayer(layer)
327                except IOError:
328                    # the layer couldn't be opened
329                    self.RunMessageBox("Add Layer",
330                                       "Can't open the file '%s'." % filename)
331                else:
332                    if not has_layers:
333                        # if we're adding a layer to an empty map, for the
334                        # new map to the window
335                        self.canvas.FitMapToWindow()
336          dlg.Destroy()          dlg.Destroy()
337    
338      def RemoveLayer(self):      def RemoveLayer(self):
339          layer = self.current_layer()          layer = self.current_layer()
340          if layer is not None:          if layer is not None:
341              self.canvas.Map().RemoveLayer(layer)              self.canvas.Map().RemoveLayer(layer)
         else:  
             dlg = wxMessageDialog(self, "No layer is selected.\n",  
                                   "Remove layer", wxOK | wxICON_INFORMATION)  
             dlg.ShowModal()  
             dlg.Destroy()  
342    
343      def RaiseLayer(self):      def RaiseLayer(self):
344          layer = self.current_layer()          layer = self.current_layer()
# Line 274  class MainWindow(wxFrame): Line 355  class MainWindow(wxFrame):
355    
356          If no layer is selected, return None          If no layer is selected, return None
357          """          """
358          tree = main.app.tree.tree          return self.interactor.SelectedLayer()
         layer = tree.GetPyData(tree.GetSelection())  
         if isinstance(layer, Layer):  
             return layer  
         return None  
359    
360      def has_selected_layer(self):      def has_selected_layer(self):
361          """Return true if a layer is currently selected"""          """Return true if a layer is currently selected"""
362          tree = main.app.tree.tree          return self.interactor.HasSelectedLayer()
         layer = tree.GetPyData(tree.GetSelection())  
         return isinstance(layer, Layer)  
363    
364      def choose_color(self):      def choose_color(self):
365          """Run the color selection dialog and return the selected color.          """Run the color selection dialog and return the selected color.
# Line 339  class MainWindow(wxFrame): Line 414  class MainWindow(wxFrame):
414      def LayerShowTable(self):      def LayerShowTable(self):
415          layer = self.current_layer()          layer = self.current_layer()
416          if layer is not None:          if layer is not None:
417              tv = tableview.TableFrame(self, layer.table)              table = layer.table
418              tv.Show(true)              name = "table_view" + str(id(table))
419                dialog = self.get_open_dialog(name)
420                if dialog is None:
421                    dialog = tableview.TableFrame(self, self.interactor, name,
422                                                  "Table: %s" % layer.Title(),
423                                                  layer, table)
424                    self.add_dialog(name, dialog)
425                    dialog.Show(true)
426                else:
427                    # FIXME: bring dialog to front here
428                    pass
429    
430      def Projection(self):      def Projection(self):
431          map = self.canvas.Map()          map = self.canvas.Map()
432          proj = map.projection          proj = map.projection
433          if proj is None:          if proj is None:
434              proj4Dlg = proj4dialog.Proj4Dialog(NULL, None)              proj4Dlg = proj4dialog.Proj4Dialog(NULL, None, map.BoundingBox())
435          else:          else:
436              proj4Dlg = proj4dialog.Proj4Dialog(NULL, map.projection.params)              proj4Dlg = proj4dialog.Proj4Dialog(NULL, map.projection.params,
437                                                   map.BoundingBox())
438          if proj4Dlg.ShowModal() == wxID_OK:          if proj4Dlg.ShowModal() == wxID_OK:
439              params = proj4Dlg.GetParams()              params = proj4Dlg.GetParams()
440              if params is not None:              if params is not None:
# Line 368  class MainWindow(wxFrame): Line 454  class MainWindow(wxFrame):
454          self.canvas.PanTool()          self.canvas.PanTool()
455    
456      def IdentifyTool(self):      def IdentifyTool(self):
         if self.identify_view is None:  
             self.identify_view = identifyview.IdentifyView(self, main.app)  
             self.identify_view.Show(true)  
457          self.canvas.IdentifyTool()          self.canvas.IdentifyTool()
458            self.identify_view_on_demand(None, None)
459    
460      def LabelTool(self):      def LabelTool(self):
461          self.canvas.LabelTool()          self.canvas.LabelTool()
# Line 382  class MainWindow(wxFrame): Line 466  class MainWindow(wxFrame):
466      def PrintMap(self):      def PrintMap(self):
467          self.canvas.Print()          self.canvas.Print()
468    
469        def identify_view_on_demand(self, layer, shape):
470            name = "identify_view"
471            if self.canvas.CurrentTool() == "IdentifyTool":
472                if not self.dialog_open(name):
473                    dialog = identifyview.IdentifyView(self, self.interactor, name)
474                    self.add_dialog(name, dialog)
475                    dialog.Show(true)
476                else:
477                    # FIXME: bring dialog to front?
478                    pass
479    
480  #  #
481  # Define all the commands available in the main window  # Define all the commands available in the main window
# Line 393  def call_method(context, methodname, *ar Line 487  def call_method(context, methodname, *ar
487      """Call the context's method methodname with args *args"""      """Call the context's method methodname with args *args"""
488      apply(getattr(context, methodname), args)      apply(getattr(context, methodname), args)
489    
490  def _method_command(name, title, method, helptext = "", sensitive = None):  def _method_command(name, title, method, helptext = "",
491                        icon = "", sensitive = None):
492      """Add a command implemented by a method of the context object"""      """Add a command implemented by a method of the context object"""
493      registry.Add(Command(name, title, call_method, args=(method,),      registry.Add(Command(name, title, call_method, args=(method,),
494                           helptext = helptext, sensitive = sensitive))                           helptext = helptext, icon = icon,
495                             sensitive = sensitive))
496    
497  def _tool_command(name, title, method, toolname, helptext = "",  def _tool_command(name, title, method, toolname, helptext = "",
498                    icon = ""):                    icon = ""):
499      """Add a tool command"""      """Add a tool command"""
# Line 415  _method_command("new_session", "&New Ses Line 512  _method_command("new_session", "&New Ses
512  _method_command("open_session", "&Open Session", "OpenSession")  _method_command("open_session", "&Open Session", "OpenSession")
513  _method_command("save_session", "&Save Session", "SaveSession")  _method_command("save_session", "&Save Session", "SaveSession")
514  _method_command("save_session_as", "Save Session &As", "SaveSessionAs")  _method_command("save_session_as", "Save Session &As", "SaveSessionAs")
515    _method_command("show_session_tree", "Show Session &Tree", "ShowSessionTree")
516  _method_command("exit", "&Exit", "Exit")  _method_command("exit", "&Exit", "Exit")
517    
518  # Help menu  # Help menu
# Line 434  _tool_command("map_identify_tool", "&Ide Line 532  _tool_command("map_identify_tool", "&Ide
532                helptext = "Switch to map-mode 'identify'", icon = "identify")                helptext = "Switch to map-mode 'identify'", icon = "identify")
533  _tool_command("map_label_tool", "&Label", "LabelTool", "LabelTool",  _tool_command("map_label_tool", "&Label", "LabelTool", "LabelTool",
534                helptext = "Add/Remove labels", icon = "label")                helptext = "Add/Remove labels", icon = "label")
535  _method_command("map_full_extent", "&Full extent", "FullExtent")  _method_command("map_full_extent", "&Full extent", "FullExtent",
536                   helptext = "Full Extent", icon = "fullextent")
537  _method_command("map_print", "Prin&t", "PrintMap", helptext = "Print the map")  _method_command("map_print", "Prin&t", "PrintMap", helptext = "Print the map")
538    
539  # Layer menu  # Layer menu
540  _method_command("layer_add", "&Add", "AddLayer",  _method_command("layer_add", "&Add Layer", "AddLayer",
541                  helptext = "Add a new layer to active map")                  helptext = "Add a new layer to active map")
542  _method_command("layer_remove", "&Remove", "RemoveLayer",  _method_command("layer_remove", "&Remove Layer", "RemoveLayer",
543                  helptext = "Remove selected layer(s)",                  helptext = "Remove selected layer(s)",
544                  sensitive = _has_selected_layer)                  sensitive = _has_selected_layer)
545  _method_command("layer_fill_color", "&Fill Color", "LayerFillColor",  _method_command("layer_fill_color", "&Fill Color", "LayerFillColor",

Legend:
Removed from v.6  
changed lines
  Added in v.181

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26