/[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 1861 by jan, Fri Oct 24 16:03:03 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                ("longlat", _("Geographic"), GeoPanel)]#longlat is an alias of proj
65          self.receiver = receiver          self.receiver = receiver
66          self.originalProjection = -1          self.haveTried = False
67          self.curProjPanel = None          self.curProjPanel = None
68            self.__usrProjFile = None
69            self.__sysProjFile = None
70    
71            self.build_dialog()
72            self.Layout()
73    
74          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  
75    
76          self.__DoOnProjAvail()          self.projection_list.SelectProjection(self.originalProjection)
77                    self.projection_list.SetFocus()
78          EVT_BUTTON(self, ID_PROJ_TRY, self._OnTry)  
79          EVT_BUTTON(self, ID_PROJ_REVERT, self._OnRevert)      def build_dialog(self):
80          EVT_BUTTON(self, ID_PROJ_OK, self._OnOK)          """Build the dialog's widgets and set the event handlers"""
81          EVT_BUTTON(self, ID_PROJ_CLOSE, self._OnClose)          self.topBox = top_box = wxBoxSizer(wxVERTICAL)
82          EVT_CHOICE(self, ID_PROJ_PROJCHOICE, self._OnProjChoice)  
83          EVT_LISTBOX(self, ID_PROJ_AVAIL, self._OnProjAvail)          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            # Destroy the projection list explicitly so that it properly
213            # unsubscribes everything. It would be cleaner if the projection
214            # could do this by itself but wx doesn't always send destroy
215            # events for non-top-level widgets
216            self.projection_list.Destroy()
217            NonModalNonParentDialog.OnClose(self, event)
218    
219      def _OnRevert(self, event):      def OnApply(self, event):
220          if self.originalProjection != -1:          self.__SetProjection()
221              self.receiver.SetProjection(self.originalProjection)          self.haveTried = True
222    
223      def _OnOK(self, event):      def OnOK(self, event):
224          self.__SetProjection()          self.__SetProjection()
225          self.Close()          self.Close()
226    
227      def _OnClose(self, event):      def OnCancel(self, event):
228            """Cancel just closes the dialog, but we call it cancel so we
229            can overload the functionality of wxDialog.
230            """
231          self.Close()          self.Close()
232    
233        def _OnRevert(self, event):
234            if self.haveTried:
235                self.receiver.SetProjection(self.originalProjection)
236                self.haveTried = False
237    
238      def _OnNew(self, event):      def _OnNew(self, event):
239          self.__DoOnNew()  
240            self.projection_list.ClearSelection()
241            self.projname.Clear()
242    
243            # supply a projection panel if there wasn't one
244            if self.curProjPanel is None:
245                self.projchoice.SetSelection(0)
246                self.__DoOnProjChoice()
247    
248            if self.curProjPanel is not None:
249                self.curProjPanel.Clear()
250    
251      def _OnSave(self, event):      def _OnSave(self, event):
252    
253          sel = self.availprojs.GetSelections()          sel = self.projection_list.selected_projections()
254          assert len(sel) == 1,  "button shouldn't be enabled"          assert len(sel) == 1,  "button shouldn't be enabled"
255    
256          proj, projfile = self.availprojs.GetClientData(sel[0])          proj, projfile = sel[0]
257    
258          assert proj is not None and projfile is not None          assert proj is not None and projfile is not None
259    
260          newproj = self.__GetProjection()          newproj = self.__GetProjection()
261    
262          if newproj is not None:          if newproj is not None:
263              projfile.Remove(proj)              # FIXME: we should only allow this for the user proj file.
264              projfile.Add(newproj)              projfile.Replace(proj, newproj)
265              try:              self.write_proj_file(projfile)
266                  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()  
267    
268      def _OnSaveAs(self, event):      def _OnAddToList(self, event):
269    
270          proj = self.__GetProjection()          proj = self.__GetProjection()
271          if proj is not None:          if proj is not None:
272              self.__usrProjFile.Add(proj)              self.__usrProjFile.Add(proj)
273              try:              self.write_proj_file(self.__usrProjFile)
274                  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  
275    
276          """Save the projection somewhere.      def show_warnings(self, title, filename, warnings):
277            """Show the warnings (a list of strings) in a dialog
278    
279          There are three important cases to consider.          If the list is empty no dialog will be shown.
             1. the file already exists and the user wants to overwrite it.  
             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  
   
         The list of available projections is then updated.  
