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

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

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

revision 741 by jonathan, Fri Apr 25 09:14:27 2003 UTC revision 1941 by bh, Tue Nov 11 18:27:48 2003 UTC
# Line 1  Line 1 
1  #!/usr/bin/env python  # Copyright (c) 2003 by Intevation GmbH
2  # generated by wxGlade 0.2.1 on Thu Apr 17 11:51:39 2003  # Authors:
3    # Jonathan Coles <[email protected]>
4    # Frank Koormann <[email protected]>
5    # Jan-Oliver Wagner <[email protected]>
6    #
7    # This program is free software under the GPL (>=v2)
8    # Read the file COPYING coming with Thuban for details.
9    
10    """Projection dialog"""
11    
12    __version__ = "$Revision$"
13    # $Source$
14    # $Id$
15    
16  import os, sys  import os
17  from wxPython.wx import *  from wxPython.wx import *
18    
19  from Thuban import _  from Thuban import _
20    
21  from Thuban.Model.proj import Projection, ProjFile  from Thuban.Model.proj import Projection, ProjFile
22    
23  from Thuban.Model.resource import GetUserProjFiles, GetSystemProjFiles, \  from Thuban.Model.resource import get_user_proj_file, get_system_proj_file, \
24                                    ReadProjFile, WriteProjFile                                    read_proj_file, write_proj_file, \
25  from Thuban.UI.dialogs import NonModalDialog                                    DEFAULT_PROJ_FILE, EPSG_PROJ_FILE, \
26                                      EPSG_DEPRECATED_PROJ_FILE
27    from Thuban.UI.dialogs import NonModalNonParentDialog
28    
29    from common import ThubanBeginBusyCursor, ThubanEndBusyCursor
30    from sizers import NotebookLikeSizer
31    from projlist import PROJ_SELECTION_CHANGED, ProjectionList
32    from common import ThubanBeginBusyCursor, ThubanEndBusyCursor
33    
34    
35    
 ID_PROJ_ADVANCED  = 4001  
36  ID_PROJ_PROJCHOICE = 4002  ID_PROJ_PROJCHOICE = 4002
37  ID_PROJ_ADDTOLIST    = 4003  ID_PROJ_ADDTOLIST    = 4003
38  ID_PROJ_NEW       = 4004  ID_PROJ_NEW       = 4004
 ID_PROJ_TRY       = 4005  
39  ID_PROJ_REVERT    = 4006  ID_PROJ_REVERT    = 4006
 ID_PROJ_OK        = 4007  
 ID_PROJ_CLOSE     = 4008  
40  ID_PROJ_AVAIL     = 4009  ID_PROJ_AVAIL     = 4009
41  ID_PROJ_SAVE      = 4010  ID_PROJ_SAVE      = 4010
42  ID_PROJ_IMPORT    = 4011  ID_PROJ_IMPORT    = 4011
# Line 31  ID_PROJ_PROJNAME  = 4014 Line 47  ID_PROJ_PROJNAME  = 4014
47  CLIENT_PROJ = 0  CLIENT_PROJ = 0
48  CLIENT_PROJFILE = 1  CLIENT_PROJFILE = 1
49    
50  class ProjFrame(NonModalDialog):  class ProjFrame(NonModalNonParentDialog):
51    
52      def __init__(self, parent, name, receiver, *args, **kwds):      def __init__(self, parent, name, title, receiver):
53          """Initialize the projection dialog.          """Initialize the projection dialog.
54    
55          receiver -- An object that implements the following methods:          receiver -- An object that implements the following methods:
56                          SetProjection(projection)                          SetProjection(projection)
57                          GetProjection()                          GetProjection()
58          """          """
59                    NonModalNonParentDialog.__init__(self, parent, name, title)
60    
61            self.projection_panel_defs = [
62                ("tmerc", _("Transverse Mercator"), TMPanel),
63                ("utm", _("Universal Transverse Mercator"), UTMPanel),
64                ("lcc", _("Lambert Conic Conformal"), LCCPanel),
65                ("latlong", _("Geographic"), GeoPanel),
66                ("longlat", _("Geographic"), GeoPanel)]#longlat is an alias of proj
67          self.receiver = receiver          self.receiver = receiver
68          self.originalProjection = -1          self.haveTried = False
69          self.curProjPanel = None          self.curProjPanel = None
70            self.__usrProjFile = None
71            self._sys_proj_files = {}
72    
73          self.projPanels = []          self.build_dialog()
74          self.projPanels.append(          self.Layout()
             ("tmerc", _("Transverse Mercator"), TMPanel))  
         self.projPanels.append(  
             ("utm", _("Universal Transverse Mercator"), UTMPanel))  
         self.projPanels.append(  
             ("lcc", _("Lambert Conic Conformal"), LCCPanel))  
         self.projPanels.append(  
             ("latlong", _("Geographic"), GeoPanel))  
   
         NonModalDialog.__init__(self, parent, name, "")  
         # originally generate by wxGlade  
         self.panel_1 = wxPanel(self, -1)  
         self.panel_edit = wxPanel(self, -1)  
         self.panel_buttons = wxPanel(self, -1)  
         self.label_5 = wxStaticText(self.panel_1, -1, _("Available Projections:"))  
         self.availprojs = wxListBox(self.panel_1, ID_PROJ_AVAIL, style=wxLB_EXTENDED |wxLB_SORT)  
         self.projfilepath = wxStaticText(self.panel_1, -1, "")  
         self.label_2 = wxStaticText(self.panel_edit, -1, _("Name:"))  
         self.projname = wxTextCtrl(self.panel_edit, ID_PROJ_PROJNAME, "")  
         self.label_3 = wxStaticText(self.panel_edit, -1, _("Projection:"))  
         self.projchoice = wxChoice(self.panel_edit, ID_PROJ_PROJCHOICE)  
         self.button_import = wxButton(self.panel_1, ID_PROJ_IMPORT, _("Import..."))  
         self.button_export = wxButton(self.panel_1, ID_PROJ_EXPORT, _("Export..."))  
         self.button_remove = wxButton(self.panel_1, ID_PROJ_REMOVE, _("Remove"))  
         self.button_new = wxButton(self.panel_edit, ID_PROJ_NEW, _("New"))  
         self.button_save = wxButton(self.panel_edit, ID_PROJ_SAVE,_("Save"))  
         self.button_add = wxButton(self.panel_edit, ID_PROJ_ADDTOLIST,  
                                       _("Add to List"))  
         self.button_try = wxButton(self.panel_buttons, ID_PROJ_TRY, _("Try"))  
         self.button_revert = wxButton(self.panel_buttons, ID_PROJ_REVERT, _("Revert"))  
         self.button_ok = wxButton(self.panel_buttons, ID_PROJ_OK, _("OK"))  
         self.button_close = wxButton(self.panel_buttons, ID_PROJ_CLOSE, _("Close"))  
   
         self.__set_properties()  
         self.__do_layout()  
         # wxGlade  
