/[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 976 by frank, Thu May 22 11:39:31 2003 UTC revision 2700 by dpinte, Mon Sep 18 14:27:02 2006 UTC
# Line 1  Line 1 
1  # Copyright (c) 2003 by Intevation GmbH  # Copyright (c) 2003, 2004 by Intevation GmbH
2  # Authors:  # Authors:
3  # Jonathan Coles <[email protected]>  # Jonathan Coles <[email protected]>
4  # Frank Koormann <[email protected]>  # 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  from wxPython.wx import *  
12    __version__ = "$Revision$"
13    # $Source$
14    # $Id$
15    
16    import sys, os
17    import wx
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 33  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 42  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.build_dialog()
74            self.Layout()
75    
76            self.originalProjection = self.receiver.GetProjection()
77    
78            self.projection_list.SelectProjection(self.originalProjection)
79            self.projection_list.SetFocus()
80    
81        def build_dialog(self):
82            """Build the dialog's widgets and set the event handlers"""
83            self.topBox = top_box = wx.BoxSizer(wx.VERTICAL)
84    
85            main_box = wx.BoxSizer(wx.HORIZONTAL)
86            top_box.Add(main_box, 1, wx.ALL|wx.EXPAND)
87    
88            #
89            #    The projection list and associated controls
90            #
91            vbox = wx.BoxSizer(wx.VERTICAL)
92            main_box.Add(vbox, 4, wx.ALL|wx.EXPAND)
93    
94          self.projPanels = []          #label = wxStaticText(self, -1, _("Available Projections:"))
95          self.projPanels.append(          #vbox.Add(label, 0, wxLEFT|wxRIGHT|wxTOP, 4)
96              ("tmerc", _("Transverse Mercator"), TMPanel))  
97          self.projPanels.append(          hbox = wx.BoxSizer(wx.HORIZONTAL)
98              ("utm", _("Universal Transverse Mercator"), UTMPanel))          vbox.Add(hbox, 1, wx.ALL|wx.EXPAND)
99          self.projPanels.append(          proj_files = [self.load_user_proj(),
100              ("lcc", _("Lambert Conic Conformal"), LCCPanel))                        self.load_system_proj(DEFAULT_PROJ_FILE)]
101          self.projPanels.append(          self.projection_list = ProjectionList(self, proj_files,
102              ("latlong", _("Geographic"), GeoPanel))                                                self.receiver.GetProjection())
103            hbox.Add(self.projection_list, 1, wx.ALL|wx.EXPAND|wx.ADJUST_MINSIZE, 4)
104          NonModalDialog.__init__(self, parent, name, title)          self.projection_list.Subscribe(PROJ_SELECTION_CHANGED,
105          # originally generate by wxGlade                                         self.proj_selection_changed)
         self.panel_1 = wxPanel(self, -1)  
         self.panel_edit = wxPanel(self, -1)  
         self.label_5 = wxStaticText(self.panel_1, -1,  
                         _("Available Projections:"))  
106    
107          # Projection List specific actions (Import/Export/Remove)          # Projection List specific actions (Import/Export/Remove)
108          self.button_import = wxButton(self.panel_1, ID_PROJ_IMPORT,          buttons = wx.BoxSizer(wx.VERTICAL)
109                                        _("Import..."))          hbox.Add(buttons, 0, wx.ALL)
110          self.button_export = wxButton(self.panel_1, ID_PROJ_EXPORT,          self.button_import = wx.Button(self, ID_PROJ_IMPORT, _("Import..."))
111                                        _("Export..."))          self.Bind(wx.EVT_BUTTON, self._OnImport, id=ID_PROJ_IMPORT)
112          self.button_remove = wxButton(self.panel_1, ID_PROJ_REMOVE,          buttons.Add(self.button_import, 1, wx.ALL|wx.EXPAND, 4)
113                                        _("Remove"))          self.button_export = wx.Button(self, ID_PROJ_EXPORT, _("Export..."))
114            self.Bind(wx.EVT_BUTTON, self._OnExport, id=ID_PROJ_EXPORT)
115          # The Projection List          buttons.Add(self.button_export, 1, wx.ALL|wx.EXPAND, 4)
116          self.availprojs = wxListBox(self.panel_1, ID_PROJ_AVAIL,          buttons.Add( (20, 20), 0, wx.EXPAND, 0)
117                                      style=wxLB_EXTENDED|wxLB_SORT)          self.button_remove = wx.Button(self, ID_PROJ_REMOVE, _("Remove"))
118          self.projfilepath = wxStaticText(self.panel_1, -1, "")          self.Bind(wx.EVT_BUTTON, self._OnRemove, id=ID_PROJ_REMOVE)
119            buttons.Add(self.button_remove, 1, wx.ALL|wx.EXPAND, 4)
120    
121            buttons.Add( (20, 20), 0, wx.EXPAND, 0)
122            label = wx.StaticText(self, -1, _("Show EPSG:"))
123            buttons.Add(label, 0, wx.LEFT|wx.RIGHT|wx.TOP, 4)
124            self.check_epsg = wx.CheckBox(self, -1, _("Normal"))
125            self.Bind(wx.EVT_CHECKBOX, self._OnShowEPSG, id=self.check_epsg.GetId())
126            buttons.Add(self.check_epsg, 1, wx.ALL|wx.EXPAND, 4)
127            self.check_epsg_depr = wx.CheckBox(self, -1, _("Deprecated"))
128            self.Bind(wx.EVT_CHECKBOX, self._OnShowEPSG, id=self.check_epsg_depr.GetId())
129            buttons.Add(self.check_epsg_depr, 1, wx.ALL|wx.EXPAND, 4)
130    
131            # The file path
132            self.projfilepath = wx.StaticText(self, -1, "")
133            vbox.Add(self.projfilepath, 0, wx.ALL|wx.EXPAND)
134    
135            #
136            #   The projection editor part
137            #
138            self.edit_box = wx.StaticBox(self, -1, _("Edit"))
139            sizer_edit = wx.StaticBoxSizer(self.edit_box, wx.HORIZONTAL)
140            main_box.Add(sizer_edit, 5, wx.ALL|wx.EXPAND)
141    
142          # Projection Specific Entries (Name/Projection)          # Projection Specific Entries (Name/Projection)
143          self.label_2 = wxStaticText(self.panel_edit, -1, _("Name:"))          self.sizer_projctrls = wx.BoxSizer(wx.VERTICAL)
144          self.projname = wxTextCtrl(self.panel_edit, ID_PROJ_PROJNAME, "")          sizer_edit.Add(self.sizer_projctrls, 1, wx.ALL|wx.EXPAND)
145          self.label_3 = wxStaticText(self.panel_edit, -1, _("Projection:"))  
146          self.projchoice = wxChoice(self.panel_edit, ID_PROJ_PROJCHOICE)          hbox = wx.BoxSizer(wx.HORIZONTAL)
147            self.sizer_projctrls.Add(hbox, 0, wx.ALL|wx.EXPAND)
148            label = wx.StaticText(self, -1, _("Name:"))
149            hbox.Add(label, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
150            self.projname = wx.TextCtrl(self, ID_PROJ_PROJNAME, "")
151            self.Bind(wx.EVT_TEXT, self._OnProjName, id=ID_PROJ_PROJNAME)
152            hbox.Add(self.projname, 1, wx.ALL|wx.EXPAND, 4)
153    
154            hbox = wx.BoxSizer(wx.HORIZONTAL)
155            self.sizer_projctrls.Add(hbox, 0, wx.ALL|wx.EXPAND)
156            label = wx.StaticText(self, -1, _("Projection:"))
157            hbox.Add(label, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
158            self.projchoice = wx.Choice(self, ID_PROJ_PROJCHOICE)
159            self.projchoice.SetSelection(0)
160            self.Bind(wx.EVT_CHOICE, self._OnProjChoice, id=ID_PROJ_PROJCHOICE)
161            hbox.Add(self.projchoice, 1, wx.ALL|wx.EXPAND, 4)
162            # Fill the projection choice list.
163            self.nbsizer = NotebookLikeSizer()
164            self.sizer_projctrls.Add(self.nbsizer, 1,
165                                     wx.ALL|wx.EXPAND|wx.ADJUST_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)          # Projection Specific actions (New/Save/Add)
181          self.button_new = wxButton(self.panel_edit, ID_PROJ_NEW, _("New"))          buttons = wx.BoxSizer(wx.VERTICAL)
182          self.button_add = wxButton(self.panel_edit, ID_PROJ_ADDTOLIST,          sizer_edit.Add(buttons, 0, wx.ALL)
183                                        _("Add to List"))          self.button_new = wx.Button(self, ID_PROJ_NEW, _("New"))
184          self.button_save = wxButton(self.panel_edit, ID_PROJ_SAVE,_("Update"))          self.Bind(wx.EVT_BUTTON, self._OnNew, id=ID_PROJ_NEW)
185            buttons.Add(self.button_new, 0, wx.EXPAND|wx.ALL, 4)
186            self.button_add = wx.Button(self, ID_PROJ_ADDTOLIST, _("Add to List"))
187            self.Bind(wx.EVT_BUTTON, self._OnAddToList, id=ID_PROJ_ADDTOLIST)
188            buttons.Add(self.button_add, 0, wx.EXPAND|wx.ALL, 4)
189            buttons.Add( (20, 20), 0, wx.EXPAND, 0)
190            self.button_save = wx.Button(self, ID_PROJ_SAVE,_("Update"))
191            self.Bind(wx.EVT_BUTTON, self._OnSave, id=ID_PROJ_SAVE)
192            buttons.Add(self.button_save, 0, wx.EXPAND|wx.ALL|wx.ALIGN_BOTTOM, 4)
193    
194            #
195          # Main Action buttons (Try/Revert/OK/Close)          # Main Action buttons (Try/Revert/OK/Close)
196          self.button_try = wxButton(self, wxID_APPLY, _("Try"))          #
197          self.button_revert = wxButton(self, ID_PROJ_REVERT,          buttons = wx.BoxSizer(wx.HORIZONTAL)
198                                        _("Revert"))          top_box.Add(buttons, 0, wx.ALL|wx.ALIGN_RIGHT, 10)
199          self.button_ok = wxButton(self, wxID_OK, _("OK"))          self.button_try = wx.Button(self, wx.ID_APPLY, _("Try"))
200            self.Bind(wx.EVT_BUTTON, self.OnApply, id=wx.ID_APPLY)
201            buttons.Add(self.button_try, 0, wx.RIGHT, 10)
202            self.button_revert = wx.Button(self, ID_PROJ_REVERT, _("Revert"))
203            self.Bind(wx.EVT_BUTTON, self._OnRevert, id=ID_PROJ_REVERT)
204            buttons.Add(self.button_revert, 0, wx.RIGHT, 10)
205            self.button_ok = wx.Button(self, wx.ID_OK, _("OK"))
206            self.Bind(wx.EVT_BUTTON, self.OnOK, id=wx.ID_OK)
207          self.button_ok.SetDefault()          self.button_ok.SetDefault()
208          self.button_close = wxButton(self, wxID_CANCEL,          buttons.Add(self.button_ok, 0, wx.RIGHT, 10)
209                                       _("Close"))          self.button_close = wx.Button(self, wx.ID_CANCEL, _("Close"))
210            self.Bind(wx.EVT_BUTTON, self.OnCancel, id=wx.ID_CANCEL)
211            buttons.Add(self.button_close, 0, wx.RIGHT, 10)
212    
         self.__set_properties()  
         self.__do_layout()  
         # wxGlade  
   
         self.originalProjection = self.receiver.GetProjection()  
   
         self.__DoOnProjAvail()  
         self.button_ok.SetFocus()  
         self.availprojs.SetFocus()  
           
         EVT_BUTTON(self, wxID_APPLY, self.OnApply)  
         EVT_BUTTON(self, ID_PROJ_REVERT, self._OnRevert)  
         EVT_BUTTON(self, wxID_OK, self.OnOK)  
         EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)  
         EVT_CHOICE(self, ID_PROJ_PROJCHOICE, self._OnProjChoice)  
         EVT_LISTBOX(self, ID_PROJ_AVAIL, self._OnProjAvail)  
         EVT_BUTTON(self, ID_PROJ_IMPORT, self._OnImport)  
         EVT_BUTTON(self, ID_PROJ_EXPORT, self._OnExport)  
         EVT_BUTTON(self, ID_PROJ_REMOVE, self._OnRemove)  
   
         EVT_BUTTON(self, ID_PROJ_NEW, self._OnNew)  
         EVT_BUTTON(self, ID_PROJ_SAVE, self._OnSave)  
         EVT_BUTTON(self, ID_PROJ_ADDTOLIST, self._OnAddToList)  
   
         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 144  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 159  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          dlg = wxFileDialog(self, _("Import"), style = wxOPEN)          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 = wx.FileDialog(self, _("Import"),
307                    self.parent.application.Path("projection"), style = wx.OPEN)
308    
309          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wx.ID_OK:
310              path = dlg.GetPath()              path = dlg.GetPath()
311    
312                ThubanBeginBusyCursor()
313              try:              try:
314                  projFile = ReadProjFile(path)                  try:
315                  for proj in projFile.GetProjections():                      projFile, warnings = read_proj_file(path)
316                      self.__usrProjFile.Add(proj)                  except IOError, (errno, errstr):
317                  WriteProjFile(self.__usrProjFile)                      self.__ShowError(dlg.GetPath(), errstr)
318              except IOError, (errno, errstr):                  else:
319                  self.__ShowError(dlg.GetPath(), errstr)                      self.show_warnings(_("Warnings"), path, warnings)
320                        for proj in projFile.GetProjections():
321              self.__FillAvailList()                          self.__usrProjFile.Add(proj)
322                        self.write_proj_file(self.__usrProjFile)
323                        self.parent.application.SetPath("projection", path)
324                finally:
325                    ThubanEndBusyCursor()
326          dlg.Destroy()          dlg.Destroy()
327    
328      def _OnExport(self, event):      def _OnExport(self, event):
329            """Handler for the 'Export' button.
330    
331          sel = self.availprojs.GetSelections()          Ask the user for a filename and write the selected projections
332            to that file.
333            """
334            sel = self.projection_list.selected_projections()
335          assert len(sel) != 0, "button should be disabled"          assert len(sel) != 0, "button should be disabled"
336    
337          dlg = wxFileDialog(self, _("Export"),          dlg = wx.FileDialog(self, _("Export"),
338                          style = wxSAVE|wxOVERWRITE_PROMPT)                  self.parent.application.Path("projection"),
339                    style=wx.SAVE|wx.OVERWRITE_PROMPT)
340          if dlg.ShowModal() == wxID_OK:  
341              path = dlg.GetPath()          if dlg.ShowModal() == wx.ID_OK:
342                proj_file = ProjFile(dlg.GetPath())
343              projFile = ProjFile(path)              for proj, pf in sel:
   
             for i in sel:  
                 proj = self.availprojs.GetClientData(i)[CLIENT_PROJ]  
344                  if proj is not None:                  if proj is not None:
345                      projFile.Add(proj)                      proj_file.Add(proj)
346                self.write_proj_file(proj_file)
347              try:              self.parent.application.SetPath("projection", dlg.GetPath())
                 WriteProjFile(projFile)  
             except IOError, (errno, errstr):  
                 self.__ShowError(dlg.GetPath(), errstr)  
348    
349          dlg.Destroy()          dlg.Destroy()
350    
351      def _OnRemove(self, event):      def _OnRemove(self, event):
352            """Handler for the 'Remove' button
353    
354          sel = self.availprojs.GetSelections()          Remove any selected projection that came from the user's
355            ProjFile. If the user ProjFile was modified write it back to
356            disk.
357            """
358            sel = self.projection_list.selected_projections()
359          assert len(sel) != 0, "button should be disabled!"          assert len(sel) != 0, "button should be disabled!"
360    
361          #          modified = False
362          # remove the items backwards so the indices don't change          for proj, pf in sel:
363          #              if proj is not None and pf is self.__usrProjFile:
364          sel = list(sel)                  pf.Remove(proj)
365          sel.sort()                  modified = True
         sel.reverse()  
   
         newselection = -1  
         if len(sel) == 1:  
             newselection = sel[0] - 1  
             if newselection < 0:  
                 newselection = 0  
   
         for i in sel:  
             proj, projfile = self.availprojs.GetClientData(i)  
   
             #  
             # this could be the case if they selected <None> or  
             # the currently used projection  
             #  
             if proj is not None and projfile is not None:  
                 projfile.Remove(proj)  
   
         try:  
             WriteProjFile(projfile)  
         except IOError, (errno, errstr):  
             self.__ShowError(projfile.GetFilename(), errstr)  
366    
367          self.__FillAvailList()          if modified:
368                self.write_proj_file(self.__usrProjFile)
369    
370          #      def _OnShowEPSG(self, event):
371          # this *could* produce incorrect results if the .proj files          """Handler for the EVT_CHECKBOX events from the EPSG check button
         # change between the last list update and this selection  
         # because the list has been repopulated.  
         #  
         if newselection != -1 and self.availprojs.GetCount() > 0:  
             self.availprojs.SetSelection(newselection)  
372    
373          self.__VerifyButtons()          If the button is checked add the EPSG_PROJ_FILE to the list of
374            projfiles shown by the projection list. Otherwise remove it
375            """
376            proj_files = [self.load_user_proj(),
377                          self.load_system_proj(DEFAULT_PROJ_FILE)]
378            if self.check_epsg.IsChecked():
379                proj_files.append(self.load_system_proj(EPSG_PROJ_FILE))
380            if self.check_epsg_depr.IsChecked():
381                proj_files.append(self.load_system_proj(EPSG_DEPRECATED_PROJ_FILE))
382            self.projection_list.SetProjFiles(proj_files)
383    
384      def _OnProjName(self, event):      def _OnProjName(self, event):
385          self.__VerifyButtons()          self.__VerifyButtons()
386    
387      def __ShowError(self, filename, errstr):      def __ShowError(self, filename, errstr):
388          wxMessageDialog(self,          wx.MessageDialog(self,
389              _("The following error occured:\n") +              _("The following error occured:\n") +
390              filename + "\n" + errstr,              filename + "\n" + errstr,
391              _("Error"), wxOK | wxICON_ERROR).ShowModal()              _("Error"), wx.OK | wx.ICON_ERROR).ShowModal()
392    
393      def __VerifyButtons(self):      def __VerifyButtons(self):
394          """Enable or disable the appropriate buttons based on the          """Update button sensitivity"""
         current state of the dialog.  
         """  
395    
396          sel = self.availprojs.GetSelections()          num_sel = self.projection_list.GetSelectedItemCount()
397    
398          self.button_import.Enable(True)          self.button_import.Enable(True)
399          self.button_export.Enable(True)          self.button_export.Enable(True)
400          self.button_save.Enable(True)          self.button_save.Enable(True)
401          self.button_remove.Enable(True)          self.button_remove.Enable(True)
402    
403          self.panel_edit.Enable(True)          self.edit_box.Enable(True)
404    
405          for ctrl in [self.button_import,          for ctrl in [self.button_import,
406                       self.button_export,                       self.button_export,
# Line 314  class ProjFrame(NonModalDialog): Line 409  class ProjFrame(NonModalDialog):
409                       self.button_add,                       self.button_add,
410                       self.projchoice,                       self.projchoice,
411                       self.projname,                       self.projname,
412                       self.panel_edit]:                       self.edit_box]:
413              ctrl.Enable(True)              ctrl.Enable(True)
414    
415          if self.curProjPanel is not None:          if self.curProjPanel is not None:
416              self.curProjPanel.Enable(True)              self.curProjPanel.Enable(True)
417    
418          if len(sel) == 0:          if num_sel == 0:
419              self.button_import.Enable(True)              self.button_import.Enable(True)
420              self.button_export.Enable(False)              self.button_export.Enable(False)
421              self.button_remove.Enable(False)              self.button_remove.Enable(False)
422              self.button_save.Enable(False)              self.button_save.Enable(False)
423    
424          elif len(sel) == 1:          elif num_sel == 1:
425    
426              proj, projFile = self.availprojs.GetClientData(sel[0])              selection = self.projection_list.selected_projections()
427                proj, projFile = selection[0]
428    
429              self.button_save.Enable(len(self.projname.GetValue()) > 0)              self.button_save.Enable(len(self.projname.GetValue()) > 0)
430              self.button_add.Enable(len(self.projname.GetValue()) > 0)              self.button_add.Enable(len(self.projname.GetValue()) > 0)
# Line 353  class ProjFrame(NonModalDialog): Line 449  class ProjFrame(NonModalDialog):
449                  self.button_save.Enable(False)                  self.button_save.Enable(False)
450    
451          else:          else:
452              self.panel_edit.Enable(False)              self.edit_box.Enable(False)
   
     def __DoOnProjAvail(self):  
453    
454          sel = self.availprojs.GetSelections()      def proj_selection_changed(self, projs):
455          if len(sel) == 1:          """Subscribed to the projection_list's PROJ_SELECTION_CHANGED message
   
             proj = self.availprojs.GetClientData(sel[0])[CLIENT_PROJ]  
             projfile = self.availprojs.GetClientData(sel[0])[CLIENT_PROJFILE]  
456    
457            Update the dialog to reflect the new selection.
458            """
459            if len(projs) == 0:
460                self.projfilepath.SetLabel(_("No Projections selected"))
461            elif len(projs) == 1:
462                proj, projfile = projs[0]
463              if proj is None:              if proj is None:
464                  # user selected <None>                  # user selected <None>
465                  self.projname.Clear()                  self.projname.Clear()
466                                    self.projfilepath.SetLabel("")
467              else:              else:
               
468                  if projfile is not None:                  if projfile is not None:
469                      self.projfilepath.SetLabel(projfile.GetFilename())                      filename = os.path.basename(projfile.GetFilename())
470                        self.projfilepath.SetLabel(_("Source of Projection: %s")
471                                                   % filename)
472                  else:                  else:
473                      # only None if the currently used projection is selected                      # only None if the currently used projection is selected
474                      self.projfilepath.SetLabel("")                      self.projfilepath.SetLabel("")
475    
476                  self.projname.SetValue(proj.GetName())                  self.projname.SetValue(proj.Label())
477    
478                  myProjType = proj.GetParameter("proj")                  myProjType = proj.GetParameter("proj")
479                  i = 0                  i = 0
480                  for projType, name, clazz in self.projPanels:                  for projType, name, cls in self.projection_panel_defs:
481                      if myProjType == projType:                      if myProjType == projType:
482                          self.projchoice.SetSelection(i)                          self.projchoice.Enable(True)
483                            self.projchoice.SetSelection(i + 1)
484                          self.__DoOnProjChoice()                          self.__DoOnProjChoice()
485    
486                          #                          #
# Line 391  class ProjFrame(NonModalDialog): Line 490  class ProjFrame(NonModalDialog):
490                          assert self.curProjPanel is not None                          assert self.curProjPanel is not None
491    
492                          self.curProjPanel.SetProjection(proj)                          self.curProjPanel.SetProjection(proj)
493                            break
494                      i += 1                      i += 1
495                    else:
496                        self.projchoice.Select(0)
497                        self.projchoice.Disable()
498                        self._show_proj_panel(UnknownProjPanel)
499                        assert self.curProjPanel is not None
500                        self.curProjPanel.SetProjection(proj)
501            else:
502                self.projfilepath.SetLabel(_("Multiple Projections selected"))
503    
504          self.__VerifyButtons()          self.__VerifyButtons()
505    
# Line 408  class ProjFrame(NonModalDialog): Line 516  class ProjFrame(NonModalDialog):
516          At the end of this method self.curProjPanel will not be None          At the end of this method self.curProjPanel will not be None
517          if there was a item selected.          if there was a item selected.
518          """          """
   
519          choice = self.projchoice          choice = self.projchoice
520    
521          sel = choice.GetSelection()          sel = choice.GetSelection()
522          if sel != -1:          if sel != -1:
523                proj_type = choice.GetClientData(sel)
524              clazz, obj = choice.GetClientData(sel)              for t, name, cls in self.projection_panel_defs:
525                    if t == proj_type:
526              if obj is None:                      self._show_proj_panel(cls)
527                  obj = clazz(self.panel_edit, self.receiver)                      break
528                  choice.SetClientData(sel, [clazz, obj])          # FIXME: what to do if sel == -1?
529    
530              if self.curProjPanel is not None:      def _show_proj_panel(self, panel_class):
531                  self.curProjPanel.Hide()          """Show the panel as the projection panel"""
532                  self.sizer_projctrls.Remove(self.curProjPanel)          if panel_class is UnknownProjPanel:
533                self.button_ok.Disable()
534              self.curProjPanel = obj              self.button_try.Disable()
535              self.curProjPanel.Show()              self.edit_box.Disable()
536                self.nbsizer.Activate(self.unknown_projection_panel)
537              self.sizer_projctrls.Add(self.curProjPanel, 1,              self.curProjPanel = self.unknown_projection_panel
538                  wxALL|wxEXPAND|wxADJUST_MINSIZE, 3)          else:
539              self.sizer_projctrls.Layout()              self.button_ok.Enable(True)
540              self.Layout()              self.button_try.Enable(True)
541              self.topBox.SetSizeHints(self)              self.edit_box.Enable(True)
542                self.unknown_projection_panel.Hide()
543                for panel in self.projection_panels:
544                    if panel.__class__ is panel_class:
545                        self.nbsizer.Activate(panel)
546                        self.curProjPanel = panel
547    
548      def __SetProjection(self):      def __SetProjection(self):
549          """Set the receiver's projection."""          """Set the receiver's projection."""
# Line 449  class ProjFrame(NonModalDialog): Line 561  class ProjFrame(NonModalDialog):
561          Could be None.          Could be None.
562          """          """
563    
564          sel = self.availprojs.GetSelections()          assert self.projection_list.GetSelectedItemCount() < 2, \
565          assert len(sel) < 2, "button should be disabled"                 "button should be disabled"
   
566    
567            sel = self.projection_list.selected_projections()
568          if len(sel) == 1:          if len(sel) == 1:
569              proj = self.availprojs.GetClientData(sel[0])[CLIENT_PROJ]              if sel[0][0] is None:
             if proj is None:  
570                  # <None> is selected                  # <None> is selected
571                  return None                  return None
572    
573          #          # self.curProjPanel should always contain the most relevant data
574          # self.curProjPanel should always contain the most          # for a projection
         # relevant data for a projection  
         #  
575          if self.curProjPanel is not None:          if self.curProjPanel is not None:
576              return Projection(self.curProjPanel.GetParameters(),              parameters = self.curProjPanel.GetParameters()
577                                self.projname.GetValue())              if parameters is not None:
578                    return Projection(parameters, self.projname.GetValue())
579    
580          return None          return None
581    
582      def __FillAvailList(self, selectCurrent = False):      def load_user_proj(self):
583          """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()  
   
         #  
         # the list can never be empty. there will always be  
         # at least this one item  
         #  
         self.availprojs.Append("<None>", (None, None))  
   
         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])  
   
         #  
         # We add the current projection to the list at last.  
         # Since the list is resorted immediately a following FindString()  
         # determines the index correctly.  
         #  
         proj = self.receiver.GetProjection()  
         if proj is not None:  
             proj_item = _("%s (current)") % proj.GetName()  
             self.availprojs.Append(proj_item, [proj, None])  
             if selectCurrent:  
                 self.availprojs.SetSelection(  
                         self.availprojs.FindString(proj_item)  
                     )  
         else:  
             if selectCurrent:  
                 self.availprojs.SetSelection(  
                         self.availprojs.FindString("<None>")  
                     )  
                   
   
     def __set_properties(self):  
   
         #self.availprojs.SetSelection(0)  
         self.projchoice.SetSelection(0)  
   
         self.__FillAvailList(selectCurrent = True)  
584    
585          self.projname.SetMaxLength(32)          If the file has not yet been loaded by the dialog, load it first
586            with get_user_proj_file and cache it in self.__usrProjFile.
587    
588      def __do_layout(self):          Show a busy cursor while loading the file.
         # originally generated by wxGlade  
589    
590          self.topBox = wxBoxSizer(wxVERTICAL)          If the file is not available, leave a note to the console.
591          self.sizer_panel = wxBoxSizer(wxVERTICAL)          """
592          sizer_6 = wxBoxSizer(wxHORIZONTAL)          if self.__usrProjFile is None:
593          self.sizer_mainbttns = wxBoxSizer(wxHORIZONTAL)              ThubanBeginBusyCursor()
594          self.sizer_mainctrls = wxBoxSizer(wxHORIZONTAL)              try:
595          self.sizer_edit = wxStaticBoxSizer(wxStaticBox(self.panel_edit, -1, _("Edit")), wxHORIZONTAL)                  projfile, warnings = get_user_proj_file()
596          sizer_11 = wxBoxSizer(wxVERTICAL)                  if warnings:
597          self.sizer_projctrls = wxBoxSizer(wxVERTICAL)                      sys.stderr.write("".join(warnings))
598          sizer_14 = wxBoxSizer(wxHORIZONTAL)                      sys.stderr.write("\n")
599          sizer_13 = wxBoxSizer(wxHORIZONTAL)                  self.__usrProjFile = projfile
600          sizer_15 = wxBoxSizer(wxVERTICAL)              finally:
601          sizer_15.Add(self.button_import, 0, wxALL, 4)                  ThubanEndBusyCursor()
602          sizer_15.Add(self.button_export, 0, wxALL, 4)          return self.__usrProjFile
603          sizer_15.Add(20, 20, 0, wxEXPAND, 0)  
604          sizer_15.Add(self.button_remove, 0, wxALL|wxALIGN_BOTTOM, 4)      def load_system_proj(self, name):
605            """Load the system ProjFile with the given name.
606          # list controls  
607          grid_sizer_1 = wxFlexGridSizer(3, 2, 0, 0)          If the file has not been loaded yet, load it first with
608          grid_sizer_1.Add(self.label_5, 0, wxLEFT|wxRIGHT|wxTOP, 4)          get_system_proj_file and put it into the cache. The name is
609          grid_sizer_1.Add(20, 20, 0, wxEXPAND, 0)          simply forwarded to get_system_proj_file.
         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, 4)  
         sizer_11.Add(self.button_add, 0, wxALL, 4)  
         sizer_11.Add(20, 20, 0, wxEXPAND, 0)  
         sizer_11.Add(self.button_save, 0, wxALL|wxALIGN_BOTTOM, 4)  
         self.sizer_edit.Add(sizer_11, 0, wxALL|wxEXPAND, 4)  
   
         sizer_6.Add(self.button_try, 0, wxRIGHT| wxEXPAND, 10)  
         sizer_6.Add(self.button_revert, 0, wxRIGHT| wxEXPAND, 10)  
         sizer_6.Add(self.button_ok, 0, wxRIGHT| wxEXPAND, 10)  
         sizer_6.Add(self.button_close, 0, wxRIGHT| wxEXPAND, 10)  
   
         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.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)  