280          """          """
281            if warnings:
282          proj = Projection(self.curProjPanel.GetParameters())              text = (_('Warnings when reading "%s":\n\n%s')
283          if self.projname.GetValue() != "":                      % (filename, "\n\n".join(warnings)))
284              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()  
285    
286      def _OnImport(self, event):      def _OnImport(self, event):
287            """Handler for the 'Import' button
288    
289            Ask the user for a filename, read the projections from that file
290            add them to the user ProjFile object and write the user file
291            back to disk.
292            """
293          dlg = wxFileDialog(self, _("Import"), style = wxOPEN)          dlg = wxFileDialog(self, _("Import"), style = wxOPEN)
294    
295          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
296              path = dlg.GetPath()              path = dlg.GetPath()
297    
298                ThubanBeginBusyCursor()
299              try:              try:
300                  projFile = ReadProjFile(path)                  try:
301                  for proj in projFile.GetProjections():                      projFile, warnings = read_proj_file(path)
302                      self.__usrProjFile.Add(proj)                  except IOError, (errno, errstr):
303                  WriteProjFile(self.__usrProjFile)                      self.__ShowError(dlg.GetPath(), errstr)
304              except IOError, (errno, errstr):                  else:
305                  wxMessageDialog(self,                      self.show_warnings(_("Warnings"), path, warnings)
306                      _("The following error occured:\n") +                      for proj in projFile.GetProjections():
307                      dlg.GetPath() + "\n" + errstr,                          self.__usrProjFile.Add(proj)
308                      _("Error"), wxOK | wxICON_ERROR).ShowModal()                      self.write_proj_file(self.__usrProjFile)
309                finally:
310              self.__FillAvailList()                  ThubanEndBusyCursor()
   
311          dlg.Destroy()          dlg.Destroy()
312    
313      def _OnExport(self, event):      def _OnExport(self, event):
314          proj = self.__GetProjection()          """Handler for the 'Export' button.
315    
316          if proj is None: return          Ask the user for a filename and write the selected projections
317            to that file.
318            """
319            sel = self.projection_list.selected_projections()
320            assert len(sel) != 0, "button should be disabled"
321    
322          dlg = wxFileDialog(self, _("Export"),          dlg = wxFileDialog(self, _("Export"), style=wxSAVE|wxOVERWRITE_PROMPT)
                            style = wxSAVE|wxOVERWRITE_PROMPT)  
323    
324          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
325              path = dlg.GetPath()              proj_file = ProjFile(dlg.GetPath())
326                for proj, pf in sel:
327              projFile = ProjFile(path)                  if proj is not None:
328              projFile.Add(proj)                      proj_file.Add(proj)
329              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()  
330    
331          dlg.Destroy()          dlg.Destroy()
332    
333      def _OnRemove(self, event):      def _OnRemove(self, event):
334            """Handler for the 'Remove' button
335    
336          sel = self.availprojs.GetSelections()          Remove any selected projection that came from the user's
337            ProjFile. If the user ProjFile was modified write it back to
338            disk.
339            """
340            sel = self.projection_list.selected_projections()
341          assert len(sel) != 0, "button should be disabled!"          assert len(sel) != 0, "button should be disabled!"
342    
343          #          modified = False
344          # remove the items backwards so the indices don't change          for proj, pf in sel:
345          #              if proj is not None and pf is self.__usrProjFile:
346          sel = list(sel)                  pf.Remove(proj)
347          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()  
   
