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

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

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

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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26