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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26