348    
349          self.__FillAvailList()          if modified:
350                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)  
351    
352      def _OnProjName(self, event):      def _OnProjName(self, event):
353          self.__VerifyButtons()          self.__VerifyButtons()
354    
355        def __ShowError(self, filename, errstr):
356            wxMessageDialog(self,
357                _("The following error occured:\n") +
358                filename + "\n" + errstr,
359                _("Error"), wxOK | wxICON_ERROR).ShowModal()
360    
361      def __VerifyButtons(self):      def __VerifyButtons(self):
362          sel = self.availprojs.GetSelections()          """Update button sensitivity"""
363    
364            num_sel = self.projection_list.GetSelectedItemCount()
365    
366          self.button_import.Enable(True)          self.button_import.Enable(True)
367          self.button_export.Enable(True)          self.button_export.Enable(True)
368          self.button_save.Enable(True)          self.button_save.Enable(True)
369          self.button_remove.Enable(True)          self.button_remove.Enable(True)
370    
371          self.panel_edit.Enable(True)          self.edit_box.Enable(True)
372    
373            for ctrl in [self.button_import,
374                         self.button_export,
375                         self.button_remove,
376                         self.button_save,
377                         self.button_add,
378                         self.projchoice,
379                         self.projname,
380                         self.edit_box]:
381                ctrl.Enable(True)
382    
383            if self.curProjPanel is not None:
384                self.curProjPanel.Enable(True)
385    
386          if len(sel) == 0:          if num_sel == 0:
387              self.button_import.Enable(True)              self.button_import.Enable(True)
388              self.button_export.Enable(False)              self.button_export.Enable(False)
389              self.button_remove.Enable(False)              self.button_remove.Enable(False)
390                self.button_save.Enable(False)
391    
392          elif len(sel) == 1:          elif num_sel == 1:
393    
394              proj, projFile = self.availprojs.GetClientData(sel[0])              selection = self.projection_list.selected_projections()
395                proj, projFile = selection[0]
396    
397              self.button_save.Enable(len(self.projname.GetValue()) > 0)              self.button_save.Enable(len(self.projname.GetValue()) > 0)
398              self.button_add.Enable(len(self.projname.GetValue()) > 0)              self.button_add.Enable(len(self.projname.GetValue()) > 0)
399    
400              if proj is None:              if proj is None:
401                  self.button_export.Enable(False)                  # <None> is selected
402                    for ctrl in [self.button_export,
403                                 self.button_remove,
404                                 self.button_save,
405                                 self.button_add,
406                                 self.projchoice,
407                                 self.projname]:
408                        ctrl.Enable(False)
409    
410                    if self.curProjPanel is not None:
411                        self.curProjPanel.Enable(False)
412    
413                elif proj is self.originalProjection:
414                  self.button_remove.Enable(False)                  self.button_remove.Enable(False)
415    
416              if projFile is None:              if projFile is None:
417                  self.button_save.Enable(False)                  self.button_save.Enable(False)
418    
419          else:          else:
420              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:  
421    
422              proj = self.availprojs.GetClientData(sel[0])[CLIENT_PROJ]      def proj_selection_changed(self, projs):
423              projfile = self.availprojs.GetClientData(sel[0])[CLIENT_PROJFILE]          """Subscribed to the projection_list's PROJ_SELECTION_CHANGED message
424    
425            Update the dialog to reflect the new selection.
426            """
427            if len(projs) == 0:
428                self.projfilepath.SetLabel(_("No Projections selected"))
429            elif len(projs) == 1:
430                proj, projfile = projs[0]
431              if proj is None:              if proj is None:
432                  # user selected <None>                  # user selected <None>
433                  self.projname.Clear()                  self.projname.Clear()
434                    self.projfilepath.SetLabel("")
435              else:              else:
               