610    
611          self.sizer_mainbttns.Add(sizer_6, 0,          Show a busy cursor while loading the file.
612              wxALL|wxEXPAND|wxADJUST_MINSIZE, 10)          """
613            if name not in self._sys_proj_files:
614                ThubanBeginBusyCursor()
615                try:
616                    projfile, warnings = get_system_proj_file(name)
617                    self.show_warnings(_("Warnings"), projfile.GetFilename(),
618                                       warnings)
619                    self._sys_proj_files[name] = projfile
620                finally:
621                    ThubanEndBusyCursor()
622            return self._sys_proj_files[name]
623    
624          self.topBox.Add(self.sizer_mainctrls, 1, wxALL|wxEXPAND, 4)      def write_proj_file(self, proj_file):
625          self.topBox.Add(self.sizer_mainbttns, 0, wxALIGN_RIGHT|wxBOTTOM, 0)          """Write the ProjFile object proj_file back to its file
626    
627          self.SetAutoLayout(1)          Show a busy cursor while writing and if an error occurs show a
628          self.SetSizer(self.topBox)          dialog with the error message.
629          self.topBox.Fit(self)          """
630          self.topBox.SetSizeHints(self)          try:
631          self.Layout()              ThubanBeginBusyCursor()
632                try:
633                    write_proj_file(proj_file)
634                finally:
635                    ThubanEndBusyCursor()
636            except IOError, (errno, errstr):
637                self.__ShowError(proj_file.GetFilename(), errstr)
638    
 # end of class ProjFrame  
639    
640    
641  class ProjPanel(wxPanel):  class ProjPanel(wx.Panel):
642      """Base class for all projection panels."""      """Base class for all projection panels."""
643    
644      def __init__(self, parent):      def __init__(self, parent):
645          wxPanel.__init__(self, parent, -1)          wx.Panel.__init__(self, parent, -1)
646    
647          self.__ellps = wxChoice(self, -1)          self.__ellps = wx.Choice(self, -1)
648          self.ellpsData = [("airy"  , _("Airy")),          self.ellpsData = [("", _("<Unknown>")),
649                              ("airy"  , _("Airy")),
650                            ("bessel", _("Bessel 1841")),                            ("bessel", _("Bessel 1841")),
651                            ("clrk66", _("Clarke 1866")),                            ("clrk66", _("Clarke 1866")),
652                            ("clrk80", _("Clarke 1880")),                            ("clrk80", _("Clarke 1880")),
653                            ("GRS80" , _("GRS 1980 (IUGG, 1980)")),                            ("GRS80" , _("GRS 1980 (IUGG, 1980)")),
654                            ("intl"  , _("International 1909 (Hayford)")),                            ("intl"  , _("International 1909 (Hayford)")),
# Line 625  class ProjPanel(wxPanel): Line 658  class ProjPanel(wxPanel):
658              self.__ellps.Append(name, tag)              self.__ellps.Append(name, tag)
659    
660          self.__ellps.SetSelection(0)          self.__ellps.SetSelection(0)
661            
662      def _DoLayout(self, childPanel = None):      def _DoLayout(self, childPanel = None):
663    
664          panelSizer = wxBoxSizer(wxVERTICAL)          panelSizer = wx.BoxSizer(wx.VERTICAL)
665    
666          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wx.BoxSizer(wx.HORIZONTAL)
667          sizer.Add(wxStaticText(self, -1, _("Ellipsoid:")), 0,          sizer.Add(wx.StaticText(self, -1, _("Ellipsoid:")), 0,
668                                      wxALL|wxALIGN_CENTER_VERTICAL, 4)                                      wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
669          sizer.Add(self.__ellps, 1, wxALL|wxEXPAND|wxADJUST_MINSIZE, 4)          sizer.Add(self.__ellps, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
670          panelSizer.Add(sizer, 0, wxALL|wxEXPAND, 4)          panelSizer.Add(sizer, 0, wx.ALL|wx.EXPAND, 4)
671    
672          if childPanel is not None:          if childPanel is not None:
673              panelSizer.Add(childPanel, 0, wxEXPAND, 0)              panelSizer.Add(childPanel, 0, wx.EXPAND, 0)
674                
675          self.SetAutoLayout(1)          self.SetAutoLayout(1)
676          self.SetSizer(panelSizer)          self.SetSizer(panelSizer)
677          panelSizer.Fit(self)          panelSizer.Fit(self)
# Line 661  class ProjPanel(wxPanel): Line 694  class ProjPanel(wxPanel):
694          self.__ellps.SetSelection(0)          self.__ellps.SetSelection(0)
695    
696      def GetParameters(self):      def GetParameters(self):
697          return ["ellps=" + self.__ellps.GetClientData(          ellps = self.__ellps.GetSelection()
698                                          self.__ellps.GetSelection())]          if ellps > 0:
699                return ["ellps=" + self.__ellps.GetClientData(ellps)]
700            return []
701    
702    
703  ID_TMPANEL_LAT = 4001  ID_TMPANEL_LAT = 4001
# Line 672  ID_TMPANEL_FALSE_NORTH = 4004 Line 707  ID_TMPANEL_FALSE_NORTH = 4004
707  ID_TMPANEL_SCALE = 4005  ID_TMPANEL_SCALE = 4005
708    
709  class UnknownProjPanel(ProjPanel):  class UnknownProjPanel(ProjPanel):
710    
711        """Panel for unknown projection types"""
712    
713      def __init__(self, parent, receiver):      def __init__(self, parent, receiver):
714          ProjPanel.__init__(self, parent)          ProjPanel.__init__(self, parent)
715    
716            self.__text = _("Thuban does not know the parameters\n"
717                            "for the current projection and cannot\n"
718                            "display a configuration panel.\n\n"
719                            "The unidentified set of parameters is:\n\n")
720    
721            self.__textbox = wx.TextCtrl(self, -1, self.__text, size=(100,200),
722                                style=wx.TE_READONLY|wx.TE_MULTILINE|wx.TE_LINEWRAP)
723          self._DoLayout()          self._DoLayout()
724    
725      def _DoLayout(self):      def _DoLayout(self):
726          sizer = wxBoxSizer(wxVERTICAL)          sizer = wx.BoxSizer(wx.VERTICAL)
727    
728          sizer.Add(wxStaticText(self, -1,          sizer.Add(self.__textbox, 0, wx.ALL|wx.EXPAND, 4)
             _("Thuban does not know the parameters for the " +  
               "current projection and cannot display a " +  
               "configuration panel.")))  
729    
730          ProjPanel._DoLayout(self, sizer)          ProjPanel._DoLayout(self, sizer)
731    
# Line 691  class UnknownProjPanel(ProjPanel): Line 733  class UnknownProjPanel(ProjPanel):
733          return "Unknown"          return "Unknown"
734    
735      def SetProjection(self, proj):      def SetProjection(self, proj):
736          pass          """Append the available parameters to the info text."""
737            text = self.__text
738            for param in proj.GetAllParameters():
739                text = text + '%s\n' % param
740            self.__textbox.SetValue(text)
741    
742      def GetParameters(self):      def GetParameters(self):
743          return None          return None
# Line 702  class TMPanel(ProjPanel): Line 748  class TMPanel(ProjPanel):
748      def __init__(self, parent, receiver):      def __init__(self, parent, receiver):
749          ProjPanel.__init__(self, parent)          ProjPanel.__init__(self, parent)
750    
751          self.__latitude = wxTextCtrl(self, ID_TMPANEL_LAT)          self.__latitude = wx.TextCtrl(self, ID_TMPANEL_LAT)
752          self.__longitude = wxTextCtrl(self, ID_TMPANEL_LONG)          self.__longitude = wx.TextCtrl(self, ID_TMPANEL_LONG)
753          self.__scale = wxTextCtrl(self, ID_TMPANEL_SCALE)          self.__falseEast = wx.TextCtrl(self, ID_TMPANEL_FASLE_EAST)
754          self.__falseEast = wxTextCtrl(self, ID_TMPANEL_FASLE_EAST)          self.__falseNorth = wx.TextCtrl(self, ID_TMPANEL_FALSE_NORTH)
755          self.__falseNorth = wxTextCtrl(self, ID_TMPANEL_FALSE_NORTH)          self.__scale = wx.TextCtrl(self, ID_TMPANEL_SCALE)
756    
757          self._DoLayout()          self._DoLayout()
758    
759      def _DoLayout(self):      def _DoLayout(self):
760    
761          sizer = wxFlexGridSizer(4, 4, 0, 0)          sizer = wx.FlexGridSizer(4, 2, 0, 0)
762          sizer.Add(wxStaticText(self, -1, _("Latitude:")), 0, wxALL, 4)          sizer.Add(wx.StaticText(self, -1, _("Latitude:")), 0, wx.ALL, 4)
763          sizer.Add(self.__latitude, 0, wxALL, 4)          sizer.Add(self.__latitude, 0, wx.ALL, 4)
764          sizer.Add(wxStaticText(self, -1, _("False Easting:")), 0, wxALL, 4)          sizer.Add(wx.StaticText(self, -1, _("Longitude:")), 0, wx.ALL, 4)
765          sizer.Add(self.__falseEast, 0, wxALL, 4)          sizer.Add(self.__longitude, 0, wx.ALL, 4)
766          sizer.Add(wxStaticText(self, -1, _("Longitude:")), 0, wxALL, 4)          sizer.Add(wx.StaticText(self, -1, _("False Easting:")), 0, wx.ALL, 4)
767          sizer.Add(self.__longitude, 0, wxALL, 4)          sizer.Add(self.__falseEast, 0, wx.ALL, 4)
768          sizer.Add(wxStaticText(self, -1, _("False Northing:")), 0, wxALL, 4)          sizer.Add(wx.StaticText(self, -1, _("False Northing:")), 0, wx.ALL, 4)
769          sizer.Add(self.__falseNorth, 0, wxALL, 4)          sizer.Add(self.__falseNorth, 0, wx.ALL, 4)
770          sizer.Add(wxStaticText(self, -1, _("Scale Factor:")), 0, wxALL, 4)          sizer.Add(wx.StaticText(self, -1, _("Scale Factor:")), 0, wx.ALL, 4)
771          sizer.Add(self.__scale, 0, wxALL, 4)          sizer.Add(self.__scale, 0, wx.ALL, 4)
772    
773          ProjPanel._DoLayout(self, sizer)          ProjPanel._DoLayout(self, sizer)
774    
# Line 771  class UTMPanel(ProjPanel): Line 817  class UTMPanel(ProjPanel):
817    
818          self.receiver = receiver          self.receiver = receiver
819    
820          self.__zone = wxSpinCtrl(self, ID_UTMPANEL_ZONE, "1", min=1, max=60)          self.__zone = wx.SpinCtrl(self, ID_UTMPANEL_ZONE, "1", min=1, max=60)
821          self.__propButton = wxButton(self, ID_UTMPANEL_PROP, _("Propose"))          self.__propButton = wx.Button(self, ID_UTMPANEL_PROP, _("Propose"))
822          self.__south = wxCheckBox(self, ID_UTMPANEL_SOUTH,          self.__south = wx.CheckBox(self, ID_UTMPANEL_SOUTH,
823                                    _("Southern Hemisphere"))                                    _("Southern Hemisphere"))
824    
825          self._DoLayout()          self._DoLayout()
826    
827          EVT_BUTTON(self, ID_UTMPANEL_PROP, self._OnPropose)          self.Bind(wx.EVT_BUTTON, self._OnPropose, id=ID_UTMPANEL_PROP)
828    
829      def _DoLayout(self):      def _DoLayout(self):
830    
831          sizer = wxBoxSizer(wxVERTICAL)          sizer = wx.BoxSizer(wx.VERTICAL)
832          psizer = wxBoxSizer(wxHORIZONTAL)          psizer = wx.BoxSizer(wx.HORIZONTAL)
833          psizer.Add(wxStaticText(self, -1, _("Zone:")), 0, wxALL, 4)          psizer.Add(wx.StaticText(self, -1, _("Zone:")), 0, wx.ALL, 4)
834          psizer.Add(self.__zone, 0, wxALL, 4)          psizer.Add(self.__zone, 0, wx.ALL, 4)
835          psizer.Add(self.__propButton, 0, wxALL, 4)          psizer.Add(self.__propButton, 0, wx.ALL, 4)
836          sizer.Add(psizer, 0, wxALL, 4)          sizer.Add(psizer, 0, wx.ALL, 4)
837          sizer.Add(self.__south, 0, wxALL, 4)          sizer.Add(self.__south, 0, wx.ALL, 4)
838    
839          ProjPanel._DoLayout(self, sizer)          ProjPanel._DoLayout(self, sizer)
840    
# Line 814  class UTMPanel(ProjPanel): Line 860  class UTMPanel(ProjPanel):
860          ProjPanel.Clear(self)          ProjPanel.Clear(self)
861    
862      def _OnPropose(self, event):      def _OnPropose(self, event):
863          UTMProposeZoneDialog          """Call the propose dialog.
864            If the receiver (e.g. the current map) has no bounding box,
865            inform the user accordingly.
866            """
867            bb = self.receiver.BoundingBox()
868            if bb is None:
869                dlg = wx.MessageDialog(self,
870                        _("Can not propose: No bounding box found."),
871                        _("Projection: Propose UTM Zone"),
872                        wx.OK | wx.ICON_INFORMATION)
873                dlg.CenterOnParent()
874                result = dlg.ShowModal()
875                dlg.Destroy()
876                return
877    
878          dlg = UTMProposeZoneDialog(self, self.receiver.BoundingBox())          dlg = UTMProposeZoneDialog(self, self.receiver.BoundingBox())
879          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wx.ID_OK:
880              self.__zone.SetValue(dlg.GetProposedZone())              self.__zone.SetValue(dlg.GetProposedZone())
881    
882  class LCCPanel(ProjPanel):  class LCCPanel(ProjPanel):
883      """Projection Panel for Lambert Conic Conformal."""      """Projection Panel for Lambert Conic Conformal."""
884    
885      def __init__(self, parent, receiver):      def __init__(self, parent, receiver):
886          ProjPanel.__init__(self, parent)          ProjPanel.__init__(self, parent)
887            
888          self.__fspLatitude = wxTextCtrl(self, -1)          self.__fspLatitude = wx.TextCtrl(self, -1)
889          self.__sspLatitude = wxTextCtrl(self, -1)          self.__sspLatitude = wx.TextCtrl(self, -1)
890          self.__originLat   = wxTextCtrl(self, -1)          self.__meridian    = wx.TextCtrl(self, -1)
891          self.__meridian    = wxTextCtrl(self, -1)          self.__originLat   = wx.TextCtrl(self, -1)
892          self.__falseEast   = wxTextCtrl(self, -1)          self.__falseEast   = wx.TextCtrl(self, -1)
893          self.__falseNorth  = wxTextCtrl(self, -1)          self.__falseNorth  = wx.TextCtrl(self, -1)
894    
895          self._DoLayout()          self._DoLayout()
896    
897      def _DoLayout(self):      def _DoLayout(self):
898    
899          sizer = wxFlexGridSizer(6, 2, 0, 0)          sizer = wx.FlexGridSizer(6, 2, 0, 0)
900          sizer.Add(wxStaticText(self, -1,          sizer.Add(wx.StaticText(self, -1,
901              _("Latitude of first standard parallel:")))              _("Latitude of first standard parallel:")))
902          sizer.Add(self.__fspLatitude, 0, wxALL, 4)          sizer.Add(self.__fspLatitude, 0, wx.ALL, 4)
903          sizer.Add(wxStaticText(self, -1,          sizer.Add(wx.StaticText(self, -1,
904              _("Latitude of second standard parallel:")))              _("Latitude of second standard parallel:")))
905          sizer.Add(self.__sspLatitude, 0, wxALL, 4)          sizer.Add(self.__sspLatitude, 0, wx.ALL, 4)
906          sizer.Add(wxStaticText(self, -1, _("Latitude of origin:")))          sizer.Add(wx.StaticText(self, -1, _("Central Meridian:")))
907          sizer.Add(self.__originLat, 0, wxALL, 4)          sizer.Add(self.__meridian, 0, wx.ALL, 4)
908          sizer.Add(wxStaticText(self, -1, _("Central Meridian:")))          sizer.Add(wx.StaticText(self, -1, _("Latitude of origin:")))
909          sizer.Add(self.__meridian, 0, wxALL, 4)          sizer.Add(self.__originLat, 0, wx.ALL, 4)
910          sizer.Add(wxStaticText(self, -1, _("False Easting:")))          sizer.Add(wx.StaticText(self, -1, _("False Easting:")))
911          sizer.Add(self.__falseEast, 0, wxALL, 4)          sizer.Add(self.__falseEast, 0, wx.ALL, 4)
912          sizer.Add(wxStaticText(self, -1, _("False Northing:")))          sizer.Add(wx.StaticText(self, -1, _("False Northing:")))
913          sizer.Add(self.__falseNorth, 0, wxALL, 4)          sizer.Add(self.__falseNorth, 0, wx.ALL, 4)
914    
915          ProjPanel._DoLayout(self, sizer)          ProjPanel._DoLayout(self, sizer)
916    
917      def GetProjName(self):      def GetProjName(self):
918          return _("Lambert Conic Conformal")          return _("Lambert Conic Conformal")
919            
920      def SetProjection(self, proj):      def SetProjection(self, proj):
921          self.__fspLatitude.SetValue(proj.GetParameter("lat_1"))          self.__fspLatitude.SetValue(proj.GetParameter("lat_1"))
922          self.__sspLatitude.SetValue(proj.GetParameter("lat_2"))          self.__sspLatitude.SetValue(proj.GetParameter("lat_2"))
# Line 868  class LCCPanel(ProjPanel): Line 928  class LCCPanel(ProjPanel):
928          ProjPanel.SetProjection(self, proj)          ProjPanel.SetProjection(self, proj)
929    
930      def GetParameters(self):      def GetParameters(self):
931          params = ["proj=lcc",          params = ["proj=lcc",
932                    "lat_1=" + self.__fspLatitude.GetValue(),                    "lat_1=" + self.__fspLatitude.GetValue(),
933                    "lat_2=" + self.__sspLatitude.GetValue(),                    "lat_2=" + self.__sspLatitude.GetValue(),
934                    "lat_0=" + self.__originLat.GetValue(),                    "lat_0=" + self.__originLat.GetValue(),
# Line 889  class LCCPanel(ProjPanel): Line 949  class LCCPanel(ProjPanel):
949    
950          ProjPanel.Clear(self)          ProjPanel.Clear(self)
951    
952  class GeoPanel(ProjPanel):  class GeoPanel(ProjPanel):
953      """Projection Panel for a Geographic Projection."""      """Projection Panel for a Geographic Projection."""
954    
955      def __init__(self, parent, receiver):      def __init__(self, parent, receiver):
# Line 898  class GeoPanel(ProjPanel): Line 958  class GeoPanel(ProjPanel):
958          self.__choices = [(_("Degrees"), "0.017453"),          self.__choices = [(_("Degrees"), "0.017453"),
959                            (_("Radians"), "1")]                            (_("Radians"), "1")]
960    
961          self.__scale = wxChoice(self, -1)          self.__scale = wx.Choice(self, -1)
962          for choice, value in self.__choices:          for choice, value in self.__choices:
963              self.__scale.Append(choice, value)              self.__scale.Append(choice, value)
964    
# Line 906  class GeoPanel(ProjPanel): Line 966  class GeoPanel(ProjPanel):
966    
967      def GetProjName(self):      def GetProjName(self):
968          return _("Geographic")          return _("Geographic")
969            
970      def SetProjection(self, proj):      def SetProjection(self, proj):
971          value = proj.GetParameter("to_meter")          value = proj.GetParameter("to_meter")
972          for i in range(len(self.__choices)):          for i in range(len(self.__choices)):
# Line 916  class GeoPanel(ProjPanel): Line 976  class GeoPanel(ProjPanel):
976          ProjPanel.SetProjection(self, proj)          ProjPanel.SetProjection(self, proj)
977    
978      def GetParameters(self):      def GetParameters(self):
979          params = ["proj=latlong",          params = ["proj=latlong",
980                    "to_meter=%s" % self.__scale.GetClientData(                    "to_meter=%s" % self.__scale.GetClientData(
981                                    self.__scale.GetSelection())]                                    self.__scale.GetSelection())]
982    
# Line 927  class GeoPanel(ProjPanel): Line 987  class GeoPanel(ProjPanel):
987          ProjPanel.Clear(self)          ProjPanel.Clear(self)
988    
989      def _DoLayout(self):      def _DoLayout(self):
990          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wx.BoxSizer(wx.HORIZONTAL)
991    
992          sizer.Add(wxStaticText(self, -1, _("Source Data is in: ")),          sizer.Add(wx.StaticText(self, -1, _("Source Data is in: ")),
993                    0, wxALL|wxALIGN_CENTER_VERTICAL, 4)                    0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
994          sizer.Add(self.__scale, 1, wxEXPAND|wxALL, 4)          sizer.Add(self.__scale, 1, wx.EXPAND|wx.ALL, 4)
995    
996          self.__scale.SetSelection(0)          self.__scale.SetSelection(0)
997    
# Line 940  class GeoPanel(ProjPanel): Line 1000  class GeoPanel(ProjPanel):
1000    
1001  ID_UTM_PROPOSE_ZONE_DIALOG_TAKE   = 4001  ID_UTM_PROPOSE_ZONE_DIALOG_TAKE   = 4001
1002  ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL = 4002  ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL = 4002
1003  class UTMProposeZoneDialog(wxDialog):  class UTMProposeZoneDialog(wx.Dialog):
1004                                                                                    
1005      """Propose a sensible Zone considering the current map extent."""      """Propose a sensible Zone considering the current map extent."""
1006                                                                                    
1007      def __init__(self, parent, (x, y, x2, y2)):      def __init__(self, parent, (x, y, x2, y2)):
1008          wxDialog.__init__(self, parent, -1, _("Projection: Propose UTM Zone"),          wx.Dialog.__init__(self, parent, -1, _("Projection: Propose UTM Zone"),
1009                            wxDefaultPosition, wxSize(200, 100))                            wx.DefaultPosition, wx.Size(200, 100))
1010          self.parent = parent          self.parent = parent
         #x, y, x2, y2 = elf.parent.parent.map_bounding_box  
1011          x = x + 180          x = x + 180
1012          x2 = x2 + 180          x2 = x2 + 180
1013          center = (x2 - x) / 2 + x          center = (x2 - x) / 2 + x
1014          self.proposedZone = int(center / 6 + 1)          self.proposedZone = int(center / 6 + 1)
1015          self.dialogLayout()          self.dialogLayout()
1016                                                                                    
1017      def dialogLayout(self):      def dialogLayout(self):
1018          topBox = wxBoxSizer(wxVERTICAL)          topBox = wx.BoxSizer(wx.VERTICAL)
1019                                                                                    
1020          textBox = wxBoxSizer(wxVERTICAL)          textBox = wx.BoxSizer(wx.VERTICAL)
1021          textBox.Add(wxStaticText(self, -1, _("The current map extent center " +          textBox.Add(wx.StaticText(self, -1, _("The current map extent center "
1022                                             "lies in UTM Zone")),                                               "lies in UTM Zone")),
1023                      0, wxALIGN_CENTER|wxALL, 4)                      0, wx.ALIGN_CENTER|wx.ALL, 4)
1024          textBox.Add(wxStaticText(self, -1, str(self.proposedZone)),          textBox.Add(wx.StaticText(self, -1, str(self.proposedZone)),
1025                      0, wxALIGN_CENTER|wxALL, 4)                      0, wx.ALIGN_CENTER|wx.ALL, 4)
1026                                                                                    
1027          topBox.Add(textBox, 1, wxEXPAND|wxALL, 4)          topBox.Add(textBox, 1, wx.EXPAND|wx.ALL, 4)
1028                                                                                    
1029          buttonBox = wxBoxSizer(wxHORIZONTAL)          buttonBox = wx.BoxSizer(wx.HORIZONTAL)
1030          buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE,          buttonBox.Add(wx.Button(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE,
1031                        _("Take")), 0, wxALL, 4)                        _("Take")), 0, wx.ALL, 4)
1032          buttonBox.Add(wxButton(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL,          buttonBox.Add(wx.Button(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL,
1033                                 _("Cancel")), 0, wxALL, 4)                                 _("Cancel")), 0, wx.ALL, 4)
1034          topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10)          topBox.Add(buttonBox, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 10)
1035          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_TAKE, self.OnTake)          self.Bind(wx.EVT_BUTTON, self.OnTake, id=ID_UTM_PROPOSE_ZONE_DIALOG_TAKE)
1036          EVT_BUTTON(self, ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL, self.OnCancel)          self.Bind(wx.EVT_BUTTON, self.OnCancel, id=ID_UTM_PROPOSE_ZONE_DIALOG_CANCEL)
1037                                                                                    
1038          self.SetAutoLayout(True)          self.SetAutoLayout(True)
1039          self.SetSizer(topBox)          self.SetSizer(topBox)
1040          topBox.Fit(self)          topBox.Fit(self)
1041          topBox.SetSizeHints(self)          topBox.SetSizeHints(self)
1042                                                                                    
1043      def OnTake(self, event):      def OnTake(self, event):
1044          self.EndModal(wxID_OK)          self.EndModal(wx.ID_OK)
1045                                                                                    
1046      def OnCancel(self, event):      def OnCancel(self, event):
1047          self.EndModal(wxID_CANCEL)          self.EndModal(wx.ID_CANCEL)
1048    
1049      def GetProposedZone(self):      def GetProposedZone(self):
1050          return self.proposedZone          return self.proposedZone

Legend:
Removed from v.976  
changed lines
  Added in v.2700

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26