GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
statusbar.py
Go to the documentation of this file.
1 """!
2 @package mapdisp.statusbar
3 
4 @brief Classes for statusbar management
5 
6 Classes:
7  - statusbar::SbException
8  - statusbar::SbManager
9  - statusbar::SbItem
10  - statusbar::SbRender
11  - statusbar::SbShowRegion
12  - statusbar::SbAlignExtent
13  - statusbar::SbResolution
14  - statusbar::SbMapScale
15  - statusbar::SbGoTo
16  - statusbar::SbProjection
17  - statusbar::SbMask
18  - statusbar::SbTextItem
19  - statusbar::SbDisplayGeometry
20  - statusbar::SbCoordinates
21  - statusbar::SbRegionExtent
22  - statusbar::SbCompRegionExtent
23  - statusbar::SbProgress
24 
25 (C) 2006-2011 by the GRASS Development Team
26 
27 This program is free software under the GNU General Public License
28 (>=v2). Read the file COPYING that comes with GRASS for details.
29 
30 @author Vaclav Petras <wenzeslaus gmail.com>
31 @author Anna Kratochvilova <kratochanna gmail.com>
32 """
33 
34 import wx
35 
36 from core import utils
37 from core.gcmd import GMessage, RunCommand
38 from core.settings import UserSettings
39 
40 from grass.script import core as grass
41 
43  """! Exception class used in SbManager and SbItems"""
44  def __init__(self, message):
45  self.message = message
46  def __str__(self):
47  return self.message
48 
49 
50 class SbManager:
51  """!Statusbar manager for wx.Statusbar and SbItems.
52 
53  Statusbar manager manages items added by AddStatusbarItem method.
54  Provides progress bar (SbProgress) and choice (wx.Choice).
55  Items with position 0 are shown according to choice selection.
56  Only one item of the same class is supposed to be in statusbar.
57  Manager user have to create statusbar on his own, add items to manager
58  and call Update method to show particular widgets.
59  User settings (group = 'display', key = 'statusbarMode', subkey = 'selection')
60  are taken into account.
61 
62  @todo generalize access to UserSettings (specify group, etc.)
63  @todo add GetMode method using name instead of index
64  """
65  def __init__(self, mapframe, statusbar):
66  """!Connects manager to statusbar
67 
68  Creates choice and progress bar.
69  """
70  self.mapFrame = mapframe
71  self.statusbar = statusbar
72 
73  self.choice = wx.Choice(self.statusbar, wx.ID_ANY)
74 
75  self.choice.Bind(wx.EVT_CHOICE, self.OnToggleStatus)
76 
77  self.statusbarItems = dict()
78 
79  self._postInitialized = False
80 
82 
83  self._hiddenItems = {}
84 
85  def SetProperty(self, name, value):
86  """!Sets property represented by one of contained SbItems
87 
88  @param name name of SbItem (from name attribute)
89  @param value value to be set
90  """
91  self.statusbarItems[name].SetValue(value)
92 
93  def GetProperty(self, name):
94  """!Returns property represented by one of contained SbItems
95 
96  @param name name of SbItem (from name attribute)
97  """
98  return self.statusbarItems[name].GetValue()
99 
100  def HasProperty(self, name):
101  """!Checks whether property is represented by one of contained SbItems
102 
103  @param name name of SbItem (from name attribute)
104 
105  @returns True if particular SbItem is contained, False otherwise
106  """
107  if name in self.statusbarItems:
108  return True
109  return False
110 
111  def AddStatusbarItem(self, item):
112  """!Adds item to statusbar
113 
114  If item position is 0, item is managed by choice.
115 
116  @see AddStatusbarItemsByClass
117  """
118  self.statusbarItems[item.name] = item
119  if item.GetPosition() == 0:
120  self.choice.Append(item.label, clientData = item) #attrError?
121 
122  def AddStatusbarItemsByClass(self, itemClasses, **kwargs):
123  """!Adds items to statusbar
124 
125  @param itemClasses list of classes of items to be add
126  @param kwargs SbItem constructor parameters
127 
128  @see AddStatusbarItem
129  """
130  for Item in itemClasses:
131  item = Item(**kwargs)
132  self.AddStatusbarItem(item)
133 
134  def HideStatusbarChoiceItemsByClass(self, itemClasses):
135  """!Hides items showed in choice
136 
137  Hides items with position 0 (items showed in choice) by removing
138  them from choice.
139 
140  @param itemClasses list of classes of items to be hided
141 
142  @see ShowStatusbarChoiceItemsByClass
143  @todo consider adding similar function which would take item names
144  """
145  index = []
146  for itemClass in itemClasses:
147  for i in range(0, self.choice.GetCount() - 1):
148  item = self.choice.GetClientData(i)
149  if item.__class__ == itemClass:
150  index.append(i)
151  self._hiddenItems[i] = item
152  # must be sorted in reverse order to be removed correctly
153  for i in sorted(index, reverse = True):
154  self.choice.Delete(i)
155 
156  def ShowStatusbarChoiceItemsByClass(self, itemClasses):
157  """!Shows items showed in choice
158 
159  Shows items with position 0 (items showed in choice) by adding
160  them to choice.
161  Items are restored in their old positions.
162 
163  @param itemClasses list of classes of items to be showed
164 
165  @see HideStatusbarChoiceItemsByClass
166  """
167  # must be sorted to be inserted correctly
168  for pos in sorted(self._hiddenItems.keys()):
169  item = self._hiddenItems[pos]
170  if item.__class__ in itemClasses:
171  self.choice.Insert(item.label, pos, item)
172 
173  def ShowItem(self, itemName):
174  """!Invokes showing of particular item
175 
176  @see Update
177  """
178  self.statusbarItems[itemName].Show()
179 
180  def _postInit(self):
181  """!Post-initialization method
182 
183  It sets internal user settings,
184  set choice's selection (from user settings) and does reposition.
185  It needs choice filled by items.
186  it is called automatically.
187  """
188  UserSettings.Set(group = 'display',
189  key = 'statusbarMode',
190  subkey = 'choices',
191  value = self.choice.GetItems(),
192  internal = True)
193 
194  self.choice.SetSelection(UserSettings.Get(group = 'display',
195  key = 'statusbarMode',
196  subkey = 'selection'))
197  self.Reposition()
198 
199  self._postInitialized = True
200 
201  def Update(self):
202  """!Updates statusbar
203 
204  It always updates mask.
205  """
206  if not self._postInitialized:
207  self._postInit()
208 
209  for item in self.statusbarItems.values():
210  if item.GetPosition() == 0:
211  item.Hide()
212  else:
213  item.Update() # mask, render
214 
215  if self.choice.GetCount() > 0:
216  item = self.choice.GetClientData(self.choice.GetSelection())
217  item.Update()
218 
219  def Reposition(self):
220  """!Reposition items in statusbar
221 
222  Set positions to all items managed by statusbar manager.
223  It should not be necessary to call it manually.
224  """
225 
226  widgets = []
227  for item in self.statusbarItems.values():
228  widgets.append((item.GetPosition(), item.GetWidget()))
229 
230  widgets.append((1, self.choice))
231  widgets.append((0, self.progressbar.GetWidget()))
232 
233  for idx, win in widgets:
234  if not win:
235  continue
236  rect = self.statusbar.GetFieldRect(idx)
237  if idx == 0: # show region / mapscale / process bar
238  # -> size
239  wWin, hWin = win.GetBestSize()
240  if win == self.progressbar.GetWidget():
241  wWin = rect.width - 6
242  # -> position
243  # if win == self.statusbarWin['region']:
244  # x, y = rect.x + rect.width - wWin, rect.y - 1
245  # align left
246  # else:
247  x, y = rect.x + 3, rect.y - 1
248  w, h = wWin, rect.height + 2
249  else: # choice || auto-rendering
250  x, y = rect.x, rect.y - 1
251  w, h = rect.width, rect.height + 2
252  if idx == 2: # mask
253  x += 5
254  y += 4
255  elif idx == 3: # render
256  x += 5
257  win.SetPosition((x, y))
258  win.SetSize((w, h))
259 
260  def GetProgressBar(self):
261  """!Returns progress bar"""
262  return self.progressbar
263 
264  def OnToggleStatus(self, event):
265  """!Toggle status text
266  """
267  self.Update()
268 
269  def SetMode(self, modeIndex):
270  """!Sets current mode
271 
272  Mode is usually driven by user through choice.
273  """
274  self.choice.SetSelection(modeIndex)
275 
276  def GetMode(self):
277  """!Returns current mode"""
278  return self.choice.GetSelection()
279 
280 class SbItem:
281  """!Base class for statusbar items.
282 
283  Each item represents functionality (or action) controlled by statusbar
284  and related to MapFrame.
285  One item is usually connected with one widget but it is not necessary.
286  Item can represent property (depends on manager).
287  Items are not widgets but can provide interface to them.
288  Items usually has requirements to MapFrame instance
289  (specified as MapFrame.methodname or MapWindow.methodname).
290 
291  @todo consider externalizing position (see SbProgress use in SbManager)
292  """
293  def __init__(self, mapframe, statusbar, position = 0):
294  """!
295 
296  @param mapframe instance of class with MapFrame interface
297  @param statusbar statusbar instance (wx.Statusbar)
298  @param position item position in statusbar
299 
300  @todo rewrite Update also in derived classes to take in account item position
301  """
302  self.mapFrame = mapframe
303  self.statusbar = statusbar
304  self.position = position
305 
306  def Show(self):
307  """!Invokes showing of underlying widget.
308 
309  In derived classes it can do what is appropriate for it,
310  e.g. showing text on statusbar (only).
311  """
312  self.widget.Show()
313 
314  def Hide(self):
315  self.widget.Hide()
316 
317  def SetValue(self, value):
318  self.widget.SetValue(value)
319 
320  def GetValue(self):
321  return self.widget.GetValue()
322 
323  def GetPosition(self):
324  return self.position
325 
326  def GetWidget(self):
327  """!Returns underlaying winget.
328 
329  @return widget or None if doesn't exist
330  """
331  return self.widget
332 
333  def _update(self, longHelp):
334  """!Default implementation for Update method.
335 
336  @param longHelp True to enable long help (help from toolbars)
337  """
338  self.statusbar.SetStatusText("", 0)
339  self.Show()
340  self.mapFrame.StatusbarEnableLongHelp(longHelp)
341 
342  def Update(self):
343  """!Called when statusbar action is activated (e.g. through wx.Choice).
344  """
345  self._update(longHelp = False)
346 
348  """!Checkbox to enable and disable auto-rendering.
349 
350  Requires MapFrame.OnRender method.
351  """
352  def __init__(self, mapframe, statusbar, position = 0):
353  SbItem.__init__(self, mapframe, statusbar, position)
354  self.name = 'render'
355 
356  self.widget = wx.CheckBox(parent = self.statusbar, id = wx.ID_ANY,
357  label = _("Render"))
358 
359  self.widget.SetValue(UserSettings.Get(group = 'display',
360  key = 'autoRendering',
361  subkey = 'enabled'))
362  self.widget.Hide()
363  self.widget.SetToolTip(wx.ToolTip (_("Enable/disable auto-rendering")))
364 
365  self.widget.Bind(wx.EVT_CHECKBOX, self.OnToggleRender)
366 
367  def OnToggleRender(self, event):
368  # (other items should call self.mapFrame.IsAutoRendered())
369  if self.GetValue():
370  self.mapFrame.OnRender(None)
371 
372  def Update(self):
373  self.Show()
374 
376  """!Checkbox to enable and disable showing of computational region.
377 
378  Requires MapFrame.OnRender, MapFrame.IsAutoRendered, MapFrame.GetWindow.
379  Expects that instance returned by MapFrame.GetWindow will handle
380  regionCoords attribute.
381  """
382  def __init__(self, mapframe, statusbar, position = 0):
383  SbItem.__init__(self, mapframe, statusbar, position)
384  self.name = 'region'
385  self.label = _("Show comp. extent")
386 
387  self.widget = wx.CheckBox(parent = self.statusbar, id = wx.ID_ANY,
388  label = _("Show computational extent"))
389 
390  self.widget.SetValue(False)
391  self.widget.Hide()
392  self.widget.SetToolTip(wx.ToolTip (_("Show/hide computational "
393  "region extent (set with g.region). "
394  "Display region drawn as a blue box inside the "
395  "computational region, "
396  "computational region inside a display region "
397  "as a red box).")))
398 
399  self.widget.Bind(wx.EVT_CHECKBOX, self.OnToggleShowRegion)
400 
401  def OnToggleShowRegion(self, event):
402  """!Shows/Hides extent (comp. region) in map canvas.
403 
404  Shows or hides according to checkbox value.
405  """
406  if self.widget.GetValue():
407  # show extent
408  self.mapFrame.GetWindow().regionCoords = []
409  elif hasattr(self.mapFrame.GetWindow(), 'regionCoords'):
410  del self.mapFrame.GetWindow().regionCoords
411 
412  # redraw map if auto-rendering is enabled
413  if self.mapFrame.IsAutoRendered():
414  self.mapFrame.OnRender(None)
415 
416  def SetValue(self, value):
417  SbItem.SetValue(self, value)
418  if value:
419  self.mapFrame.GetWindow().regionCoords = []
420  elif hasattr(self.mapFrame.GetWindow(), 'regionCoords'):
421  del self.mapFrame.GetWindow().regionCoords
422 
424  """!Checkbox to select zoom behavior.
425 
426  Used by BufferedWindow (through MapFrame property).
427  See tooltip for explanation.
428  """
429  def __init__(self, mapframe, statusbar, position = 0):
430  SbItem.__init__(self, mapframe, statusbar, position)
431  self.name = 'alignExtent'
432  self.label = _("Display mode")
433 
434  self.widget = wx.CheckBox(parent = self.statusbar, id = wx.ID_ANY,
435  label = _("Align region extent based on display size"))
436 
437  self.widget.SetValue(UserSettings.Get(group = 'display', key = 'alignExtent', subkey = 'enabled'))
438  self.widget.Hide()
439  self.widget.SetToolTip(wx.ToolTip (_("Align region extent based on display "
440  "size from center point. "
441  "Default value for new map displays can "
442  "be set up in 'User GUI settings' dialog.")))
443 
445  """!Checkbox to select used display resolution.
446 
447  Requires MapFrame.OnRender method.
448  """
449  def __init__(self, mapframe, statusbar, position = 0):
450  SbItem.__init__(self, mapframe, statusbar, position)
451  self.name = 'resolution'
452  self.label = _("Display resolution")
453 
454  self.widget = wx.CheckBox(parent = self.statusbar, id = wx.ID_ANY,
455  label = _("Constrain display resolution to computational settings"))
456 
457  self.widget.SetValue(UserSettings.Get(group = 'display', key = 'compResolution', subkey = 'enabled'))
458  self.widget.Hide()
459  self.widget.SetToolTip(wx.ToolTip (_("Constrain display resolution "
460  "to computational region settings. "
461  "Default value for new map displays can "
462  "be set up in 'User GUI settings' dialog.")))
463 
464  self.widget.Bind(wx.EVT_CHECKBOX, self.OnToggleUpdateMap)
465 
466  def OnToggleUpdateMap(self, event):
467  """!Update display when toggle display mode
468  """
469  # redraw map if auto-rendering is enabled
470  if self.mapFrame.IsAutoRendered():
471  self.mapFrame.OnRender(None)
472 
473 
475  """!Editable combobox to get/set current map scale.
476 
477  Requires MapFrame.GetMapScale, MapFrame.SetMapScale
478  and MapFrame.GetWindow (and GetWindow().UpdateMap()).
479  """
480  def __init__(self, mapframe, statusbar, position = 0):
481  SbItem.__init__(self, mapframe, statusbar, position)
482  self.name = 'mapscale'
483  self.label = _("Map scale")
484 
485  self.widget = wx.ComboBox(parent = self.statusbar, id = wx.ID_ANY,
486  style = wx.TE_PROCESS_ENTER,
487  size = (150, -1))
488 
489  self.widget.SetItems(['1:1000',
490  '1:5000',
491  '1:10000',
492  '1:25000',
493  '1:50000',
494  '1:100000',
495  '1:1000000'])
496  self.widget.Hide()
497  self.widget.SetToolTip(wx.ToolTip (_("As everyone's monitors and resolutions "
498  "are set differently these values are not "
499  "true map scales, but should get you into "
500  "the right neighborhood.")))
501 
502  self.widget.Bind(wx.EVT_TEXT_ENTER, self.OnChangeMapScale)
503  self.widget.Bind(wx.EVT_COMBOBOX, self.OnChangeMapScale)
504 
505  self.lastMapScale = None
506 
507  def Update(self):
508  scale = self.mapFrame.GetMapScale()
509  self.statusbar.SetStatusText("")
510  try:
511  self.SetValue("1:%ld" % (scale + 0.5))
512  except TypeError:
513  pass # FIXME, why this should happen?
514 
515  self.lastMapScale = scale
516  self.Show()
517 
518  # disable long help
519  self.mapFrame.StatusbarEnableLongHelp(False)
520 
521  def OnChangeMapScale(self, event):
522  """!Map scale changed by user
523  """
524  scale = event.GetString()
525 
526  try:
527  if scale[:2] != '1:':
528  raise ValueError
529  value = int(scale[2:])
530  except ValueError:
531  self.SetValue('1:%ld' % int(self.lastMapScale))
532  return
533 
534  self.mapFrame.SetMapScale(value)
535 
536  # redraw a map
537  self.mapFrame.GetWindow().UpdateMap()
538  self.GetWidget().SetFocus()
539 
540 
541 class SbGoTo(SbItem):
542  """!Textctrl to set coordinates which to focus on.
543 
544  Requires MapFrame.GetWindow, MapWindow.GoTo method.
545  """
546 
547  def __init__(self, mapframe, statusbar, position = 0):
548  SbItem.__init__(self, mapframe, statusbar, position)
549  self.name = 'goto'
550  self.label = _("Go to")
551 
552  self.widget = wx.TextCtrl(parent = self.statusbar, id = wx.ID_ANY,
553  value = "", style = wx.TE_PROCESS_ENTER,
554  size = (300, -1))
555 
556  self.widget.Hide()
557 
558  self.widget.Bind(wx.EVT_TEXT_ENTER, self.OnGoTo)
559 
560  def ReprojectENToMap(self, e, n, useDefinedProjection):
561  """!Reproject east, north from user defined projection
562 
563  @param e,n coordinate (for DMS string, else float or string)
564  @param useDefinedProjection projection defined by user in settings dialog
565 
566  @throws SbException if useDefinedProjection is True and projection is not defined in UserSettings
567  """
568  if useDefinedProjection:
569  settings = UserSettings.Get(group = 'projection', key = 'statusbar', subkey = 'proj4')
570  if not settings:
571  raise SbException(_("Projection not defined (check the settings)"))
572  else:
573  # reproject values
574  projIn = settings
575  projOut = RunCommand('g.proj',
576  flags = 'jf',
577  read = True)
578  proj = projIn.split(' ')[0].split('=')[1]
579  if proj in ('ll', 'latlong', 'longlat'):
580  e, n = utils.DMS2Deg(e, n)
581  proj, coord1 = utils.ReprojectCoordinates(coord = (e, n),
582  projIn = projIn,
583  projOut = projOut, flags = 'd')
584  e, n = coord1
585  else:
586  e, n = float(e), float(n)
587  proj, coord1 = utils.ReprojectCoordinates(coord = (e, n),
588  projIn = projIn,
589  projOut = projOut, flags = 'd')
590  e, n = coord1
591  elif self.mapFrame.GetMap().projinfo['proj'] == 'll':
592  e, n = utils.DMS2Deg(e, n)
593  else:
594  e, n = float(e), float(n)
595  return e, n
596 
597  def OnGoTo(self, event):
598  """!Go to position
599  """
600  try:
601  e, n = self.GetValue().split(';')
602  e, n = self.ReprojectENToMap(e, n, self.mapFrame.GetProperty('projection'))
603  self.mapFrame.GetWindow().GoTo(e, n)
604  self.widget.SetFocus()
605  except ValueError:
606  # FIXME: move this code to MapWindow/BufferedWindow/MapFrame
607  region = self.mapFrame.GetMap().GetCurrentRegion()
608  precision = int(UserSettings.Get(group = 'projection', key = 'format',
609  subkey = 'precision'))
610  format = UserSettings.Get(group = 'projection', key = 'format',
611  subkey = 'll')
612  if self.mapFrame.GetMap().projinfo['proj'] == 'll' and format == 'DMS':
613  self.SetValue("%s" % utils.Deg2DMS(region['center_easting'],
614  region['center_northing'],
615  precision = precision))
616  else:
617  self.SetValue("%.*f; %.*f" % \
618  (precision, region['center_easting'],
619  precision, region['center_northing']))
620  except SbException, e:
621  # FIXME: this may be useless since statusbar update checks user defined projection and this exception raises when user def proj does not exists
622  self.statusbar.SetStatusText(str(e), 0)
623 
624  def GetCenterString(self, map):
625  """!Get current map center in appropriate format"""
626  region = map.GetCurrentRegion()
627  precision = int(UserSettings.Get(group = 'projection', key = 'format',
628  subkey = 'precision'))
629  format = UserSettings.Get(group = 'projection', key = 'format',
630  subkey = 'll')
631  projection = UserSettings.Get(group='projection', key='statusbar', subkey='proj4')
632 
633  if self.mapFrame.GetProperty('projection'):
634  if not projection:
635  raise SbException(_("Projection not defined (check the settings)"))
636  else:
637  proj, coord = utils.ReprojectCoordinates(coord = (region['center_easting'],
638  region['center_northing']),
639  projOut = projection,
640  flags = 'd')
641  if coord:
642  if proj in ('ll', 'latlong', 'longlat') and format == 'DMS':
643  return "%s" % utils.Deg2DMS(coord[0],
644  coord[1],
645  precision = precision)
646  else:
647  return "%.*f; %.*f" % (precision, coord[0], precision, coord[1])
648  else:
649  raise SbException(_("Error in projection (check the settings)"))
650  else:
651  if self.mapFrame.GetMap().projinfo['proj'] == 'll' and format == 'DMS':
652  return "%s" % utils.Deg2DMS(region['center_easting'], region['center_northing'],
653  precision = precision)
654  else:
655  return "%.*f; %.*f" % (precision, region['center_easting'], precision, region['center_northing'])
656 
657 
658  def SetCenter(self):
659  """!Set current map center as item value"""
660  center = self.GetCenterString(self.mapFrame.GetMap())
661  self.SetValue(center)
662 
663  def Update(self):
664  self.statusbar.SetStatusText("")
665 
666  try:
667  self.SetCenter()
668  self.Show()
669  except SbException, e:
670  self.statusbar.SetStatusText(str(e), 0)
671 
672  # disable long help
673  self.mapFrame.StatusbarEnableLongHelp(False)
674 
675 
677  """!Checkbox to enable user defined projection (can be set in settings)"""
678  def __init__(self, mapframe, statusbar, position = 0):
679  SbItem.__init__(self, mapframe, statusbar, position)
680  self.name = 'projection'
681  self.label = _("Projection")
682 
683  self.defaultLabel = _("Use defined projection")
684 
685  self.widget = wx.CheckBox(parent = self.statusbar, id = wx.ID_ANY,
686  label = self.defaultLabel)
687 
688  self.widget.SetValue(False)
689 
690  # necessary?
691  size = self.widget.GetSize()
692  self.widget.SetMinSize((size[0] + 150, size[1]))
693 
694  self.widget.Hide()
695  self.widget.SetToolTip(wx.ToolTip (_("Reproject coordinates displayed "
696  "in the statusbar. Projection can be "
697  "defined in GUI preferences dialog "
698  "(tab 'Projection')")))
699 
700  def Update(self):
701  self.statusbar.SetStatusText("")
702  epsg = UserSettings.Get(group = 'projection', key = 'statusbar', subkey = 'epsg')
703  if epsg:
704  label = '%s (EPSG: %s)' % (self.defaultLabel, epsg)
705  self.widget.SetLabel(label)
706  else:
707  self.widget.SetLabel(self.defaultLabel)
708  self.Show()
709 
710  # disable long help
711  self.mapFrame.StatusbarEnableLongHelp(False)
712 
713 
714 class SbMask(SbItem):
715  """!StaticText to show whether mask is activated."""
716  def __init__(self, mapframe, statusbar, position = 0):
717  SbItem.__init__(self, mapframe, statusbar, position)
718  self.name = 'mask'
719 
720  self.widget = wx.StaticText(parent = self.statusbar, id = wx.ID_ANY, label = _('MASK'))
721  self.widget.SetForegroundColour(wx.Colour(255, 0, 0))
722  self.widget.Hide()
723 
724  def Update(self):
725  if grass.find_file(name = 'MASK', element = 'cell',
726  mapset = grass.gisenv()['MAPSET'])['name']:
727  self.Show()
728  else:
729  self.Hide()
730 
732  """!Base class for items without widgets.
733 
734  Only sets statusbar text.
735  """
736  def __init__(self, mapframe, statusbar, position = 0):
737  SbItem.__init__(self, mapframe, statusbar, position)
738 
739  self.text = None
740 
741  def Show(self):
742  self.statusbar.SetStatusText(self.GetValue(), self.position)
743 
744  def Hide(self):
745  self.statusbar.SetStatusText("", self.position)
746 
747  def SetValue(self, value):
748  self.text = value
749 
750  def GetValue(self):
751  return self.text
752 
753  def GetWidget(self):
754  return None
755 
756  def Update(self):
757  self._update(longHelp = True)
758 
760  """!Show current display resolution."""
761  def __init__(self, mapframe, statusbar, position = 0):
762  SbTextItem.__init__(self, mapframe, statusbar, position)
763  self.name = 'displayGeometry'
764  self.label = _("Display geometry")
765 
766  def Show(self):
767  region = self.mapFrame.GetMap().GetCurrentRegion()
768  self.SetValue("rows=%d; cols=%d; nsres=%.2f; ewres=%.2f" %
769  (region["rows"], region["cols"],
770  region["nsres"], region["ewres"]))
771  SbTextItem.Show(self)
772 
774  """!Show map coordinates when mouse moves.
775 
776  Requires MapWindow.GetLastEN method."""
777  def __init__(self, mapframe, statusbar, position = 0):
778  SbTextItem.__init__(self, mapframe, statusbar, position)
779  self.name = 'coordinates'
780  self.label = _("Coordinates")
781 
782  def Show(self):
783  precision = int(UserSettings.Get(group = 'projection', key = 'format',
784  subkey = 'precision'))
785  format = UserSettings.Get(group = 'projection', key = 'format',
786  subkey = 'll')
787  projection = self.mapFrame.GetProperty('projection')
788  try:
789  e, n = self.mapFrame.GetWindow().GetLastEN()
790  self.SetValue(self.ReprojectENFromMap(e, n, projection, precision, format))
791  except SbException, e:
792  self.SetValue(e)
793  except TypeError, e:
794  self.SetValue("")
795  except AttributeError:
796  self.SetValue("") # during initialization MapFrame has no MapWindow
797  SbTextItem.Show(self)
798 
799  def ReprojectENFromMap(self, e, n, useDefinedProjection, precision, format):
800  """!Reproject east, north to user defined projection.
801 
802  @param e,n coordinate
803 
804  @throws SbException if useDefinedProjection is True and projection is not defined in UserSettings
805  """
806  if useDefinedProjection:
807  settings = UserSettings.Get(group = 'projection', key = 'statusbar', subkey = 'proj4')
808  if not settings:
809  raise SbException(_("Projection not defined (check the settings)"))
810  else:
811  # reproject values
812  proj, coord = utils.ReprojectCoordinates(coord = (e, n),
813  projOut = settings,
814  flags = 'd')
815  if coord:
816  e, n = coord
817  if proj in ('ll', 'latlong', 'longlat') and format == 'DMS':
818  return utils.Deg2DMS(e, n, precision = precision)
819  else:
820  return "%.*f; %.*f" % (precision, e, precision, n)
821  else:
822  raise SbException(_("Error in projection (check the settings)"))
823  else:
824  if self.mapFrame.GetMap().projinfo['proj'] == 'll' and format == 'DMS':
825  return utils.Deg2DMS(e, n, precision = precision)
826  else:
827  return "%.*f; %.*f" % (precision, e, precision, n)
828 
830  """!Shows current display region"""
831  def __init__(self, mapframe, statusbar, position = 0):
832  SbTextItem.__init__(self, mapframe, statusbar, position)
833  self.name = 'displayRegion'
834  self.label = _("Extent")
835 
836  def Show(self):
837  precision = int(UserSettings.Get(group = 'projection', key = 'format',
838  subkey = 'precision'))
839  format = UserSettings.Get(group = 'projection', key = 'format',
840  subkey = 'll')
841  projection = self.mapFrame.GetProperty('projection')
842  region = self._getRegion()
843  try:
844  regionReprojected = self.ReprojectRegionFromMap(region, projection, precision, format)
845  self.SetValue(regionReprojected)
846  except SbException, e:
847  self.SetValue(e)
848  SbTextItem.Show(self)
849 
850  def _getRegion(self):
851  """!Get current display region"""
852  return self.mapFrame.GetMap().GetCurrentRegion() # display region
853 
854  def _formatRegion(self, w, e, s, n, nsres, ewres, precision = None):
855  """!Format display region string for statusbar
856 
857  @param nsres,ewres unused
858  """
859  if precision is not None:
860  return "%.*f - %.*f, %.*f - %.*f" % (precision, w, precision, e,
861  precision, s, precision, n)
862  else:
863  return "%s - %s, %s - %s" % (w, e, s, n)
864 
865 
866  def ReprojectRegionFromMap(self, region, useDefinedProjection, precision, format):
867  """!Reproject region values
868 
869  @todo reorganize this method to remove code useful only for derived class SbCompRegionExtent
870  """
871  if useDefinedProjection:
872  settings = UserSettings.Get(group = 'projection', key = 'statusbar', subkey = 'proj4')
873 
874  if not settings:
875  raise SbException(_("Projection not defined (check the settings)"))
876  else:
877  projOut = settings
878  proj, coord1 = utils.ReprojectCoordinates(coord = (region["w"], region["s"]),
879  projOut = projOut, flags = 'd')
880  proj, coord2 = utils.ReprojectCoordinates(coord = (region["e"], region["n"]),
881  projOut = projOut, flags = 'd')
882  # useless, used in derived class
883  proj, coord3 = utils.ReprojectCoordinates(coord = (0.0, 0.0),
884  projOut = projOut, flags = 'd')
885  proj, coord4 = utils.ReprojectCoordinates(coord = (region["ewres"], region["nsres"]),
886  projOut = projOut, flags = 'd')
887  if coord1 and coord2:
888  if proj in ('ll', 'latlong', 'longlat') and format == 'DMS':
889  w, s = utils.Deg2DMS(coord1[0], coord1[1], string = False,
890  precision = precision)
891  e, n = utils.Deg2DMS(coord2[0], coord2[1], string = False,
892  precision = precision)
893  ewres, nsres = utils.Deg2DMS(abs(coord3[0]) - abs(coord4[0]),
894  abs(coord3[1]) - abs(coord4[1]),
895  string = False, hemisphere = False,
896  precision = precision)
897  return self._formatRegion(w = w, s = s, e = e, n = n, ewres = ewres, nsres = nsres)
898  else:
899  w, s = coord1
900  e, n = coord2
901  ewres, nsres = coord3
902  return self._formatRegion(w = w, s = s, e = e, n = n, ewres = ewres,
903  nsres = nsres, precision = precision)
904  else:
905  raise SbException(_("Error in projection (check the settings)"))
906 
907  else:
908  if self.mapFrame.GetMap().projinfo['proj'] == 'll' and format == 'DMS':
909  w, s = utils.Deg2DMS(region["w"], region["s"],
910  string = False, precision = precision)
911  e, n = utils.Deg2DMS(region["e"], region["n"],
912  string = False, precision = precision)
913  ewres, nsres = utils.Deg2DMS(region['ewres'], region['nsres'],
914  string = False, precision = precision)
915  return self._formatRegion(w = w, s = s, e = e, n = n, ewres = ewres, nsres = nsres)
916  else:
917  w, s = region["w"], region["s"]
918  e, n = region["e"], region["n"]
919  ewres, nsres = region['ewres'], region['nsres']
920  return self._formatRegion(w = w, s = s, e = e, n = n, ewres = ewres,
921  nsres = nsres, precision = precision)
922 
923 
925  """!Shows computational region."""
926  def __init__(self, mapframe, statusbar, position = 0):
927  SbRegionExtent.__init__(self, mapframe, statusbar, position)
928  self.name = 'computationalRegion'
929  self.label = _("Computational region")
930 
931  def _formatRegion(self, w, e, s, n, ewres, nsres, precision = None):
932  """!Format computational region string for statusbar"""
933  if precision is not None:
934  return "%.*f - %.*f, %.*f - %.*f (%.*f, %.*f)" % (precision, w, precision, e,
935  precision, s, precision, n,
936  precision, ewres, precision, nsres)
937  else:
938  return "%s - %s, %s - %s (%s, %s)" % (w, e, s, n, ewres, nsres)
939 
940  def _getRegion(self):
941  """!Returns computational region."""
942  return self.mapFrame.GetMap().GetRegion() # computational region
943 
944 
946  """!General progress bar to show progress.
947 
948  Underlaying widget is wx.Gauge.
949  """
950  def __init__(self, mapframe, statusbar, position = 0):
951  SbItem.__init__(self, mapframe, statusbar, position)
952  self.name = 'progress'
953 
954  # on-render gauge
955  self.widget = wx.Gauge(parent = self.statusbar, id = wx.ID_ANY,
956  range = 0, style = wx.GA_HORIZONTAL)
957  self.widget.Hide()
958 
959  def GetRange(self):
960  """!Returns progress range."""
961  return self.widget.GetRange()
962 
963  def SetRange(self, range):
964  """!Sets progress range."""
965  self.widget.SetRange(range)
966 
967  def SetValue(self, value):
968  if value >= value:
969  self.widget.SetValue(self.GetRange())
970  else:
971  self.widget.SetValue(value)
972 
973 
975  """!SpinCtrl to select GCP to focus on
976 
977  Requires MapFrame.GetSrcWindow, MapFrame.GetTgtWindow, MapFrame.GetListCtrl,
978  MapFrame.GetMapCoordList.
979  """
980 
981  def __init__(self, mapframe, statusbar, position = 0):
982  SbItem.__init__(self, mapframe, statusbar, position)
983  self.name = 'gotoGCP'
984  self.label = _("Go to GCP No.")
985 
986  self.widget = wx.SpinCtrl(parent = self.statusbar, id = wx.ID_ANY,
987  value = "", min = 0)
988  self.widget.Hide()
989 
990  self.widget.Bind(wx.EVT_TEXT_ENTER, self.OnGoToGCP)
991  self.widget.Bind(wx.EVT_SPINCTRL, self.OnGoToGCP)
992 
993  def OnGoToGCP(self, event):
994  """!Zooms to given GCP."""
995  GCPNo = self.GetValue()
996  mapCoords = self.mapFrame.GetMapCoordList()
997 
998  if GCPNo < 0 or GCPNo > len(mapCoords): # always false, spin checks it
999  GMessage(parent = self,
1000  message = "%s 1 - %s." % (_("Valid Range:"),
1001  len(mapCoords)))
1002  return
1003 
1004  if GCPNo == 0:
1005  return
1006 
1007  listCtrl = self.mapFrame.GetListCtrl()
1008 
1009  listCtrl.selectedkey = GCPNo
1010  listCtrl.selected = listCtrl.FindItemData(-1, GCPNo)
1011  listCtrl.render = False
1012  listCtrl.SetItemState(listCtrl.selected,
1013  wx.LIST_STATE_SELECTED,
1014  wx.LIST_STATE_SELECTED)
1015  listCtrl.render = True
1016 
1017  listCtrl.EnsureVisible(listCtrl.selected)
1018 
1019  srcWin = self.mapFrame.GetSrcWindow()
1020  tgtWin = self.mapFrame.GetTgtWindow()
1021 
1022  # Source MapWindow:
1023  begin = (mapCoords[GCPNo][1], mapCoords[GCPNo][2])
1024  begin = srcWin.Cell2Pixel(begin)
1025  end = begin
1026  srcWin.Zoom(begin, end, 0)
1027 
1028  # redraw map
1029  srcWin.UpdateMap()
1030 
1031  if self.mapFrame.GetShowTarget():
1032  # Target MapWindow:
1033  begin = (mapCoords[GCPNo][3], mapCoords[GCPNo][4])
1034  begin = tgtWin.Cell2Pixel(begin)
1035  end = begin
1036  tgtWin.Zoom(begin, end, 0)
1037 
1038  # redraw map
1039  tgtWin.UpdateMap()
1040 
1041  self.GetWidget().SetFocus()
1042 
1043  def Update(self):
1044  self.statusbar.SetStatusText("")
1045  max = self.mapFrame.GetListCtrl().GetItemCount()
1046  if max < 1:
1047  max = 1
1048  self.widget.SetRange(0, max)
1049  self.Show()
1050 
1051  # disable long help
1052  self.mapFrame.StatusbarEnableLongHelp(False)
1053 
1055  """!Shows RMS error.
1056 
1057  Requires MapFrame.GetFwdError, MapFrame.GetBkwError.
1058  """
1059  def __init__(self, mapframe, statusbar, position = 0):
1060  SbTextItem.__init__(self, mapframe, statusbar, position)
1061  self.name = 'RMSError'
1062  self.label = _("RMS error")
1063 
1064  def Show(self):
1065  self.SetValue(_("Forward: %(forw)s, Backward: %(back)s") %
1066  { 'forw' : self.mapFrame.GetFwdError(),
1067  'back' : self.mapFrame.GetBkwError() })
1068  SbTextItem.Show(self)
def SetProperty
Sets property represented by one of contained SbItems.
Definition: statusbar.py:85
def GetValue
Definition: widgets.py:118
Statusbar manager for wx.Statusbar and SbItems.
Definition: statusbar.py:50
wxGUI command interface
Base class for items without widgets.
Definition: statusbar.py:731
def __init__
Connects manager to statusbar.
Definition: statusbar.py:65
def _update
Default implementation for Update method.
Definition: statusbar.py:333
def OnToggleShowRegion
Shows/Hides extent (comp.
Definition: statusbar.py:401
StaticText to show whether mask is activated.
Definition: statusbar.py:714
def _postInit
Post-initialization method.
Definition: statusbar.py:180
def GetWidget
Returns underlaying winget.
Definition: statusbar.py:326
def Update
Updates statusbar.
Definition: statusbar.py:201
def _getRegion
Get current display region.
Definition: statusbar.py:850
def SetValue
Definition: widgets.py:115
def SetCenter
Set current map center as item value.
Definition: statusbar.py:658
Definition: parser.c:120
Textctrl to set coordinates which to focus on.
Definition: statusbar.py:541
def SetRange
Sets progress range.
Definition: statusbar.py:963
def Update
Called when statusbar action is activated (e.g.
Definition: statusbar.py:342
def Show
Invokes showing of underlying widget.
Definition: statusbar.py:306
Exception class used in SbManager and SbItems.
Definition: statusbar.py:42
def ShowItem
Invokes showing of particular item.
Definition: statusbar.py:173
def AddStatusbarItem
Adds item to statusbar.
Definition: statusbar.py:111
Editable combobox to get/set current map scale.
Definition: statusbar.py:474
def split
Platform spefic shlex.split.
Definition: core/utils.py:37
def OnToggleStatus
Toggle status text.
Definition: statusbar.py:264
Checkbox to enable user defined projection (can be set in settings)
Definition: statusbar.py:676
def GetRange
Returns progress range.
Definition: statusbar.py:959
def SetMode
Sets current mode.
Definition: statusbar.py:269
def OnGoToGCP
Zooms to given GCP.
Definition: statusbar.py:993
def ReprojectRegionFromMap
Reproject region values.
Definition: statusbar.py:866
def GetProperty
Returns property represented by one of contained SbItems.
Definition: statusbar.py:93
def GetProgressBar
Returns progress bar.
Definition: statusbar.py:260
def OnChangeMapScale
Map scale changed by user.
Definition: statusbar.py:521
def HideStatusbarChoiceItemsByClass
Hides items showed in choice.
Definition: statusbar.py:134
Checkbox to enable and disable auto-rendering.
Definition: statusbar.py:347
def HasProperty
Checks whether property is represented by one of contained SbItems.
Definition: statusbar.py:100
def DMS2Deg
Convert dms value to deg.
Definition: core/utils.py:421
def OnGoTo
Go to position.
Definition: statusbar.py:597
SpinCtrl to select GCP to focus on.
Definition: statusbar.py:974
Show map coordinates when mouse moves.
Definition: statusbar.py:773
def OnToggleUpdateMap
Update display when toggle display mode.
Definition: statusbar.py:466
def Reposition
Reposition items in statusbar.
Definition: statusbar.py:219
Checkbox to select used display resolution.
Definition: statusbar.py:444
Shows RMS error.
Definition: statusbar.py:1054
Shows computational region.
Definition: statusbar.py:924
def GetMode
Returns current mode.
Definition: statusbar.py:276
Base class for statusbar items.
Definition: statusbar.py:280
Shows current display region.
Definition: statusbar.py:829
def ShowStatusbarChoiceItemsByClass
Shows items showed in choice.
Definition: statusbar.py:156
Show current display resolution.
Definition: statusbar.py:759
General progress bar to show progress.
Definition: statusbar.py:945
def ReprojectENFromMap
Reproject east, north to user defined projection.
Definition: statusbar.py:799
def GetCenterString
Get current map center in appropriate format.
Definition: statusbar.py:624
Default GUI settings.
def AddStatusbarItemsByClass
Adds items to statusbar.
Definition: statusbar.py:122
tuple range
Definition: tools.py:1406
def ReprojectENToMap
Reproject east, north from user defined projection.
Definition: statusbar.py:560
Checkbox to select zoom behavior.
Definition: statusbar.py:423
def ReprojectCoordinates
Reproject coordinates.
Definition: core/utils.py:602
def _formatRegion
Format display region string for statusbar.
Definition: statusbar.py:854
Checkbox to enable and disable showing of computational region.
Definition: statusbar.py:375
def RunCommand
Run GRASS command.
Definition: gcmd.py:625
def Deg2DMS
Convert deg value to dms string.
Definition: core/utils.py:367