/[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 880 by jonathan, Fri May 9 16:33:30 2003 UTC revision 1933 by bh, Tue Nov 11 16:37:53 2003 UTC
# Line 1  Line 1 
1  # Copyright (c) 2003 by Intevation GmbH  # Copyright (c) 2003 by Intevation GmbH
2  # Authors:  # Authors:
3  # Jonathan Coles <[email protected]>  # 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)  # This program is free software under the GPL (>=v2)
8  # Read the file COPYING coming with Thuban for details.  # Read the file COPYING coming with Thuban for details.
9                                                                                    
10  import os, sys, math  """Projection dialog"""
11    
12    __version__ = "$Revision$"
13    # $Source$
14    # $Id$
15    
16    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
# Line 32  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, title, receiver):      def __init__(self, parent, name, title, receiver):
52          """Initialize the projection dialog.          """Initialize the projection dialog.
# Line 41  class ProjFrame(NonModalDialog): Line 55  class ProjFrame(NonModalDialog):
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.haveTried = False          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, title)  
         # 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, wxID_APPLY, _("Try"))  
         self.button_revert = wxButton(self.panel_buttons, ID_PROJ_REVERT,  
                                       _("Revert"))  
         self.button_ok = wxButton(self.panel_buttons, wxID_OK, _("OK"))  
         self.button_ok.SetDefault()  
         self.button_close = wxButton(self.panel_buttons, wxID_CANCEL,  
                                      _("Close"))  
   
         self.__set_properties()  
         self.__do_layout()  
         # wxGlade  
74    
75          self.originalProjection = self.receiver.GetProjection()          self.originalProjection = self.receiver.GetProjection()
76    
77          self.__DoOnProjAvail()          self.projection_list.SelectProjection(self.originalProjection)
78          self.button_ok.SetFocus()          self.projection_list.SetFocus()
79          self.availprojs.SetFocus()  
80                def build_dialog(self):
81          EVT_BUTTON(self, wxID_APPLY, self.OnApply)          """Build the dialog's widgets and set the event handlers"""
82          EVT_BUTTON(self, ID_PROJ_REVERT, self._OnRevert)          self.topBox = top_box = wxBoxSizer(wxVERTICAL)
83          EVT_BUTTON(self, wxID_OK, self.OnOK)  
84          EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)          main_box = wxBoxSizer(wxHORIZONTAL)
85          EVT_CHOICE(self, ID_PROJ_PROJCHOICE, self._OnProjChoice)          top_box.Add(main_box, 1, wxALL|wxEXPAND)
86          EVT_LISTBOX(self, ID_PROJ_AVAIL, self._OnProjAvail)  
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            #
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    
         EVT_TEXT(self, ID_PROJ_PROJNAME, self._OnProjName)  
206    
207            #
208            # 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 OnApply(self, event):      def OnApply(self, event):
226          self.__SetProjection()          self.__SetProjection()
# Line 133  class ProjFrame(NonModalDialog): Line 241  class ProjFrame(NonModalDialog):
241              self.receiver.SetProjection(self.originalProjection)              self.receiver.SetProjection(self.originalProjection)
242              self.haveTried = False              self.haveTried = False
243    
   
244      def _OnNew(self, event):      def _OnNew(self, event):
245    
246          # clear all selections          self.projection_list.ClearSelection()
         sel = self.availprojs.GetSelections()  
         for index in sel:  
             self.availprojs.SetSelection(index, False)  
   
247          self.projname.Clear()          self.projname.Clear()
248    
249          # supply a projection panel if there wasn't one          # supply a projection panel if there wasn't one
# Line 148  class ProjFrame(NonModalDialog): Line 251  class ProjFrame(NonModalDialog):
251              self.projchoice.SetSelection(0)              self.projchoice.SetSelection(0)
252              self.__DoOnProjChoice()              self.__DoOnProjChoice()
253    
254          self.curProjPanel.Clear()          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                # FIXME: we should only allow this for the user proj file.
270              projfile.Replace(proj, newproj)              projfile.Replace(proj, newproj)
271              try:              self.write_proj_file(projfile)
272                  WriteProjFile(projfile)              self.projection_list.SelectProjection(newproj)
             except IOError, (errno, errstr):  
                 self.__ShowError(projfile.GetFilename(), errstr)  
             self.availprojs.SetClientData(sel[0], [newproj, projfile])  
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):  
                 self.__ShowError(self.__userProjFile.GetFilename(), errstr)  
