/[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 964 by jonathan, Wed May 21 17:24:09 2003 UTC revision 2022 by frank, Fri Dec 5 13:36:10 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                                      EPSG_DEPRECATED_PROJ_FILE
27    from Thuban.UI.dialogs import NonModalNonParentDialog
28    
29    from common import ThubanBeginBusyCursor, ThubanEndBusyCursor
30    from sizers import NotebookLikeSizer
31    from projlist import PROJ_SELECTION_CHANGED, ProjectionList
32    from common import ThubanBeginBusyCursor, ThubanEndBusyCursor
33    
34    
35    
 ID_PROJ_ADVANCED  = 4001  
36  ID_PROJ_PROJCHOICE = 4002  ID_PROJ_PROJCHOICE = 4002
37  ID_PROJ_ADDTOLIST    = 4003  ID_PROJ_ADDTOLIST    = 4003
38  ID_PROJ_NEW       = 4004  ID_PROJ_NEW       = 4004
# Line 32  ID_PROJ_PROJNAME  = 4014 Line 47  ID_PROJ_PROJNAME  = 4014
47  CLIENT_PROJ = 0  CLIENT_PROJ = 0
48  CLIENT_PROJFILE = 1  CLIENT_PROJFILE = 1
49    
50  class ProjFrame(NonModalDialog):  class ProjFrame(NonModalNonParentDialog):
51    
52      def __init__(self, parent, name, title, receiver):      def __init__(self, parent, name, title, receiver):
53          """Initialize the projection dialog.          """Initialize the projection dialog.
# Line 41  class ProjFrame(NonModalDialog): Line 56  class ProjFrame(NonModalDialog):
56                          SetProjection(projection)                          SetProjection(projection)
57                          GetProjection()                          GetProjection()
58          """          """
59                    NonModalNonParentDialog.__init__(self, parent, name, title)
60    
61            self.projection_panel_defs = [
62                ("tmerc", _("Transverse Mercator"), TMPanel),
63                ("utm", _("Universal Transverse Mercator"), UTMPanel),
64                ("lcc", _("Lambert Conic Conformal"), LCCPanel),
65                ("latlong", _("Geographic"), GeoPanel),
66                ("longlat", _("Geographic"), GeoPanel)]#longlat is an alias of proj
67          self.receiver = receiver          self.receiver = receiver
68          self.haveTried = False          self.haveTried = False
69          self.curProjPanel = None          self.curProjPanel = None
70            self.__usrProjFile = None
71            self._sys_proj_files = {}
72    
73          self.projPanels = []          self.build_dialog()
74          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  
75    
76          self.originalProjection = self.receiver.GetProjection()          self.originalProjection = self.receiver.GetProjection()
77    
78          self.__DoOnProjAvail()          self.projection_list.SelectProjection(self.originalProjection)
79          self.button_ok.SetFocus()          self.projection_list.SetFocus()
80          self.availprojs.SetFocus()  
81                def build_dialog(self):
82          EVT_BUTTON(self, wxID_APPLY, self.OnApply)          """Build the dialog's widgets and set the event handlers"""
83          EVT_BUTTON(self, ID_PROJ_REVERT, self._OnRevert)          self.topBox = top_box = wxBoxSizer(wxVERTICAL)
84          EVT_BUTTON(self, wxID_OK, self.OnOK)  
85          EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)          main_box = wxBoxSizer(wxHORIZONTAL)
86          EVT_CHOICE(self, ID_PROJ_PROJCHOICE, self._OnProjChoice)          top_box.Add(main_box, 1, wxALL|wxEXPAND)
87          EVT_LISTBOX(self, ID_PROJ_AVAIL, self._OnProjAvail)  
88            #
89            #    The projection list and associated controls
90            #
91            vbox = wxBoxSizer(wxVERTICAL)
92            main_box.Add(vbox, 4, wxALL|wxEXPAND)
93    
94            #label = wxStaticText(self, -1, _("Available Projections:"))
95            #vbox.Add(label, 0, wxLEFT|wxRIGHT|wxTOP, 4)
96    
97            hbox = wxBoxSizer(wxHORIZONTAL)
98            vbox.Add(hbox, 1, wxALL|wxEXPAND)
99            proj_files = [self.load_user_proj(),
100                          self.load_system_proj(DEFAULT_PROJ_FILE)]
101            self.projection_list = ProjectionList(self, proj_files,
102                                                  self.receiver.GetProjection())
103            hbox.Add(self.projection_list, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)
104            self.projection_list.Subscribe(PROJ_SELECTION_CHANGED,
105                                           self.proj_selection_changed)
106    
107            # Projection List specific actions (Import/Export/Remove)
108            buttons = wxBoxSizer(wxVERTICAL)
109            hbox.Add(buttons, 0, wxALL)
110            self.button_import = wxButton(self, ID_PROJ_IMPORT, _("Import..."))
111          EVT_BUTTON(self, ID_PROJ_IMPORT, self._OnImport)          EVT_BUTTON(self, ID_PROJ_IMPORT, self._OnImport)
112            buttons.Add(self.button_import, 1, wxALL|wxEXPAND, 4)
113            self.button_export = wxButton(self, ID_PROJ_EXPORT, _("Export..."))
114          EVT_BUTTON(self, ID_PROJ_EXPORT, self._OnExport)          EVT_BUTTON(self, ID_PROJ_EXPORT, self._OnExport)
115            buttons.Add(self.button_export, 1, wxALL|wxEXPAND, 4)
116            buttons.Add(20, 20, 0, wxEXPAND, 0)
117            self.button_remove = wxButton(self, ID_PROJ_REMOVE, _("Remove"))
118          EVT_BUTTON(self, ID_PROJ_REMOVE, self._OnRemove)          EVT_BUTTON(self, ID_PROJ_REMOVE, self._OnRemove)
119            buttons.Add(self.button_remove, 1, wxALL|wxEXPAND, 4)
120    
121            buttons.Add(20, 20, 0, wxEXPAND, 0)
122            label = wxStaticText(self, -1, _("Show EPSG:"))
123            buttons.Add(label, 0, wxLEFT|wxRIGHT|wxTOP, 4)
124            self.check_epsg = wxCheckBox(self, -1, _("Normal"))
125            EVT_CHECKBOX(self, self.check_epsg.GetId(), self._OnShowEPSG)
126            buttons.Add(self.check_epsg, 1, wxALL|wxEXPAND, 4)
127            self.check_epsg_depr = wxCheckBox(self, -1, _("Deprecated"))
128            EVT_CHECKBOX(self, self.check_epsg_depr.GetId(), self._OnShowEPSG)
129            buttons.Add(self.check_epsg_depr, 1, wxALL|wxEXPAND, 4)
130    
131            # The file path
132            self.projfilepath = wxStaticText(self, -1, "")
133            vbox.Add(self.projfilepath, 0, wxALL|wxEXPAND)
134    
135            #
136            #   The projection editor part
137            #
138            self.edit_box = wxStaticBox(self, -1, _("Edit"))
139            sizer_edit = wxStaticBoxSizer(self.edit_box, wxHORIZONTAL)
140            main_box.Add(sizer_edit, 5, wxALL|wxEXPAND)
141    
142            # Projection Specific Entries (Name/Projection)
143            self.sizer_projctrls = wxBoxSizer(wxVERTICAL)
144            sizer_edit.Add(self.sizer_projctrls, 1, wxALL|wxEXPAND)
145    
146            hbox = wxBoxSizer(wxHORIZONTAL)
147            self.sizer_projctrls.Add(hbox, 0, wxALL|wxEXPAND)
148            label = wxStaticText(self, -1, _("Name:"))
149            hbox.Add(label, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
150            self.projname = wxTextCtrl(self, ID_PROJ_PROJNAME, "")
151            EVT_TEXT(self, ID_PROJ_PROJNAME, self._OnProjName)
152            hbox.Add(self.projname, 1, wxALL|wxEXPAND, 4)
153    
154            hbox = wxBoxSizer(wxHORIZONTAL)
155            self.sizer_projctrls.Add(hbox, 0, wxALL|wxEXPAND)
156            label = wxStaticText(self, -1, _("Projection:"))
157            hbox.Add(label, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
158            self.projchoice = wxChoice(self, ID_PROJ_PROJCHOICE)
159            self.projchoice.SetSelection(0)
160            EVT_CHOICE(self, ID_PROJ_PROJCHOICE, self._OnProjChoice)
161            hbox.Add(self.projchoice, 1, wxALL|wxEXPAND, 4)
162            # Fill the projection choice list.
163            self.nbsizer = NotebookLikeSizer()
164            self.sizer_projctrls.Add(self.nbsizer, 1,
165                                     wxALL|wxEXPAND|wxADJUST_MINSIZE, 3)
166            self.projection_panels = []
167            self.projchoice.Append(_("<Unknown>"), "")
168            for proj_type, name, cls in self.projection_panel_defs:
169                self.projchoice.Append(name, proj_type)
170                panel = cls(self, self.receiver)
171                panel.Hide()
172                panel.projection_index = len(self.projection_panels)
173                panel.projection_type = proj_type
174                self.projection_panels.append(panel)
175                self.nbsizer.Add(panel)
176            self.unknown_projection_panel = UnknownProjPanel(self, self.receiver)
177            self.unknown_projection_panel.Hide()
178            self.nbsizer.Add(self.unknown_projection_panel)
179    
180            # Projection Specific actions (New/Save/Add)
181            buttons = wxBoxSizer(wxVERTICAL)
182            sizer_edit.Add(buttons, 0, wxALL)
183            self.button_new = wxButton(self, ID_PROJ_NEW, _("New"))
184          EVT_BUTTON(self, ID_PROJ_NEW, self._OnNew)          EVT_BUTTON(self, ID_PROJ_NEW, self._OnNew)
185          EVT_BUTTON(self, ID_PROJ_SAVE, self._OnSave)          buttons.Add(self.button_new, 0, wxEXPAND|wxALL, 4)
186            self.button_add = wxButton(self, ID_PROJ_ADDTOLIST, _("Add to List"))
187          EVT_BUTTON(self, ID_PROJ_ADDTOLIST, self._OnAddToList)          EVT_BUTTON(self, ID_PROJ_ADDTOLIST, self._OnAddToList)
188            buttons.Add(self.button_add, 0, wxEXPAND|wxALL, 4)
189            buttons.Add(20, 20, 0, wxEXPAND, 0)
190            self.button_save = wxButton(self, ID_PROJ_SAVE,_("Update"))
191            EVT_BUTTON(self, ID_PROJ_SAVE, self._OnSave)
192            buttons.Add(self.button_save, 0, wxEXPAND|wxALL|wxALIGN_BOTTOM, 4)
193    
194            #
195            # Main Action buttons (Try/Revert/OK/Close)
196            #
197            buttons = wxBoxSizer(wxHORIZONTAL)
198            top_box.Add(buttons, 0, wxALL|wxALIGN_RIGHT, 10)
199            self.button_try = wxButton(self, wxID_APPLY, _("Try"))
200            EVT_BUTTON(self, wxID_APPLY, self.OnApply)
201            buttons.Add(self.button_try, 0, wxRIGHT, 10)
202            self.button_revert = wxButton(self, ID_PROJ_REVERT, _("Revert"))
203            EVT_BUTTON(self, ID_PROJ_REVERT, self._OnRevert)
204            buttons.Add(self.button_revert, 0, wxRIGHT, 10)
205            self.button_ok = wxButton(self, wxID_OK, _("OK"))
206            EVT_BUTTON(self, wxID_OK, self.OnOK)
207            self.button_ok.SetDefault()
208            buttons.Add(self.button_ok, 0, wxRIGHT, 10)
209            self.button_close = wxButton(self, wxID_CANCEL, _("Close"))
210            EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
211            buttons.Add(self.button_close, 0, wxRIGHT, 10)
212    
         EVT_TEXT(self, ID_PROJ_PROJNAME, self._OnProjName)  
213    
214            #
215            # Automatic Layout
216            #
217            self.SetAutoLayout(1)
218            self.SetSizer(top_box)
219            top_box.Fit(self)
220            top_box.SetSizeHints(self)
221    
222        def OnClose(self, event):
223            self.projection_list.Unsubscribe(PROJ_SELECTION_CHANGED,
224                                             self.proj_selection_changed)
225            # Destroy the projection list explicitly so that it properly
226            # unsubscribes everything. It would be cleaner if the projection
227            # could do this by itself but wx doesn't always send destroy
228            # events for non-top-level widgets
229            self.projection_list.Destroy()
230            NonModalNonParentDialog.OnClose(self, event)
231    
232      def OnApply(self, event):      def OnApply(self, event):
233          self.__SetProjection()          self.__SetProjection()
# Line 133  class ProjFrame(NonModalDialog): Line 248  class ProjFrame(NonModalDialog):
248              self.receiver.SetProjection(self.originalProjection)              self.receiver.SetProjection(self.originalProjection)
249              self.haveTried = False              self.haveTried = False
250    
   
251      def _OnNew(self, event):      def _OnNew(self, event):
252    
253          # clear all selections          self.projection_list.ClearSelection()
         sel = self.availprojs.GetSelections()  
         for index in sel:  
             self.availprojs.SetSelection(index, False)  
   
254          self.projname.Clear()          self.projname.Clear()
255    
256          # supply a projection panel if there wasn't one          # supply a projection panel if there wasn't one
# Line 148  class ProjFrame(NonModalDialog): Line 258  class ProjFrame(NonModalDialog):
258              self.projchoice.SetSelection(0)              self.projchoice.SetSelection(0)
259              self.__DoOnProjChoice()              self.__DoOnProjChoice()
260    
261          self.curProjPanel.Clear()          if self.curProjPanel is not None:
262                self.curProjPanel.Clear()
263    
264      def _OnSave(self, event):      def _OnSave(self, event):
265    
266          sel = self.availprojs.GetSelections()          sel = self.projection_list.selected_projections()
267          assert len(sel) == 1,  "button shouldn't be enabled"          assert len(sel) == 1,  "button shouldn't be enabled"
268    
269          proj, projfile = self.availprojs.GetClientData(sel[0])          proj, projfile = sel[0]
270    
271          assert proj is not None and projfile is not None          assert proj is not None and projfile is not None
272    
273          newproj = self.__GetProjection()          newproj = self.__GetProjection()
274    
275          if newproj is not None:          if newproj is not None:
276                # FIXME: we should only allow this for the user proj file.
277              projfile.Replace(proj, newproj)              projfile.Replace(proj, newproj)
278              try:              self.write_proj_file(projfile)
279                  WriteProjFile(projfile)              self.projection_list.SelectProjection(newproj)
             except IOError, (errno, errstr):  
                 self.__ShowError(projfile.GetFilename(), errstr)  
             self.availprojs.SetClientData(sel[0], [newproj, projfile])  
280    
281      def _OnAddToList(self, event):      def _OnAddToList(self, event):
282    
283          proj = self.__GetProjection()          proj = self.__GetProjection()
284          if proj is not None:          if proj is not None:
285              self.__usrProjFile.Add(proj)              self.__usrProjFile.Add(proj)
286              try:              self.write_proj_file(self.__usrProjFile)
287                  WriteProjFile(self.__usrProjFile)              self.projection_list.SelectProjection(proj)
             except IOError, (errno, errstr):  
                 self.__ShowError(self.__userProjFile.GetFilename(), errstr)  
288    
289              self.__FillAvailList()      def show_warnings(self, title, filename, warnings):
290            """Show the warnings (a list of strings) in a dialog
291    
292      def _OnProjAvail(self, event):          If the list is empty no dialog will be shown.
293          self.__DoOnProjAvail()          """
294            if warnings:
295                text = (_('Warnings when reading "%s":\n\n%s')
296                        % (filename, "\n\n".join(warnings)))
297                self.parent.RunMessageBox(title, text)
298    
299      def _OnImport(self, event):      def _OnImport(self, event):
300            """Handler for the 'Import' button
301    
302            Ask the user for a filename, read the projections from that file
303            add them to the user ProjFile object and write the user file
304            back to disk.
305            """
306          dlg = wxFileDialog(self, _("Import"), style = wxOPEN)          dlg = wxFileDialog(self, _("Import"), style = wxOPEN)
307    
308          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
309              path = dlg.GetPath()              path = dlg.GetPath()
310    
311                ThubanBeginBusyCursor()
312              try:              try:
313                  projFile = ReadProjFile(path)                  try:
314                  for proj in projFile.GetProjections():                      projFile, warnings = read_proj_file(path)
315                      self.__usrProjFile.Add(proj)                  except IOError, (errno, errstr):
316                  WriteProjFile(self.__usrProjFile)                      self.__ShowError(dlg.GetPath(), errstr)
317              except IOError, (errno, errstr):                  else:
318                  self.__ShowError(dlg.GetPath(), errstr)                      self.show_warnings(_("Warnings"), path, warnings)
319                        for proj in projFile.GetProjections():
320              self.__FillAvailList()                          self.__usrProjFile.Add(proj)
321                        self.write_proj_file(self.__usrProjFile)
322                finally:
323                    ThubanEndBusyCursor()
324          dlg.Destroy()          dlg.Destroy()
325    
326      def _OnExport(self, event):      def _OnExport(self, event):
327            """Handler for the 'Export' button.
328    
329          sel = self.availprojs.GetSelections()          Ask the user for a filename and write the selected projections
330            to that file.
331            """
332            sel = self.projection_list.selected_projections()
333          assert len(sel) != 0, "button should be disabled"          assert len(sel) != 0, "button should be disabled"
334    
335          dlg = wxFileDialog(self, _("Export"),          dlg = wxFileDialog(self, _("Export"), style=wxSAVE|wxOVERWRITE_PROMPT)
                         style = wxSAVE|wxOVERWRITE_PROMPT)  
336    
337          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
338              path = dlg.GetPath()              proj_file = ProjFile(dlg.GetPath())
339                for proj, pf in sel:
             projFile = ProjFile(path)  
   
             for i in sel:  
                 proj = self.availprojs.GetClientData(i)[CLIENT_PROJ]  
340                  if proj is not None:                  if proj is not None:
341                      projFile.Add(proj)                      proj_file.Add(proj)
342                self.write_proj_file(proj_file)
             try:  
                 WriteProjFile(projFile)  
             except IOError, (errno, errstr):  
                 self.__ShowError(dlg.GetPath(), errstr)  
343    
344          dlg.Destroy()          dlg.Destroy()
345    
346      def _OnRemove(self, event):      def _OnRemove(self, event):
347            """Handler for the 'Remove' button
348    
349          sel = self.availprojs.GetSelections()          Remove any selected projection that came from the user's
350            ProjFile. If the user ProjFile was modified write it back to
351            disk.
352            """
353            sel = self.projection_list.selected_projections()
354          assert len(sel) != 0, "button should be disabled!"          assert len(sel) != 0, "button should be disabled!"
355    
356          #          modified = False
357          # remove the items backwards so the indices don't change          for proj, pf in sel:
358          #              if proj is not None and pf is self.__usrProjFile:
359          sel = list(sel)                  pf.Remove(proj)
360          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)  
361    
362          try:          if modified:
363              WriteProjFile(projfile)              self.write_proj_file(self.__usrProjFile)
         except IOError, (errno, errstr):  
             self.__ShowError(projfile.GetFilename(), errstr)  
364    
365          self.__FillAvailList()      def _OnShowEPSG(self, event):
366            """Handler for the EVT_CHECKBOX events from the EPSG check button
367    
368          #          If the button is checked add the EPSG_PROJ_FILE to the list of
369          # this *could* produce incorrect results if the .proj files          projfiles shown by the projection list. Otherwise remove it
370          # change between the last list update and this selection          """
371          # because the list has been repopulated.          proj_files = [self.load_user_proj(),
372          #                        self.load_system_proj(DEFAULT_PROJ_FILE)]
373          if newselection != -1 and self.availprojs.GetCount() > 0:          if self.check_epsg.IsChecked():
374              self.availprojs.SetSelection(newselection)              proj_files.append(self.load_system_proj(EPSG_PROJ_FILE))
375            if self.check_epsg_depr.IsChecked():
376          self.__VerifyButtons()              proj_files.append(self.load_system_proj(EPSG_DEPRECATED_PROJ_FILE))
377            self.projection_list.SetProjFiles(proj_files)
378    
379      def _OnProjName(self, event):      def _OnProjName(self, event):
380          self.__VerifyButtons()          self.__VerifyButtons()
381    
382      def __ShowError(self, filename, errstr):      def __ShowError(self, filename, errstr):
383          wxMessageDialog(self,          wxMessageDialog(self,
384              _("The following error occured:\n") +              _("The following error occured:\n") +
385              filename + "\n" + errstr,              filename + "\n" + errstr,
386              _("Error"), wxOK | wxICON_ERROR).ShowModal()              _("Error"), wxOK | wxICON_ERROR).ShowModal()
387    
388      def __VerifyButtons(self):      def __VerifyButtons(self):
389          """Enable or disable the appropriate buttons based on the          """Update button sensitivity"""
         current state of the dialog.  
         """  
390    
391          sel = self.availprojs.GetSelections()          num_sel = self.projection_list.GetSelectedItemCount()
392    
393          self.button_import.Enable(True)          self.button_import.Enable(True)
394          self.button_export.Enable(True)          self.button_export.Enable(True)
395          self.button_save.Enable(True)          self.button_save.Enable(True)
396          self.button_remove.Enable(True)          self.button_remove.Enable(True)
397    
398          self.panel_edit.Enable(True)          self.edit_box.Enable(True)
399    
400          for ctrl in [self.button_import,          for ctrl in [self.button_import,
401                       self.button_export,                       self.button_export,
# Line 303  class ProjFrame(NonModalDialog): Line 404  class ProjFrame(NonModalDialog):
404                       self.button_add,                       self.button_add,
405                       self.projchoice,                       self.projchoice,
406                       self.projname,                       self.projname,
407                       self.panel_edit]:                       self.edit_box]:
408              ctrl.Enable(True)              ctrl.Enable(True)
409    
410          if self.curProjPanel is not None:          if self.curProjPanel is not None:
411              self.curProjPanel.Enable(True)              self.curProjPanel.Enable(True)
412    
413          if len(sel) == 0:          if num_sel == 0:
414              self.button_import.Enable(True)              self.button_import.Enable(True)
415              self.button_export.Enable(False)              self.button_export.Enable(False)
416              self.button_remove.Enable(False)              self.button_remove.Enable(False)
417              self.button_save.Enable(False)              self.button_save.Enable(False)
418    
419          elif len(sel) == 1:          elif num_sel == 1:
420    
421              proj, projFile = self.availprojs.GetClientData(sel[0])              selection = self.projection_list.selected_projections()
422                proj, projFile = selection[0]
423    
424              self.button_save.Enable(len(self.projname.GetValue()) > 0)              self.button_save.Enable(len(self.projname.GetValue()) > 0)
425              self.button_add.Enable(len(self.projname.GetValue()) > 0)              self.button_add.Enable(len(self.projname.GetValue()) > 0)
# Line 342  class ProjFrame(NonModalDialog): Line 444  class ProjFrame(NonModalDialog):
444                  self.button_save.Enable(False)                  self.button_save.Enable(False)
445    
446          else:          else:
447              self.panel_edit.Enable(False)              self.edit_box.Enable(False)
448    
449      def __DoOnProjAvail(self):      def proj_selection_changed(self, projs):
450            """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]  
451    
452            Update the dialog to reflect the new selection.
453            """
454            if len(projs) == 0:
455                self.projfilepath.SetLabel(_("No Projections selected"))
456            elif len(projs) == 1:
457                proj, projfile = projs[0]
458              if proj is None:              if proj is None:
459                  # user selected <None>                  # user selected <None>
460                  self.projname.Clear()                  self.projname.Clear()
461                                    self.projfilepath.SetLabel("")
462              else:              else:
               
463                  if projfile is not None:                  if projfile is not None:
464                      self.projfilepath.SetLabel(projfile.GetFilename())                      filename = os.path.basename(projfile.GetFilename())
465                        self.projfilepath.SetLabel(_("Source of Projection: %s")
466                                                   % filename)
467                  else:                  else:
468                      # only None if the currently used projection is selected                      # only None if the currently used projection is selected
469                      self.projfilepath.SetLabel("")                      self.projfilepath.SetLabel("")
470    
471                  self.projname.SetValue(proj.GetName())                  self.projname.SetValue(proj.Label())
472    
473                  myProjType = proj.GetParameter("proj")                  myProjType = proj.GetParameter("proj")
474                  i = 0                  i = 0
475                  for projType, name, clazz in self.projPanels:                  for projType, name, cls in self.projection_panel_defs:
476                      if myProjType == projType:                      if myProjType == projType:
477                          self.projchoice.SetSelection(i)                          self.projchoice.Enable(True)
478                            self.projchoice.SetSelection(i + 1)
479                          self.__DoOnProjChoice()                          self.__DoOnProjChoice()
480    
481                          #                          #
# Line 380  class ProjFrame(NonModalDialog): Line 485  class ProjFrame(NonModalDialog):
485                          assert self.curProjPanel is not None                          assert self.curProjPanel is not None
486    
487                          self.curProjPanel.SetProjection(proj)                          self.curProjPanel.SetProjection(proj)
488                            break
489                      i += 1                      i += 1
490                    else:
491                        self.projchoice.Select(0)
492                        self.projchoice.Disable()
493                        self._show_proj_panel(UnknownProjPanel)
494                        assert self.curProjPanel is not None
495                        self.curProjPanel.SetProjection(proj)
496            else:
497                self.projfilepath.SetLabel(_("Multiple Projections selected"))
498    
499          self.__VerifyButtons()          self.__VerifyButtons()
500    
# Line 397  class ProjFrame(NonModalDialog): Line 511  class ProjFrame(NonModalDialog):
511          At the end of this method self.curProjPanel will not be None          At the end of this method self.curProjPanel will not be None
512          if there was a item selected.          if there was a item selected.
513          """          """
   
514          choice = self.projchoice          choice = self.projchoice
515    
516          sel = choice.GetSelection()          sel = choice.GetSelection()
517          if sel != -1:          if sel != -1:
518                proj_type = choice.GetClientData(sel)
519              clazz, obj = choice.GetClientData(sel)              for t, name, cls in self.projection_panel_defs:
520                    if t == proj_type:
521              if obj is None:                      self._show_proj_panel(cls)
522                  obj = clazz(self.panel_edit, self.receiver)                      break
523                  choice.SetClientData(sel, [clazz, obj])          # FIXME: what to do if sel == -1?
524    
525              if self.curProjPanel is not None:      def _show_proj_panel(self, panel_class):
526                  self.curProjPanel.Hide()          """Show the panel as the projection panel"""
527                  self.sizer_projctrls.Remove(self.curProjPanel)          if panel_class is UnknownProjPanel:
528                self.edit_box.Disable()
529              self.curProjPanel = obj              self.nbsizer.Activate(self.unknown_projection_panel)
530              self.curProjPanel.Show()              self.curProjPanel = self.unknown_projection_panel
531            else:
532              self.sizer_projctrls.Add(self.curProjPanel, 1,              self.edit_box.Enable(True)
533                  wxALL|wxEXPAND|wxADJUST_MINSIZE, 3)              self.unknown_projection_panel.Hide()
534              self.sizer_projctrls.Layout()              for panel in self.projection_panels:
535              self.Layout()                  if panel.__class__ is panel_class:
536              self.topBox.SetSizeHints(self)                      self.nbsizer.Activate(panel)
537                        self.curProjPanel = panel
538    
539      def __SetProjection(self):      def __SetProjection(self):
540          """Set the receiver's projection."""          """Set the receiver's projection."""
# Line 438  class ProjFrame(NonModalDialog): Line 552  class ProjFrame(NonModalDialog):
552          Could be None.          Could be None.
553          """          """
554    
555          sel = self.availprojs.GetSelections()          assert self.projection_list.GetSelectedItemCount() < 2, \
556          assert len(sel) < 2, "button should be disabled"                 "button should be disabled"
   
557    
558            sel = self.projection_list.selected_projections()
559          if len(sel) == 1:          if len(sel) == 1:
560              proj = self.availprojs.GetClientData(sel[0])[CLIENT_PROJ]              if sel[0][0] is None:
             if proj is None:  
561                  # <None> is selected                  # <None> is selected
562                  return None                  return None
563    
564          #          # self.curProjPanel should always contain the most relevant data
565          # self.curProjPanel should always contain the most          # for a projection
         # relevant data for a projection  
         #  
566          if self.curProjPanel is not None:          if self.curProjPanel is not None:
567              return Projection(self.curProjPanel.GetParameters(),              return Projection(self.curProjPanel.GetParameters(),
568                                self.projname.GetValue())                                self.projname.GetValue())
569    
570          return None          return None
571    
572      def __FillAvailList(self, selectCurrent = False):      def load_user_proj(self):
573          """Populate the list of available projections.          """Return the user's ProjFile
           
         selectCurrent -- if True, select the projection used by  
                          the receiver, otherwise select nothing.  
         """  
574    
575          self.availprojs.Clear()          If the file has not yet been loaded by the dialog, load it first
576            with get_user_proj_file and cache it in self.__usrProjFile.
577    
578          #          Show a busy cursor while loading the file.
579          # We add the current projection to the list first so that      
580          # we are sure that it's at index 0. That way we can          If the file is not available, leave a note to the console.
581          # set the selection with confidence. The problem is the          """
582          # the list is automatically sorted when an item is appended          if self.__usrProjFile is None:
583          # and the index of where it was inserted is not returned.              ThubanBeginBusyCursor()
584          #              try:
585          proj = self.receiver.GetProjection()                  projfile, warnings = get_user_proj_file()
586          if proj is not None:                  if warnings:
587              self.availprojs.Append(_("%s (current)") % proj.GetName(),                      sys.stderr.write("".join(warnings))
588                                     [proj, None])                  self.__usrProjFile = projfile
589              if selectCurrent:              finally:
590                  self.availprojs.SetSelection(0)                  ThubanEndBusyCursor()
591                  self.availprojs.SetFirstItem(0)          return self.__usrProjFile
592    
593          #      def load_system_proj(self, name):
594          # the list can never be empty. there will always be          """Load the system ProjFile with the given name.
595          # at least this one item  
596          #          If the file has not been loaded yet, load it first with
597          self.availprojs.Append("<None>", (None, None))          get_system_proj_file and put it into the cache. The name is
598            simply forwarded to get_system_proj_file.
         # 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])  
   
     def __set_properties(self):  
   
         #self.availprojs.SetSelection(0)  
         self.projchoice.SetSelection(0)  
   
         self.__FillAvailList(selectCurrent = True)  
   
         self.projname.SetMaxLength(32)  
   
     def __do_layout(self):  
         # originally generated by wxGlade  
599    
600          self.topBox = wxBoxSizer(wxVERTICAL)          Show a busy cursor while loading the file.
601          self.sizer_panel = wxBoxSizer(wxVERTICAL)          """
602          sizer_6 = wxBoxSizer(wxHORIZONTAL)          if name not in self._sys_proj_files:
603          self.sizer_mainctrls = wxBoxSizer(wxHORIZONTAL)              ThubanBeginBusyCursor()
604          self.sizer_edit = wxStaticBoxSizer(wxStaticBox(self.panel_edit, -1, _("Edit")), wxHORIZONTAL)              try:
605          sizer_11 = wxBoxSizer(wxVERTICAL)                  projfile, warnings = get_system_proj_file(name)
606          self.sizer_projctrls = wxBoxSizer(wxVERTICAL)                  self.show_warnings(_("Warnings"), projfile.GetFilename(),
607          sizer_14 = wxBoxSizer(wxHORIZONTAL)                                     warnings)
608          sizer_13 = wxBoxSizer(wxHORIZONTAL)                  self._sys_proj_files[name] = projfile
609          sizer_15 = wxBoxSizer(wxVERTICAL)              finally:
610          sizer_15.Add(self.button_import, 0, wxALL, 4)                  ThubanEndBusyCursor()
611          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, 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)  
612    
613          self.topBox.Add(self.sizer_mainctrls, 1, wxALL|wxEXPAND, 4)      def write_proj_file(self, proj_file):
614          self.topBox.Add(self.panel_buttons, 0, wxEXPAND, 0)          """Write the ProjFile object proj_file back to its file
615    
616          self.SetAutoLayout(1)          Show a busy cursor while writing and if an error occurs show a
617          self.SetSizer(self.topBox)          dialog with the error message.
618          self.topBox.Fit(self)          """
619          self.topBox.SetSizeHints(self)          try:
620          self.Layout()              ThubanBeginBusyCursor()
621                try:
622                    write_proj_file(proj_file)
623                finally:
624                    ThubanEndBusyCursor()
625            except IOError, (errno, errstr):
626                self.__ShowError(proj_file.GetFilename(), errstr)
627    
 # end of class ProjFrame  
628    
629    
630  class ProjPanel(wxPanel):  class ProjPanel(wxPanel):
# Line 607  class ProjPanel(wxPanel): Line 634  class ProjPanel(wxPanel):
634          wxPanel.__init__(self, parent, -1)          wxPanel.__init__(self, parent, -1)
635    
636          self.__ellps = wxChoice(self, -1)          self.__ellps = wxChoice(self, -1)
637          self.ellpsData = [("airy"  , _("Airy")),          self.ellpsData = [("", _("<Unknown>")),
638                              ("airy"  , _("Airy")),
639                            ("bessel", _("Bessel 1841")),                            ("bessel", _("Bessel 1841")),
640                            ("clrk66", _("Clarke 1866")),                            ("clrk66", _("Clarke 1866")),
641                            ("clrk80", _("Clarke 1880")),                            ("clrk80", _("Clarke 1880")),
642                            ("GRS80" , _("GRS 1980 (IUGG, 1980)")),                            ("GRS80" , _("GRS 1980 (IUGG, 1980)")),
643                            ("intl"  , _("International 1909 (Hayford)")),                            ("intl"  , _("International 1909 (Hayford)")),
# Line 624  class ProjPanel(wxPanel): Line 652  class ProjPanel(wxPanel):
652    
653          panelSizer = wxBoxSizer(wxVERTICAL)          panelSizer = wxBoxSizer(wxVERTICAL)
654    
         if childPanel is not None:  
             panelSizer.Add(childPanel, 0, wxEXPAND, 0)  
               
655          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wxBoxSizer(wxHORIZONTAL)
656          sizer.Add(wxStaticText(self, -1, _("Ellipsoid:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Ellipsoid:")), 0,
657          sizer.Add(self.__ellps, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)                                      wxALL|wxALIGN_CENTER_VERTICAL, 4)
658            sizer.Add(self.__ellps, 1, wxALL|wxALIGN_CENTER_VERTICAL, 4)
659          panelSizer.Add(sizer, 0, wxALL|wxEXPAND, 4)          panelSizer.Add(sizer, 0, wxALL|wxEXPAND, 4)
660    
661            if childPanel is not None:
662                panelSizer.Add(childPanel, 0, wxEXPAND, 0)
663                
664          self.SetAutoLayout(1)          self.SetAutoLayout(1)
665          self.SetSizer(panelSizer)          self.SetSizer(panelSizer)
666          panelSizer.Fit(self)          panelSizer.Fit(self)
# Line 654  class ProjPanel(wxPanel): Line 683  class ProjPanel(wxPanel):
683          self.__ellps.SetSelection(0)          self.__ellps.SetSelection(0)
684    
685      def GetParameters(self):      def GetParameters(self):
686          return ["ellps=" + self.__ellps.GetClientData(          ellps = self.__ellps.GetSelection()
687                                          self.__ellps.GetSelection())]          if ellps > 0:
688                return ["ellps=" + self.__ellps.GetClientData(ellps)]
689            return []
690    
691    
692  ID_TMPANEL_LAT = 4001  ID_TMPANEL_LAT = 4001
# Line 665  ID_TMPANEL_FALSE_NORTH = 4004 Line 696  ID_TMPANEL_FALSE_NORTH = 4004
696  ID_TMPANEL_SCALE = 4005  ID_TMPANEL_SCALE = 4005
697    
698  class UnknownProjPanel(ProjPanel):  class UnknownProjPanel(ProjPanel):
699    
700        """Panel for unknown projection types"""
701    
702      def __init__(self, parent, receiver):      def __init__(self, parent, receiver):
703          ProjPanel.__init__(self, parent)          ProjPanel.__init__(self, parent)
704    
705            self.__text = _("Thuban does not know the parameters\n"
706                            "for the current projection and cannot\n"
707                            "display a configuration panel.\n\n"
708                            "The unidentified set of parameters is:\n\n")
709    
710            self.__textbox = wxTextCtrl(self, -1, self.__text, size=(100,200),
711                                style=wxTE_READONLY|wxTE_MULTILINE|wxTE_LINEWRAP)
712          self._DoLayout()          self._DoLayout()
713    
714      def _DoLayout(self):      def _DoLayout(self):
715          sizer = wxBoxSizer(wxVERTICAL)          sizer = wxBoxSizer(wxVERTICAL)
716    
717          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.")))  
718    
719          ProjPanel._DoLayout(self, sizer)          ProjPanel._DoLayout(self, sizer)
720    
# Line 684  class UnknownProjPanel(ProjPanel): Line 722  class UnknownProjPanel(ProjPanel):
722          return "Unknown"          return "Unknown"
723    
724      def SetProjection(self, proj):      def SetProjection(self, proj):
725          pass          """Append the available parameters to the info text."""
726            text = self.__text
727            for param in proj.GetAllParameters():
728                text = text + '%s\n' % param
729            self.__textbox.SetValue(text)
730    
731      def GetParameters(self):      def GetParameters(self):
732          return None          return None
# Line 705  class TMPanel(ProjPanel): Line 747  class TMPanel(ProjPanel):
747    
748      def _DoLayout(self):      def _DoLayout(self):
749    
750          sizer = wxFlexGridSizer(4, 4, 0, 0)          sizer = wxFlexGridSizer(4, 2, 0, 0)
751          sizer.Add(wxStaticText(self, -1, _("Latitude:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Latitude:")), 0, wxALL, 4)
752          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)  
753          sizer.Add(wxStaticText(self, -1, _("Longitude:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("Longitude:")), 0, wxALL, 4)
754          sizer.Add(self.__longitude, 0, wxALL, 4)          sizer.Add(self.__longitude, 0, wxALL, 4)
755            sizer.Add(wxStaticText(self, -1, _("False Easting:")), 0, wxALL, 4)
756            sizer.Add(self.__falseEast, 0, wxALL, 4)
757          sizer.Add(wxStaticText(self, -1, _("False Northing:")), 0, wxALL, 4)          sizer.Add(wxStaticText(self, -1, _("False Northing:")), 0, wxALL, 4)
758          sizer.Add(self.__falseNorth, 0, wxALL, 4)          sizer.Add(self.__falseNorth, 0, wxALL, 4)
759          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 849  class UTMPanel(ProjPanel):
849          ProjPanel.Clear(self)          ProjPanel.Clear(self)
850    
851      def _OnPropose(self, event):      def _OnPropose(self, event):
852          UTMProposeZoneDialog          """Call the propose dialog.
853            If the receiver (e.g. the current map) has no bounding box,
854            inform the user accordingly.
855            """
856            bb = self.receiver.BoundingBox()
857            if bb is None:
858                dlg = wxMessageDialog(self,
859                        _("Can not propose: No bounding box found."),
860                        _("Projection: Propose UTM Zone"),
861                        wxOK | wxICON_INFORMATION)
862                dlg.CenterOnParent()
863                result = dlg.ShowModal()
864                dlg.Destroy()
865                return
866    
867          dlg = UTMProposeZoneDialog(self, self.receiver.BoundingBox())          dlg = UTMProposeZoneDialog(self, self.receiver.BoundingBox())
868          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
869              self.__zone.SetValue(dlg.GetProposedZone())              self.__zone.SetValue(dlg.GetProposedZone())
# Line 820  class LCCPanel(ProjPanel): Line 876  class LCCPanel(ProjPanel):
876                    
877          self.__fspLatitude = wxTextCtrl(self, -1)          self.__fspLatitude = wxTextCtrl(self, -1)
878          self.__sspLatitude = wxTextCtrl(self, -1)          self.__sspLatitude = wxTextCtrl(self, -1)
         self.__originLat   = wxTextCtrl(self, -1)  
879          self.__meridian    = wxTextCtrl(self, -1)          self.__meridian    = wxTextCtrl(self, -1)
880            self.__originLat   = wxTextCtrl(self, -1)
881          self.__falseEast   = wxTextCtrl(self, -1)          self.__falseEast   = wxTextCtrl(self, -1)
882          self.__falseNorth  = wxTextCtrl(self, -1)          self.__falseNorth  = wxTextCtrl(self, -1)
883    
# Line 836  class LCCPanel(ProjPanel): Line 892  class LCCPanel(ProjPanel):
892          sizer.Add(wxStaticText(self, -1,          sizer.Add(wxStaticText(self, -1,
893              _("Latitude of second standard parallel:")))              _("Latitude of second standard parallel:")))
894          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)  
895          sizer.Add(wxStaticText(self, -1, _("Central Meridian:")))          sizer.Add(wxStaticText(self, -1, _("Central Meridian:")))
896          sizer.Add(self.__meridian, 0, wxALL, 4)          sizer.Add(self.__meridian, 0, wxALL, 4)
897            sizer.Add(wxStaticText(self, -1, _("Latitude of origin:")))
898            sizer.Add(self.__originLat, 0, wxALL, 4)
899          sizer.Add(wxStaticText(self, -1, _("False Easting:")))          sizer.Add(wxStaticText(self, -1, _("False Easting:")))
900          sizer.Add(self.__falseEast, 0, wxALL, 4)          sizer.Add(self.__falseEast, 0, wxALL, 4)
901          sizer.Add(wxStaticText(self, -1, _("False Northing:")))          sizer.Add(wxStaticText(self, -1, _("False Northing:")))
# Line 923  class GeoPanel(ProjPanel): Line 979  class GeoPanel(ProjPanel):
979          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wxBoxSizer(wxHORIZONTAL)
980    
981          sizer.Add(wxStaticText(self, -1, _("Source Data is in: ")),          sizer.Add(wxStaticText(self, -1, _("Source Data is in: ")),
982                    0, wxALL, 4)                    0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
983          sizer.Add(self.__scale, 1, wxEXPAND|wxALL, 4)          sizer.Add(self.__scale, 1, wxEXPAND|wxALL, 4)
984    
985          self.__scale.SetSelection(0)          self.__scale.SetSelection(0)
# Line 934  class GeoPanel(ProjPanel): Line 990  class GeoPanel(ProjPanel):
990  ID_UTM_PROPOSE_ZONE_DIALOG_TAKE   = 4001  ID_UTM_PROPOSE_ZONE_DIALOG_TAKE   = 4001
991  ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL = 4002  ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL = 4002
992  class UTMProposeZoneDialog(wxDialog):  class UTMProposeZoneDialog(wxDialog):
993                                                                                    
994      """Propose a sensible Zone considering the current map extent."""      """Propose a sensible Zone considering the current map extent."""
995                                                                                    
996      def __init__(self, parent, (x, y, x2, y2)):      def __init__(self, parent, (x, y, x2, y2)):
997          wxDialog.__init__(self, parent, -1, _("Projection: Propose UTM Zone"),          wxDialog.__init__(self, parent, -1, _("Projection: Propose UTM Zone"),
998                            wxDefaultPosition, wxSize(200, 100))                            wxDefaultPosition, wxSize(200, 100))
999          self.parent = parent          self.parent = parent
         #x, y, x2, y2 = elf.parent.parent.map_bounding_box  
1000          x = x + 180          x = x + 180
1001          x2 = x2 + 180          x2 = x2 + 180
1002          center = (x2 - x) / 2 + x          center = (x2 - x) / 2 + x
1003          self.proposedZone = int(center / 6 + 1)          self.proposedZone = int(center / 6 + 1)
1004          self.dialogLayout()          self.dialogLayout()
1005                                                                                    
1006      def dialogLayout(self):      def dialogLayout(self):
1007          topBox = wxBoxSizer(wxVERTICAL)          topBox = wxBoxSizer(wxVERTICAL)
1008                                                                                    
1009          textBox = wxBoxSizer(wxVERTICAL)          textBox = wxBoxSizer(wxVERTICAL)
1010          textBox.Add(wxStaticText(self, -1, _("The current map extent center " +          textBox.Add(wxStaticText(self, -1, _("The current map extent center "
1011                                             "lies in UTM Zone")),                                               "lies in UTM Zone")),
1012                      0, wxALIGN_CENTER|wxALL, 4)                      0, wxALIGN_CENTER|wxALL, 4)
1013          textBox.Add(wxStaticText(self, -1, str(self.proposedZone)),          textBox.Add(wxStaticText(self, -1, str(self.proposedZone)),
1014                      0, wxALIGN_CENTER|wxALL, 4)                      0, wxALIGN_CENTER|wxALL, 4)
1015                                                                                    
1016          topBox.Add(textBox, 1, wxEXPAND|wxALL, 4)          topBox.Add(textBox, 1, wxEXPAND|wxALL, 4)
1017                                                                                    
1018          buttonBox = wxBoxSizer(wxHORIZONTAL)          buttonBox = wxBoxSizer(wxHORIZONTAL)
1019          buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE,          buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE,
1020                        _("Take")), 0, wxALL, 4)                        _("Take")), 0, wxALL, 4)
# Line 968  class UTMProposeZoneDialog(wxDialog): Line 1023  class UTMProposeZoneDialog(wxDialog):
1023          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10)          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10)
1024          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE, self.OnTake)          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE, self.OnTake)
1025          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL, self.OnCancel)          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL, self.OnCancel)
1026                                                                                    
1027          self.SetAutoLayout(True)          self.SetAutoLayout(True)
1028          self.SetSizer(topBox)          self.SetSizer(topBox)
1029          topBox.Fit(self)          topBox.Fit(self)
1030          topBox.SetSizeHints(self)          topBox.SetSizeHints(self)
1031                                                                                    
1032      def OnTake(self, event):      def OnTake(self, event):
1033          self.EndModal(wxID_OK)          self.EndModal(wxID_OK)
1034                                                                                    
1035      def OnCancel(self, event):      def OnCancel(self, event):
1036          self.EndModal(wxID_CANCEL)          self.EndModal(wxID_CANCEL)
1037    

Legend:
Removed from v.964  
changed lines
  Added in v.2022

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26