436                  if projfile is not None:                  if projfile is not None:
437                      self.projfilepath.SetLabel(projfile.GetFileName())                      filename = os.path.basename(projfile.GetFilename())
438                        self.projfilepath.SetLabel(_("Source of Projection: %s")
439                                                   % filename)
440                  else:                  else:
441                      # only None if the currently used projection is selected                      # only None if the currently used projection is selected
442                      self.projfilepath.SetLabel("")                      self.projfilepath.SetLabel("")
443    
444                  self.projname.SetValue(proj.GetName())                  self.projname.SetValue(proj.Label())
445    
446                  myProjType = proj.GetParameter("proj")                  myProjType = proj.GetParameter("proj")
447                  i = 0                  i = 0
448                  for projType, name, clazz in self.projPanels:                  for projType, name, cls in self.projection_panel_defs:
449                      if myProjType == projType:                      if myProjType == projType:
450                          self.projchoice.SetSelection(i)                          self.projchoice.Enable(True)
451                            self.projchoice.SetSelection(i + 1)
452                          self.__DoOnProjChoice()                          self.__DoOnProjChoice()
453    
454                            #
455                            # self.curProjPanel should not be null
456                            # after a call to __DoOnProjChoice
457                            #
458                            assert self.curProjPanel is not None
459    
460                          self.curProjPanel.SetProjection(proj)                          self.curProjPanel.SetProjection(proj)
461                            break
462                      i += 1                      i += 1
463                    else:
464                        self.projchoice.Select(0)
465                        self.projchoice.Disable()
466                        self._show_proj_panel(UnknownProjPanel)
467                        assert self.curProjPanel is not None
468                        self.curProjPanel.SetProjection(proj)
469            else:
470                self.projfilepath.SetLabel(_("Multiple Projections selected"))
471    
472          self.__VerifyButtons()          self.__VerifyButtons()
473    
# Line 410  class ProjFrame(NonModalDialog): Line 475  class ProjFrame(NonModalDialog):
475          self.__DoOnProjChoice()          self.__DoOnProjChoice()
476    
477      def __DoOnProjChoice(self):      def __DoOnProjChoice(self):
478            """Create and layout a projection panel based on the selected
479            projection type.
480    
481            This is necessary to have in seperate method since calls to
482            wxChoice.SetSelection() do not trigger an event.
483    
484            At the end of this method self.curProjPanel will not be None
485            if there was a item selected.
486            """
487          choice = self.projchoice          choice = self.projchoice
488    
489          sel = choice.GetSelection()          sel = choice.GetSelection()
490          if sel != -1:          if sel != -1:
491                proj_type = choice.GetClientData(sel)
492              clazz, obj = choice.GetClientData(sel)              for t, name, cls in self.projection_panel_defs:
493                    if t == proj_type:
494              if obj is None:                      self._show_proj_panel(cls)
495                  obj = clazz(self.panel_edit, self.receiver)                      break
496                  choice.SetClientData(sel, [clazz, obj])          # FIXME: what to do if sel == -1?
497    
498              if self.curProjPanel is not None:      def _show_proj_panel(self, panel_class):
499                  self.curProjPanel.Hide()          """Show the panel as the projection panel"""
500                  self.sizer_projctrls.Remove(self.curProjPanel)          if panel_class is UnknownProjPanel:
501                self.edit_box.Disable()
502              self.curProjPanel = obj              self.nbsizer.Activate(self.unknown_projection_panel)
503              self.curProjPanel.Show()              self.curProjPanel = self.unknown_projection_panel
504            else:
505              self.sizer_projctrls.Add(self.curProjPanel, 1,              self.edit_box.Enable(True)
506                  wxALL|wxEXPAND|wxADJUST_MINSIZE, 3)              self.unknown_projection_panel.Hide()
507              self.sizer_projctrls.Layout()              for panel in self.projection_panels:
508              self.Layout()                  if panel.__class__ is panel_class:
509              self.topBox.SetSizeHints(self)                      self.nbsizer.Activate(panel)
510                        self.curProjPanel = panel
511    
512      def __SetProjection(self):      def __SetProjection(self):
513            """Set the receiver's projection."""
514    
515          #          #
516          # save the original projection only once in case          # save the original projection only once in case
517          # we try to apply several different projections          # we try to apply several different projections
518          #          #
         if self.originalProjection == -1:  
             self.originalProjection = self.receiver.GetProjection()  
   
519          self.receiver.SetProjection(self.__GetProjection())          self.receiver.SetProjection(self.__GetProjection())
520    
521      def __GetProjection(self):      def __GetProjection(self):
522          """Return the packaged projection.          """Return a suitable Projection object based on the current
523            state of the dialog box selections.
524    
525          Could be None.          Could be None.
526          """          """
527    
528          proj = None          assert self.projection_list.GetSelectedItemCount() < 2, \
529                   "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()  
530    
531          #          sel = self.projection_list.selected_projections()
532          # the list can never be empty. there will always be          if len(sel) == 1:
533          # at least this one item              if sel[0][0] is None:
534          #                  # <None> is selected
535          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()  
536    
537          # begin wxGlade: ProjFrame.__set_properties          # self.curProjPanel should always contain the most relevant data
538          self.SetTitle(_("Projections"))          # for a projection
539          self.availprojs.SetSelection(0)          if self.curProjPanel is not None:
540          self.projchoice.SetSelection(0)              return Projection(self.curProjPanel.GetParameters(),
541          # end wxGlade                                self.projname.GetValue())
542    
543          self.projname.SetMaxLength(32)          return None
544    
545      def __do_layout(self):      def load_user_proj(self):
546          # originally generated by wxGlade          ThubanBeginBusyCursor()
547            try:
548                if self.__usrProjFile is None:
549                    projfile, warnings = get_user_proj_file()
550                    self.show_warnings(_("Warnings"), projfile.GetFilename(),
551                                       warnings)
552                    self.__usrProjFile = projfile
553                return self.__usrProjFile
554            finally:
555                ThubanEndBusyCursor()
556    
557          self.topBox = wxBoxSizer(wxVERTICAL)      def load_system_proj(self):
558          self.sizer_panel = wxBoxSizer(wxVERTICAL)          ThubanBeginBusyCursor()
559          sizer_6 = wxBoxSizer(wxHORIZONTAL)          try:
560          self.sizer_mainctrls = wxBoxSizer(wxHORIZONTAL)              if self.__sysProjFile is None:
561          self.sizer_edit = wxStaticBoxSizer(wxStaticBox(self.panel_edit, -1, _("Edit")), wxHORIZONTAL)                  projfile, warnings = get_system_proj_file()
562          sizer_11 = wxBoxSizer(wxVERTICAL)                  self.show_warnings(_("Warnings"), projfile.GetFilename(),
563          self.sizer_projctrls = wxBoxSizer(wxVERTICAL)                                     warnings)
564          sizer_14 = wxBoxSizer(wxHORIZONTAL)                  self.__sysProjFile = projfile
565          sizer_13 = wxBoxSizer(wxHORIZONTAL)              return self.__sysProjFile
566          sizer_15 = wxBoxSizer(wxVERTICAL)          finally:
567          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)  
568    
569          self.topBox.Add(self.sizer_mainctrls, 1, wxALL|wxEXPAND, 4)      def write_proj_file(self, proj_file):
570          self.topBox.Add(self.panel_buttons, 0, wxEXPAND, 0)          """Write the ProjFile object proj_file back to its file
571    
572          self.SetAutoLayout(1)          Show a busy cursor while writing and if an error occurs show a
573          self.SetSizer(self.topBox)          dialog with the error message.
574          self.topBox.Fit(self)          """
575          self.topBox.SetSizeHints(self)          try:
576          self.Layout()              ThubanBeginBusyCursor()
577                try:
578                    write_proj_file(proj_file)
579                finally:
580                    ThubanEndBusyCursor()
581            except IOError, (errno, errstr):
582                self.__ShowError(proj_file.GetFilename(), errstr)
583    
 # end of class ProjFrame  
