/[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 730 by jonathan, Thu Apr 24 16:07:41 2003 UTC revision 1851 by bh, Tue Oct 21 14:17:24 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  from Thuban.UI.dialogs import NonModalNonParentDialog
26    
27    from common import ThubanBeginBusyCursor, ThubanEndBusyCursor
28    from sizers import NotebookLikeSizer
29    from projlist import PROJ_SELECTION_CHANGED, ProjectionList
30    from common import ThubanBeginBusyCursor, ThubanEndBusyCursor
31    
32    
33    
 ID_PROJ_ADVANCED  = 4001  
34  ID_PROJ_PROJCHOICE = 4002  ID_PROJ_PROJCHOICE = 4002
35  ID_PROJ_SAVEAS    = 4003  ID_PROJ_ADDTOLIST    = 4003
36  ID_PROJ_NEW       = 4004  ID_PROJ_NEW       = 4004
 ID_PROJ_TRY       = 4005  
37  ID_PROJ_REVERT    = 4006  ID_PROJ_REVERT    = 4006
 ID_PROJ_OK        = 4007  
 ID_PROJ_CLOSE     = 4008  
38  ID_PROJ_AVAIL     = 4009  ID_PROJ_AVAIL     = 4009
39  ID_PROJ_SAVE      = 4010  ID_PROJ_SAVE      = 4010
40  ID_PROJ_IMPORT    = 4011  ID_PROJ_IMPORT    = 4011
# Line 31  ID_PROJ_PROJNAME  = 4014 Line 45  ID_PROJ_PROJNAME  = 4014
45  CLIENT_PROJ = 0  CLIENT_PROJ = 0
46  CLIENT_PROJFILE = 1  CLIENT_PROJFILE = 1
47    
48  class ProjFrame(NonModalDialog):  class ProjFrame(NonModalNonParentDialog):
49    
50      def __init__(self, parent, name, receiver, *args, **kwds):      def __init__(self, parent, name, title, receiver):
51          """Initialize the projection dialog.          """Initialize the projection dialog.
52    
53          receiver -- An object that implements the following methods:          receiver -- An object that implements the following methods:
54                          SetProjection(projection)                          SetProjection(projection)
55                          GetProjection()                          GetProjection()
56          """          """
57                    NonModalNonParentDialog.__init__(self, parent, name, title)
58    
59            self.projection_panel_defs = [
60                ("tmerc", _("Transverse Mercator"), TMPanel),
61                ("utm", _("Universal Transverse Mercator"), UTMPanel),
62                ("lcc", _("Lambert Conic Conformal"), LCCPanel),
63                ("latlong", _("Geographic"), GeoPanel)]
64          self.receiver = receiver          self.receiver = receiver
65          self.originalProjection = -1          self.haveTried = False
66          self.curProjPanel = None          self.curProjPanel = None
67            self.__usrProjFile = None
68            self.__sysProjFile = None
69    
70            self.build_dialog()
71            self.Layout()
72    
73          self.projPanels = []          self.originalProjection = self.receiver.GetProjection()
         self.projPanels.append(  
             ("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_SAVEAS,  
                                       _("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  
74    
75          self.__DoOnProjAvail()          self.projection_list.SelectProjection(self.originalProjection)
76                    self.button_ok.SetFocus()
77          EVT_BUTTON(self, ID_PROJ_TRY, self._OnTry)          self.projection_list.SetFocus()
78          EVT_BUTTON(self, ID_PROJ_REVERT, self._OnRevert)  
79          EVT_BUTTON(self, ID_PROJ_OK, self._OnOK)      def build_dialog(self):
80          EVT_BUTTON(self, ID_PROJ_CLOSE, self._OnClose)          """Build the dialog's widgets and set the event handlers"""
81          EVT_CHOICE(self, ID_PROJ_PROJCHOICE, self._OnProjChoice)          self.topBox = top_box = wxBoxSizer(wxVERTICAL)
82          EVT_LISTBOX(self, ID_PROJ_AVAIL, self._OnProjAvail)  
83            main_box = wxBoxSizer(wxHORIZONTAL)
84            top_box.Add(main_box, 1, wxALL|wxEXPAND)
85    
86            #
87            #    The projection list and associated controls
88            #
89            vbox = wxBoxSizer(wxVERTICAL)
90            main_box.Add(vbox, 4, wxALL|wxEXPAND)
91    
92            #label = wxStaticText(self, -1, _("Available Projections:"))
93            #vbox.Add(label, 0, wxLEFT|wxRIGHT|wxTOP, 4)
94    
95            hbox = wxBoxSizer(wxHORIZONTAL)
96            vbox.Add(hbox, 1, wxALL|wxEXPAND)
97            self.projection_list = ProjectionList(self, self.load_system_proj(),
98                                                  self.load_user_proj(),
99                                                  self.receiver.GetProjection())
100            hbox.Add(self.projection_list, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)
101            self.projection_list.Subscribe(PROJ_SELECTION_CHANGED,
102                                           self.proj_selection_changed)
103    
104            # Projection List specific actions (Import/Export/Remove)
105            buttons = wxBoxSizer(wxVERTICAL)
106            hbox.Add(buttons, 0, wxALL)
107            self.button_import = wxButton(self, ID_PROJ_IMPORT, _("Import..."))
108          EVT_BUTTON(self, ID_PROJ_IMPORT, self._OnImport)          EVT_BUTTON(self, ID_PROJ_IMPORT, self._OnImport)
109            buttons.Add(self.button_import, 1, wxALL|wxEXPAND, 4)
110            self.button_export = wxButton(self, ID_PROJ_EXPORT, _("Export..."))
111          EVT_BUTTON(self, ID_PROJ_EXPORT, self._OnExport)          EVT_BUTTON(self, ID_PROJ_EXPORT, self._OnExport)
112            buttons.Add(self.button_export, 1, wxALL|wxEXPAND, 4)
113            buttons.Add(20, 20, 0, wxEXPAND, 0)
114            self.button_remove = wxButton(self, ID_PROJ_REMOVE, _("Remove"))
115          EVT_BUTTON(self, ID_PROJ_REMOVE, self._OnRemove)          EVT_BUTTON(self, ID_PROJ_REMOVE, self._OnRemove)
116            buttons.Add(self.button_remove, 1, wxALL|wxEXPAND, 4)
117    
118            # The file path
119            self.projfilepath = wxStaticText(self, -1, "")
120            vbox.Add(self.projfilepath, 0, wxALL|wxEXPAND)
121    
122            #
123            #   The projection editor part
124            #
125            self.edit_box = wxStaticBox(self, -1, _("Edit"))
126            sizer_edit = wxStaticBoxSizer(self.edit_box, wxHORIZONTAL)
127            main_box.Add(sizer_edit, 5, wxALL|wxEXPAND)
128    
129            # Projection Specific Entries (Name/Projection)
130            self.sizer_projctrls = wxBoxSizer(wxVERTICAL)
131            sizer_edit.Add(self.sizer_projctrls, 1, wxALL|wxEXPAND)
132    
133            hbox = wxBoxSizer(wxHORIZONTAL)
134            self.sizer_projctrls.Add(hbox, 0, wxALL|wxEXPAND)
135            label = wxStaticText(self, -1, _("Name:"))
136            hbox.Add(label, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
137            self.projname = wxTextCtrl(self, ID_PROJ_PROJNAME, "")
138            EVT_TEXT(self, ID_PROJ_PROJNAME, self._OnProjName)
139            hbox.Add(self.projname, 1, wxALL|wxEXPAND, 4)
140    
141            hbox = wxBoxSizer(wxHORIZONTAL)
142            self.sizer_projctrls.Add(hbox, 0, wxALL|wxEXPAND)
143            label = wxStaticText(self, -1, _("Projection:"))
144            hbox.Add(label, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
145            self.projchoice = wxChoice(self, ID_PROJ_PROJCHOICE)
146            self.projchoice.SetSelection(0)
147            EVT_CHOICE(self, ID_PROJ_PROJCHOICE, self._OnProjChoice)
148            hbox.Add(self.projchoice, 1, wxALL|wxEXPAND, 4)
149            # Fill the projection choice list.
150            self.nbsizer = NotebookLikeSizer()
151            self.sizer_projctrls.Add(self.nbsizer, 1,
152                                     wxALL|wxEXPAND|wxADJUST_MINSIZE, 3)
153            self.projection_panels = []
154            self.projchoice.Append(_("<Unknown>"), "")
155            for proj_type, name, cls in self.projection_panel_defs:
156                self.projchoice.Append(name, proj_type)
157                panel = cls(self, self.receiver)
158                panel.Hide()
159                panel.projection_index = len(self.projection_panels)
160                panel.projection_type = proj_type
161                self.projection_panels.append(panel)
162                self.nbsizer.Add(panel)
163            self.unknown_projection_panel = UnknownProjPanel(self, self.receiver)
164            self.unknown_projection_panel.Hide()
165            self.nbsizer.Add(self.unknown_projection_panel)
166    
167            # Projection Specific actions (New/Save/Add)
168            buttons = wxBoxSizer(wxVERTICAL)
169            sizer_edit.Add(buttons, 0, wxALL)
170            self.button_new = wxButton(self, ID_PROJ_NEW, _("New"))
171          EVT_BUTTON(self, ID_PROJ_NEW, self._OnNew)          EVT_BUTTON(self, ID_PROJ_NEW, self._OnNew)
172            buttons.Add(self.button_new, 0, wxEXPAND|wxALL, 4)
173            self.button_add = wxButton(self, ID_PROJ_ADDTOLIST, _("Add to List"))
174            EVT_BUTTON(self, ID_PROJ_ADDTOLIST, self._OnAddToList)
175            buttons.Add(self.button_add, 0, wxEXPAND|wxALL, 4)
176            buttons.Add(20, 20, 0, wxEXPAND, 0)
177            self.button_save = wxButton(self, ID_PROJ_SAVE,_("Update"))
178          EVT_BUTTON(self, ID_PROJ_SAVE, self._OnSave)          EVT_BUTTON(self, ID_PROJ_SAVE, self._OnSave)
179          EVT_BUTTON(self, ID_PROJ_SAVEAS, self._OnSaveAs)          buttons.Add(self.button_save, 0, wxEXPAND|wxALL|wxALIGN_BOTTOM, 4)
180    
181          EVT_TEXT(self, ID_PROJ_PROJNAME, self._OnProjName)          #
182            # Main Action buttons (Try/Revert/OK/Close)
183            #
184            buttons = wxBoxSizer(wxHORIZONTAL)
185            top_box.Add(buttons, 0, wxALL|wxALIGN_RIGHT, 10)
186            self.button_try = wxButton(self, wxID_APPLY, _("Try"))
187            EVT_BUTTON(self, wxID_APPLY, self.OnApply)
188            buttons.Add(self.button_try, 0, wxRIGHT, 10)
189            self.button_revert = wxButton(self, ID_PROJ_REVERT, _("Revert"))
190            EVT_BUTTON(self, ID_PROJ_REVERT, self._OnRevert)
191            buttons.Add(self.button_revert, 0, wxRIGHT, 10)
192            self.button_ok = wxButton(self, wxID_OK, _("OK"))
193            EVT_BUTTON(self, wxID_OK, self.OnOK)
194            self.button_ok.SetDefault()
195            buttons.Add(self.button_ok, 0, wxRIGHT, 10)
196            self.button_close = wxButton(self, wxID_CANCEL, _("Close"))
197            EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
198            buttons.Add(self.button_close, 0, wxRIGHT, 10)
199    
     def GetReceiver(self):  
         return self.receiver  
200    
201      def _OnTry(self, event):          #
202          self.__SetProjection()          # Automatic Layout
203            #
204            self.SetAutoLayout(1)
205            self.SetSizer(top_box)
206            top_box.Fit(self)
207            top_box.SetSizeHints(self)
208    
209        def OnClose(self, event):
210            self.projection_list.Unsubscribe(PROJ_SELECTION_CHANGED,
211                                             self.proj_selection_changed)
212            NonModalNonParentDialog.OnClose(self, event)
213    
214      def _OnRevert(self, event):      def OnApply(self, event):
215          if self.originalProjection != -1:          self.__SetProjection()
216              self.receiver.SetProjection(self.originalProjection)          self.haveTried = True
217    
218      def _OnOK(self, event):      def OnOK(self, event):
219          self.__SetProjection()          self.__SetProjection()
220          self.Close()          self.Close()
221    
222      def _OnClose(self, event):      def OnCancel(self, event):
223            """Cancel just closes the dialog, but we call it cancel so we
224            can overload the functionality of wxDialog.
225            """
226          self.Close()          self.Close()
227    
228        def _OnRevert(self, event):
229            if self.haveTried:
230                self.receiver.SetProjection(self.originalProjection)
231                self.haveTried = False
232    
233      def _OnNew(self, event):      def _OnNew(self, event):
234          self.__DoOnNew()  
235            self.projection_list.ClearSelection()
236            self.projname.Clear()
237    
238            # supply a projection panel if there wasn't one
239            if self.curProjPanel is None:
240                self.projchoice.SetSelection(0)
241                self.__DoOnProjChoice()
242    
243            if self.curProjPanel is not None:
244                self.curProjPanel.Clear()
245    
246      def _OnSave(self, event):      def _OnSave(self, event):
247    
248          sel = self.availprojs.GetSelections()          sel = self.projection_list.selected_projections()
249          assert len(sel) == 1,  "button shouldn't be enabled"          assert len(sel) == 1,  "button shouldn't be enabled"
250    
251          proj, projfile = self.availprojs.GetClientData(sel[0])          proj, projfile = sel[0]
252    
253          assert proj is not None and projfile is not None          assert proj is not None and projfile is not None
254    
255          newproj = self.__GetProjection()          newproj = self.__GetProjection()
256    
257          if newproj is not None:          if newproj is not None:
258              projfile.Remove(proj)              # FIXME: we should only allow this for the user proj file.
259              projfile.Add(newproj)              projfile.Replace(proj, newproj)
260              try:              self.write_proj_file(projfile)
261                  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()  
262    
263      def _OnSaveAs(self, event):      def _OnAddToList(self, event):
264    
265          proj = self.__GetProjection()          proj = self.__GetProjection()
266          if proj is not None:          if proj is not None:
267              self.__usrProjFile.Add(proj)              self.__usrProjFile.Add(proj)
268              try:              self.write_proj_file(self.__usrProjFile)
269                  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()  
   
         return  
   
         """Save the projection somewhere.  
270    
271          There are three important cases to consider.      def show_warnings(self, title, filename, warnings):
272              1. the file already exists and the user wants to overwrite it.          """Show the warnings (a list of strings) in a dialog
             2. the file already exists and the user wants to append the  
                current projection to the end of the file  
             3. the file doesn't exist and the user wants to create it  
273    
274          The list of available projections is then updated.          If the list is empty no dialog will be shown.
275          """          """
276            if warnings:
277          proj = Projection(self.curProjPanel.GetParameters())              text = (_('Warnings when reading "%s":\n\n%s')
278          if self.projname.GetValue() != "":                      % (filename, "\n\n".join(warnings)))
279              proj.SetName(self.projname.GetValue())              self.parent.RunMessageBox(title, text)
   
         dlg = wxFileDialog(self, _("Save As"), style = wxSAVE)  
         if dlg.ShowModal() == wxID_OK:  
             path = dlg.GetPath()  
   
             if os.access(path, os.F_OK):  
                 # file already exists.  
                 if os.access(path, os.W_OK | os.R_OK):  
                   
                     # is it a .proj file?  
                     try:  
                         projFile = ReadProjFile(path)  
                     except:  
                         # obviously not.  
                         dlg = wxMessageDialog(self,  
                             path + _(" already exists. Overwrite?"),  
                             _(""),  
                             wxYES | wxNO)  
   
                         if dlg.ShowModal() == wxID_YES:  
                             projFile = ProjFile(path)  
                         else:  
                             return # returning early  
                     else:  
                         # ask the user to overwrite or append  
                         dlg = wxMessageDialog(self,  
                             _("The selected projection file already exists.\n"+  
                               "The current projection can be added to the " +  
                               "file, or it can completely replace the " +  
                               "selected file.\n\nShould the current " +  
                               "projection be added to the file?"),  
                             _("Question"),  
                             wxYES | wxNO | wxICON_QUESTION)  
   
                         if dlg.ShowModal() == wxID_NO:  
                             projFile = ProjFile(path)  
                 else:  
                     # can't access the file  
                     dlg = wxMessageDialog(self,  
                         _("Couldn't access ") + path,  
                         _(""),  
                         wxOK | wxICON | wxICON_EXCLAMATION)  
                     return  
   
             else:  
                 # file doesn't exist. make a new one.  
                 projFile = ProjFile(path)  
                   
             #  
             # if we get this far we have a valid projFile and  
             # can just write the file  
             #  
             projFile.Add(proj)  
             try:  
                 WriteProjFile(projFile)  
                 self.__FillAvailList()  
             except IOError, (errno, errstr):  
                 wxMessageDialog(self,  
                     _("The following error occured:\n") +  
                     dlg.GetPath() + "\n" + errstr,  
                     _("Error"), wxOK | wxICON_ERROR).ShowModal()  
         dlg.Destroy()  
   
     def _OnProjAvail(self, event):  
         self.__DoOnProjAvail()  
280    
281      def _OnImport(self, event):      def _OnImport(self, event):
282            """Handler for the 'Import' button
283    
284            Ask the user for a filename, read the projections from that file
285            add them to the user ProjFile object and write the user file
286            back to disk.
287            """
288          dlg = wxFileDialog(self, _("Import"), style = wxOPEN)          dlg = wxFileDialog(self, _("Import"), style = wxOPEN)
289    
290          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
291              path = dlg.GetPath()              path = dlg.GetPath()
292    
293                ThubanBeginBusyCursor()
294              try:              try:
295                  projFile = ReadProjFile(path)                  try:
296                  for proj in projFile.GetProjections():                      projFile, warnings = read_proj_file(path)
297                      self.__usrProjFile.Add(proj)                  except IOError, (errno, errstr):
298                  WriteProjFile(self.__usrProjFile)                      self.__ShowError(dlg.GetPath(), errstr)
299              except IOError, (errno, errstr):                  else:
300                  wxMessageDialog(self,                      self.show_warnings(_("Warnings"), path, warnings)
301                      _("The following error occured:\n") +                      for proj in projFile.GetProjections():
302                      dlg.GetPath() + "\n" + errstr,                          self.__usrProjFile.Add(proj)
303                      _("Error"), wxOK | wxICON_ERROR).ShowModal()                      self.write_proj_file(self.__usrProjFile)
304                finally:
305              self.__FillAvailList()                  ThubanEndBusyCursor()
   
306          dlg.Destroy()          dlg.Destroy()
307    
308      def _OnExport(self, event):      def _OnExport(self, event):
309          proj = self.__GetProjection()          """Handler for the 'Export' button.
310    
311          if proj is None: return          Ask the user for a filename and write the selected projections
312            to that file.
313            """
314            sel = self.projection_list.selected_projections()
315            assert len(sel) != 0, "button should be disabled"
316    
317          dlg = wxFileDialog(self, _("Export"),          dlg = wxFileDialog(self, _("Export"), style=wxSAVE|wxOVERWRITE_PROMPT)
                            style = wxSAVE|wxOVERWRITE_PROMPT)  
318    
319          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
320              path = dlg.GetPath()              proj_file = ProjFile(dlg.GetPath())
321                for proj, pf in sel:
322              projFile = ProjFile(path)                  if proj is not None:
323              projFile.Add(proj)                      proj_file.Add(proj)
324              try:              self.write_proj_file(proj_file)
                 WriteProjFile(projFile)  
             except IOError, (errno, errstr):  
                 wxMessageDialog(self,  
                     _("The following error occured:\n") +  
                     dlg.GetPath() + "\n" + errstr,  
                     _("Error"), wxOK | wxICON_ERROR).ShowModal()  
325    
326          dlg.Destroy()          dlg.Destroy()
327    
328      def _OnRemove(self, event):      def _OnRemove(self, event):
329            """Handler for the 'Remove' button
330    
331          sel = self.availprojs.GetSelections()          Remove any selected projection that came from the user's
332            ProjFile. If the user ProjFile was modified write it back to
333            disk.
334            """
335            sel = self.projection_list.selected_projections()
336          assert len(sel) != 0, "button should be disabled!"          assert len(sel) != 0, "button should be disabled!"
337    
338          #          modified = False
339          # remove the items backwards so the indices don't change          for proj, pf in sel:
340          #              if proj is not None and pf is self.__usrProjFile:
341          sel = list(sel)                  pf.Remove(proj)
342          sel.sort()                  modified = True
         sel.reverse()  
   
         newselection = -1  
         if len(sel) == 1:  
             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)  
   
         try:  
             WriteProjFile(projfile)  
         except IOError, (errno, errstr):  
             wxMessageDialog(self,  
                 _("The following error occured:\n") +  
                 projfile.GetFileName() + "\n" + errstr,  
                 _("Error"), wxOK | wxICON_ERROR).ShowModal()  
   
343    
344          self.__FillAvailList()          if modified:
345                self.write_proj_file(self.__usrProjFile)
         #  
         # this *could* produce incorrect results if the .proj files  
         # change between the last list update and this selection  
         # because the list has been repopulated.  
         #  
         if newselection != -1 and self.availprojs.GetCount() > 0:  
             self.availprojs.SetSelection(newselection)  
346    
347      def _OnProjName(self, event):      def _OnProjName(self, event):
348          self.__VerifyButtons()          self.__VerifyButtons()
349    
350        def __ShowError(self, filename, errstr):
351            wxMessageDialog(self,
352                _("The following error occured:\n") +
353                filename + "\n" + errstr,
354                _("Error"), wxOK | wxICON_ERROR).ShowModal()
355    
356      def __VerifyButtons(self):      def __VerifyButtons(self):
357          sel = self.availprojs.GetSelections()          """Update button sensitivity"""
358    
359            num_sel = self.projection_list.GetSelectedItemCount()
360    
361          self.button_import.Enable(True)          self.button_import.Enable(True)
362          self.button_export.Enable(True)          self.button_export.Enable(True)
363          self.button_save.Enable(True)          self.button_save.Enable(True)
364          self.button_remove.Enable(True)          self.button_remove.Enable(True)
365    
366          self.panel_edit.Enable(True)          self.edit_box.Enable(True)
367    
368            for ctrl in [self.button_import,
369                         self.button_export,
370                         self.button_remove,
371                         self.button_save,
372                         self.button_add,
373                         self.projchoice,
374                         self.projname,
375                         self.edit_box]:
376                ctrl.Enable(True)
377    
378            if self.curProjPanel is not None:
379                self.curProjPanel.Enable(True)
380    
381          if len(sel) == 0:          if num_sel == 0:
382              self.button_import.Enable(True)              self.button_import.Enable(True)
383              self.button_export.Enable(False)              self.button_export.Enable(False)
384              self.button_remove.Enable(False)              self.button_remove.Enable(False)
385                self.button_save.Enable(False)
386    
387          elif len(sel) == 1:          elif num_sel == 1:
388    
389              proj, projFile = self.availprojs.GetClientData(sel[0])              selection = self.projection_list.selected_projections()
390                proj, projFile = selection[0]
391    
392              self.button_save.Enable(len(self.projname.GetValue()) > 0)              self.button_save.Enable(len(self.projname.GetValue()) > 0)
393              self.button_add.Enable(len(self.projname.GetValue()) > 0)              self.button_add.Enable(len(self.projname.GetValue()) > 0)
394    
395              if proj is None:              if proj is None:
396                  self.button_export.Enable(False)                  # <None> is selected
397                    for ctrl in [self.button_export,
398                                 self.button_remove,
399                                 self.button_save,
400                                 self.button_add,
401                                 self.projchoice,
402                                 self.projname]:
403                        ctrl.Enable(False)
404    
405                    if self.curProjPanel is not None:
406                        self.curProjPanel.Enable(False)
407    
408                elif proj is self.originalProjection:
409                  self.button_remove.Enable(False)                  self.button_remove.Enable(False)
410    
411              if projFile is None:              if projFile is None:
412                  self.button_save.Enable(False)                  self.button_save.Enable(False)
413    
414          else:          else:
415              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):  
   
         sel = self.availprojs.GetSelections()  
         if len(sel) == 1:  
416    
417              proj = self.availprojs.GetClientData(sel[0])[CLIENT_PROJ]      def proj_selection_changed(self, projs):
418              projfile = self.availprojs.GetClientData(sel[0])[CLIENT_PROJFILE]          """Subscribed to the projection_list's PROJ_SELECTION_CHANGED message
419    
420            Update the dialog to reflect the new selection.
421            """
422            if len(projs) == 0:
423                self.projfilepath.SetLabel(_("No Projections selected"))
424            elif len(projs) == 1:
425                proj, projfile = projs[0]
426              if proj is None:              if proj is None:
427                  # user selected <None>                  # user selected <None>
428                  self.projname.Clear()                  self.projname.Clear()
429                    self.projfilepath.SetLabel("")
430              else:              else:
               
431                  if projfile is not None:                  if projfile is not None:
432                      self.projfilepath.SetLabel(projfile.GetFileName())                      filename = os.path.basename(projfile.GetFilename())
433                        self.projfilepath.SetLabel(_("Source of Projection: %s")
434                                                   % filename)
435                  else:                  else:
436                      # only None if the currently used projection is selected                      # only None if the currently used projection is selected
437                      self.projfilepath.SetLabel("")                      self.projfilepath.SetLabel("")
438    
439                  self.projname.SetValue(proj.GetName())                  self.projname.SetValue(proj.Label())
440    
441                  myProjType = proj.GetParameter("proj")                  myProjType = proj.GetParameter("proj")
442                  i = 0                  i = 0
443                  for projType, name, clazz in self.projPanels:                  for projType, name, cls in self.projection_panel_defs:
444                      if myProjType == projType:                      if myProjType == projType:
445                          self.projchoice.SetSelection(i)                          self.projchoice.Enable(True)
446                            self.projchoice.SetSelection(i + 1)
447                          self.__DoOnProjChoice()                          self.__DoOnProjChoice()
448    
449                            #
450                            # self.curProjPanel should not be null
451                            # after a call to __DoOnProjChoice
452                            #
453                            assert self.curProjPanel is not None
454    
455                          self.curProjPanel.SetProjection(proj)                          self.curProjPanel.SetProjection(proj)
456                            break
457                      i += 1                      i += 1
458                    else:
459                        self.projchoice.Select(0)
460                        self.projchoice.Disable()
461                        self._show_proj_panel(UnknownProjPanel)
462            else:
463                self.projfilepath.SetLabel(_("Multiple Projections selected"))
464    
465          self.__VerifyButtons()          self.__VerifyButtons()
466    
# Line 410  class ProjFrame(NonModalDialog): Line 468  class ProjFrame(NonModalDialog):
468          self.__DoOnProjChoice()          self.__DoOnProjChoice()
469    
470      def __DoOnProjChoice(self):      def __DoOnProjChoice(self):
471            """Create and layout a projection panel based on the selected
472            projection type.
473    
474            This is necessary to have in seperate method since calls to
475            wxChoice.SetSelection() do not trigger an event.
476    
477            At the end of this method self.curProjPanel will not be None
478            if there was a item selected.
479            """
480          choice = self.projchoice          choice = self.projchoice
481    
482          sel = choice.GetSelection()          sel = choice.GetSelection()
483          if sel != -1:          if sel != -1:
484                proj_type = choice.GetClientData(sel)
485              clazz, obj = choice.GetClientData(sel)              for t, name, cls in self.projection_panel_defs:
486                    if t == proj_type:
487              if obj is None:                      self._show_proj_panel(cls)
488                  obj = clazz(self.panel_edit, self.receiver)                      break
489                  choice.SetClientData(sel, [clazz, obj])          # FIXME: what to do if sel == -1?
490    
491              if self.curProjPanel is not None:      def _show_proj_panel(self, panel_class):
492                  self.curProjPanel.Hide()          """Show the panel as the projection panel"""
493                  self.sizer_projctrls.Remove(self.curProjPanel)          if panel_class is UnknownProjPanel:
494                self.edit_box.Disable()
495              self.curProjPanel = obj              self.nbsizer.Activate(self.unknown_projection_panel)
496              self.curProjPanel.Show()              self.curProjPanel = self.unknown_projection_panel
497            else:
498              self.sizer_projctrls.Add(self.curProjPanel, 1,              self.edit_box.Enable(True)
499                  wxALL|wxEXPAND|wxADJUST_MINSIZE, 3)              self.unknown_projection_panel.Hide()
500              self.sizer_projctrls.Layout()              for panel in self.projection_panels:
501              self.Layout()                  if panel.__class__ is panel_class:
502              self.topBox.SetSizeHints(self)                      self.nbsizer.Activate(panel)
503                        self.curProjPanel = panel
504    
505      def __SetProjection(self):      def __SetProjection(self):
506            """Set the receiver's projection."""
507    
508          #          #
509          # save the original projection only once in case          # save the original projection only once in case
510          # we try to apply several different projections          # we try to apply several different projections
511          #          #
         if self.originalProjection == -1:  
             self.originalProjection = self.receiver.GetProjection()  
   
512          self.receiver.SetProjection(self.__GetProjection())          self.receiver.SetProjection(self.__GetProjection())
513    
514      def __GetProjection(self):      def __GetProjection(self):
515          """Return the packaged projection.          """Return a suitable Projection object based on the current
516            state of the dialog box selections.
517    
518          Could be None.          Could be None.
519          """          """
520    
521          proj = None          assert self.projection_list.GetSelectedItemCount() < 2, \
522                   "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()  
523    
524          #          sel = self.projection_list.selected_projections()
525          # the list can never be empty. there will always be          if len(sel) == 1:
526          # at least this one item              if sel[0][0] is None:
527          #                  # <None> is selected
528          self.availprojs.Append("<None>", (None, None))                  return 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  
   
         proj = self.receiver.GetProjection()  
         if proj is not None:  
             self.availprojs.Append(proj.GetName() + _(" (current)"),  
                                    [proj, None])  
   
         for proj, name, clazz in self.projPanels:  
             self.projchoice.Append(name, [clazz, None])  
   
     def __set_properties(self):  
         self.__FillAvailList()  
529    
530          # begin wxGlade: ProjFrame.__set_properties          # self.curProjPanel should always contain the most relevant data
531          self.SetTitle(_("Projections"))          # for a projection
532          self.availprojs.SetSelection(0)          if self.curProjPanel is not None:
533          self.projchoice.SetSelection(0)              return Projection(self.curProjPanel.GetParameters(),
534          # end wxGlade                                self.projname.GetValue())
535    
536          self.projname.SetMaxLength(32)          return None
537    
538      def __do_layout(self):      def load_user_proj(self):
539          # originally generated by wxGlade          ThubanBeginBusyCursor()
540            try:
541                if self.__usrProjFile is None:
542                    projfile, warnings = get_user_proj_file()
543                    self.show_warnings(_("Warnings"), projfile.GetFilename(),
544                                       warnings)
545                    self.__usrProjFile = projfile
546                return self.__usrProjFile
547            finally:
548                ThubanEndBusyCursor()
549    
550          self.topBox = wxBoxSizer(wxVERTICAL)      def load_system_proj(self):
551          self.sizer_panel = wxBoxSizer(wxVERTICAL)          ThubanBeginBusyCursor()
552          sizer_6 = wxBoxSizer(wxHORIZONTAL)          try:
553          self.sizer_mainctrls = wxBoxSizer(wxHORIZONTAL)              if self.__sysProjFile is None:
554          self.sizer_edit = wxStaticBoxSizer(wxStaticBox(self.panel_edit, -1, _("Edit")), wxHORIZONTAL)                  projfile, warnings = get_system_proj_file()
555          sizer_11 = wxBoxSizer(wxVERTICAL)                  self.show_warnings(_("Warnings"), projfile.GetFilename(),
556          self.sizer_projctrls = wxBoxSizer(wxVERTICAL)                                     warnings)
557          sizer_14 = wxBoxSizer(wxHORIZONTAL)                  self.__sysProjFile = projfile
558          sizer_13 = wxBoxSizer(wxHORIZONTAL)              return self.__sysProjFile
559          sizer_15 = wxBoxSizer(wxVERTICAL)          finally:
560          sizer_15.Add(self.button_import, 0, wxALL, 4)              ThubanEndBusyCursor()
         sizer_15.Add(self.button_export, 0, wxALL, 4)  
         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)  
561    
562          self.topBox.Add(self.sizer_mainctrls, 1, wxALL|wxEXPAND, 4)      def write_proj_file(self, proj_file):
563          self.topBox.Add(self.panel_buttons, 0, wxEXPAND, 0)          """Write the ProjFile object proj_file back to its file
564    
565          self.SetAutoLayout(1)          Show a busy cursor while writing and if an error occurs show a
566          self.SetSizer(self.topBox)          dialog with the error message.
567          self.topBox.Fit(self)          """
568          self.topBox.SetSizeHints(self)          try:
569          self.Layout()              ThubanBeginBusyCursor()
570                try:
571                    write_proj_file(proj_file)
572                finally:
573                    ThubanEndBusyCursor()
574            except IOError, (errno, errstr):
575                self.__ShowError(proj_file.GetFilename(), errstr)
576    
 # end of class ProjFrame  
577    
578    
579  class ProjPanel(wxPanel):  class ProjPanel(wxPanel):
# Line 606  class ProjPanel(wxPanel): Line 583  class ProjPanel(wxPanel):
583          wxPanel.__init__(self, parent, -1)          wxPanel.__init__(self, parent, -1)
584    
585          self.__ellps = wxChoice(self, -1)          self.__ellps = wxChoice(self, -1)
586          self.ellpsData = [("bessel", _("Bessel 1841")),          self.ellpsData = [("", _("<Unknown>")),
587                            ("clrk66", _("Clarke 1866")),                            ("airy"  , _("Airy")),
588                              ("bessel", _("Bessel 1841")),
589                              ("clrk66", _("Clarke 1866")),
590                            ("clrk80", _("Clarke 1880")),                            ("clrk80", _("Clarke 1880")),
591                            ("GRS80" , _("GRS 1980 (IUGG, 1980)")),                            ("GRS80" , _("GRS 1980 (IUGG, 1980)")),
592                            ("intl"  , _("International 1909 (Hayford)")),                            ("intl"  , _("International 1909 (Hayford)")),
# Line 622  class ProjPanel(wxPanel): Line 601  class ProjPanel(wxPanel):
601    
602          panelSizer = wxBoxSizer(wxVERTICAL)          panelSizer = wxBoxSizer(wxVERTICAL)
603    
         if childPanel is not None:  
             panelSizer.Add(childPanel, 0, wxALL|wxEXPAND, 4)  
               
604          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wxBoxSizer(wxHORIZONTAL)
605          sizer.Add(wxStaticText(self, -1, _("Ellipsoid:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Ellipsoid:")), 0,
606          sizer.Add(self.__ellps, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)                                      wxALL|wxALIGN_CENTER_VERTICAL, 4)
607            sizer.Add(self.__ellps, 1, wxALL|wxALIGN_CENTER_VERTICAL, 4)
608          panelSizer.Add(sizer, 0, wxALL|wxEXPAND, 4)          panelSizer.Add(sizer, 0, wxALL|wxEXPAND, 4)
609    
610            if childPanel is not None:
611                panelSizer.Add(childPanel, 0, wxEXPAND, 0)
612                
613          self.SetAutoLayout(1)          self.SetAutoLayout(1)
614          self.SetSizer(panelSizer)          self.SetSizer(panelSizer)
615          panelSizer.Fit(self)          panelSizer.Fit(self)
# Line 652  class ProjPanel(wxPanel): Line 632  class ProjPanel(wxPanel):
632          self.__ellps.SetSelection(0)          self.__ellps.SetSelection(0)
633    
634      def GetParameters(self):      def GetParameters(self):
635          return ["ellps=" + self.__ellps.GetClientData(          ellps = self.__ellps.GetSelection()
636                                          self.__ellps.GetSelection())]          if ellps > 0:
637                return ["ellps=" + self.__ellps.GetClientData(ellps)]
638            return []
639    
640    
641  ID_TMPANEL_LAT = 4001  ID_TMPANEL_LAT = 4001
# Line 663  ID_TMPANEL_FALSE_NORTH = 4004 Line 645  ID_TMPANEL_FALSE_NORTH = 4004
645  ID_TMPANEL_SCALE = 4005  ID_TMPANEL_SCALE = 4005
646    
647  class UnknownProjPanel(ProjPanel):  class UnknownProjPanel(ProjPanel):
648    
649        """Panel for unknown projection types"""
650    
651      def __init__(self, parent, receiver):      def __init__(self, parent, receiver):
652          ProjPanel.__init__(self, parent)          ProjPanel.__init__(self, parent)
653    
# Line 671  class UnknownProjPanel(ProjPanel): Line 656  class UnknownProjPanel(ProjPanel):
656      def _DoLayout(self):      def _DoLayout(self):
657          sizer = wxBoxSizer(wxVERTICAL)          sizer = wxBoxSizer(wxVERTICAL)
658    
659          sizer.Add(wxStaticText(self, -1,          sizer.Add(wxStaticText(self, -1,
660              _("Thuban does not know the parameters for the " +                                 _("Thuban does not know the parameters\n"
661                "current projection and cannot display a " +                                   "for the current projection and cannot\n"
662                "configuration panel.")))                                   "display a configuration panel.")))
663    
664          ProjPanel._DoLayout(self, sizer)          ProjPanel._DoLayout(self, sizer)
665    
# Line 703  class TMPanel(ProjPanel): Line 688  class TMPanel(ProjPanel):
688    
689      def _DoLayout(self):      def _DoLayout(self):
690    
691          sizer = wxFlexGridSizer(4, 4, 0, 0)          sizer = wxFlexGridSizer(4, 2, 0, 0)
692          sizer.Add(wxStaticText(self, -1, _("Latitude:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Latitude:")), 0, wxALL, 4)
693          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)  
694          sizer.Add(wxStaticText(self, -1, _("Longitude:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Longitude:")), 0, wxALL, 4)
695          sizer.Add(self.__longitude, 0, wxALL, 4)          sizer.Add(self.__longitude, 0, wxALL, 4)
696            sizer.Add(wxStaticText(self, -1, _("False Easting:")), 0, wxALL, 4)
697            sizer.Add(self.__falseEast, 0, wxALL, 4)
698          sizer.Add(wxStaticText(self, -1, _("False Northing:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("False Northing:")), 0, wxALL, 4)
699          sizer.Add(self.__falseNorth, 0, wxALL, 4)          sizer.Add(self.__falseNorth, 0, wxALL, 4)
700          sizer.Add(wxStaticText(self, -1, _("Scale Factor:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Scale Factor:")), 0, wxALL, 4)
# Line 763  class UTMPanel(ProjPanel): Line 748  class UTMPanel(ProjPanel):
748          self.receiver = receiver          self.receiver = receiver
749    
750          self.__zone = wxSpinCtrl(self, ID_UTMPANEL_ZONE, "1", min=1, max=60)          self.__zone = wxSpinCtrl(self, ID_UTMPANEL_ZONE, "1", min=1, max=60)
751            self.__propButton = wxButton(self, ID_UTMPANEL_PROP, _("Propose"))
752          self.__south = wxCheckBox(self, ID_UTMPANEL_SOUTH,          self.__south = wxCheckBox(self, ID_UTMPANEL_SOUTH,
753                                    _("Southern Hemisphere"))                                    _("Southern Hemisphere"))
         self.__propButton = wxButton(self, ID_UTMPANEL_PROP, _("Propose"))  
754    
755          self._DoLayout()          self._DoLayout()
756    
# Line 805  class UTMPanel(ProjPanel): Line 790  class UTMPanel(ProjPanel):
790          ProjPanel.Clear(self)          ProjPanel.Clear(self)
791    
792      def _OnPropose(self, event):      def _OnPropose(self, event):
793          UTMProposeZoneDialog          """Call the propose dialog.
794            If the receiver (e.g. the current map) has no bounding box,
795            inform the user accordingly.
796            """
797            bb = self.receiver.BoundingBox()
798            if bb is None:
799                dlg = wxMessageDialog(self,
800                        _("Can not propose: No bounding box found."),
801                        _("Projection: Propose UTM Zone"),
802                        wxOK | wxICON_INFORMATION)
803                dlg.CenterOnParent()
804                result = dlg.ShowModal()
805                dlg.Destroy()
806                return
807    
808          dlg = UTMProposeZoneDialog(self, self.receiver.BoundingBox())          dlg = UTMProposeZoneDialog(self, self.receiver.BoundingBox())
809          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
810              self.__zone.SetValue(dlg.GetProposedZone())              self.__zone.SetValue(dlg.GetProposedZone())
# Line 818  class LCCPanel(ProjPanel): Line 817  class LCCPanel(ProjPanel):
817                    
818          self.__fspLatitude = wxTextCtrl(self, -1)          self.__fspLatitude = wxTextCtrl(self, -1)
819          self.__sspLatitude = wxTextCtrl(self, -1)          self.__sspLatitude = wxTextCtrl(self, -1)
         self.__originLat   = wxTextCtrl(self, -1)  
820          self.__meridian    = wxTextCtrl(self, -1)          self.__meridian    = wxTextCtrl(self, -1)
821            self.__originLat   = wxTextCtrl(self, -1)
822          self.__falseEast   = wxTextCtrl(self, -1)          self.__falseEast   = wxTextCtrl(self, -1)
823          self.__falseNorth  = wxTextCtrl(self, -1)          self.__falseNorth  = wxTextCtrl(self, -1)
824    
# Line 834  class LCCPanel(ProjPanel): Line 833  class LCCPanel(ProjPanel):
833          sizer.Add(wxStaticText(self, -1,          sizer.Add(wxStaticText(self, -1,
834              _("Latitude of second standard parallel:")))              _("Latitude of second standard parallel:")))
835          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)  
836          sizer.Add(wxStaticText(self, -1, _("Central Meridian:")))          sizer.Add(wxStaticText(self, -1, _("Central Meridian:")))
837          sizer.Add(self.__meridian, 0, wxALL, 4)          sizer.Add(self.__meridian, 0, wxALL, 4)
838            sizer.Add(wxStaticText(self, -1, _("Latitude of origin:")))
839            sizer.Add(self.__originLat, 0, wxALL, 4)
840          sizer.Add(wxStaticText(self, -1, _("False Easting:")))          sizer.Add(wxStaticText(self, -1, _("False Easting:")))
841          sizer.Add(self.__falseEast, 0, wxALL, 4)          sizer.Add(self.__falseEast, 0, wxALL, 4)
842          sizer.Add(wxStaticText(self, -1, _("False Northing:")))          sizer.Add(wxStaticText(self, -1, _("False Northing:")))
# Line 885  class GeoPanel(ProjPanel): Line 884  class GeoPanel(ProjPanel):
884    
885      def __init__(self, parent, receiver):      def __init__(self, parent, receiver):
886          ProjPanel.__init__(self, parent)          ProjPanel.__init__(self, parent)
887          ProjPanel._DoLayout(self, None)  
888            self.__choices = [(_("Degrees"), "0.017453"),
889                              (_("Radians"), "1")]
890    
891            self.__scale = wxChoice(self, -1)
892            for choice, value in self.__choices:
893                self.__scale.Append(choice, value)
894    
895            self._DoLayout()
896    
897      def GetProjName(self):      def GetProjName(self):
898          return _("Geographic")          return _("Geographic")
899                    
900      def SetProjection(self, proj):      def SetProjection(self, proj):
901            value = proj.GetParameter("to_meter")
902            for i in range(len(self.__choices)):
903                choice, data = self.__choices[i]
904                if value == data:
905                    self.__scale.SetSelection(i)
906          ProjPanel.SetProjection(self, proj)          ProjPanel.SetProjection(self, proj)
907    
908      def GetParameters(self):      def GetParameters(self):
909          params = ["proj=latlong"]          params = ["proj=latlong",
910                      "to_meter=%s" % self.__scale.GetClientData(
911                                      self.__scale.GetSelection())]
912    
913          params.extend(ProjPanel.GetParameters(self))          params.extend(ProjPanel.GetParameters(self))
914          return params          return params
915    
916      def Clear(self):      def Clear(self):
917          ProjPanel.Clear(self)          ProjPanel.Clear(self)
918    
919        def _DoLayout(self):
920            sizer = wxBoxSizer(wxHORIZONTAL)
921    
922            sizer.Add(wxStaticText(self, -1, _("Source Data is in: ")),
923                      0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
924            sizer.Add(self.__scale, 1, wxEXPAND|wxALL, 4)
925    
926            self.__scale.SetSelection(0)
927    
928            ProjPanel._DoLayout(self, sizer)
929    
930    
931  ID_UTM_PROPOSE_ZONE_DIALOG_TAKE   = 4001  ID_UTM_PROPOSE_ZONE_DIALOG_TAKE   = 4001
932  ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL = 4002  ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL = 4002
933  class UTMProposeZoneDialog(wxDialog):  class UTMProposeZoneDialog(wxDialog):
934                                                                                    
935      """Propose a sensible Zone considering the current map extent."""      """Propose a sensible Zone considering the current map extent."""
936                                                                                    
937      def __init__(self, parent, (x, y, x2, y2)):      def __init__(self, parent, (x, y, x2, y2)):
938          wxDialog.__init__(self, parent, -1, _("Projection: Propose UTM Zone"),          wxDialog.__init__(self, parent, -1, _("Projection: Propose UTM Zone"),
939                            wxDefaultPosition, wxSize(200, 100))                            wxDefaultPosition, wxSize(200, 100))
940          self.parent = parent          self.parent = parent
         #x, y, x2, y2 = elf.parent.parent.map_bounding_box  
941          x = x + 180          x = x + 180
942          x2 = x2 + 180          x2 = x2 + 180
943          center = (x2 - x) / 2 + x          center = (x2 - x) / 2 + x
944          self.proposedZone = int(center / 6 + 1)          self.proposedZone = int(center / 6 + 1)
945          self.dialogLayout()          self.dialogLayout()
946                                                                                    
947      def dialogLayout(self):      def dialogLayout(self):
948          topBox = wxBoxSizer(wxVERTICAL)          topBox = wxBoxSizer(wxVERTICAL)
949                                                                                    
950          textBox = wxBoxSizer(wxVERTICAL)          textBox = wxBoxSizer(wxVERTICAL)
951          textBox.Add(wxStaticText(self, -1, _("The current map extent center " +          textBox.Add(wxStaticText(self, -1, _("The current map extent center "
952                                             "lies in UTM Zone")),                                               "lies in UTM Zone")),
953                      0, wxALIGN_CENTER|wxALL, 4)                      0, wxALIGN_CENTER|wxALL, 4)
954          textBox.Add(wxStaticText(self, -1, str(self.proposedZone)),          textBox.Add(wxStaticText(self, -1, str(self.proposedZone)),
955                      0, wxALIGN_CENTER|wxALL, 4)                      0, wxALIGN_CENTER|wxALL, 4)
956                                                                                    
957          topBox.Add(textBox, 1, wxEXPAND|wxALL, 4)          topBox.Add(textBox, 1, wxEXPAND|wxALL, 4)
958                                                                                    
959          buttonBox = wxBoxSizer(wxHORIZONTAL)          buttonBox = wxBoxSizer(wxHORIZONTAL)
960          buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE,          buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE,
961                        _("Take")), 0, wxALL, 4)                        _("Take")), 0, wxALL, 4)
# Line 939  class UTMProposeZoneDialog(wxDialog): Line 964  class UTMProposeZoneDialog(wxDialog):
964          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10)          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10)
965          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE, self.OnTake)          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE, self.OnTake)
966          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL, self.OnCancel)          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL, self.OnCancel)
967                                                                                    
968          self.SetAutoLayout(True)          self.SetAutoLayout(True)
969          self.SetSizer(topBox)          self.SetSizer(topBox)
970          topBox.Fit(self)          topBox.Fit(self)
971          topBox.SetSizeHints(self)          topBox.SetSizeHints(self)
972                                                                                    
973      def OnTake(self, event):      def OnTake(self, event):
974          self.EndModal(wxID_OK)          self.EndModal(wxID_OK)
975                                                                                    
976      def OnCancel(self, event):      def OnCancel(self, event):
977          self.EndModal(wxID_CANCEL)          self.EndModal(wxID_CANCEL)
978    

Legend:
Removed from v.730  
changed lines
  Added in v.1851

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26