75    
76          self.__DoOnProjAvail()          self.originalProjection = self.receiver.GetProjection()
77            
78          EVT_BUTTON(self, ID_PROJ_TRY, self._OnTry)          self.projection_list.SelectProjection(self.originalProjection)
79          EVT_BUTTON(self, ID_PROJ_REVERT, self._OnRevert)          self.projection_list.SetFocus()
80          EVT_BUTTON(self, ID_PROJ_OK, self._OnOK)  
81          EVT_BUTTON(self, ID_PROJ_CLOSE, self._OnClose)      def build_dialog(self):
82          EVT_CHOICE(self, ID_PROJ_PROJCHOICE, self._OnProjChoice)          """Build the dialog's widgets and set the event handlers"""
83          EVT_LISTBOX(self, ID_PROJ_AVAIL, self._OnProjAvail)          self.topBox = top_box = wxBoxSizer(wxVERTICAL)
84    
85            main_box = wxBoxSizer(wxHORIZONTAL)
86            top_box.Add(main_box, 1, wxALL|wxEXPAND)
87    
88            #
89            #    The projection list and associated controls
90            #
91            vbox = wxBoxSizer(wxVERTICAL)
92            main_box.Add(vbox, 4, wxALL|wxEXPAND)
93    
94            #label = wxStaticText(self, -1, _("Available Projections:"))
95            #vbox.Add(label, 0, wxLEFT|wxRIGHT|wxTOP, 4)
96    
97            hbox = wxBoxSizer(wxHORIZONTAL)
98            vbox.Add(hbox, 1, wxALL|wxEXPAND)
99            proj_files = [self.load_user_proj(),
100                          self.load_system_proj(DEFAULT_PROJ_FILE)]
101            self.projection_list = ProjectionList(self, proj_files,
102                                                  self.receiver.GetProjection())
103            hbox.Add(self.projection_list, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)
104            self.projection_list.Subscribe(PROJ_SELECTION_CHANGED,
105                                           self.proj_selection_changed)
106    
107            # Projection List specific actions (Import/Export/Remove)
108            buttons = wxBoxSizer(wxVERTICAL)
109            hbox.Add(buttons, 0, wxALL)
110            self.button_import = wxButton(self, ID_PROJ_IMPORT, _("Import..."))
111          EVT_BUTTON(self, ID_PROJ_IMPORT, self._OnImport)          EVT_BUTTON(self, ID_PROJ_IMPORT, self._OnImport)
112            buttons.Add(self.button_import, 1, wxALL|wxEXPAND, 4)
113            self.button_export = wxButton(self, ID_PROJ_EXPORT, _("Export..."))
114          EVT_BUTTON(self, ID_PROJ_EXPORT, self._OnExport)          EVT_BUTTON(self, ID_PROJ_EXPORT, self._OnExport)
115            buttons.Add(self.button_export, 1, wxALL|wxEXPAND, 4)
116            buttons.Add(20, 20, 0, wxEXPAND, 0)
117            self.button_remove = wxButton(self, ID_PROJ_REMOVE, _("Remove"))
118          EVT_BUTTON(self, ID_PROJ_REMOVE, self._OnRemove)          EVT_BUTTON(self, ID_PROJ_REMOVE, self._OnRemove)
119            buttons.Add(self.button_remove, 1, wxALL|wxEXPAND, 4)
120    
121            buttons.Add(20, 20, 0, wxEXPAND, 0)
122            label = wxStaticText(self, -1, _("Show EPSG:"))
123            buttons.Add(label, 0, wxLEFT|wxRIGHT|wxTOP, 4)
124            self.check_epsg = wxCheckBox(self, -1, _("Normal"))
125            EVT_CHECKBOX(self, self.check_epsg.GetId(), self._OnShowEPSG)
126            buttons.Add(self.check_epsg, 1, wxALL|wxEXPAND, 4)
127            self.check_epsg_depr = wxCheckBox(self, -1, _("Deprecated"))
128            EVT_CHECKBOX(self, self.check_epsg_depr.GetId(), self._OnShowEPSG)
129            buttons.Add(self.check_epsg_depr, 1, wxALL|wxEXPAND, 4)
130    
131            # The file path
132            self.projfilepath = wxStaticText(self, -1, "")
133            vbox.Add(self.projfilepath, 0, wxALL|wxEXPAND)
134    
135            #
136            #   The projection editor part
137            #
138            self.edit_box = wxStaticBox(self, -1, _("Edit"))
139            sizer_edit = wxStaticBoxSizer(self.edit_box, wxHORIZONTAL)
140            main_box.Add(sizer_edit, 5, wxALL|wxEXPAND)
141    
142            # Projection Specific Entries (Name/Projection)
143            self.sizer_projctrls = wxBoxSizer(wxVERTICAL)
144            sizer_edit.Add(self.sizer_projctrls, 1, wxALL|wxEXPAND)
145    
146            hbox = wxBoxSizer(wxHORIZONTAL)
147            self.sizer_projctrls.Add(hbox, 0, wxALL|wxEXPAND)
148            label = wxStaticText(self, -1, _("Name:"))
149            hbox.Add(label, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
150            self.projname = wxTextCtrl(self, ID_PROJ_PROJNAME, "")
151            EVT_TEXT(self, ID_PROJ_PROJNAME, self._OnProjName)
152            hbox.Add(self.projname, 1, wxALL|wxEXPAND, 4)
153    
154            hbox = wxBoxSizer(wxHORIZONTAL)
155            self.sizer_projctrls.Add(hbox, 0, wxALL|wxEXPAND)
156            label = wxStaticText(self, -1, _("Projection:"))
157            hbox.Add(label, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
158            self.projchoice = wxChoice(self, ID_PROJ_PROJCHOICE)
159            self.projchoice.SetSelection(0)
160            EVT_CHOICE(self, ID_PROJ_PROJCHOICE, self._OnProjChoice)
161            hbox.Add(self.projchoice, 1, wxALL|wxEXPAND, 4)
162            # Fill the projection choice list.
163            self.nbsizer = NotebookLikeSizer()
164            self.sizer_projctrls.Add(self.nbsizer, 1,
165                                     wxALL|wxEXPAND|wxADJUST_MINSIZE, 3)
166            self.projection_panels = []
167            self.projchoice.Append(_("<Unknown>"), "")
168            for proj_type, name, cls in self.projection_panel_defs:
169                self.projchoice.Append(name, proj_type)
170                panel = cls(self, self.receiver)
171                panel.Hide()
172                panel.projection_index = len(self.projection_panels)
173                panel.projection_type = proj_type
174                self.projection_panels.append(panel)
175                self.nbsizer.Add(panel)
176            self.unknown_projection_panel = UnknownProjPanel(self, self.receiver)
177            self.unknown_projection_panel.Hide()
178            self.nbsizer.Add(self.unknown_projection_panel)
179    
180            # Projection Specific actions (New/Save/Add)
181            buttons = wxBoxSizer(wxVERTICAL)
182            sizer_edit.Add(buttons, 0, wxALL)
183            self.button_new = wxButton(self, ID_PROJ_NEW, _("New"))
184          EVT_BUTTON(self, ID_PROJ_NEW, self._OnNew)          EVT_BUTTON(self, ID_PROJ_NEW, self._OnNew)
185          EVT_BUTTON(self, ID_PROJ_SAVE, self._OnSave)          buttons.Add(self.button_new, 0, wxEXPAND|wxALL, 4)
186            self.button_add = wxButton(self, ID_PROJ_ADDTOLIST, _("Add to List"))
187          EVT_BUTTON(self, ID_PROJ_ADDTOLIST, self._OnAddToList)          EVT_BUTTON(self, ID_PROJ_ADDTOLIST, self._OnAddToList)
188            buttons.Add(self.button_add, 0, wxEXPAND|wxALL, 4)
189            buttons.Add(20, 20, 0, wxEXPAND, 0)
190            self.button_save = wxButton(self, ID_PROJ_SAVE,_("Update"))
191            EVT_BUTTON(self, ID_PROJ_SAVE, self._OnSave)
192            buttons.Add(self.button_save, 0, wxEXPAND|wxALL|wxALIGN_BOTTOM, 4)
193    
194          EVT_TEXT(self, ID_PROJ_PROJNAME, self._OnProjName)          #
195            # Main Action buttons (Try/Revert/OK/Close)
196            #
197            buttons = wxBoxSizer(wxHORIZONTAL)
198            top_box.Add(buttons, 0, wxALL|wxALIGN_RIGHT, 10)
199            self.button_try = wxButton(self, wxID_APPLY, _("Try"))
200            EVT_BUTTON(self, wxID_APPLY, self.OnApply)
201            buttons.Add(self.button_try, 0, wxRIGHT, 10)
202            self.button_revert = wxButton(self, ID_PROJ_REVERT, _("Revert"))
203            EVT_BUTTON(self, ID_PROJ_REVERT, self._OnRevert)
204            buttons.Add(self.button_revert, 0, wxRIGHT, 10)
205            self.button_ok = wxButton(self, wxID_OK, _("OK"))
206            EVT_BUTTON(self, wxID_OK, self.OnOK)
207            self.button_ok.SetDefault()
208            buttons.Add(self.button_ok, 0, wxRIGHT, 10)
209            self.button_close = wxButton(self, wxID_CANCEL, _("Close"))
210            EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
211            buttons.Add(self.button_close, 0, wxRIGHT, 10)
212    
     def GetReceiver(self):  
         return self.receiver  
213    
214      def _OnTry(self, event):          #
215          self.__SetProjection()          # Automatic Layout
216            #
217            self.SetAutoLayout(1)
218            self.SetSizer(top_box)
219            top_box.Fit(self)
220            top_box.SetSizeHints(self)
221    
222        def OnClose(self, event):
223            self.projection_list.Unsubscribe(PROJ_SELECTION_CHANGED,
224                                             self.proj_selection_changed)
225            # Destroy the projection list explicitly so that it properly
226            # unsubscribes everything. It would be cleaner if the projection
227            # could do this by itself but wx doesn't always send destroy
228            # events for non-top-level widgets
229            self.projection_list.Destroy()
230            NonModalNonParentDialog.OnClose(self, event)
231    
232      def _OnRevert(self, event):      def OnApply(self, event):
233          if self.originalProjection != -1:          self.__SetProjection()
234              self.receiver.SetProjection(self.originalProjection)          self.haveTried = True
235    
236      def _OnOK(self, event):      def OnOK(self, event):
237          self.__SetProjection()          self.__SetProjection()
238          self.Close()          self.Close()
239    
240      def _OnClose(self, event):      def OnCancel(self, event):
241            """Cancel just closes the dialog, but we call it cancel so we
242            can overload the functionality of wxDialog.
243            """
244          self.Close()          self.Close()
245    
246        def _OnRevert(self, event):
247            if self.haveTried:
248                self.receiver.SetProjection(self.originalProjection)
249                self.haveTried = False
250    
251      def _OnNew(self, event):      def _OnNew(self, event):
252          self.__DoOnNew()  
253            self.projection_list.ClearSelection()
254            self.projname.Clear()
255    
256            # supply a projection panel if there wasn't one
257            if self.curProjPanel is None:
258                self.projchoice.SetSelection(0)
259                self.__DoOnProjChoice()
260    
261            if self.curProjPanel is not None:
262                self.curProjPanel.Clear()
263    
264      def _OnSave(self, event):      def _OnSave(self, event):
265    
266          sel = self.availprojs.GetSelections()          sel = self.projection_list.selected_projections()
267          assert len(sel) == 1,  "button shouldn't be enabled"          assert len(sel) == 1,  "button shouldn't be enabled"
268    
269          proj, projfile = self.availprojs.GetClientData(sel[0])          proj, projfile = sel[0]
270    
271          assert proj is not None and projfile is not None          assert proj is not None and projfile is not None
272    
273          newproj = self.__GetProjection()          newproj = self.__GetProjection()
274    
275          if newproj is not None:          if newproj is not None:
276              projfile.Remove(proj)              # FIXME: we should only allow this for the user proj file.
277              projfile.Add(newproj)              projfile.Replace(proj, newproj)
278              try:              self.write_proj_file(projfile)
279                  WriteProjFile(projfile)              self.projection_list.SelectProjection(newproj)
             except IOError, (errno, errstr):  
                 wxMessageDialog(self,  
                     _("The following error occured:\n") +  
                     projfile.GetFilename() + "\n" + errstr,  
                     _("Error"), wxOK | wxICON_ERROR).ShowModal()  
             self.__FillAvailList()  
280    
281      def _OnAddToList(self, event):      def _OnAddToList(self, event):
282    
283          proj = self.__GetProjection()          proj = self.__GetProjection()
284          if proj is not None:          if proj is not None:
285              self.__usrProjFile.Add(proj)              self.__usrProjFile.Add(proj)
286              try:              self.write_proj_file(self.__usrProjFile)
287                  WriteProjFile(self.__usrProjFile)              self.projection_list.SelectProjection(proj)
             except IOError, (errno, errstr):  
                 wxMessageDialog(self,  
                     _("The following error occured:\n") +  
                     self.__usrProjFile.GetFilename() + "\n" + errstr,  
                     _("Error"), wxOK | wxICON_ERROR).ShowModal()  
             self.__FillAvailList()  
288    
289      def _OnProjAvail(self, event):      def show_warnings(self, title, filename, warnings):
290          self.__DoOnProjAvail()          """Show the warnings (a list of strings) in a dialog
291    
292            If the list is empty no dialog will be shown.
293            """
294            if warnings:
295                text = (_('Warnings when reading "%s":\n\n%s')
296                        % (filename, "\n\n".join(warnings)))
297                self.parent.RunMessageBox(title, text)
298    
299      def _OnImport(self, event):      def _OnImport(self, event):
300            """Handler for the 'Import' button
301    
302            Ask the user for a filename, read the projections from that file
303            add them to the user ProjFile object and write the user file
304            back to disk.
305            """
306          dlg = wxFileDialog(self, _("Import"), style = wxOPEN)          dlg = wxFileDialog(self, _("Import"), style = wxOPEN)
307    
308          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
309              path = dlg.GetPath()              path = dlg.GetPath()
310    
311                ThubanBeginBusyCursor()
312              try:              try:
313                  projFile = ReadProjFile(path)                  try:
314                  for proj in projFile.GetProjections():                      projFile, warnings = read_proj_file(path)
315                      self.__usrProjFile.Add(proj)                  except IOError, (errno, errstr):
316                  WriteProjFile(self.__usrProjFile)                      self.__ShowError(dlg.GetPath(), errstr)
317              except IOError, (errno, errstr):                  else:
318                  wxMessageDialog(self,                      self.show_warnings(_("Warnings"), path, warnings)
319                      _("The following error occured:\n") +                      for proj in projFile.GetProjections():
320                      dlg.GetPath() + "\n" + errstr,                          self.__usrProjFile.Add(proj)
321                      _("Error"), wxOK | wxICON_ERROR).ShowModal()                      self.write_proj_file(self.__usrProjFile)
322                finally:
323              self.__FillAvailList()                  ThubanEndBusyCursor()
   
324          dlg.Destroy()          dlg.Destroy()
325    
326      def _OnExport(self, event):      def _OnExport(self, event):
327            """Handler for the 'Export' button.
328    
329          sel = self.availprojs.GetSelections()          Ask the user for a filename and write the selected projections
330            to that file.
331            """
332            sel = self.projection_list.selected_projections()
333          assert len(sel) != 0, "button should be disabled"          assert len(sel) != 0, "button should be disabled"
334    
335          dlg = wxFileDialog(self, _("Export"),          dlg = wxFileDialog(self, _("Export"), style=wxSAVE|wxOVERWRITE_PROMPT)
                         style = wxSAVE|wxOVERWRITE_PROMPT)  
336    
337          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
338              path = dlg.GetPath()              proj_file = ProjFile(dlg.GetPath())
339                for proj, pf in sel:
             projFile = ProjFile(path)  
   
             for i in sel:  
                 proj = self.availprojs.GetClientData(i)[CLIENT_PROJ]  
340                  if proj is not None:                  if proj is not None:
341                      projFile.Add(proj)                      proj_file.Add(proj)
342                self.write_proj_file(proj_file)
             try:  
                 WriteProjFile(projFile)  
             except IOError, (errno, errstr):  
                 wxMessageDialog(self,  
                     _("The following error occured:\n") +  
                     dlg.GetPath() + "\n" + errstr,  
                     _("Error"), wxOK | wxICON_ERROR).ShowModal()  
343    
344          dlg.Destroy()          dlg.Destroy()
345    
346      def _OnRemove(self, event):      def _OnRemove(self, event):
347            """Handler for the 'Remove' button
348    
349          sel = self.availprojs.GetSelections()          Remove any selected projection that came from the user's
350            ProjFile. If the user ProjFile was modified write it back to
351            disk.
352            """
353            sel = self.projection_list.selected_projections()
354          assert len(sel) != 0, "button should be disabled!"          assert len(sel) != 0, "button should be disabled!"
355    
356          #          modified = False
357          # remove the items backwards so the indices don't change          for proj, pf in sel:
358          #              if proj is not None and pf is self.__usrProjFile:
359          sel = list(sel)                  pf.Remove(proj)
360          sel.sort()                  modified = True
         sel.reverse()  
361    
362          newselection = -1          if modified:
363          if len(sel) == 1:              self.write_proj_file(self.__usrProjFile)
             newselection = sel[0] - 1  
             if newselection < 0:  
                 newselection = 0  
   
         for i in sel:  
             proj, projfile = self.availprojs.GetClientData(i)  
   
             #  
             # this could be the case if they selected <None> or  
             # the currently used projection  
             #  
             if proj is not None and projfile is not None:  
                 projfile.Remove(proj)  
364    
365          try:      def _OnShowEPSG(self, event):
366              WriteProjFile(projfile)          """Handler for the EVT_CHECKBOX events from the EPSG check button
         except IOError, (errno, errstr):  
             wxMessageDialog(self,  
                 _("The following error occured:\n") +  
                 projfile.GetFilename() + "\n" + errstr,  
                 _("Error"), wxOK | wxICON_ERROR).ShowModal()  
367    
368            If the button is checked add the EPSG_PROJ_FILE to the list of
369          self.__FillAvailList()          projfiles shown by the projection list. Otherwise remove it
370            """
371          #          proj_files = [self.load_user_proj(),
372          # this *could* produce incorrect results if the .proj files                        self.load_system_proj(DEFAULT_PROJ_FILE)]
373          # change between the last list update and this selection          if self.check_epsg.IsChecked():
374          # because the list has been repopulated.              proj_files.append(self.load_system_proj(EPSG_PROJ_FILE))
375          #          if self.check_epsg_depr.IsChecked():
376          if newselection != -1 and self.availprojs.GetCount() > 0:              proj_files.append(self.load_system_proj(EPSG_DEPRECATED_PROJ_FILE))
377              self.availprojs.SetSelection(newselection)          self.projection_list.SetProjFiles(proj_files)
378    
379      def _OnProjName(self, event):      def _OnProjName(self, event):
380          self.__VerifyButtons()          self.__VerifyButtons()
381    
382        def __ShowError(self, filename, errstr):
383            wxMessageDialog(self,
384                _("The following error occured:\n") +
385                filename + "\n" + errstr,
386                _("Error"), wxOK | wxICON_ERROR).ShowModal()
387    
388      def __VerifyButtons(self):      def __VerifyButtons(self):
389          sel = self.availprojs.GetSelections()          """Update button sensitivity"""
390    
391            num_sel = self.projection_list.GetSelectedItemCount()
392    
393          self.button_import.Enable(True)          self.button_import.Enable(True)
394          self.button_export.Enable(True)          self.button_export.Enable(True)
395          self.button_save.Enable(True)          self.button_save.Enable(True)
396          self.button_remove.Enable(True)          self.button_remove.Enable(True)
397    
398          self.panel_edit.Enable(True)          self.edit_box.Enable(True)
399    
400            for ctrl in [self.button_import,
401                         self.button_export,
402                         self.button_remove,
403                         self.button_save,
404                         self.button_add,
405                         self.projchoice,
406                         self.projname,
407                         self.edit_box]:
408                ctrl.Enable(True)
409    
410            if self.curProjPanel is not None:
411                self.curProjPanel.Enable(True)
412    
413          if len(sel) == 0:          if num_sel == 0:
414              self.button_import.Enable(True)              self.button_import.Enable(True)
415              self.button_export.Enable(False)              self.button_export.Enable(False)
416              self.button_remove.Enable(False)              self.button_remove.Enable(False)
417                self.button_save.Enable(False)
418    
419          elif len(sel) == 1:          elif num_sel == 1:
420    
421              proj, projFile = self.availprojs.GetClientData(sel[0])              selection = self.projection_list.selected_projections()
422                proj, projFile = selection[0]
423    
424              self.button_save.Enable(len(self.projname.GetValue()) > 0)              self.button_save.Enable(len(self.projname.GetValue()) > 0)
425              self.button_add.Enable(len(self.projname.GetValue()) > 0)              self.button_add.Enable(len(self.projname.GetValue()) > 0)
426    
427              if proj is None:              if proj is None:
428                  self.button_export.Enable(False)                  # <None> is selected
429                    for ctrl in [self.button_export,
430                                 self.button_remove,
431                                 self.button_save,
432                                 self.button_add,
433                                 self.projchoice,
434                                 self.projname]:
435                        ctrl.Enable(False)
436    
437                    if self.curProjPanel is not None:
438                        self.curProjPanel.Enable(False)
439    
440                elif proj is self.originalProjection:
441                  self.button_remove.Enable(False)                  self.button_remove.Enable(False)
442    
443              if projFile is None:              if projFile is None:
444                  self.button_save.Enable(False)                  self.button_save.Enable(False)
445    
446          else:          else:
447              self.panel_edit.Enable(False)              self.edit_box.Enable(False)
   
     def __DoOnNew(self):  
         sel = self.availprojs.GetSelections()  
         if len(sel) != 0:  
             self.availprojs.SetSelection(sel, False)  
         self.projname.Clear()  
         self.curProjPanel.Clear()  
   
     def __DoOnProjAvail(self):  
448    
449          sel = self.availprojs.GetSelections()      def proj_selection_changed(self, projs):
450          if len(sel) == 1:          """Subscribed to the projection_list's PROJ_SELECTION_CHANGED message
   
             proj = self.availprojs.GetClientData(sel[0])[CLIENT_PROJ]  
             projfile = self.availprojs.GetClientData(sel[0])[CLIENT_PROJFILE]  
451    
452            Update the dialog to reflect the new selection.
453            """
454            if len(projs) == 0:
455                self.projfilepath.SetLabel(_("No Projections selected"))
456            elif len(projs) == 1:
457                proj, projfile = projs[0]
458              if proj is None:              if proj is None:
459                  # user selected <None>                  # user selected <None>
460                  self.projname.Clear()                  self.projname.Clear()
461                    self.projfilepath.SetLabel("")
462              else:              else:
               
463                  if projfile is not None:                  if projfile is not None:
464                      self.projfilepath.SetLabel(projfile.GetFilename())                      filename = os.path.basename(projfile.GetFilename())
465                        self.projfilepath.SetLabel(_("Source of Projection: %s")
466                                                   % filename)
467                  else:                  else:
468                      # only None if the currently used projection is selected                      # only None if the currently used projection is selected
469                      self.projfilepath.SetLabel("")                      self.projfilepath.SetLabel("")
470    
471                  self.projname.SetValue(proj.GetName())                  self.projname.SetValue(proj.Label())
472    
473                  myProjType = proj.GetParameter("proj")                  myProjType = proj.GetParameter("proj")
474                  i = 0                  i = 0
475                  for projType, name, clazz in self.projPanels:                  for projType, name, cls in self.projection_panel_defs:
476                      if myProjType == projType:                      if myProjType == projType:
477                          self.projchoice.SetSelection(i)                          self.projchoice.Enable(True)
478                            self.projchoice.SetSelection(i + 1)
479                          self.__DoOnProjChoice()                          self.__DoOnProjChoice()
480    
481                            #
482                            # self.curProjPanel should not be null
483                            # after a call to __DoOnProjChoice
484                            #
485                            assert self.curProjPanel is not None
486    
487                          self.curProjPanel.SetProjection(proj)                          self.curProjPanel.SetProjection(proj)
488                            break
489                      i += 1                      i += 1
490                    else:
491                        self.projchoice.Select(0)
492                        self.projchoice.Disable()
493                        self._show_proj_panel(UnknownProjPanel)
494                        assert self.curProjPanel is not None
495                        self.curProjPanel.SetProjection(proj)
496            else:
497                self.projfilepath.SetLabel(_("Multiple Projections selected"))
498    
499          self.__VerifyButtons()          self.__VerifyButtons()
500    
# Line 336  class ProjFrame(NonModalDialog): Line 502  class ProjFrame(NonModalDialog):
502          self.__DoOnProjChoice()          self.__DoOnProjChoice()
503    
504      def __DoOnProjChoice(self):      def __DoOnProjChoice(self):
505            """Create and layout a projection panel based on the selected
506            projection type.
507    
508            This is necessary to have in seperate method since calls to
509            wxChoice.SetSelection() do not trigger an event.
510    
511            At the end of this method self.curProjPanel will not be None
512            if there was a item selected.
513            """
514          choice = self.projchoice          choice = self.projchoice
515    
516          sel = choice.GetSelection()          sel = choice.GetSelection()
517          if sel != -1:          if sel != -1:
518                proj_type = choice.GetClientData(sel)
519              clazz, obj = choice.GetClientData(sel)              for t, name, cls in self.projection_panel_defs:
520                    if t == proj_type:
521              if obj is None:                      self._show_proj_panel(cls)
522                  obj = clazz(self.panel_edit, self.receiver)                      break
523                  choice.SetClientData(sel, [clazz, obj])          # FIXME: what to do if sel == -1?
524    
525              if self.curProjPanel is not None:      def _show_proj_panel(self, panel_class):
526                  self.curProjPanel.Hide()          """Show the panel as the projection panel"""
527                  self.sizer_projctrls.Remove(self.curProjPanel)          if panel_class is UnknownProjPanel:
528                self.edit_box.Disable()
529              self.curProjPanel = obj              self.nbsizer.Activate(self.unknown_projection_panel)
530              self.curProjPanel.Show()              self.curProjPanel = self.unknown_projection_panel
531            else:
532              self.sizer_projctrls.Add(self.curProjPanel, 1,              self.edit_box.Enable(True)
533                  wxALL|wxEXPAND|wxADJUST_MINSIZE, 3)              self.unknown_projection_panel.Hide()
534              self.sizer_projctrls.Layout()              for panel in self.projection_panels:
535              self.Layout()                  if panel.__class__ is panel_class:
536              self.topBox.SetSizeHints(self)                      self.nbsizer.Activate(panel)
537                        self.curProjPanel = panel
538    
539      def __SetProjection(self):      def __SetProjection(self):
540            """Set the receiver's projection."""
541    
542          #          #
543          # save the original projection only once in case          # save the original projection only once in case
544          # we try to apply several different projections          # we try to apply several different projections
545          #          #
         if self.originalProjection == -1:  
             self.originalProjection = self.receiver.GetProjection()  
   
546          self.receiver.SetProjection(self.__GetProjection())          self.receiver.SetProjection(self.__GetProjection())
547    
548      def __GetProjection(self):      def __GetProjection(self):
549          """Return the packaged projection.          """Return a suitable Projection object based on the current
550            state of the dialog box selections.
551    
552          Could be None.          Could be None.
553          """          """
554    
555          proj = None          assert self.projection_list.GetSelectedItemCount() < 2, \
556                   "button should be disabled"
         if self.curProjPanel is not None:  
             proj = Projection(self.curProjPanel.GetParameters())  
             proj.SetName(self.projname.GetValue())  
   
         return proj  
   
     def __FillAvailList(self):  
         self.availprojs.Clear()  
   
         #  
         # the list can never be empty. there will always be  
         # at least this one item  
         #  
         self.availprojs.Append("<None>", (None, None))  
   
         self.__sysProjFile = None  
         self.__usrProjFile = None  
   
         projfile = GetSystemProjFiles()  
         if len(projfile) > 0:  
             projfile = projfile[0]  
             for proj in projfile.GetProjections():  
                 self.availprojs.Append(proj.GetName(), [proj, projfile])  
             self.__sysProjFile = projfile  
   
         projfile = GetUserProjFiles()  
         if len(projfile) > 0:  
             projfile = projfile[0]  
             for proj in projfile.GetProjections():  
                 self.availprojs.Append(proj.GetName(), [proj, projfile])  
             self.__usrProjFile = projfile  
   
 #       projfiles = GetSystemProjFiles()  
 #       for projfile in projfiles:  
 #           for proj in projfile.GetProjections():  
 #               self.availprojs.Append(proj.GetName(), [proj, projfile])  
 #       self.__sysProjFiles = projfiles  
   
 #       projfiles = GetUserProjFiles()  
 #       for projfile in projfiles:  
 #           for proj in projfile.GetProjections():  
 #               self.availprojs.Append(proj.GetName(), [proj, projfile])  
 #       self.__usrProjFiles = projfiles  
557    
558          proj = self.receiver.GetProjection()          sel = self.projection_list.selected_projections()
559          if proj is not None:          if len(sel) == 1:
560              self.availprojs.Append(_("%s (current)") % proj.GetName(),              if sel[0][0] is None:
561                                     [proj, None])                  # <None> is selected
562                    return None
563    
564          for proj, name, clazz in self.projPanels:          # self.curProjPanel should always contain the most relevant data
565              self.projchoice.Append(name, [clazz, None])          # for a projection
566            if self.curProjPanel is not None:
567                return Projection(self.curProjPanel.GetParameters(),
568                                  self.projname.GetValue())
569    
570      def __set_properties(self):          return None
         self.__FillAvailList()  
571    
572          # begin wxGlade: ProjFrame.__set_properties      def load_user_proj(self):
573          self.SetTitle(_("Projections"))          """Return the user's ProjFile
         self.availprojs.SetSelection(0)  
         self.projchoice.SetSelection(0)  
         # end wxGlade  
574    
575          self.projname.SetMaxLength(32)          If the file has not yet been loaded by the dialog, load it first
576            with get_user_proj_file and cache it in self.__usrProjFile.
577    
578      def __do_layout(self):          Show a busy cursor while loading the file.
579          # originally generated by wxGlade          """
580            if self.__usrProjFile is None:
581                ThubanBeginBusyCursor()
582                try:
583                    projfile, warnings = get_user_proj_file()
584                    self.show_warnings(_("Warnings"), projfile.GetFilename(),
585                                       warnings)
586                    self.__usrProjFile = projfile
587                finally:
588                    ThubanEndBusyCursor()
589            return self.__usrProjFile
590    
591        def load_system_proj(self, name):
592            """Load the system ProjFile with the given name.
593    
594            If the file has not been loaded yet, load it first with
595            get_system_proj_file and put it into the cache. The name is
596            simply forwarded to get_system_proj_file.
597    
598          self.topBox = wxBoxSizer(wxVERTICAL)          Show a busy cursor while loading the file.
599          self.sizer_panel = wxBoxSizer(wxVERTICAL)          """
600          sizer_6 = wxBoxSizer(wxHORIZONTAL)          if name not in self._sys_proj_files:
601          self.sizer_mainctrls = wxBoxSizer(wxHORIZONTAL)              ThubanBeginBusyCursor()
602          self.sizer_edit = wxStaticBoxSizer(wxStaticBox(self.panel_edit, -1, _("Edit")), wxHORIZONTAL)              try:
603          sizer_11 = wxBoxSizer(wxVERTICAL)                  projfile, warnings = get_system_proj_file(name)
604          self.sizer_projctrls = wxBoxSizer(wxVERTICAL)                  self.show_warnings(_("Warnings"), projfile.GetFilename(),
605          sizer_14 = wxBoxSizer(wxHORIZONTAL)                                     warnings)
606          sizer_13 = wxBoxSizer(wxHORIZONTAL)                  self._sys_proj_files[name] = projfile
607          sizer_15 = wxBoxSizer(wxVERTICAL)              finally:
608          sizer_15.Add(self.button_import, 0, wxALL, 4)                  ThubanEndBusyCursor()
609          sizer_15.Add(self.button_export, 0, wxALL, 4)          return self._sys_proj_files[name]
         sizer_15.Add(20, 20, 0, wxEXPAND, 0)  
         sizer_15.Add(self.button_remove, 0, wxALL|wxALIGN_BOTTOM, 4)  
   
         # list controls  
         grid_sizer_1 = wxFlexGridSizer(3, 2, 0, 0)  
         grid_sizer_1.Add(self.label_5, 0, wxLEFT|wxRIGHT|wxTOP, 4)  
         grid_sizer_1.Add(20, 20, 0, wxEXPAND, 0)  
         grid_sizer_1.Add(self.availprojs, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)  
         grid_sizer_1.Add(sizer_15, 0, wxALL|wxEXPAND, 4)  
         grid_sizer_1.Add(self.projfilepath, 0, wxALL|wxADJUST_MINSIZE, 4)  
         grid_sizer_1.AddGrowableRow(1)  
         grid_sizer_1.AddGrowableCol(0)  
   
         # edit controls  
         sizer_13.Add(self.label_2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)  
         sizer_13.Add(self.projname, 1, wxALL, 4)  
         self.sizer_projctrls.Add(sizer_13, 0, wxEXPAND, 0)  
         sizer_14.Add(self.label_3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)  
         sizer_14.Add(self.projchoice, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)  
         self.sizer_projctrls.Add(sizer_14, 0, wxEXPAND, 0)  
         self.sizer_edit.Add(self.sizer_projctrls, 1, wxEXPAND, 0)  
         sizer_11.Add(self.button_new, 0, wxALL|wxEXPAND, 4)  
         sizer_11.Add(self.button_save, 0, wxALL|wxEXPAND, 4)  
         sizer_11.Add(self.button_add, 0, wxALL|wxEXPAND, 4)  
         self.sizer_edit.Add(sizer_11, 0, wxALL|wxEXPAND, 4)  
   
         sizer_6.Add(20, 20, 1, wxEXPAND, 0)  
         sizer_6.Add(self.button_try, 0, wxALL, 4)  
         sizer_6.Add(20, 20, 1, 0, 0)  
         sizer_6.Add(self.button_revert, 0, wxALL, 4)  
         sizer_6.Add(20, 20, 1, 0, 0)  
         sizer_6.Add(self.button_ok, 0, wxALL, 4)  
         sizer_6.Add(20, 20, 1, 0, 0)  
         sizer_6.Add(self.button_close, 0, wxALL, 4)  
         sizer_6.Add(20, 20, 1, wxEXPAND, 0)  
   
         self.panel_1.SetAutoLayout(1)  
         self.panel_1.SetSizer(grid_sizer_1)  
         grid_sizer_1.Fit(self.panel_1)  
         grid_sizer_1.SetSizeHints(self.panel_1)  
   
         self.panel_edit.SetAutoLayout(1)  
         self.panel_edit.SetSizer(self.sizer_edit)  
         self.sizer_edit.Fit(self.panel_edit)  
         self.sizer_edit.SetSizeHints(self.panel_edit)  
   
         self.panel_buttons.SetAutoLayout(1)  
         self.panel_buttons.SetSizer(sizer_6)  
         sizer_6.Fit(self.panel_buttons)  
         sizer_6.SetSizeHints(self.panel_buttons)  
   
         self.sizer_mainctrls.Add(self.panel_1, 0,  
             wxALL|wxEXPAND|wxADJUST_MINSIZE, 0)  
         self.sizer_mainctrls.Add(self.panel_edit, 1,  
             wxALL|wxEXPAND|wxADJUST_MINSIZE, 0)  
610    
611          self.topBox.Add(self.sizer_mainctrls, 1, wxALL|wxEXPAND, 4)      def write_proj_file(self, proj_file):
612          self.topBox.Add(self.panel_buttons, 0, wxEXPAND, 0)          """Write the ProjFile object proj_file back to its file
613    
614          self.SetAutoLayout(1)          Show a busy cursor while writing and if an error occurs show a
615          self.SetSizer(self.topBox)          dialog with the error message.
616          self.topBox.Fit(self)          """
617          self.topBox.SetSizeHints(self)          try:
618          self.Layout()              ThubanBeginBusyCursor()
619                try:
620                    write_proj_file(proj_file)
621                finally:
622                    ThubanEndBusyCursor()
623            except IOError, (errno, errstr):
624                self.__ShowError(proj_file.GetFilename(), errstr)
625    
 # end of class ProjFrame  
626    
627    
628  class ProjPanel(wxPanel):  class ProjPanel(wxPanel):
# Line 532  class ProjPanel(wxPanel): Line 632  class ProjPanel(wxPanel):
632          wxPanel.__init__(self, parent, -1)          wxPanel.__init__(self, parent, -1)
633    
634          self.__ellps = wxChoice(self, -1)          self.__ellps = wxChoice(self, -1)
635          self.ellpsData = [("bessel", _("Bessel 1841")),          self.ellpsData = [("", _("<Unknown>")),
636                            ("clrk66", _("Clarke 1866")),                            ("airy"  , _("Airy")),
637                              ("bessel", _("Bessel 1841")),
638                              ("clrk66", _("Clarke 1866")),
639                            ("clrk80", _("Clarke 1880")),                            ("clrk80", _("Clarke 1880")),
640                            ("GRS80" , _("GRS 1980 (IUGG, 1980)")),                            ("GRS80" , _("GRS 1980 (IUGG, 1980)")),
641                            ("intl"  , _("International 1909 (Hayford)")),                            ("intl"  , _("International 1909 (Hayford)")),
# Line 548  class ProjPanel(wxPanel): Line 650  class ProjPanel(wxPanel):
650    
651          panelSizer = wxBoxSizer(wxVERTICAL)          panelSizer = wxBoxSizer(wxVERTICAL)
652    
         if childPanel is not None:  
             panelSizer.Add(childPanel, 0, wxALL|wxEXPAND, 4)  
               
653          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wxBoxSizer(wxHORIZONTAL)
654          sizer.Add(wxStaticText(self, -1, _("Ellipsoid:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Ellipsoid:")), 0,
655          sizer.Add(self.__ellps, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)                                      wxALL|wxALIGN_CENTER_VERTICAL, 4)
656            sizer.Add(self.__ellps, 1, wxALL|wxALIGN_CENTER_VERTICAL, 4)
657          panelSizer.Add(sizer, 0, wxALL|wxEXPAND, 4)          panelSizer.Add(sizer, 0, wxALL|wxEXPAND, 4)
658    
659            if childPanel is not None:
660                panelSizer.Add(childPanel, 0, wxEXPAND, 0)
661                
662          self.SetAutoLayout(1)          self.SetAutoLayout(1)
663          self.SetSizer(panelSizer)          self.SetSizer(panelSizer)
664          panelSizer.Fit(self)          panelSizer.Fit(self)
# Line 578  class ProjPanel(wxPanel): Line 681  class ProjPanel(wxPanel):
681          self.__ellps.SetSelection(0)          self.__ellps.SetSelection(0)
682    
683      def GetParameters(self):      def GetParameters(self):
684          return ["ellps=" + self.__ellps.GetClientData(          ellps = self.__ellps.GetSelection()
685                                          self.__ellps.GetSelection())]          if ellps > 0:
686                return ["ellps=" + self.__ellps.GetClientData(ellps)]
687            return []
688    
689    
690  ID_TMPANEL_LAT = 4001  ID_TMPANEL_LAT = 4001
# Line 589  ID_TMPANEL_FALSE_NORTH = 4004 Line 694  ID_TMPANEL_FALSE_NORTH = 4004
694  ID_TMPANEL_SCALE = 4005  ID_TMPANEL_SCALE = 4005
695    
696  class UnknownProjPanel(ProjPanel):  class UnknownProjPanel(ProjPanel):
697    
698        """Panel for unknown projection types"""
699    
700      def __init__(self, parent, receiver):      def __init__(self, parent, receiver):
701          ProjPanel.__init__(self, parent)          ProjPanel.__init__(self, parent)
702    
703            self.__text = _("Thuban does not know the parameters\n"
704                            "for the current projection and cannot\n"
705                            "display a configuration panel.\n\n"
706                            "The unidentified set of parameters is:\n\n")
707    
708            self.__textbox = wxTextCtrl(self, -1, self.__text, size=(100,200),
709                                style=wxTE_READONLY|wxTE_MULTILINE|wxTE_LINEWRAP)
710          self._DoLayout()          self._DoLayout()
711    
712      def _DoLayout(self):      def _DoLayout(self):
713          sizer = wxBoxSizer(wxVERTICAL)          sizer = wxBoxSizer(wxVERTICAL)
714    
715          sizer.Add(wxStaticText(self, -1,          sizer.Add(self.__textbox, 0, wxALL|wxEXPAND, 4)
             _("Thuban does not know the parameters for the " +  
               "current projection and cannot display a " +  
               "configuration panel.")))  
716    
717          ProjPanel._DoLayout(self, sizer)          ProjPanel._DoLayout(self, sizer)
718    
# Line 608  class UnknownProjPanel(ProjPanel): Line 720  class UnknownProjPanel(ProjPanel):
720          return "Unknown"          return "Unknown"
721    
722      def SetProjection(self, proj):      def SetProjection(self, proj):
723          pass          """Append the available parameters to the info text."""
724            text = self.__text
725            for param in proj.GetAllParameters():
726                text = text + '%s\n' % param
727            self.__textbox.SetValue(text)
728    
729      def GetParameters(self):      def GetParameters(self):
730          return None          return None
# Line 629  class TMPanel(ProjPanel): Line 745  class TMPanel(ProjPanel):
745    
746      def _DoLayout(self):      def _DoLayout(self):
747    
748          sizer = wxFlexGridSizer(4, 4, 0, 0)          sizer = wxFlexGridSizer(4, 2, 0, 0)
749          sizer.Add(wxStaticText(self, -1, _("Latitude:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Latitude:")), 0, wxALL, 4)
750          sizer.Add(self.__latitude, 0, wxALL, 4)          sizer.Add(self.__latitude, 0, wxALL, 4)
         sizer.Add(wxStaticText(self, -1, _("False Easting:")), 0, wxALL, 4)  
         sizer.Add(self.__falseEast, 0, wxALL, 4)  
751          sizer.Add(wxStaticText(self, -1, _("Longitude:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Longitude:")), 0, wxALL, 4)
752          sizer.Add(self.__longitude, 0, wxALL, 4)          sizer.Add(self.__longitude, 0, wxALL, 4)
753            sizer.Add(wxStaticText(self, -1, _("False Easting:")), 0, wxALL, 4)
754            sizer.Add(self.__falseEast, 0, wxALL, 4)
755          sizer.Add(wxStaticText(self, -1, _("False Northing:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("False Northing:")), 0, wxALL, 4)
756          sizer.Add(self.__falseNorth, 0, wxALL, 4)          sizer.Add(self.__falseNorth, 0, wxALL, 4)
757          sizer.Add(wxStaticText(self, -1, _("Scale Factor:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Scale Factor:")), 0, wxALL, 4)
# Line 689  class UTMPanel(ProjPanel): Line 805  class UTMPanel(ProjPanel):
805          self.receiver = receiver          self.receiver = receiver
806    
807          self.__zone = wxSpinCtrl(self, ID_UTMPANEL_ZONE, "1", min=1, max=60)          self.__zone = wxSpinCtrl(self, ID_UTMPANEL_ZONE, "1", min=1, max=60)
808            self.__propButton = wxButton(self, ID_UTMPANEL_PROP, _("Propose"))
809          self.__south = wxCheckBox(self, ID_UTMPANEL_SOUTH,          self.__south = wxCheckBox(self, ID_UTMPANEL_SOUTH,
810                                    _("Southern Hemisphere"))                                    _("Southern Hemisphere"))
         self.__propButton = wxButton(self, ID_UTMPANEL_PROP, _("Propose"))  
811    
812          self._DoLayout()          self._DoLayout()
813    
# Line 731  class UTMPanel(ProjPanel): Line 847  class UTMPanel(ProjPanel):
847          ProjPanel.Clear(self)          ProjPanel.Clear(self)
848    
849      def _OnPropose(self, event):      def _OnPropose(self, event):
850          UTMProposeZoneDialog          """Call the propose dialog.
851            If the receiver (e.g. the current map) has no bounding box,
852            inform the user accordingly.
853            """
854            bb = self.receiver.BoundingBox()
855            if bb is None:
856                dlg = wxMessageDialog(self,
857                        _("Can not propose: No bounding box found."),
858                        _("Projection: Propose UTM Zone"),
859                        wxOK | wxICON_INFORMATION)
860                dlg.CenterOnParent()
861                result = dlg.ShowModal()
862                dlg.Destroy()
863                return
864    
865          dlg = UTMProposeZoneDialog(self, self.receiver.BoundingBox())          dlg = UTMProposeZoneDialog(self, self.receiver.BoundingBox())
866          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
867              self.__zone.SetValue(dlg.GetProposedZone())              self.__zone.SetValue(dlg.GetProposedZone())
# Line 744  class LCCPanel(ProjPanel): Line 874  class LCCPanel(ProjPanel):
874                    
875          self.__fspLatitude = wxTextCtrl(self, -1)          self.__fspLatitude = wxTextCtrl(self, -1)
876          self.__sspLatitude = wxTextCtrl(self, -1)          self.__sspLatitude = wxTextCtrl(self, -1)
         self.__originLat   = wxTextCtrl(self, -1)  
877          self.__meridian    = wxTextCtrl(self, -1)          self.__meridian    = wxTextCtrl(self, -1)
878            self.__originLat   = wxTextCtrl(self, -1)
879          self.__falseEast   = wxTextCtrl(self, -1)          self.__falseEast   = wxTextCtrl(self, -1)
880          self.__falseNorth  = wxTextCtrl(self, -1)          self.__falseNorth  = wxTextCtrl(self, -1)
881    
# Line 760  class LCCPanel(ProjPanel): Line 890  class LCCPanel(ProjPanel):
890          sizer.Add(wxStaticText(self, -1,          sizer.Add(wxStaticText(self, -1,
891              _("Latitude of second standard parallel:")))              _("Latitude of second standard parallel:")))
892          sizer.Add(self.__sspLatitude, 0, wxALL, 4)          sizer.Add(self.__sspLatitude, 0, wxALL, 4)
         sizer.Add(wxStaticText(self, -1, _("Latitude of origin:")))  
         sizer.Add(self.__originLat, 0, wxALL, 4)  
893          sizer.Add(wxStaticText(self, -1, _("Central Meridian:")))          sizer.Add(wxStaticText(self, -1, _("Central Meridian:")))
894          sizer.Add(self.__meridian, 0, wxALL, 4)          sizer.Add(self.__meridian, 0, wxALL, 4)
895            sizer.Add(wxStaticText(self, -1, _("Latitude of origin:")))
896            sizer.Add(self.__originLat, 0, wxALL, 4)
897          sizer.Add(wxStaticText(self, -1, _("False Easting:")))          sizer.Add(wxStaticText(self, -1, _("False Easting:")))
898          sizer.Add(self.__falseEast, 0, wxALL, 4)          sizer.Add(self.__falseEast, 0, wxALL, 4)
899          sizer.Add(wxStaticText(self, -1, _("False Northing:")))          sizer.Add(wxStaticText(self, -1, _("False Northing:")))
# Line 811  class GeoPanel(ProjPanel): Line 941  class GeoPanel(ProjPanel):
941    
942      def __init__(self, parent, receiver):      def __init__(self, parent, receiver):
943          ProjPanel.__init__(self, parent)          ProjPanel.__init__(self, parent)
944          ProjPanel._DoLayout(self, None)  
945            self.__choices = [(_("Degrees"), "0.017453"),
946                              (_("Radians"), "1")]
947    
948            self.__scale = wxChoice(self, -1)
949            for choice, value in self.__choices:
950                self.__scale.Append(choice, value)
951    
952            self._DoLayout()
953    
954      def GetProjName(self):      def GetProjName(self):
955          return _("Geographic")          return _("Geographic")
956                    
957      def SetProjection(self, proj):      def SetProjection(self, proj):
958            value = proj.GetParameter("to_meter")
959            for i in range(len(self.__choices)):
960                choice, data = self.__choices[i]
961                if value == data:
962                    self.__scale.SetSelection(i)
963          ProjPanel.SetProjection(self, proj)          ProjPanel.SetProjection(self, proj)
964    
965      def GetParameters(self):      def GetParameters(self):
966          params = ["proj=latlong"]          params = ["proj=latlong",
967                      "to_meter=%s" % self.__scale.GetClientData(
968                                      self.__scale.GetSelection())]
969    
970          params.extend(ProjPanel.GetParameters(self))          params.extend(ProjPanel.GetParameters(self))
971          return params          return params
972    
973      def Clear(self):      def Clear(self):
974          ProjPanel.Clear(self)          ProjPanel.Clear(self)
975    
976        def _DoLayout(self):
977            sizer = wxBoxSizer(wxHORIZONTAL)
978    
979            sizer.Add(wxStaticText(self, -1, _("Source Data is in: ")),
980                      0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
981            sizer.Add(self.__scale, 1, wxEXPAND|wxALL, 4)
982    
983            self.__scale.SetSelection(0)
984    
985            ProjPanel._DoLayout(self, sizer)
986    
987    
988  ID_UTM_PROPOSE_ZONE_DIALOG_TAKE   = 4001  ID_UTM_PROPOSE_ZONE_DIALOG_TAKE   = 4001
989  ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL = 4002  ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL = 4002
990  class UTMProposeZoneDialog(wxDialog):  class UTMProposeZoneDialog(wxDialog):
991                                                                                    
992      """Propose a sensible Zone considering the current map extent."""      """Propose a sensible Zone considering the current map extent."""
993                                                                                    
994      def __init__(self, parent, (x, y, x2, y2)):      def __init__(self, parent, (x, y, x2, y2)):
995          wxDialog.__init__(self, parent, -1, _("Projection: Propose UTM Zone"),          wxDialog.__init__(self, parent, -1, _("Projection: Propose UTM Zone"),
996                            wxDefaultPosition, wxSize(200, 100))                            wxDefaultPosition, wxSize(200, 100))
997          self.parent = parent          self.parent = parent
         #x, y, x2, y2 = elf.parent.parent.map_bounding_box  
998          x = x + 180          x = x + 180
999          x2 = x2 + 180          x2 = x2 + 180
1000          center = (x2 - x) / 2 + x          center = (x2 - x) / 2 + x
1001          self.proposedZone = int(center / 6 + 1)          self.proposedZone = int(center / 6 + 1)
1002          self.dialogLayout()          self.dialogLayout()
1003                                                                                    
1004      def dialogLayout(self):      def dialogLayout(self):
1005          topBox = wxBoxSizer(wxVERTICAL)          topBox = wxBoxSizer(wxVERTICAL)
1006                                                                                    
1007          textBox = wxBoxSizer(wxVERTICAL)          textBox = wxBoxSizer(wxVERTICAL)
1008          textBox.Add(wxStaticText(self, -1, _("The current map extent center " +          textBox.Add(wxStaticText(self, -1, _("The current map extent center "
1009                                             "lies in UTM Zone")),                                               "lies in UTM Zone")),
1010                      0, wxALIGN_CENTER|wxALL, 4)                      0, wxALIGN_CENTER|wxALL, 4)
1011          textBox.Add(wxStaticText(self, -1, str(self.proposedZone)),          textBox.Add(wxStaticText(self, -1, str(self.proposedZone)),
1012                      0, wxALIGN_CENTER|wxALL, 4)                      0, wxALIGN_CENTER|wxALL, 4)
1013                                                                                    
1014          topBox.Add(textBox, 1, wxEXPAND|wxALL, 4)          topBox.Add(textBox, 1, wxEXPAND|wxALL, 4)
1015                                                                                    
1016          buttonBox = wxBoxSizer(wxHORIZONTAL)          buttonBox = wxBoxSizer(wxHORIZONTAL)
1017          buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE,          buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE,
1018                        _("Take")), 0, wxALL, 4)                        _("Take")), 0, wxALL, 4)
# Line 865  class UTMProposeZoneDialog(wxDialog): Line 1021  class UTMProposeZoneDialog(wxDialog):
1021          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10)          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10)
1022          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE, self.OnTake)          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE, self.OnTake)
1023          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL, self.OnCancel)          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL, self.OnCancel)
1024                                                                                    
1025          self.SetAutoLayout(True)          self.SetAutoLayout(True)
1026          self.SetSizer(topBox)          self.SetSizer(topBox)
1027          topBox.Fit(self)          topBox.Fit(self)
1028          topBox.SetSizeHints(self)          topBox.SetSizeHints(self)
1029                                                                                    
1030      def OnTake(self, event):      def OnTake(self, event):
1031          self.EndModal(wxID_OK)          self.EndModal(wxID_OK)
1032                                                                                    
1033      def OnCancel(self, event):      def OnCancel(self, event):
1034          self.EndModal(wxID_CANCEL)          self.EndModal(wxID_CANCEL)
1035    

Legend:
Removed from v.741  
changed lines
  Added in v.1941

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26