281    
282              self.__FillAvailList()      def show_warnings(self, title, filename, warnings):
283            """Show the warnings (a list of strings) in a dialog
284    
285      def _OnProjAvail(self, event):          If the list is empty no dialog will be shown.
286          self.__DoOnProjAvail()          """
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                  self.__ShowError(dlg.GetPath(), errstr)                      self.show_warnings(_("Warnings"), path, warnings)
312                        for proj in projFile.GetProjections():
313              self.__FillAvailList()                          self.__usrProjFile.Add(proj)
314                        self.write_proj_file(self.__usrProjFile)
315                finally:
316                    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):  
                 self.__ShowError(dlg.GetPath(), errstr)  
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()  
   
         newselection = -1  
         if len(sel) == 1:  
             newselection = sel[0] - 1  
             if newselection < 0:  
                 newselection = 0  
   
         for i in sel:  
             proj, projfile = self.availprojs.GetClientData(i)  
   
             #  
             # this could be the case if they selected <None> or  
             # the currently used projection  
             #  
             if proj is not None and projfile is not None:  
                 projfile.Remove(proj)  
354    
355          try:          if modified:
356              WriteProjFile(projfile)              self.write_proj_file(self.__usrProjFile)
         except IOError, (errno, errstr):  
             self.__ShowError(projfile.GetFilename(), errstr)  
357    
358          self.__FillAvailList()      def _OnShowEPSG(self, event):
359            """Handler for the EVT_CHECKBOX events from the EPSG check button
360    
361          #          If the button is checked add the EPSG_PROJ_FILE to the list of
362          # this *could* produce incorrect results if the .proj files          projfiles shown by the projection list. Otherwise remove it
363          # change between the last list update and this selection          """
364          # because the list has been repopulated.          if self.check_epsg.IsChecked():
365          #              proj_files = [self.load_user_proj(),
366          if newselection != -1 and self.availprojs.GetCount() > 0:                            self.load_system_proj(DEFAULT_PROJ_FILE),
367              self.availprojs.SetSelection(newselection)                            self.load_system_proj(EPSG_PROJ_FILE)]
368            else:
369          self.__VerifyButtons()              proj_files = [self.load_user_proj(),
370                              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):      def __ShowError(self, filename, errstr):
377          wxMessageDialog(self,          wxMessageDialog(self,
378              _("The following error occured:\n") +              _("The following error occured:\n") +
379              filename + "\n" + errstr,              filename + "\n" + errstr,
380              _("Error"), wxOK | wxICON_ERROR).ShowModal()              _("Error"), wxOK | wxICON_ERROR).ShowModal()
381    
382      def __VerifyButtons(self):      def __VerifyButtons(self):
383          """Enable or disable the appropriate buttons based on the          """Update button sensitivity"""
         current state of the dialog.  
         """  
384    
385          sel = self.availprojs.GetSelections()          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,          for ctrl in [self.button_import,
395                       self.button_export,                       self.button_export,
# Line 303  class ProjFrame(NonModalDialog): Line 398  class ProjFrame(NonModalDialog):
398                       self.button_add,                       self.button_add,
399                       self.projchoice,                       self.projchoice,
400                       self.projname,                       self.projname,
401                       self.panel_edit]:                       self.edit_box]:
402              ctrl.Enable(True)              ctrl.Enable(True)
403    
404          if self.curProjPanel is not None:          if self.curProjPanel is not None:
405              self.curProjPanel.Enable(True)              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)              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)
# Line 342  class ProjFrame(NonModalDialog): Line 438  class ProjFrame(NonModalDialog):
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 __DoOnProjAvail(self):  
   
         sel = self.availprojs.GetSelections()  
         if len(sel) == 1:  
442    
443              proj = self.availprojs.GetClientData(sel[0])[CLIENT_PROJ]      def proj_selection_changed(self, projs):
444              projfile = self.availprojs.GetClientData(sel[0])[CLIENT_PROJFILE]          """Subscribed to the projection_list's PROJ_SELECTION_CHANGED message
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                          #                          #
# Line 380  class ProjFrame(NonModalDialog): Line 479  class ProjFrame(NonModalDialog):
479                          assert self.curProjPanel is not None                          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 397  class ProjFrame(NonModalDialog): Line 505  class ProjFrame(NonModalDialog):
505          At the end of this method self.curProjPanel will not be None          At the end of this method self.curProjPanel will not be None
506          if there was a item selected.          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."""          """Set the receiver's projection."""
# Line 438  class ProjFrame(NonModalDialog): Line 546  class ProjFrame(NonModalDialog):
546          Could be None.          Could be None.
547          """          """
548    
549          sel = self.availprojs.GetSelections()          assert self.projection_list.GetSelectedItemCount() < 2, \
550          assert len(sel) < 2, "button should be disabled"                 "button should be disabled"
   
551    
552            sel = self.projection_list.selected_projections()
553          if len(sel) == 1:          if len(sel) == 1:
554              proj = self.availprojs.GetClientData(sel[0])[CLIENT_PROJ]              if sel[0][0] is None:
             if proj is None:  