584    
585    
586  class ProjPanel(wxPanel):  class ProjPanel(wxPanel):
# Line 606  class ProjPanel(wxPanel): Line 590  class ProjPanel(wxPanel):
590          wxPanel.__init__(self, parent, -1)          wxPanel.__init__(self, parent, -1)
591    
592          self.__ellps = wxChoice(self, -1)          self.__ellps = wxChoice(self, -1)
593          self.ellpsData = [("bessel", _("Bessel 1841")),          self.ellpsData = [("", _("<Unknown>")),
594                            ("clrk66", _("Clarke 1866")),                            ("airy"  , _("Airy")),
595                              ("bessel", _("Bessel 1841")),
596                              ("clrk66", _("Clarke 1866")),
597                            ("clrk80", _("Clarke 1880")),                            ("clrk80", _("Clarke 1880")),
598                            ("GRS80" , _("GRS 1980 (IUGG, 1980)")),                            ("GRS80" , _("GRS 1980 (IUGG, 1980)")),
599                            ("intl"  , _("International 1909 (Hayford)")),                            ("intl"  , _("International 1909 (Hayford)")),
# Line 622  class ProjPanel(wxPanel): Line 608  class ProjPanel(wxPanel):
608    
609          panelSizer = wxBoxSizer(wxVERTICAL)          panelSizer = wxBoxSizer(wxVERTICAL)
610    
         if childPanel is not None:  
             panelSizer.Add(childPanel, 0, wxALL|wxEXPAND, 4)  
               
611          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wxBoxSizer(wxHORIZONTAL)
612          sizer.Add(wxStaticText(self, -1, _("Ellipsoid:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Ellipsoid:")), 0,
613          sizer.Add(self.__ellps, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)                                      wxALL|wxALIGN_CENTER_VERTICAL, 4)
614            sizer.Add(self.__ellps, 1, wxALL|wxALIGN_CENTER_VERTICAL, 4)
615          panelSizer.Add(sizer, 0, wxALL|wxEXPAND, 4)          panelSizer.Add(sizer, 0, wxALL|wxEXPAND, 4)
616    
617            if childPanel is not None:
618                panelSizer.Add(childPanel, 0, wxEXPAND, 0)
619                
620          self.SetAutoLayout(1)          self.SetAutoLayout(1)
621          self.SetSizer(panelSizer)          self.SetSizer(panelSizer)
622          panelSizer.Fit(self)          panelSizer.Fit(self)
# Line 652  class ProjPanel(wxPanel): Line 639  class ProjPanel(wxPanel):
639          self.__ellps.SetSelection(0)          self.__ellps.SetSelection(0)
640    
641      def GetParameters(self):      def GetParameters(self):
642          return ["ellps=" + self.__ellps.GetClientData(          ellps = self.__ellps.GetSelection()
643                                          self.__ellps.GetSelection())]          if ellps > 0:
644                return ["ellps=" + self.__ellps.GetClientData(ellps)]
645            return []
646    
647    
648  ID_TMPANEL_LAT = 4001  ID_TMPANEL_LAT = 4001
# Line 663  ID_TMPANEL_FALSE_NORTH = 4004 Line 652  ID_TMPANEL_FALSE_NORTH = 4004
652  ID_TMPANEL_SCALE = 4005  ID_TMPANEL_SCALE = 4005
653    
654  class UnknownProjPanel(ProjPanel):  class UnknownProjPanel(ProjPanel):
655    
656        """Panel for unknown projection types"""
657    
658      def __init__(self, parent, receiver):      def __init__(self, parent, receiver):
659          ProjPanel.__init__(self, parent)          ProjPanel.__init__(self, parent)
660    
661            self.__text = _("Thuban does not know the parameters\n"
662                            "for the current projection and cannot\n"
663                            "display a configuration panel.\n\n"
664                            "The unidentified set of parameters is:\n\n")
665    
666            self.__textbox = wxTextCtrl(self, -1, self.__text, size=(100,200),
667                                style=wxTE_READONLY|wxTE_MULTILINE|wxTE_LINEWRAP)
668          self._DoLayout()          self._DoLayout()
669    
670      def _DoLayout(self):      def _DoLayout(self):
671          sizer = wxBoxSizer(wxVERTICAL)          sizer = wxBoxSizer(wxVERTICAL)
672    
673          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.")))  
674    
675          ProjPanel._DoLayout(self, sizer)          ProjPanel._DoLayout(self, sizer)
676    
# Line 682  class UnknownProjPanel(ProjPanel): Line 678  class UnknownProjPanel(ProjPanel):
678          return "Unknown"          return "Unknown"
679    
680      def SetProjection(self, proj):      def SetProjection(self, proj):
681          pass          """Append the available parameters to the info text."""
682            text = self.__text
683            for param in proj.GetAllParameters():
684                text = text + '%s\n' % param
685            self.__textbox.SetValue(text)
686    
687      def GetParameters(self):      def GetParameters(self):
688          return None          return None
# Line 703  class TMPanel(ProjPanel): Line 703  class TMPanel(ProjPanel):
703    
704      def _DoLayout(self):      def _DoLayout(self):
705    
706          sizer = wxFlexGridSizer(4, 4, 0, 0)          sizer = wxFlexGridSizer(4, 2, 0, 0)
707          sizer.Add(wxStaticText(self, -1, _("Latitude:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Latitude:")), 0, wxALL, 4)
708          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)  
709          sizer.Add(wxStaticText(self, -1, _("Longitude:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Longitude:")), 0, wxALL, 4)
710          sizer.Add(self.__longitude, 0, wxALL, 4)          sizer.Add(self.__longitude, 0, wxALL, 4)
711            sizer.Add(wxStaticText(self, -1, _("False Easting:")), 0, wxALL, 4)
712            sizer.Add(self.__falseEast, 0, wxALL, 4)
713          sizer.Add(wxStaticText(self, -1, _("False Northing:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("False Northing:")), 0, wxALL, 4)
714          sizer.Add(self.__falseNorth, 0, wxALL, 4)          sizer.Add(self.__falseNorth, 0, wxALL, 4)
715          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 763  class UTMPanel(ProjPanel):
763          self.receiver = receiver          self.receiver = receiver
764    
765          self.__zone = wxSpinCtrl(self, ID_UTMPANEL_ZONE, "1", min=1, max=60)          self.__zone = wxSpinCtrl(self, ID_UTMPANEL_ZONE, "1", min=1, max=60)
766            self.__propButton = wxButton(self, ID_UTMPANEL_PROP, _("Propose"))
767          self.__south = wxCheckBox(self, ID_UTMPANEL_SOUTH,          self.__south = wxCheckBox(self, ID_UTMPANEL_SOUTH,
768                                    _("Southern Hemisphere"))                                    _("Southern Hemisphere"))
         self.__propButton = wxButton(self, ID_UTMPANEL_PROP, _("Propose"))  
769    
770          self._DoLayout()          self._DoLayout()
771    
# Line 805  class UTMPanel(ProjPanel): Line 805  class UTMPanel(ProjPanel):
805          ProjPanel.Clear(self)          ProjPanel.Clear(self)
806    
807      def _OnPropose(self, event):      def _OnPropose(self, event):
808          UTMProposeZoneDialog          """Call the propose dialog.
809            If the receiver (e.g. the current map) has no bounding box,
810            inform the user accordingly.
811            """
812            bb = self.receiver.BoundingBox()
813            if bb is None:
814                dlg = wxMessageDialog(self,
815                        _("Can not propose: No bounding box found."),
816                        _("Projection: Propose UTM Zone"),
817                        wxOK | wxICON_INFORMATION)
818                dlg.CenterOnParent()
819                result = dlg.ShowModal()
820                dlg.Destroy()
821                return
822    
823          dlg = UTMProposeZoneDialog(self, self.receiver.BoundingBox())          dlg = UTMProposeZoneDialog(self, self.receiver.BoundingBox())
824          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
825              self.__zone.SetValue(dlg.GetProposedZone())              self.__zone.SetValue(dlg.GetProposedZone())
# Line 818  class LCCPanel(ProjPanel): Line 832  class LCCPanel(ProjPanel):
832                    
833          self.__fspLatitude = wxTextCtrl(self, -1)          self.__fspLatitude = wxTextCtrl(self, -1)
834          self.__sspLatitude = wxTextCtrl(self, -1)          self.__sspLatitude = wxTextCtrl(self, -1)
         self.__originLat   = wxTextCtrl(self, -1)  
835          self.__meridian    = wxTextCtrl(self, -1)          self.__meridian    = wxTextCtrl(self, -1)
836            self.__originLat   = wxTextCtrl(self, -1)
837          self.__falseEast   = wxTextCtrl(self, -1)          self.__falseEast   = wxTextCtrl(self, -1)
838          self.__falseNorth  = wxTextCtrl(self, -1)          self.__falseNorth  = wxTextCtrl(self, -1)
839    
# Line 834  class LCCPanel(ProjPanel): Line 848  class LCCPanel(ProjPanel):
848          sizer.Add(wxStaticText(self, -1,          sizer.Add(wxStaticText(self, -1,
849              _("Latitude of second standard parallel:")))              _("Latitude of second standard parallel:")))
850          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)  
851          sizer.Add(wxStaticText(self, -1, _("Central Meridian:")))          sizer.Add(wxStaticText(self, -1, _("Central Meridian:")))
852          sizer.Add(self.__meridian, 0, wxALL, 4)          sizer.Add(self.__meridian, 0, wxALL, 4)
853            sizer.Add(wxStaticText(self, -1, _("Latitude of origin:")))
854            sizer.Add(self.__originLat, 0, wxALL, 4)
855          sizer.Add(wxStaticText(self, -1, _("False Easting:")))          sizer.Add(wxStaticText(self, -1, _("False Easting:")))
856          sizer.Add(self.__falseEast, 0, wxALL, 4)          sizer.Add(self.__falseEast, 0, wxALL, 4)
857          sizer.Add(wxStaticText(self, -1, _("False Northing:")))          sizer.Add(wxStaticText(self, -1, _("False Northing:")))
# Line 885  class GeoPanel(ProjPanel): Line 899  class GeoPanel(ProjPanel):
899    
900      def __init__(self, parent, receiver):      def __init__(self, parent, receiver):
901          ProjPanel.__init__(self, parent)          ProjPanel.__init__(self, parent)
902          ProjPanel._DoLayout(self, None)  
903            self.__choices = [(_("Degrees"), "0.017453"),
904                              (_("Radians"), "1")]
905    
906            self.__scale = wxChoice(self, -1)
907            for choice, value in self.__choices:
908                self.__scale.Append(choice, value)
909    
910            self._DoLayout()
911    
912      def GetProjName(self):      def GetProjName(self):
913          return _("Geographic")          return _("Geographic")
914                    
915      def SetProjection(self, proj):      def SetProjection(self, proj):
916            value = proj.GetParameter("to_meter")
917            for i in range(len(self.__choices)):
918                choice, data = self.__choices[i]
919                if value == data:
920                    self.__scale.SetSelection(i)
921          ProjPanel.SetProjection(self, proj)          ProjPanel.SetProjection(self, proj)
922    
923      def GetParameters(self):      def GetParameters(self):
924          params = ["proj=latlong"]          params = ["proj=latlong",
925                      "to_meter=%s" % self.__scale.GetClientData(
926                                      self.__scale.GetSelection())]
927    
928          params.extend(ProjPanel.GetParameters(self))          params.extend(ProjPanel.GetParameters(self))
929          return params          return params
930    
931      def Clear(self):      def Clear(self):
932          ProjPanel.Clear(self)          ProjPanel.Clear(self)
933    
934        def _DoLayout(self):
935            sizer = wxBoxSizer(wxHORIZONTAL)
936    
937            sizer.Add(wxStaticText(self, -1, _("Source Data is in: ")),
938                      0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
939            sizer.Add(self.__scale, 1, wxEXPAND|wxALL, 4)
940    
941            self.__scale.SetSelection(0)
942    
943            ProjPanel._DoLayout(self, sizer)
944    
945    
946  ID_UTM_PROPOSE_ZONE_DIALOG_TAKE   = 4001  ID_UTM_PROPOSE_ZONE_DIALOG_TAKE   = 4001
947  ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL = 4002  ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL = 4002
948  class UTMProposeZoneDialog(wxDialog):  class UTMProposeZoneDialog(wxDialog):
949                                                                                    
950      """Propose a sensible Zone considering the current map extent."""      """Propose a sensible Zone considering the current map extent."""
951                                                                                    
952      def __init__(self, parent, (x, y, x2, y2)):      def __init__(self, parent, (x, y, x2, y2)):
953          wxDialog.__init__(self, parent, -1, _("Projection: Propose UTM Zone"),          wxDialog.__init__(self, parent, -1, _("Projection: Propose UTM Zone"),
954                            wxDefaultPosition, wxSize(200, 100))                            wxDefaultPosition, wxSize(200, 100))
955          self.parent = parent          self.parent = parent
         #x, y, x2, y2 = elf.parent.parent.map_bounding_box  
956          x = x + 180          x = x + 180
957          x2 = x2 + 180          x2 = x2 + 180
958          center = (x2 - x) / 2 + x          center = (x2 - x) / 2 + x
959          self.proposedZone = int(center / 6 + 1)          self.proposedZone = int(center / 6 + 1)
960          self.dialogLayout()          self.dialogLayout()
961                                                                                    
962      def dialogLayout(self):      def dialogLayout(self):
963          topBox = wxBoxSizer(wxVERTICAL)          topBox = wxBoxSizer(wxVERTICAL)
964                                                                                    
965          textBox = wxBoxSizer(wxVERTICAL)          textBox = wxBoxSizer(wxVERTICAL)
966          textBox.Add(wxStaticText(self, -1, _("The current map extent center " +          textBox.Add(wxStaticText(self, -1, _("The current map extent center "
967                                             "lies in UTM Zone")),                                               "lies in UTM Zone")),
968                      0, wxALIGN_CENTER|wxALL, 4)                      0, wxALIGN_CENTER|wxALL, 4)
969          textBox.Add(wxStaticText(self, -1, str(self.proposedZone)),          textBox.Add(wxStaticText(self, -1, str(self.proposedZone)),
970                      0, wxALIGN_CENTER|wxALL, 4)                      0, wxALIGN_CENTER|wxALL, 4)
971                                                                                    
972          topBox.Add(textBox, 1, wxEXPAND|wxALL, 4)          topBox.Add(textBox, 1, wxEXPAND|wxALL, 4)
973                                                                                    
974          buttonBox = wxBoxSizer(wxHORIZONTAL)          buttonBox = wxBoxSizer(wxHORIZONTAL)
975          buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE,          buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE,
976                        _("Take")), 0, wxALL, 4)                        _("Take")), 0, wxALL, 4)
# Line 939  class UTMProposeZoneDialog(wxDialog): Line 979  class UTMProposeZoneDialog(wxDialog):
979          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10)          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10)
980          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE, self.OnTake)          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE, self.OnTake)
981          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL, self.OnCancel)          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL, self.OnCancel)
982                                                                                    
983          self.SetAutoLayout(True)          self.SetAutoLayout(True)
984          self.SetSizer(topBox)          self.SetSizer(topBox)
985          topBox.Fit(self)          topBox.Fit(self)
986          topBox.SetSizeHints(self)          topBox.SetSizeHints(self)
987                                                                                    
988      def OnTake(self, event):      def OnTake(self, event):
989          self.EndModal(wxID_OK)          self.EndModal(wxID_OK)
990                                                                                    
991      def OnCancel(self, event):      def OnCancel(self, event):
992          self.EndModal(wxID_CANCEL)          self.EndModal(wxID_CANCEL)
993    

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26