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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 37 - (hide annotations)
Thu Sep 6 17:16:54 2001 UTC (23 years, 6 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/mainwindow.py
File MIME type: text/x-python
File size: 18847 byte(s)
	* Thuban/UI/mainwindow.py (MainWindow.current_layer):
	(MainWindow.has_selected_layer): Simply call the appropriate
	interactor method

	* Thuban/UI/mainwindow.py (MainWindow.__init__):
	(MainWindow.LayerShowTable):
	(MainWindow.identify_view_on_demand): Store the interactor in an
	instvar and use that reference instead of going through main.app

	* Thuban/UI/mainwindow.py (MainWindow.ShowSessionTree):
	* Thuban/UI/application.py (ThubanApplication.OnInit):
	* Thuban/UI/main.py (main): Create the session tree view in main
	with the new mainwindow method ShowSessionTree and not directly
	the application's OnInit method

1 bh 6 # Copyright (C) 2001 by Intevation GmbH
2     # Authors:
3     # Jan-Oliver Wagner <[email protected]>
4     # Bernhard Herzog <[email protected]>
5     #
6     # This program is free software under the GPL (>=v2)
7     # Read the file COPYING coming with Thuban for details.
8    
9     """
10     The main window
11     """
12    
13     __version__ = "$Revision$"
14    
15     import sys, os
16    
17     from wxPython.wx import *
18    
19     import Thuban
20     from Thuban.Model.session import Session
21     from Thuban.Model.map import Map
22     from Thuban.Model.layer import Layer
23     from Thuban.Model.color import Color
24     from Thuban.Model.proj import Projection
25    
26     import view
27     import tree
28     import proj4dialog
29     import tableview, identifyview
30    
31     import main
32     from command import registry, Command
33 bh 31 from messages import SELECTED_SHAPE
34 bh 6
35    
36     # the directory where the toolbar icons are stored
37     bitmapdir = os.path.join(Thuban.__path__[0], os.pardir, "Resources", "Bitmaps")
38     bitmapext = ".xpm"
39    
40    
41     class MainWindow(wxFrame):
42    
43 bh 24 def __init__(self, parent, ID, interactor):
44 bh 6 wxFrame.__init__(self, parent, ID, 'Thuban',
45     wxDefaultPosition, wxSize(400, 300))
46    
47 bh 37 self.interactor = interactor
48    
49 bh 6 self.CreateStatusBar()
50     self.SetStatusText("This is the wxPython-based "
51     "Graphical User Interface for exploring geographic data")
52    
53     self.identify_view = None
54    
55     self.init_ids()
56    
57     menuBar = wxMenuBar()
58    
59     menu = wxMenu()
60     menuBar.Append(menu, "&File");
61     for name in ["new_session", "open_session", None,
62     "save_session", "save_session_as", None,
63     "exit"]:
64     self.add_menu_command(menu, name)
65    
66     menu = wxMenu()
67     menuBar.Append(menu, "&Map");
68     for name in ["map_projection",
69     None,
70     "map_zoom_in_tool", "map_zoom_out_tool", "map_pan_tool",
71     "map_identify_tool", "map_label_tool",
72     None,
73     "map_full_extent",
74     None,
75     "map_print"]:
76     self.add_menu_command(menu, name)
77    
78     menu = wxMenu()
79     menuBar.Append(menu, "&Layer");
80     for name in ["layer_add", "layer_remove",
81     None,
82     "layer_fill_color", "layer_transparent_fill",
83     "layer_ourline_color", "layer_no_outline",
84     None,
85     "layer_raise", "layer_lower",
86     None,
87     "layer_show", "layer_hide",
88     None,
89     "layer_show_table"]:
90     self.add_menu_command(menu, name)
91    
92     menu = wxMenu()
93     menuBar.Append(menu, "&Help");
94     self.add_menu_command(menu, "help_about")
95    
96     self.SetMenuBar(menuBar)
97    
98     # toolbar
99     toolbar = self.CreateToolBar(wxTB_3DBUTTONS)
100     for name in ["map_zoom_in_tool", "map_zoom_out_tool", "map_pan_tool",
101     "map_identify_tool", "map_label_tool"]:
102     self.add_toolbar_command(toolbar, name)
103 bh 13 # call Realize to make sure that the tools appear.
104     toolbar.Realize()
105 bh 6
106     # Create the map canvas
107 bh 24 canvas = view.MapCanvas(self, -1, interactor)
108 bh 6 self.canvas = canvas
109    
110 bh 31 self.init_dialogs()
111    
112     interactor.Subscribe(SELECTED_SHAPE, self.identify_view_on_demand)
113    
114 bh 6 EVT_CLOSE(self, self.OnClose)
115    
116     def init_ids(self):
117     """Initialize the ids"""
118     self.current_id = 6000
119     self.id_to_name = {}
120     self.name_to_id = {}
121    
122     def get_id(self, name):
123     """Return the wxWindows id for the command named name.
124    
125     Create a new one if there isn't one yet"""
126     ID = self.name_to_id.get(name)
127     if ID is None:
128     ID = self.current_id
129     self.current_id = self.current_id + 1
130     self.name_to_id[name] = ID
131     self.id_to_name[ID] = name
132     return ID
133    
134     def add_menu_command(self, menu, name):
135     """Add the command with name name to the menu menu.
136    
137     If name is None, add a separator.
138     """
139     if name is None:
140     menu.AppendSeparator()
141     else:
142     command = registry.Command(name)
143     if command is not None:
144     ID = self.get_id(name)
145     menu.Append(ID, command.Title(), command.HelpText(),
146     command.IsCheckCommand())
147     EVT_MENU(self, ID, self.invoke_command)
148     if command.IsDynamic():
149     EVT_UPDATE_UI(self, ID, self.update_command_ui)
150     else:
151     print "Unknown command %s" % name
152    
153     def add_toolbar_command(self, toolbar, name):
154     """Add the command with name name to the toolbar toolbar.
155    
156     If name is None, add a separator.
157     """
158     # Assume that all toolbar commands are also menu commmands so
159     # that we don't have to add the event handlers here
160     if name is None:
161     toolbar.AddSeparator()
162     else:
163     command = registry.Command(name)
164     if command is not None:
165     ID = self.get_id(name)
166     filename = os.path.join(bitmapdir, command.Icon()) + bitmapext
167     bitmap = wxBitmap(filename, wxBITMAP_TYPE_XPM)
168     toolbar.AddTool(ID, bitmap,
169     shortHelpString = command.HelpText(),
170     isToggle = command.IsCheckCommand())
171     else:
172     print "Unknown command %s" % name
173    
174     def invoke_command(self, event):
175     name = self.id_to_name.get(event.GetId())
176     if name is not None:
177     command = registry.Command(name)
178     command.Execute(self)
179     else:
180     print "Unknown command ID %d" % event.GetId()
181    
182     def update_command_ui(self, event):
183     #print "update_command_ui", self.id_to_name[event.GetId()]
184     command = registry.Command(self.id_to_name[event.GetId()])
185     if command is not None:
186     event.Enable(command.Sensitive(self))
187     event.SetText(command.DynText(self))
188 bh 13 if command.IsCheckCommand():
189     event.Check(command.Checked(self))
190 bh 6
191 bh 20 def RunMessageBox(self, title, text, flags = wxOK | wxICON_INFORMATION):
192     """Run a modla message box with the given text, title and flags
193     and return the result"""
194     dlg = wxMessageDialog(self, text, title, flags)
195     result = dlg.ShowModal()
196     dlg.Destroy()
197     return result
198    
199 bh 31 def init_dialogs(self):
200     """Initialize the dialog handling"""
201     # The mainwindow maintains a dict mapping names to open
202     # non-modal dialogs. The dialogs are put into this dict when
203     # they're created and removed when they're closed
204     self.dialogs = {}
205    
206     def add_dialog(self, name, dialog):
207     if self.dialogs.has_key(name):
208     raise RuntimeError("The Dialog named %s is already open" % name)
209     self.dialogs[name] = dialog
210    
211     def dialog_open(self, name):
212     return self.dialogs.has_key(name)
213    
214     def remove_dialog(self, name):
215     del self.dialogs[name]
216    
217     def get_open_dialog(self, name):
218     return self.dialogs.get(name)
219    
220 bh 6 def NewSession(self):
221     session = Session("")
222     session.AddMap(Map(""))
223     main.app.SetSession(session)
224    
225     def OpenSession(self):
226     dlg = wxFileDialog(self, "Select a session file", ".", "",
227     "*.session", wxOPEN)
228     if dlg.ShowModal() == wxID_OK:
229     main.app.OpenSession(dlg.GetPath())
230     dlg.Destroy()
231    
232     def SaveSession(self):
233     main.app.SaveSession()
234    
235     def SaveSessionAs(self):
236     dlg = wxFileDialog(self, "Enter a filename for session", ".", "",
237     "*.session", wxOPEN)
238     if dlg.ShowModal() == wxID_OK:
239     main.app.session.SetFilename(dlg.GetPath())
240     main.app.SaveSession()
241     dlg.Destroy()
242    
243     def Exit(self):
244     self.Close(false)
245    
246     def OnClose(self, event):
247     veto = 0
248     if main.app.session.WasModified():
249     flags = wxYES_NO | wxICON_QUESTION
250     if event.CanVeto():
251     flags = flags | wxCANCEL
252 bh 20 result = self.RunMessageBox("Exit",
253     ("The session has been modified."
254     " Do you want to save it?"),
255     flags)
256 bh 6 if result == wxID_YES:
257     self.SaveSession()
258     elif result == wxID_CANCEL:
259     veto = 1
260    
261     if veto:
262     event.Veto()
263     else:
264     self.Destroy()
265    
266     def SetMap(self, map):
267     self.canvas.SetMap(map)
268    
269 bh 37 def ShowSessionTree(self):
270     name = "session_tree"
271     dialog = self.get_open_dialog(name)
272     if dialog is None:
273     dialog = tree.SessionTreeView(self, main.app, name)
274     self.add_dialog(name, dialog)
275     dialog.Show(true)
276     else:
277     # FIXME: bring dialog to front here
278     pass
279    
280 bh 6 def About(self):
281 bh 20 self.RunMessageBox("About",
282     ("Thuban is a program for\n"
283     "exploring geographic data.\n"
284     "Copyright (C) 2001 Intevation GmbH.\n"
285     "Thuban is licensed under the GPL"),
286     wxOK | wxICON_INFORMATION)
287 bh 6
288     def AddLayer(self):
289     dlg = wxFileDialog(self, "Select a session file", ".", "", "*.*",
290     wxOPEN)
291     if dlg.ShowModal() == wxID_OK:
292     filename = dlg.GetPath()
293     title = os.path.splitext(os.path.basename(filename))[0]
294     layer = Layer(title, filename)
295 bh 18 map = self.canvas.Map()
296     has_layers = map.HasLayers()
297 bh 20 try:
298     map.AddLayer(layer)
299     except IOError:
300     # the layer couldn't be opened
301     self.RunMessageBox("Add Layer",
302     "Can't open the file '%s'." % filename)
303     else:
304     if not has_layers:
305     # if we're adding a layer to an empty map, for the
306     # new map to the window
307     self.canvas.FitMapToWindow()
308 bh 6 dlg.Destroy()
309    
310     def RemoveLayer(self):
311     layer = self.current_layer()
312     if layer is not None:
313     self.canvas.Map().RemoveLayer(layer)
314    
315     def RaiseLayer(self):
316     layer = self.current_layer()
317     if layer is not None:
318     self.canvas.Map().RaiseLayer(layer)
319    
320     def LowerLayer(self):
321     layer = self.current_layer()
322     if layer is not None:
323     self.canvas.Map().LowerLayer(layer)
324    
325     def current_layer(self):
326     """Return the currently selected layer.
327    
328     If no layer is selected, return None
329     """
330 bh 37 return self.interactor.SelectedLayer()
331 bh 6
332     def has_selected_layer(self):
333     """Return true if a layer is currently selected"""
334 bh 37 return self.interactor.HasSelectedLayer()
335 bh 6
336     def choose_color(self):
337     """Run the color selection dialog and return the selected color.
338    
339     If the user cancels, return None.
340     """
341     dlg = wxColourDialog(self)
342     color = None
343     if dlg.ShowModal() == wxID_OK:
344     data = dlg.GetColourData()
345     wxc = data.GetColour()
346     color = Color(wxc.Red() / 255.0,
347     wxc.Green() / 255.0,
348     wxc.Blue() / 255.0)
349     dlg.Destroy()
350     return color
351    
352     def LayerFillColor(self):
353     layer = self.current_layer()
354     if layer is not None:
355     color = self.choose_color()
356     if color is not None:
357     layer.SetFill(color)
358    
359     def LayerTransparentFill(self):
360     layer = self.current_layer()
361     if layer is not None:
362     layer.SetFill(None)
363    
364     def LayerOutlineColor(self):
365     layer = self.current_layer()
366     if layer is not None:
367     color = self.choose_color()
368     if color is not None:
369     layer.SetStroke(color)
370    
371     def LayerNoOutline(self):
372     layer = self.current_layer()
373     if layer is not None:
374     layer.SetStroke(None)
375    
376     def HideLayer(self):
377     layer = self.current_layer()
378     if layer is not None:
379     layer.SetVisible(0)
380    
381     def ShowLayer(self):
382     layer = self.current_layer()
383     if layer is not None:
384     layer.SetVisible(1)
385    
386     def LayerShowTable(self):
387     layer = self.current_layer()
388     if layer is not None:
389 bh 31 table = layer.table
390     name = "table_view" + str(id(table))
391     dialog = self.get_open_dialog(name)
392     if dialog is None:
393 bh 37 dialog = tableview.TableFrame(self, self.interactor, name,
394 bh 31 "Table: %s" % layer.Title(),
395 bh 33 layer, table)
396 bh 31 self.add_dialog(name, dialog)
397     dialog.Show(true)
398     else:
399     # FIXME: bring dialog to front here
400     pass
401 bh 6
402     def Projection(self):
403     map = self.canvas.Map()
404     proj = map.projection
405     if proj is None:
406     proj4Dlg = proj4dialog.Proj4Dialog(NULL, None)
407     else:
408     proj4Dlg = proj4dialog.Proj4Dialog(NULL, map.projection.params)
409     if proj4Dlg.ShowModal() == wxID_OK:
410     params = proj4Dlg.GetParams()
411     if params is not None:
412     proj = Projection(params)
413     else:
414     proj = None
415     map.SetProjection(proj)
416     proj4Dlg.Destroy()
417    
418     def ZoomInTool(self):
419     self.canvas.ZoomInTool()
420    
421     def ZoomOutTool(self):
422     self.canvas.ZoomOutTool()
423    
424     def PanTool(self):
425     self.canvas.PanTool()
426    
427     def IdentifyTool(self):
428     self.canvas.IdentifyTool()
429    
430     def LabelTool(self):
431     self.canvas.LabelTool()
432    
433     def FullExtent(self):
434     self.canvas.FitMapToWindow()
435    
436     def PrintMap(self):
437     self.canvas.Print()
438    
439 bh 31 def identify_view_on_demand(self, layer, shape):
440     name = "identify_view"
441     if self.canvas.CurrentTool() == "IdentifyTool":
442     if not self.dialog_open(name):
443 bh 37 dialog = identifyview.IdentifyView(self, self.interactor, name)
444 bh 31 self.add_dialog(name, dialog)
445     dialog.Show(true)
446     else:
447 bh 33 # FIXME: bring dialog to front?
448 bh 31 pass
449 bh 6
450     #
451     # Define all the commands available in the main window
452     #
453    
454    
455     # Helper functions to define common command implementations
456     def call_method(context, methodname, *args):
457     """Call the context's method methodname with args *args"""
458     apply(getattr(context, methodname), args)
459    
460     def _method_command(name, title, method, helptext = "", sensitive = None):
461     """Add a command implemented by a method of the context object"""
462     registry.Add(Command(name, title, call_method, args=(method,),
463     helptext = helptext, sensitive = sensitive))
464     def _tool_command(name, title, method, toolname, helptext = "",
465     icon = ""):
466     """Add a tool command"""
467     def check_current_tool(context, name=toolname):
468     return context.canvas.CurrentTool() == name
469     registry.Add(Command(name, title, call_method, args=(method,),
470     helptext = helptext, icon = icon,
471     checked = check_current_tool))
472    
473     def _has_selected_layer(context):
474     """Return true if a layer is selected in the context"""
475     return context.has_selected_layer()
476    
477     # File menu
478     _method_command("new_session", "&New Session", "NewSession")
479     _method_command("open_session", "&Open Session", "OpenSession")
480     _method_command("save_session", "&Save Session", "SaveSession")
481     _method_command("save_session_as", "Save Session &As", "SaveSessionAs")
482     _method_command("exit", "&Exit", "Exit")
483    
484     # Help menu
485     _method_command("help_about", "&About", "About")
486    
487    
488     # Map menu
489     _method_command("map_projection", "Pro&jection", "Projection")
490    
491     _tool_command("map_zoom_in_tool", "&Zoom in", "ZoomInTool", "ZoomInTool",
492     helptext = "Switch to map-mode 'zoom-in'", icon = "zoom_in")
493     _tool_command("map_zoom_out_tool", "Zoom &out", "ZoomOutTool", "ZoomOutTool",
494     helptext = "Switch to map-mode 'zoom-out'", icon = "zoom_out")
495     _tool_command("map_pan_tool", "&Pan", "PanTool", "PanTool",
496     helptext = "Switch to map-mode 'pan'", icon = "pan")
497     _tool_command("map_identify_tool", "&Identify", "IdentifyTool", "IdentifyTool",
498     helptext = "Switch to map-mode 'identify'", icon = "identify")
499     _tool_command("map_label_tool", "&Label", "LabelTool", "LabelTool",
500     helptext = "Add/Remove labels", icon = "label")
501     _method_command("map_full_extent", "&Full extent", "FullExtent")
502     _method_command("map_print", "Prin&t", "PrintMap", helptext = "Print the map")
503    
504     # Layer menu
505     _method_command("layer_add", "&Add", "AddLayer",
506     helptext = "Add a new layer to active map")
507     _method_command("layer_remove", "&Remove", "RemoveLayer",
508     helptext = "Remove selected layer(s)",
509     sensitive = _has_selected_layer)
510     _method_command("layer_fill_color", "&Fill Color", "LayerFillColor",
511     helptext = "Set the fill color of selected layer(s)",
512     sensitive = _has_selected_layer)
513     _method_command("layer_transparent_fill", "&Transparent Fill",
514     "LayerTransparentFill",
515     helptext = "Do not fill the selected layer(s)",
516     sensitive = _has_selected_layer)
517     _method_command("layer_ourline_color", "&Outline Color", "LayerOutlineColor",
518     helptext = "Set the outline color of selected layer(s)",
519     sensitive = _has_selected_layer)
520     _method_command("layer_no_outline", "&No Outline", "LayerNoOutline",
521     helptext = "Do not draw the outline of the selected layer(s)",
522     sensitive = _has_selected_layer)
523     _method_command("layer_raise", "&Raise", "RaiseLayer",
524     helptext = "Raise selected layer(s)",
525     sensitive = _has_selected_layer)
526     _method_command("layer_lower", "&Lower", "LowerLayer",
527     helptext = "Lower selected layer(s)",
528     sensitive = _has_selected_layer)
529     _method_command("layer_show", "&Show", "ShowLayer",
530     helptext = "Make selected layer(s) visible",
531     sensitive = _has_selected_layer)
532     _method_command("layer_hide", "&Hide", "HideLayer",
533     helptext = "Make selected layer(s) unvisible",
534     sensitive = _has_selected_layer)
535     _method_command("layer_show_table", "Show Ta&ble", "LayerShowTable",
536     helptext = "Show the selected layer's table",
537     sensitive = _has_selected_layer)

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26