555                  # <None> is selected                  # <None> is selected
556                  return None                  return None
557    
558          #          # self.curProjPanel should always contain the most relevant data
559          # self.curProjPanel should always contain the most          # for a projection
         # relevant data for a projection  
         #  
560          if self.curProjPanel is not None:          if self.curProjPanel is not None:
561              return Projection(self.curProjPanel.GetParameters(),              return Projection(self.curProjPanel.GetParameters(),
562                                self.projname.GetValue())                                self.projname.GetValue())
563    
564          return None          return None
565    
566      def __FillAvailList(self, selectCurrent = False):      def load_user_proj(self):
567          """Populate the list of available projections.          """Return the user's ProjFile
           
         selectCurrent -- if True, select the projection used by  
                          the receiver, otherwise select nothing.  
         """  
   
         self.availprojs.Clear()  
   
         #  
         # We add the current projection to the list first so that  
         # we are sure that it's at index 0. That way we can  
         # set the selection with confidence. The problem is the  
         # the list is automatically sorted when an item is appended  
         # and the index of where it was inserted is not returned.  
         #  
         proj = self.receiver.GetProjection()  
         if proj is not None:  
             self.availprojs.Append(_("%s (current)") % proj.GetName(),  
                                    [proj, None])  
             if selectCurrent:  
                 self.availprojs.SetSelection(0)  
                 self.availprojs.SetFirstItem(0)  
   
         #  
         # the list can never be empty. there will always be  
         # at least this one item  
         #  
         self.availprojs.Append("<None>", (None, None))  
   
         # proj is only None when <None> should be selected  
         if proj is None and selectCurrent:  
             self.availprojs.SetSelection(0)  
             self.availprojs.SetFirstItem(0)  
   
         projfile = GetSystemProjFiles()  
         projfile = projfile[0]  
         for proj in projfile.GetProjections():  
             self.availprojs.Append(proj.GetName(), [proj, projfile])  
         self.__sysProjFile = projfile  
   
         projfile = GetUserProjFiles()  
         projfile = projfile[0]  
         for proj in projfile.GetProjections():  
             self.availprojs.Append(proj.GetName(), [proj, projfile])  
         self.__usrProjFile = projfile  
   
         for proj, name, clazz in self.projPanels:  
             self.projchoice.Append(name, [clazz, None])  
568    
569      def __set_properties(self):          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          #self.availprojs.SetSelection(0)          Show a busy cursor while loading the file.
573          self.projchoice.SetSelection(0)          """
574            if self.__usrProjFile is None:
575          self.__FillAvailList(selectCurrent = True)              ThubanBeginBusyCursor()
576                try:
577          self.projname.SetMaxLength(32)                  projfile, warnings = get_user_proj_file()
578                    self.show_warnings(_("Warnings"), projfile.GetFilename(),
579      def __do_layout(self):                                     warnings)
580          # originally generated by wxGlade                  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 607  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 = [("airy"  , _("Airy")),          self.ellpsData = [("", _("<Unknown>")),
630                              ("airy"  , _("Airy")),
631                            ("bessel", _("Bessel 1841")),                            ("bessel", _("Bessel 1841")),
632                            ("clrk66", _("Clarke 1866")),                            ("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 624  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, wxEXPAND, 0)  
               
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 654  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 665  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 684  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 705  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 807  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 820  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 836  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 888  class GeoPanel(ProjPanel): Line 936  class GeoPanel(ProjPanel):
936      def __init__(self, parent, receiver):      def __init__(self, parent, receiver):
937          ProjPanel.__init__(self, parent)          ProjPanel.__init__(self, parent)
938    
939          self.__choices = [(_("Radians"), "1"),          self.__choices = [(_("Degrees"), "0.017453"),
940                            (_("Degrees"), "0.017453")]                            (_("Radians"), "1")]
941    
942          self.__scale = wxChoice(self, -1)          self.__scale = wxChoice(self, -1)
943          for choice, value in self.__choices:          for choice, value in self.__choices:
# Line 923  class GeoPanel(ProjPanel): Line 971  class GeoPanel(ProjPanel):
971          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wxBoxSizer(wxHORIZONTAL)
972    
973          sizer.Add(wxStaticText(self, -1, _("Source Data is in: ")),          sizer.Add(wxStaticText(self, -1, _("Source Data is in: ")),
974                    0, wxALL, 4)                    0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
975          sizer.Add(self.__scale, 1, wxEXPAND|wxALL, 4)          sizer.Add(self.__scale, 1, wxEXPAND|wxALL, 4)
976    
977          self.__scale.SetSelection(0)          self.__scale.SetSelection(0)
# Line 934  class GeoPanel(ProjPanel): Line 982  class GeoPanel(ProjPanel):
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 968  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.880  
changed lines
  Added in v.1933

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26