GRASS Programmer's Manual  6.4.4(2014)-r
lmgr/frame.py
Go to the documentation of this file.
1 """!
2 @package lmgr::frame
3 
4 @brief Layer Manager - main menu, layer management toolbar, notebook
5 control for display management and access to command console.
6 
7 Classes:
8  - frame::GMFrame
9 
10 (C) 2006-2014 by the GRASS Development Team
11 
12 This program is free software under the GNU General Public License
13 (>=v2). Read the file COPYING that comes with GRASS for details.
14 
15 @author Michael Barton (Arizona State University)
16 @author Jachym Cepicky (Mendel University of Agriculture)
17 @author Martin Landa <landa.martin gmail.com>
18 @author Vaclav Petras <wenzeslaus gmail.com> (menu customization)
19 """
20 
21 import sys
22 import os
23 import tempfile
24 import stat
25 import platform
26 try:
27  import xml.etree.ElementTree as etree
28 except ImportError:
29  import elementtree.ElementTree as etree # Python <= 2.4
30 
31 from core import globalvar
32 import wx
33 import wx.aui
34 try:
35  import wx.lib.agw.flatnotebook as FN
36 except ImportError:
37  import wx.lib.flatnotebook as FN
38 
39 sys.path.append(os.path.join(globalvar.ETCDIR, "python"))
40 from grass.script import core as grass
41 
42 from core.gcmd import Command, RunCommand, GError, GMessage
43 from core.settings import UserSettings
44 from core.utils import SetAddOnPath
45 from gui_core.preferences import MapsetAccess, PreferencesDialog, EVT_SETTINGS_CHANGED
46 from lmgr.layertree import LayerTree, LMIcons
47 from lmgr.menudata import ManagerData
48 from gui_core.widgets import GNotebook
49 from modules.mcalc_builder import MapCalcFrame
50 from dbmgr.manager import AttributeManager
51 from core.workspace import ProcessWorkspaceFile, ProcessGrcFile, WriteWorkspaceFile
52 from gui_core.goutput import GMConsole
53 from gui_core.dialogs import DxfImportDialog, GdalImportDialog, MapLayersDialog
54 from gui_core.dialogs import LocationDialog, MapsetDialog, CreateNewVector, GroupDialog
55 from modules.ogc_services import WMSDialog
56 from modules.colorrules import RasterColorTable, VectorColorTable
57 from gui_core.menu import Menu
58 from gmodeler.model import Model
59 from gmodeler.frame import ModelFrame
60 from psmap.frame import PsMapFrame
61 from core.debug import Debug
62 from gui_core.ghelp import MenuTreeWindow, AboutWindow
63 from modules.extensions import InstallExtensionWindow, UninstallExtensionWindow
64 from lmgr.toolbars import LMWorkspaceToolbar, LMDataToolbar, LMToolsToolbar
65 from lmgr.toolbars import LMMiscToolbar, LMVectorToolbar, LMNvizToolbar
66 from lmgr.pyshell import PyShellWindow
67 from gui_core.forms import GUI
68 from gcp.manager import GCPWizard
69 from nviz.main import haveNviz
70 
71 class GMFrame(wx.Frame):
72  """!Layer Manager frame with notebook widget for controlling GRASS
73  GIS. Includes command console page for typing GRASS (and other)
74  commands, tree widget page for managing map layers.
75  """
76  def __init__(self, parent, id = wx.ID_ANY, title = None,
77  workspace = None,
78  size = globalvar.GM_WINDOW_SIZE, style = wx.DEFAULT_FRAME_STYLE, **kwargs):
79  self.parent = parent
80  if title:
81  self.baseTitle = title
82  else:
83  self.baseTitle = _("GRASS GIS %s Layer Manager") % grass.version()['version']
84  self.iconsize = (16, 16)
85 
86  wx.Frame.__init__(self, parent = parent, id = id, size = size,
87  style = style, **kwargs)
88  self.SetTitle(self.baseTitle)
89  self.SetName("LayerManager")
90 
91  self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
92 
93  self._auimgr = wx.aui.AuiManager(self)
94 
95  # initialize variables
96  self.disp_idx = 0 # index value for map displays and layer trees
97  self.curr_page = None # currently selected page for layer tree notebook
98  self.curr_pagenum = None # currently selected page number for layer tree notebook
99  self.workspaceFile = workspace # workspace file
100  self.workspaceChanged = False # track changes in workspace
101  self.georectifying = None # reference to GCP class or None
102  self.gcpmanagement = None # reference to GCP class or None
103 
104  # list of open dialogs
105  self.dialogs = dict()
106  self.dialogs['preferences'] = None
107  self.dialogs['atm'] = list()
108 
109  # creating widgets
110  self._createMenuBar()
111  self.statusbar = self.CreateStatusBar(number = 1)
112  self.notebook = self._createNoteBook()
113  self.toolbars = { 'workspace' : LMWorkspaceToolbar(parent = self),
114  'data' : LMDataToolbar(parent = self),
115  'tools' : LMToolsToolbar(parent = self),
116  'misc' : LMMiscToolbar(parent = self),
117  'vector' : LMVectorToolbar(parent = self),
118  'nviz' : LMNvizToolbar(parent = self)}
119 
120  self._toolbarsData = { 'workspace' : ("toolbarWorkspace", # name
121  _("Workspace Toolbar"), # caption
122  1), # row
123  'data' : ("toolbarData",
124  _("Data Toolbar"),
125  1),
126  'misc' : ("toolbarMisc",
127  _("Misc Toolbar"),
128  2),
129  'tools' : ("toolbarTools",
130  _("Tools Toolbar"),
131  2),
132  'vector' : ("toolbarVector",
133  _("Vector Toolbar"),
134  2),
135  'nviz' : ("toolbarNviz",
136  _("3D view Toolbar"),
137  2),
138  }
139  if sys.platform == 'win32':
140  self._toolbarsList = ('workspace', 'data',
141  'vector', 'tools', 'misc', 'nviz')
142  else:
143  self._toolbarsList = ('data', 'workspace',
144  'nviz', 'misc', 'tools', 'vector')
145  for toolbar in self._toolbarsList:
146  name, caption, row = self._toolbarsData[toolbar]
147  self._auimgr.AddPane(self.toolbars[toolbar],
148  wx.aui.AuiPaneInfo().
149  Name(name).Caption(caption).
150  ToolbarPane().Top().Row(row).
151  LeftDockable(False).RightDockable(False).
152  BottomDockable(False).TopDockable(True).
153  CloseButton(False).Layer(2).
154  BestSize((self.toolbars[toolbar].GetBestSize())))
155 
156  self._auimgr.GetPane('toolbarNviz').Hide()
157  # bindings
158  self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
159  self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
160 
161  # minimal frame size
162  self.SetMinSize((500, 400))
163 
164  # AUI stuff
165  self._auimgr.AddPane(self.notebook, wx.aui.AuiPaneInfo().
166  Left().CentrePane().BestSize((-1,-1)).Dockable(False).
167  CloseButton(False).DestroyOnClose(True).Row(1).Layer(0))
168 
169  self._auimgr.Update()
170 
171  wx.CallAfter(self.notebook.SetSelectionByName, 'layers')
172 
173  # use default window layout ?
174  if UserSettings.Get(group = 'general', key = 'defWindowPos', subkey = 'enabled'):
175  dim = UserSettings.Get(group = 'general', key = 'defWindowPos', subkey = 'dim')
176  try:
177  x, y = map(int, dim.split(',')[0:2])
178  w, h = map(int, dim.split(',')[2:4])
179  self.SetPosition((x, y))
180  self.SetSize((w, h))
181  except:
182  pass
183  else:
184  self.Centre()
185 
186  self.Layout()
187  self.Show()
188 
189  # load workspace file if requested
190  if self.workspaceFile:
191  # load given workspace file
192  if self.LoadWorkspaceFile(self.workspaceFile):
193  self.SetTitle(self.baseTitle + " - " + os.path.basename(self.workspaceFile))
194  else:
195  self.workspaceFile = None
196  else:
197  # start default initial display
198  self.NewDisplay(show = False)
199 
200  # show map display widnow
201  # -> OnSize() -> UpdateMap()
202  if self.curr_page and not self.curr_page.maptree.mapdisplay.IsShown():
203  self.curr_page.maptree.mapdisplay.Show()
204 
205  # redirect stderr to log area
206  self.goutput.Redirect()
207 
208  # fix goutput's pane size (required for Mac OSX)`
209  self.goutput.SetSashPosition(int(self.GetSize()[1] * .8))
210 
211  self.workspaceChanged = False
212 
213  # start with layer manager on top
214  if self.curr_page:
215  self.curr_page.maptree.mapdisplay.Raise()
216  wx.CallAfter(self.Raise)
217 
218  def _createMenuBar(self):
219  """!Creates menu bar"""
220  self.menubar = Menu(parent = self, data = ManagerData())
221  self.SetMenuBar(self.menubar)
222  self.menucmd = self.menubar.GetCmd()
223 
224  def _createTabMenu(self):
225  """!Creates context menu for display tabs.
226 
227  Used to rename display.
228  """
229  menu = wx.Menu()
230  item = wx.MenuItem(menu, id = wx.ID_ANY, text = _("Rename Map Display"))
231  menu.AppendItem(item)
232  self.Bind(wx.EVT_MENU, self.OnRenameDisplay, item)
233 
234  return menu
235 
236  def _setCopyingOfSelectedText(self):
237  copy = UserSettings.Get(group = 'manager', key = 'copySelectedTextToClipboard', subkey = 'enabled')
238  self.goutput.SetCopyingOfSelectedText(copy)
239 
240  def IsPaneShown(self, name):
241  """!Check if pane (toolbar, ...) of given name is currently shown"""
242  if self._auimgr.GetPane(name).IsOk():
243  return self._auimgr.GetPane(name).IsShown()
244  return False
245 
246  def _createNoteBook(self):
247  """!Creates notebook widgets"""
248  self.notebook = GNotebook(parent = self, style = globalvar.FNPageDStyle)
249  # create displays notebook widget and add it to main notebook page
250  cbStyle = globalvar.FNPageStyle
251  if globalvar.hasAgw:
252  self.gm_cb = FN.FlatNotebook(self, id = wx.ID_ANY, agwStyle = cbStyle)
253  else:
254  self.gm_cb = FN.FlatNotebook(self, id = wx.ID_ANY, style = cbStyle)
255  self.gm_cb.SetTabAreaColour(globalvar.FNPageColor)
256  menu = self._createTabMenu()
257  self.gm_cb.SetRightClickMenu(menu)
258  self.notebook.AddPage(page = self.gm_cb, text = _("Map layers"), name = 'layers')
259 
260  # create 'command output' text area
261  self.goutput = GMConsole(self)
262  self.notebook.AddPage(page = self.goutput, text = _("Command console"), name = 'output')
264 
265  # create 'search module' notebook page
266  if not UserSettings.Get(group = 'manager', key = 'hideTabs', subkey = 'search'):
267  self.search = MenuTreeWindow(parent = self)
268  self.notebook.AddPage(page = self.search, text = _("Search module"), name = 'search')
269  else:
270  self.search = None
271 
272  # create 'python shell' notebook page
273  if not UserSettings.Get(group = 'manager', key = 'hideTabs', subkey = 'pyshell'):
274  self.pyshell = PyShellWindow(parent = self)
275  self.notebook.AddPage(page = self.pyshell, text = _("Python shell"), name = 'pyshell')
276  else:
277  self.pyshell = None
278 
279  # bindings
280  self.gm_cb.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.OnCBPageChanged)
281  self.notebook.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
282  self.gm_cb.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CLOSING, self.OnCBPageClosed)
283 
284  return self.notebook
285 
286  def AddNvizTools(self):
287  """!Add nviz notebook page"""
288  Debug.msg(5, "GMFrame.AddNvizTools()")
289  if not haveNviz:
290  return
291 
292  from nviz.main import NvizToolWindow
293 
294  # show toolbar
295  self._auimgr.GetPane('toolbarNviz').Show()
296  # reorder other toolbars
297  for pos, toolbar in enumerate(('toolbarVector', 'toolbarTools', 'toolbarMisc','toolbarNviz')):
298  self._auimgr.GetPane(toolbar).Row(2).Position(pos)
299  self._auimgr.Update()
300 
301  # create nviz tools tab
302  self.nviz = NvizToolWindow(parent = self,
303  display = self.curr_page.maptree.GetMapDisplay())
304  idx = self.notebook.GetPageIndexByName('layers')
305  self.notebook.InsertPage(indx = idx + 1, page = self.nviz, text = _("3D view"), name = 'nviz')
306  self.notebook.SetSelectionByName('nviz')
307 
308 
309  def RemoveNvizTools(self):
310  """!Remove nviz notebook page"""
311  # if more mapwindow3D were possible, check here if nb page should be removed
312  self.notebook.SetSelectionByName('layers')
313  self.notebook.DeletePage(self.notebook.GetPageIndexByName('nviz'))
314 
315  # hide toolbar
316  self._auimgr.GetPane('toolbarNviz').Hide()
317  for pos, toolbar in enumerate(('toolbarVector', 'toolbarTools', 'toolbarMisc')):
318  self._auimgr.GetPane(toolbar).Row(2).Position(pos)
319  self._auimgr.Update()
320 
321  def WorkspaceChanged(self):
322  """!Update window title"""
323  if not self.workspaceChanged:
324  self.workspaceChanged = True
325 
326  if self.workspaceFile:
327  self.SetTitle(self.baseTitle + " - " + os.path.basename(self.workspaceFile) + '*')
328 
329  def OnLocationWizard(self, event):
330  """!Launch location wizard"""
331  from location_wizard.wizard import LocationWizard
332  from location_wizard.dialogs import RegionDef
333 
334  gWizard = LocationWizard(parent = self,
335  grassdatabase = grass.gisenv()['GISDBASE'])
336  location = gWizard.location
337 
338  if location != None:
339  dlg = wx.MessageDialog(parent = self,
340  message = _('Location <%s> created.\n\n'
341  'Do you want to switch to the '
342  'new location?') % location,
343  caption=_("Switch to new location?"),
344  style = wx.YES_NO | wx.NO_DEFAULT |
345  wx.ICON_QUESTION | wx.CENTRE)
346 
347  ret = dlg.ShowModal()
348  dlg.Destroy()
349  if ret == wx.ID_YES:
350  if RunCommand('g.mapset', parent = self,
351  location = location,
352  mapset = 'PERMANENT') != 0:
353  return
354 
355  GMessage(parent = self,
356  message = _("Current location is <%(loc)s>.\n"
357  "Current mapset is <%(mapset)s>.") % \
358  { 'loc' : location, 'mapset' : 'PERMANENT' })
359 
360  # code duplication with gis_set.py
361  dlg = wx.MessageDialog(parent = self,
362  message = _("Do you want to set the default "
363  "region extents and resolution now?"),
364  caption = _("Location <%s> created") % location,
365  style = wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
366  dlg.CenterOnScreen()
367  if dlg.ShowModal() == wx.ID_YES:
368  dlg.Destroy()
369  defineRegion = RegionDef(self, location = location)
370  defineRegion.CenterOnScreen()
371  defineRegion.ShowModal()
372  defineRegion.Destroy()
373  else:
374  dlg.Destroy()
375 
376  def OnSettingsChanged(self, event):
377  """!Here can be functions which have to be called after EVT_SETTINGS_CHANGED.
378  Now only set copying of selected text to clipboard (in goutput).
379  """
380  ### self._createMenuBar() # bug when menu is re-created on the fly
382 
383  def OnGCPManager(self, event):
384  """!Launch georectifier module
385  """
386  GCPWizard(self)
387 
388  def OnGModeler(self, event):
389  """!Launch Graphical Modeler"""
390  win = ModelFrame(parent = self)
391  win.CentreOnScreen()
392 
393  win.Show()
394 
395  def OnPsMap(self, event):
396  """!Launch Cartographic Composer
397  """
398  win = PsMapFrame(parent = self)
399  win.CentreOnScreen()
400 
401  win.Show()
402 
403  def OnDone(self, cmd, returncode):
404  """Command execution finished"""
405  if hasattr(self, "model"):
406  self.model.DeleteIntermediateData(log = self.goutput)
407  del self.model
408  self.SetStatusText('')
409 
410  def OnRunModel(self, event):
411  """!Run model"""
412  filename = ''
413  dlg = wx.FileDialog(parent = self, message =_("Choose model to run"),
414  defaultDir = os.getcwd(),
415  wildcard = _("GRASS Model File (*.gxm)|*.gxm"))
416  if dlg.ShowModal() == wx.ID_OK:
417  filename = dlg.GetPath()
418 
419  if not filename:
420  dlg.Destroy()
421  return
422 
423  self.model = Model()
424  self.model.LoadModel(filename)
425  self.model.Run(log = self.goutput, onDone = self.OnDone, parent = self)
426 
427  dlg.Destroy()
428 
429  def OnMapsets(self, event):
430  """!Launch mapset access dialog
431  """
432  dlg = MapsetAccess(parent = self, id = wx.ID_ANY)
433  dlg.CenterOnScreen()
434 
435  if dlg.ShowModal() == wx.ID_OK:
436  ms = dlg.GetMapsets()
437  RunCommand('g.mapsets',
438  parent = self,
439  mapset = '%s' % ','.join(ms))
440 
441  def OnCBPageChanged(self, event):
442  """!Page in notebook (display) changed"""
443  self.curr_page = self.gm_cb.GetCurrentPage()
444  self.curr_pagenum = self.gm_cb.GetSelection()
445  try:
446  self.curr_page.maptree.mapdisplay.SetFocus()
447  self.curr_page.maptree.mapdisplay.Raise()
448  except:
449  pass
450 
451  event.Skip()
452 
453  def OnPageChanged(self, event):
454  """!Page in notebook changed"""
455  page = event.GetSelection()
456  if page == self.notebook.GetPageIndexByName('output'):
457  # remove '(...)'
458  self.notebook.SetPageText(page, _("Command console"))
459  wx.CallAfter(self.goutput.ResetFocus)
460  self.SetStatusText('', 0)
461 
462  event.Skip()
463 
464  def OnCBPageClosed(self, event):
465  """!Page of notebook closed
466  Also close associated map display
467  """
468  if UserSettings.Get(group = 'manager', key = 'askOnQuit', subkey = 'enabled'):
469  maptree = self.curr_page.maptree
470 
471  if self.workspaceFile:
472  message = _("Do you want to save changes in the workspace?")
473  else:
474  message = _("Do you want to store current settings "
475  "to workspace file?")
476 
477  # ask user to save current settings
478  if maptree.GetCount() > 0:
479  name = self.gm_cb.GetPageText(self.curr_pagenum)
480  dlg = wx.MessageDialog(self,
481  message = message,
482  caption = _("Close Map Display %s") % name,
483  style = wx.YES_NO | wx.YES_DEFAULT |
484  wx.CANCEL | wx.ICON_QUESTION | wx.CENTRE)
485  ret = dlg.ShowModal()
486  if ret == wx.ID_YES:
487  if not self.workspaceFile:
488  self.OnWorkspaceSaveAs()
489  else:
491  elif ret == wx.ID_CANCEL:
492  event.Veto()
493  dlg.Destroy()
494  return
495  dlg.Destroy()
496 
497  self.gm_cb.GetPage(event.GetSelection()).maptree.Map.Clean()
498  self.gm_cb.GetPage(event.GetSelection()).maptree.Close(True)
499 
500  self.curr_page = None
501 
502  event.Skip()
503 
504  def GetLayerTree(self):
505  """!Get current layer tree"""
506  if self.curr_page:
507  return self.curr_page.maptree
508  return None
509 
510  def GetLogWindow(self):
511  """!Get widget for command output"""
512  return self.goutput
513 
514  def GetMenuCmd(self, event):
515  """!Get GRASS command from menu item
516 
517  Return command as a list"""
518  layer = None
519 
520  if event:
521  cmd = self.menucmd[event.GetId()]
522 
523  try:
524  cmdlist = cmd.split(' ')
525  except: # already list?
526  cmdlist = cmd
527 
528  # check list of dummy commands for GUI modules that do not have GRASS
529  # bin modules or scripts.
530  if cmd in ['vcolors', 'r.mapcalc', 'r3.mapcalc']:
531  return cmdlist
532 
533  try:
534  layer = self.curr_page.maptree.layer_selected
535  name = self.curr_page.maptree.GetPyData(layer)[0]['maplayer'].name
536  type = self.curr_page.maptree.GetPyData(layer)[0]['type']
537  except:
538  layer = None
539 
540  if layer and len(cmdlist) == 1: # only if no paramaters given
541  if (type == 'raster' and cmdlist[0][0] == 'r' and cmdlist[0][1] != '3') or \
542  (type == 'vector' and cmdlist[0][0] == 'v'):
543  input = GUI().GetCommandInputMapParamKey(cmdlist[0])
544  if input:
545  cmdlist.append("%s=%s" % (input, name))
546 
547  return cmdlist
548 
549  def RunMenuCmd(self, event = None, cmd = []):
550  """!Run command selected from menu"""
551  if event:
552  cmd = self.GetMenuCmd(event)
553  self.goutput.RunCmd(cmd, switchPage = False)
554 
555  def OnMenuCmd(self, event = None, cmd = []):
556  """!Parse command selected from menu"""
557  if event:
558  cmd = self.GetMenuCmd(event)
559  GUI(parent = self).ParseCommand(cmd)
560 
561  def OnVDigit(self, event):
562  """!Start vector digitizer
563  """
564  if not self.curr_page:
565  self.MsgNoLayerSelected()
566  return
567 
568  tree = self.GetLayerTree()
569  layer = tree.layer_selected
570  # no map layer selected
571  if not layer:
572  self.MsgNoLayerSelected()
573  return
574 
575  # available only for vector map layers
576  try:
577  mapLayer = tree.GetPyData(layer)[0]['maplayer']
578  except:
579  mapLayer = None
580 
581  if not mapLayer or mapLayer.GetType() != 'vector':
582  GMessage(parent = self,
583  message = _("Selected map layer is not vector."))
584  return
585 
586  if mapLayer.GetMapset() != grass.gisenv()['MAPSET']:
587  GMessage(parent = self,
588  message = _("Editing is allowed only for vector maps from the "
589  "current mapset."))
590  return
591 
592  if not tree.GetPyData(layer)[0]:
593  return
594  dcmd = tree.GetPyData(layer)[0]['cmd']
595  if not dcmd:
596  return
597 
598  tree.OnStartEditing(None)
599 
600  def OnRunScript(self, event):
601  """!Run script"""
602  # open dialog and choose script file
603  dlg = wx.FileDialog(parent = self, message = _("Choose script file to run"),
604  defaultDir = os.getcwd(),
605  wildcard = _("Python script (*.py)|*.py|Bash script (*.sh)|*.sh"))
606 
607  filename = None
608  if dlg.ShowModal() == wx.ID_OK:
609  filename = dlg.GetPath()
610 
611  if not filename:
612  return False
613 
614  if not os.path.exists(filename):
615  GError(parent = self,
616  message = _("Script file '%s' doesn't exist. "
617  "Operation canceled.") % filename)
618  return
619 
620  # check permission
621  if not os.access(filename, os.X_OK):
622  dlg = wx.MessageDialog(self,
623  message = _("Script <%s> is not executable. "
624  "Do you want to set the permissions "
625  "that allows you to run this script "
626  "(note that you must be the owner of the file)?" % \
627  os.path.basename(filename)),
628  caption = _("Set permission?"),
629  style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
630  if dlg.ShowModal() != wx.ID_YES:
631  return
632  dlg.Destroy()
633  try:
634  mode = stat.S_IMODE(os.lstat(filename)[stat.ST_MODE])
635  os.chmod(filename, mode | stat.S_IXUSR)
636  except OSError:
637  GError(_("Unable to set permission. Operation canceled."), parent = self)
638  return
639 
640  # check GRASS_ADDON_PATH
641  addonPath = os.getenv('GRASS_ADDON_PATH', [])
642  if addonPath:
643  addonPath = addonPath.split(os.pathsep)
644  dirName = os.path.dirname(filename)
645  if dirName not in addonPath:
646  addonPath.append(dirName)
647  dlg = wx.MessageDialog(self,
648  message = _("Directory '%s' is not defined in GRASS_ADDON_PATH. "
649  "Do you want add this directory to GRASS_ADDON_PATH?") % \
650  dirName,
651  caption = _("Update Addons path?"),
652  style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
653  if dlg.ShowModal() == wx.ID_YES:
654  SetAddOnPath(os.pathsep.join(addonPath))
655 
656  self.goutput.WriteCmdLog(_("Launching script '%s'...") % filename)
657  self.goutput.RunCmd([filename], switchPage = True)
658 
659  def OnChangeLocation(self, event):
660  """Change current location"""
661  dlg = LocationDialog(parent = self)
662  if dlg.ShowModal() == wx.ID_OK:
663  location, mapset = dlg.GetValues()
664  dlg.Destroy()
665 
666  if not location or not mapset:
667  GError(parent = self,
668  message = _("No location/mapset provided. Operation canceled."))
669  return # this should not happen
670 
671  if RunCommand('g.mapset', parent = self,
672  location = location,
673  mapset = mapset) != 0:
674  return # error reported
675 
676  # close workspace
677  self.OnWorkspaceClose()
678  self.OnWorkspaceNew()
679  GMessage(parent = self,
680  message = _("Current location is <%(loc)s>.\n"
681  "Current mapset is <%(mapset)s>.") % \
682  { 'loc' : location, 'mapset' : mapset })
683 
684  def OnCreateMapset(self, event):
685  """!Create new mapset"""
686  dlg = wx.TextEntryDialog(parent = self,
687  message = _('Enter name for new mapset:'),
688  caption = _('Create new mapset'))
689 
690  if dlg.ShowModal() == wx.ID_OK:
691  mapset = dlg.GetValue()
692  if not mapset:
693  GError(parent = self,
694  message = _("No mapset provided. Operation canceled."))
695  return
696 
697  ret = RunCommand('g.mapset',
698  parent = self,
699  flags = 'c',
700  mapset = mapset)
701  if ret == 0:
702  GMessage(parent = self,
703  message = _("Current mapset is <%s>.") % mapset)
704 
705  def OnChangeMapset(self, event):
706  """Change current mapset"""
707  dlg = MapsetDialog(parent = self)
708 
709  if dlg.ShowModal() == wx.ID_OK:
710  mapset = dlg.GetMapset()
711  dlg.Destroy()
712 
713  if not mapset:
714  GError(parent = self,
715  message = _("No mapset provided. Operation canceled."))
716  return
717 
718  if RunCommand('g.mapset',
719  parent = self,
720  mapset = mapset) == 0:
721  GMessage(parent = self,
722  message = _("Current mapset is <%s>.") % mapset)
723 
724  def OnNewVector(self, event):
725  """!Create new vector map layer"""
726  dlg = CreateNewVector(self, log = self.goutput,
727  cmd = (('v.edit',
728  { 'tool' : 'create' },
729  'map')))
730 
731  if not dlg:
732  return
733 
734  name = dlg.GetName(full = True)
735  if name and dlg.IsChecked('add'):
736  # add layer to map layer tree
737  self.curr_page.maptree.AddLayer(ltype = 'vector',
738  lname = name,
739  lcmd = ['d.vect', 'map=%s' % name])
740  dlg.Destroy()
741 
742  def OnSystemInfo(self, event):
743  """!Print system information"""
744  vInfo = grass.version()
745 
746  # GDAL/OGR
747  try:
748  from osgeo import gdal
749  gdalVersion = gdal.__version__
750  except:
751  try:
752  gdalVersion = grass.Popen(['gdalinfo', '--version'], stdout = grass.PIPE).communicate()[0].rstrip('\n')
753  except:
754  gdalVersion = _("unknown")
755  # PROJ4
756  try:
757  projVersion = RunCommand('proj', getErrorMsg = True)[1].splitlines()[0]
758  except:
759  projVersion = _("unknown")
760  # check also OSGeo4W on MS Windows
761  if sys.platform == 'win32' and \
762  not os.path.exists(os.path.join(os.getenv("GISBASE"), "WinGRASS-README.url")):
763  osgeo4w = ' (OSGeo4W)'
764  else:
765  osgeo4w = ''
766 
767  self.goutput.WriteCmdLog(_("System Info"))
768  # platform from UTF-8 conversion was added because of Fedora 19
769  # which has the name Schrodinger's cat (umlaut and special ' character)
770  # which appears in the platform.platform() string
771  self.goutput.WriteLog("%s: %s\n"
772  "%s: %s\n"
773  # "%s: %s (%s)\n"
774  "GDAL/OGR: %s\n"
775  "PROJ4: %s\n"
776  "Python: %s\n"
777  "wxPython: %s\n"
778  "%s: %s%s\n"% (_("GRASS version"), vInfo['version'],
779  _("GRASS SVN Revision"), vInfo['revision'],
780  # _("GIS Library Revision"), vInfo['libgis_revision'], vInfo['libgis_date'].split(' ', 1)[0],
781  gdalVersion, projVersion,
782  platform.python_version(),
783  wx.__version__,
784  _("Platform"), platform.platform().decode('utf8', errors='replace'), osgeo4w),
785  switchPage = True)
786  self.goutput.WriteCmdLog(' ')
787 
788  def OnAboutGRASS(self, event):
789  """!Display 'About GRASS' dialog"""
790  win = AboutWindow(self)
791  win.CentreOnScreen()
792  win.Show(True)
793 
794  def _popupMenu(self, data):
795  """!Create popup menu
796  """
797  point = wx.GetMousePosition()
798  menu = wx.Menu()
799 
800  for key, handler in data:
801  if key is None:
802  menu.AppendSeparator()
803  continue
804  item = wx.MenuItem(menu, wx.ID_ANY, LMIcons[key].GetLabel())
805  item.SetBitmap(LMIcons[key].GetBitmap(self.iconsize))
806  menu.AppendItem(item)
807  self.Bind(wx.EVT_MENU, handler, item)
808 
809  # create menu
810  self.PopupMenu(menu)
811  menu.Destroy()
812 
813  def OnImportMenu(self, event):
814  """!Import maps menu (import, link)
815  """
816  self._popupMenu((('rastImport', self.OnImportGdalLayers),
817  ('vectImport', self.OnImportOgrLayers)))
818 
819  def OnWorkspaceNew(self, event = None):
820  """!Create new workspace file
821 
822  Erase current workspace settings first
823  """
824  Debug.msg(4, "GMFrame.OnWorkspaceNew():")
825 
826  # start new map display if no display is available
827  if not self.curr_page:
828  self.NewDisplay()
829 
830  maptree = self.curr_page.maptree
831 
832  # ask user to save current settings
833  if self.workspaceFile and self.workspaceChanged:
834  self.OnWorkspaceSave()
835  elif self.workspaceFile is None and maptree.GetCount() > 0:
836  dlg = wx.MessageDialog(self, message = _("Current workspace is not empty. "
837  "Do you want to store current settings "
838  "to workspace file?"),
839  caption = _("Create new workspace?"),
840  style = wx.YES_NO | wx.YES_DEFAULT | \
841  wx.CANCEL | wx.ICON_QUESTION)
842  ret = dlg.ShowModal()
843  if ret == wx.ID_YES:
844  self.OnWorkspaceSaveAs()
845  elif ret == wx.ID_CANCEL:
846  dlg.Destroy()
847  return
848 
849  dlg.Destroy()
850 
851  # delete all items
852  maptree.DeleteAllItems()
853 
854  # add new root element
855  maptree.root = maptree.AddRoot("Map Layers")
856  self.curr_page.maptree.SetPyData(maptree.root, (None,None))
857 
858  # no workspace file loaded
859  self.workspaceFile = None
860  self.workspaceChanged = False
861  self.SetTitle(self.baseTitle)
862 
863  def OnWorkspaceOpen(self, event = None):
864  """!Open file with workspace definition"""
865  dlg = wx.FileDialog(parent = self, message = _("Choose workspace file"),
866  defaultDir = os.getcwd(), wildcard = _("GRASS Workspace File (*.gxw)|*.gxw"))
867 
868  filename = ''
869  if dlg.ShowModal() == wx.ID_OK:
870  filename = dlg.GetPath()
871 
872  if filename == '':
873  return
874 
875  Debug.msg(4, "GMFrame.OnWorkspaceOpen(): filename=%s" % filename)
876 
877  # delete current layer tree content
878  self.OnWorkspaceClose()
879 
880  self.LoadWorkspaceFile(filename)
881 
882  self.workspaceFile = filename
883  self.SetTitle(self.baseTitle + " - " + os.path.basename(self.workspaceFile))
884 
885  def LoadWorkspaceFile(self, filename):
886  """!Load layer tree definition stored in GRASS Workspace XML file (gxw)
887 
888  @todo Validate against DTD
889 
890  @return True on success
891  @return False on error
892  """
893  # dtd
894  dtdFilename = os.path.join(globalvar.ETCWXDIR, "xml", "grass-gxw.dtd")
895 
896  # parse workspace file
897  try:
898  gxwXml = ProcessWorkspaceFile(etree.parse(filename))
899  except Exception, e:
900  GError(parent = self,
901  message = _("Reading workspace file <%s> failed.\n"
902  "Invalid file, unable to parse XML document.") % filename)
903  return
904 
905  busy = wx.BusyInfo(message = _("Please wait, loading workspace..."),
906  parent = self)
907  wx.Yield()
908 
909  #
910  # load layer manager window properties
911  #
912  if not UserSettings.Get(group = 'general', key = 'workspace',
913  subkey = ['posManager', 'enabled']):
914  if gxwXml.layerManager['pos']:
915  self.SetPosition(gxwXml.layerManager['pos'])
916  if gxwXml.layerManager['size']:
917  self.SetSize(gxwXml.layerManager['size'])
918 
919  #
920  # start map displays first (list of layers can be empty)
921  #
922  displayId = 0
923  mapdisplay = list()
924  for display in gxwXml.displays:
925  mapdisp = self.NewDisplay(name = display['name'], show = False)
926  mapdisplay.append(mapdisp)
927  maptree = self.gm_cb.GetPage(displayId).maptree
928 
929  # set windows properties
930  mapdisp.SetProperties(render = display['render'],
931  mode = display['mode'],
932  showCompExtent = display['showCompExtent'],
933  alignExtent = display['alignExtent'],
934  constrainRes = display['constrainRes'],
935  projection = display['projection']['enabled'])
936 
937  if display['projection']['enabled']:
938  if display['projection']['epsg']:
939  UserSettings.Set(group = 'display', key = 'projection', subkey = 'epsg',
940  value = display['projection']['epsg'])
941  if display['projection']['proj']:
942  UserSettings.Set(group = 'display', key = 'projection', subkey = 'proj4',
943  value = display['projection']['proj'])
944 
945  # set position and size of map display
946  if not UserSettings.Get(group = 'general', key = 'workspace', subkey = ['posDisplay', 'enabled']):
947  if display['pos']:
948  mapdisp.SetPosition(display['pos'])
949  if display['size']:
950  mapdisp.SetSize(display['size'])
951 
952  # set extent if defined
953  if display['extent']:
954  w, s, e, n = display['extent']
955  region = maptree.Map.region = maptree.Map.GetRegion(w = w, s = s, e = e, n = n)
956  mapdisp.GetWindow().ResetZoomHistory()
957  mapdisp.GetWindow().ZoomHistory(region['n'],
958  region['s'],
959  region['e'],
960  region['w'])
961 
962  mapdisp.Show()
963 
964  displayId += 1
965 
966  maptree = None
967  selected = [] # list of selected layers
968  #
969  # load list of map layers
970  #
971  for layer in gxwXml.layers:
972  display = layer['display']
973  maptree = self.gm_cb.GetPage(display).maptree
974 
975  newItem = maptree.AddLayer(ltype = layer['type'],
976  lname = layer['name'],
977  lchecked = layer['checked'],
978  lopacity = layer['opacity'],
979  lcmd = layer['cmd'],
980  lgroup = layer['group'],
981  lnviz = layer['nviz'],
982  lvdigit = layer['vdigit'])
983 
984  if layer.has_key('selected'):
985  if layer['selected']:
986  selected.append((maptree, newItem))
987  else:
988  maptree.SelectItem(newItem, select = False)
989 
990  for maptree, layer in selected:
991  if not maptree.IsSelected(layer):
992  maptree.SelectItem(layer, select = True)
993  maptree.layer_selected = layer
994 
995  busy.Destroy()
996 
997  for idx, mdisp in enumerate(mapdisplay):
998  mdisp.MapWindow2D.UpdateMap()
999  # nviz
1000  if gxwXml.displays[idx]['viewMode'] == '3d':
1001  mdisp.AddNviz()
1002  self.nviz.UpdateState(view = gxwXml.nviz_state['view'],
1003  iview = gxwXml.nviz_state['iview'],
1004  light = gxwXml.nviz_state['light'])
1005  mdisp.MapWindow3D.constants = gxwXml.nviz_state['constants']
1006  for idx, constant in enumerate(mdisp.MapWindow3D.constants):
1007  mdisp.MapWindow3D.AddConstant(constant, idx + 1)
1008  for page in ('view', 'light', 'fringe', 'constant', 'cplane'):
1009  self.nviz.UpdatePage(page)
1010  self.nviz.UpdateSettings()
1011  mdisp.toolbars['map'].combo.SetSelection(1)
1012 
1013  mdisp.Show() # show mapdisplay
1014 
1015  return True
1016 
1017  def OnWorkspaceLoadGrcFile(self, event):
1018  """!Load map layers from GRC file (Tcl/Tk GUI) into map layer tree"""
1019  dlg = wx.FileDialog(parent = self, message = _("Choose GRC file to load"),
1020  defaultDir = os.getcwd(), wildcard = _("Old GRASS Workspace File (*.grc)|*.grc"))
1021 
1022  filename = ''
1023  if dlg.ShowModal() == wx.ID_OK:
1024  filename = dlg.GetPath()
1025 
1026  if filename == '':
1027  return
1028 
1029  Debug.msg(4, "GMFrame.OnWorkspaceLoadGrcFile(): filename=%s" % filename)
1030 
1031  # start new map display if no display is available
1032  if not self.curr_page:
1033  self.NewDisplay()
1034 
1035  busy = wx.BusyInfo(message = _("Please wait, loading workspace..."),
1036  parent = self)
1037  wx.Yield()
1038 
1039  maptree = None
1040  for layer in ProcessGrcFile(filename).read(self):
1041  maptree = self.gm_cb.GetPage(layer['display']).maptree
1042  newItem = maptree.AddLayer(ltype = layer['type'],
1043  lname = layer['name'],
1044  lchecked = layer['checked'],
1045  lopacity = layer['opacity'],
1046  lcmd = layer['cmd'],
1047  lgroup = layer['group'])
1048 
1049  busy.Destroy()
1050 
1051  if maptree:
1052  # reverse list of map layers
1053  maptree.Map.ReverseListOfLayers()
1054 
1055  def OnWorkspaceSaveAs(self, event = None):
1056  """!Save workspace definition to selected file"""
1057  dlg = wx.FileDialog(parent = self, message = _("Choose file to save current workspace"),
1058  defaultDir = os.getcwd(), wildcard = _("GRASS Workspace File (*.gxw)|*.gxw"), style = wx.FD_SAVE)
1059 
1060  filename = ''
1061  if dlg.ShowModal() == wx.ID_OK:
1062  filename = dlg.GetPath()
1063 
1064  if filename == '':
1065  return False
1066 
1067  # check for extension
1068  if filename[-4:] != ".gxw":
1069  filename += ".gxw"
1070 
1071  if os.path.exists(filename):
1072  dlg = wx.MessageDialog(self, message = _("Workspace file <%s> already exists. "
1073  "Do you want to overwrite this file?") % filename,
1074  caption = _("Save workspace"), style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
1075  if dlg.ShowModal() != wx.ID_YES:
1076  dlg.Destroy()
1077  return False
1078 
1079  Debug.msg(4, "GMFrame.OnWorkspaceSaveAs(): filename=%s" % filename)
1080 
1081  self.SaveToWorkspaceFile(filename)
1082  self.workspaceFile = filename
1083  self.SetTitle(self.baseTitle + " - " + os.path.basename(self.workspaceFile))
1084 
1085  def OnWorkspaceSave(self, event = None):
1086  """!Save file with workspace definition"""
1087  if self.workspaceFile:
1088  dlg = wx.MessageDialog(self, message = _("Workspace file <%s> already exists. "
1089  "Do you want to overwrite this file?") % \
1090  self.workspaceFile,
1091  caption = _("Save workspace"), style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
1092  if dlg.ShowModal() == wx.ID_NO:
1093  dlg.Destroy()
1094  else:
1095  Debug.msg(4, "GMFrame.OnWorkspaceSave(): filename=%s" % self.workspaceFile)
1097  self.SetTitle(self.baseTitle + " - " + os.path.basename(self.workspaceFile))
1098  self.workspaceChanged = False
1099  else:
1100  self.OnWorkspaceSaveAs()
1101 
1102  def SaveToWorkspaceFile(self, filename):
1103  """!Save layer tree layout to workspace file
1104 
1105  Return True on success, False on error
1106  """
1107  tmpfile = tempfile.TemporaryFile(mode = 'w+b')
1108  try:
1109  WriteWorkspaceFile(lmgr = self, file = tmpfile)
1110  except StandardError, e:
1111  GError(parent = self,
1112  message = _("Writing current settings to workspace file "
1113  "failed."))
1114  return False
1115 
1116  try:
1117  mfile = open(filename, "w")
1118  tmpfile.seek(0)
1119  for line in tmpfile.readlines():
1120  mfile.write(line)
1121  except IOError:
1122  GError(parent = self,
1123  message = _("Unable to open file <%s> for writing.") % filename)
1124  return False
1125 
1126  mfile.close()
1127 
1128  return True
1129 
1130  def OnWorkspaceClose(self, event = None):
1131  """!Close file with workspace definition
1132 
1133  If workspace has been modified ask user to save the changes.
1134  """
1135  Debug.msg(4, "GMFrame.OnWorkspaceClose(): file=%s" % self.workspaceFile)
1136 
1137  self.OnDisplayCloseAll()
1138  self.workspaceFile = None
1139  self.workspaceChanged = False
1140  self.SetTitle(self.baseTitle)
1141  self.disp_idx = 0
1142  self.curr_page = None
1143 
1144  def OnDisplayClose(self, event = None):
1145  """!Close current map display window
1146  """
1147  if self.curr_page and self.curr_page.maptree.mapdisplay:
1148  self.curr_page.maptree.mapdisplay.OnCloseWindow(event)
1149 
1150  def OnDisplayCloseAll(self, event = None):
1151  """!Close all open map display windows
1152  """
1153  displays = list()
1154  for page in range(0, self.gm_cb.GetPageCount()):
1155  displays.append(self.gm_cb.GetPage(page).maptree.mapdisplay)
1156 
1157  for display in displays:
1158  display.OnCloseWindow(event)
1159 
1160  def OnRenameDisplay(self, event):
1161  """!Change Map Display name"""
1162  name = self.gm_cb.GetPageText(self.curr_pagenum)
1163  dlg = wx.TextEntryDialog(self, message = _("Enter new name:"),
1164  caption = _("Rename Map Display"), defaultValue = name)
1165  if dlg.ShowModal() == wx.ID_OK:
1166  name = dlg.GetValue()
1167  self.gm_cb.SetPageText(page = self.curr_pagenum, text = name)
1168  mapdisplay = self.curr_page.maptree.mapdisplay
1169  mapdisplay.SetTitle(_("GRASS GIS %(version) Map Display: %(name)s - Location: %(loc)s") % \
1170  { 'version' : grass.version()['version'],
1171  'name' : name,
1172  'loc' : grass.gisenv()["LOCATION_NAME"] })
1173  dlg.Destroy()
1174 
1175  def RulesCmd(self, event):
1176  """!Launches dialog for commands that need rules input and
1177  processes rules
1178  """
1179  cmd = self.GetMenuCmd(event)
1180 
1181  if cmd[0] == 'r.colors':
1182  ctable = RasterColorTable(self)
1183  else:
1184  ctable = VectorColorTable(self, attributeType = 'color')
1185  ctable.CentreOnScreen()
1186  ctable.Show()
1187 
1188  def OnXTermNoXMon(self, event):
1189  """!
1190  Run commands that need xterm
1191  """
1192  self.OnXTerm(event, need_xmon = False)
1193 
1194  def OnXTerm(self, event, need_xmon = True):
1195  """!
1196  Run commands that need interactive xmon
1197 
1198  @param need_xmon True to start X monitor
1199  """
1200  # unset display mode
1201  if os.getenv('GRASS_RENDER_IMMEDIATE'):
1202  del os.environ['GRASS_RENDER_IMMEDIATE']
1203 
1204  if need_xmon:
1205  # open next available xmon
1206  xmonlist = []
1207 
1208  # make list of xmons that are not running
1209  ret = RunCommand('d.mon',
1210  flags = 'L',
1211  read = True)
1212 
1213  for line in ret.split('\n'):
1214  line = line.strip()
1215  if line.startswith('x') and 'not running' in line:
1216  xmonlist.append(line[0:2])
1217 
1218  # find available xmon
1219  xmon = xmonlist[0]
1220 
1221  # bring up the xmon
1222  cmdlist = ['d.mon', xmon]
1223  p = Command(cmdlist, wait=False)
1224 
1225  # run the command
1226  command = self.GetMenuCmd(event)
1227  command = ' '.join(command)
1228 
1229  gisbase = os.environ['GISBASE']
1230 
1231  if sys.platform == "win32":
1232  runbat = os.path.join(gisbase,'etc','grass-run.bat')
1233  cmdlist = ["start", runbat, runbat, command]
1234  else:
1235  if sys.platform == "darwin":
1236  xtermwrapper = os.path.join(gisbase,'etc','grass-xterm-mac')
1237  else:
1238  xtermwrapper = os.path.join(gisbase,'etc','grass-xterm-wrapper')
1239 
1240  grassrun = os.path.join(gisbase,'etc','grass-run.sh')
1241  cmdlist = [xtermwrapper, '-e', grassrun, command]
1242 
1243  p = Command(cmdlist, wait=False)
1244 
1245  # reset display mode
1246  os.environ['GRASS_RENDER_IMMEDIATE'] = 'TRUE'
1247 
1248  def OnEditImageryGroups(self, event, cmd = None):
1249  """!Show dialog for creating and editing groups.
1250  """
1251  dlg = GroupDialog(self)
1252  dlg.CentreOnScreen()
1253  dlg.Show()
1254 
1255  def OnInstallExtension(self, event):
1256  """!Install extension from GRASS Addons SVN repository"""
1257  win = InstallExtensionWindow(self, size = (650, 550))
1258  win.CentreOnScreen()
1259  win.Show()
1260 
1261  def OnUninstallExtension(self, event):
1262  """!Uninstall extension"""
1263  win = UninstallExtensionWindow(self, size = (650, 300))
1264  win.CentreOnScreen()
1265  win.Show()
1266 
1267  def OnPreferences(self, event):
1268  """!General GUI preferences/settings
1269  """
1270  if not self.dialogs['preferences']:
1271  dlg = PreferencesDialog(parent = self)
1272  self.dialogs['preferences'] = dlg
1273  self.dialogs['preferences'].CenterOnScreen()
1274 
1275  dlg.Bind(EVT_SETTINGS_CHANGED, self.OnSettingsChanged)
1276 
1277  self.dialogs['preferences'].ShowModal()
1278 
1279  def OnHelp(self, event):
1280  """!Show help
1281  """
1282  self.goutput.RunCmd(['g.manual','-i'])
1283 
1284  def OnHistogram(self, event):
1285  """!Init histogram display canvas and tools
1286  """
1287  from modules.histogram import HistogramFrame
1288  win = HistogramFrame(self)
1289 
1290  win.CentreOnScreen()
1291  win.Show()
1292  win.Refresh()
1293  win.Update()
1294 
1295  def OnProfile(self, event):
1296  """!Launch profile tool
1297  """
1298  win = profile.ProfileFrame(parent = self)
1299 
1300  win.CentreOnParent()
1301  win.Show()
1302  win.Refresh()
1303  win.Update()
1304 
1305  def OnMapCalculator(self, event, cmd = ''):
1306  """!Init map calculator for interactive creation of mapcalc statements
1307  """
1308  if event:
1309  try:
1310  cmd = self.GetMenuCmd(event)
1311  except KeyError:
1312  cmd = ['r.mapcalc']
1313 
1314  win = MapCalcFrame(parent = self,
1315  cmd = cmd[0])
1316  win.CentreOnScreen()
1317  win.Show()
1318 
1319  def OnVectorCleaning(self, event, cmd = ''):
1320  """!Init interactive vector cleaning
1321  """
1322  from modules.vclean import VectorCleaningFrame
1323  win = VectorCleaningFrame(parent = self)
1324  win.CentreOnScreen()
1325  win.Show()
1326 
1327  def OnImportDxfFile(self, event, cmd = None):
1328  """!Convert multiple DXF layers to GRASS vector map layers"""
1329  dlg = DxfImportDialog(parent = self)
1330  dlg.CentreOnScreen()
1331  dlg.Show()
1332 
1333  def OnImportGdalLayers(self, event, cmd = None):
1334  """!Convert multiple GDAL layers to GRASS raster map layers"""
1335  dlg = GdalImportDialog(parent = self)
1336  dlg.CentreOnScreen()
1337  dlg.Show()
1338 
1339  def OnLinkGdalLayers(self, event, cmd = None):
1340  """!Link multiple GDAL layers to GRASS raster map layers"""
1341  dlg = GdalImportDialog(parent = self, link = True)
1342  dlg.CentreOnScreen()
1343  dlg.Show()
1344 
1345  def OnImportOgrLayers(self, event, cmd = None):
1346  """!Convert multiple OGR layers to GRASS vector map layers"""
1347  dlg = GdalImportDialog(parent = self, ogr = True)
1348  dlg.CentreOnScreen()
1349  dlg.Show()
1350 
1351  def OnLinkOgrLayers(self, event, cmd = None):
1352  """!Links multiple OGR layers to GRASS vector map layers"""
1353  dlg = GdalImportDialog(parent = self, ogr = True, link = True)
1354  dlg.CentreOnScreen()
1355  dlg.Show()
1356 
1357  def OnImportWMS(self, event, cmd = None):
1358  """!Import data from OGC WMS server"""
1359  dlg = WMSDialog(parent = self, service = 'wms')
1360  dlg.CenterOnScreen()
1361 
1362  if dlg.ShowModal() == wx.ID_OK: # -> import layers
1363  layers = dlg.GetLayers()
1364 
1365  if len(layers.keys()) > 0:
1366  for layer in layers.keys():
1367  cmd = ['r.in.wms',
1368  'mapserver=%s' % dlg.GetSettings()['server'],
1369  'layers=%s' % layer,
1370  'output=%s' % layer,
1371  'format=png',
1372  '--overwrite']
1373  styles = ','.join(layers[layer])
1374  if styles:
1375  cmd.append('styles=%s' % styles)
1376  self.goutput.RunCmd(cmd, switchPage = True)
1377 
1378  self.curr_page.maptree.AddLayer(ltype = 'raster',
1379  lname = layer,
1380  lcmd = ['d.rast', 'map=%s' % layer],
1381  multiple = False)
1382  else:
1383  self.goutput.WriteWarning(_("Nothing to import. No WMS layer selected."))
1384 
1385 
1386  dlg.Destroy()
1387 
1388  def OnShowAttributeTable(self, event, selection = None):
1389  """!Show attribute table of the given vector map layer
1390  """
1391  if not self.curr_page:
1392  self.MsgNoLayerSelected()
1393  return
1394 
1395  tree = self.GetLayerTree()
1396  layer = tree.layer_selected
1397  # no map layer selected
1398  if not layer:
1399  self.MsgNoLayerSelected()
1400  return
1401 
1402  # available only for vector map layers
1403  try:
1404  maptype = tree.GetPyData(layer)[0]['maplayer'].type
1405  except:
1406  maptype = None
1407 
1408  if not maptype or maptype != 'vector':
1409  GMessage(parent = self,
1410  message = _("Selected map layer is not vector."))
1411  return
1412 
1413  if not tree.GetPyData(layer)[0]:
1414  return
1415  dcmd = tree.GetPyData(layer)[0]['cmd']
1416  if not dcmd:
1417  return
1418 
1419  busy = wx.BusyInfo(message = _("Please wait, loading attribute data..."),
1420  parent = self)
1421  wx.Yield()
1422 
1423  dbmanager = AttributeManager(parent = self, id = wx.ID_ANY,
1424  size = wx.Size(500, 300),
1425  item = layer, log = self.goutput,
1426  selection = selection)
1427 
1428  busy.Destroy()
1429 
1430  # register ATM dialog
1431  self.dialogs['atm'].append(dbmanager)
1432 
1433  # show ATM window
1434  dbmanager.Show()
1435 
1436  def OnNewDisplayWMS(self, event = None):
1437  """!Create new layer tree and map display instance"""
1438  self.NewDisplayWMS()
1439 
1440  def OnNewDisplay(self, event = None):
1441  """!Create new layer tree and map display instance"""
1442  self.NewDisplay()
1443 
1444  def NewDisplay(self, name = None, show = True):
1445  """!Create new layer tree, which will
1446  create an associated map display frame
1447 
1448  @param name name of new map display
1449  @param show show map display window if True
1450 
1451  @return reference to mapdisplay intance
1452  """
1453  Debug.msg(1, "GMFrame.NewDisplay(): idx=%d" % self.disp_idx)
1454 
1455  # make a new page in the bookcontrol for the layer tree (on page 0 of the notebook)
1456  self.pg_panel = wx.Panel(self.gm_cb, id = wx.ID_ANY, style = wx.EXPAND)
1457  if name:
1458  dispName = name
1459  else:
1460  dispName = "Display " + str(self.disp_idx + 1)
1461  self.gm_cb.AddPage(self.pg_panel, text = dispName, select = True)
1462  self.curr_page = self.gm_cb.GetCurrentPage()
1463 
1464  # create layer tree (tree control for managing GIS layers) and put on new notebook page
1465  self.curr_page.maptree = LayerTree(self.curr_page, id = wx.ID_ANY, pos = wx.DefaultPosition,
1466  size = wx.DefaultSize, style = wx.TR_HAS_BUTTONS |
1467  wx.TR_LINES_AT_ROOT| wx.TR_HIDE_ROOT |
1468  wx.TR_DEFAULT_STYLE| wx.NO_BORDER | wx.FULL_REPAINT_ON_RESIZE,
1469  idx = self.disp_idx, lmgr = self, notebook = self.gm_cb,
1470  auimgr = self._auimgr, showMapDisplay = show)
1471 
1472  # layout for controls
1473  cb_boxsizer = wx.BoxSizer(wx.VERTICAL)
1474  cb_boxsizer.Add(self.curr_page.maptree, proportion = 1, flag = wx.EXPAND, border = 1)
1475  self.curr_page.SetSizer(cb_boxsizer)
1476  cb_boxsizer.Fit(self.curr_page.maptree)
1477  self.curr_page.Layout()
1478  self.curr_page.maptree.Layout()
1479 
1480  # use default window layout
1481  if UserSettings.Get(group = 'general', key = 'defWindowPos', subkey = 'enabled'):
1482  dim = UserSettings.Get(group = 'general', key = 'defWindowPos', subkey = 'dim')
1483  idx = 4 + self.disp_idx * 4
1484  try:
1485  x, y = map(int, dim.split(',')[idx:idx + 2])
1486  w, h = map(int, dim.split(',')[idx + 2:idx + 4])
1487  self.curr_page.maptree.mapdisplay.SetPosition((x, y))
1488  self.curr_page.maptree.mapdisplay.SetSize((w, h))
1489  except:
1490  pass
1491 
1492  self.disp_idx += 1
1493 
1494  return self.curr_page.maptree.mapdisplay
1495 
1496  def OnAddMaps(self, event = None):
1497  """!Add selected map layers into layer tree"""
1498  dialog = MapLayersDialog(parent = self, title = _("Add selected map layers into layer tree"))
1499 
1500  if dialog.ShowModal() != wx.ID_OK:
1501  dialog.Destroy()
1502  return
1503 
1504  # start new map display if no display is available
1505  if not self.curr_page:
1506  self.NewDisplay()
1507 
1508  maptree = self.curr_page.maptree
1509 
1510  for layerName in dialog.GetMapLayers():
1511  ltype = dialog.GetLayerType(cmd = True)
1512  if ltype == 'rast':
1513  cmd = ['d.rast', 'map=%s' % layerName]
1514  wxType = 'raster'
1515  elif ltype == 'rast3d':
1516  cmd = ['d.rast3d', 'map=%s' % layerName]
1517  wxType = '3d-raster'
1518  elif ltype == 'vect':
1519  cmd = ['d.vect', 'map=%s' % layerName]
1520  wxType = 'vector'
1521  else:
1522  GError(parent = self,
1523  message = _("Unsupported map layer type <%s>.") % ltype)
1524  return
1525 
1526  newItem = maptree.AddLayer(ltype = wxType,
1527  lname = layerName,
1528  lchecked = False,
1529  lopacity = 1.0,
1530  lcmd = cmd,
1531  lgroup = None)
1532  dialog.Destroy()
1533 
1534  def OnAddRaster(self, event):
1535  """!Add raster map layer"""
1536  # start new map display if no display is available
1537  if not self.curr_page:
1538  self.NewDisplay(show = True)
1539 
1540  self.notebook.SetSelectionByName('layers')
1541  self.curr_page.maptree.AddLayer('raster')
1542 
1543  def OnAddRasterMisc(self, event):
1544  """!Create misc raster popup-menu"""
1545  # start new map display if no display is available
1546  if not self.curr_page:
1547  self.NewDisplay(show = True)
1548 
1549  self._popupMenu((('addRast3d', self.OnAddRaster3D),
1550  (None, None),
1551  ('addRgb', self.OnAddRasterRGB),
1552  ('addHis', self.OnAddRasterHIS),
1553  (None, None),
1554  ('addShaded', self.OnAddRasterShaded),
1555  (None, None),
1556  ('addRArrow', self.OnAddRasterArrow),
1557  ('addRNum', self.OnAddRasterNum)))
1558 
1559  # show map display
1560  self.curr_page.maptree.mapdisplay.Show()
1561 
1562  def OnAddVector(self, event):
1563  """!Add vector map to the current layer tree"""
1564  # start new map display if no display is available
1565  if not self.curr_page:
1566  self.NewDisplay(show = True)
1567 
1568  self.notebook.SetSelectionByName('layers')
1569  self.curr_page.maptree.AddLayer('vector')
1570 
1571  def OnAddVectorMisc(self, event):
1572  """!Create misc vector popup-menu"""
1573  # start new map display if no display is available
1574  if not self.curr_page:
1575  self.NewDisplay(show = True)
1576 
1577  self._popupMenu((('addThematic', self.OnAddVectorTheme),
1578  ('addChart', self.OnAddVectorChart)))
1579 
1580  # show map display
1581  self.curr_page.maptree.mapdisplay.Show()
1582 
1583  def OnAddVectorTheme(self, event):
1584  """!Add thematic vector map to the current layer tree"""
1585  self.notebook.SetSelectionByName('layers')
1586  self.curr_page.maptree.AddLayer('thememap')
1587 
1588  def OnAddVectorChart(self, event):
1589  """!Add chart vector map to the current layer tree"""
1590  self.notebook.SetSelectionByName('layers')
1591  self.curr_page.maptree.AddLayer('themechart')
1592 
1593  def OnAddOverlay(self, event):
1594  """!Create decoration overlay menu"""
1595  # start new map display if no display is available
1596  if not self.curr_page:
1597  self.NewDisplay(show = True)
1598 
1599  self._popupMenu((('addGrid', self.OnAddGrid),
1600  ('addLabels', self.OnAddLabels),
1601  ('addGeodesic', self.OnAddGeodesic),
1602  ('addRhumb', self.OnAddRhumb),
1603  (None, None),
1604  ('addCmd', self.OnAddCommand)))
1605 
1606  # show map display
1607  self.curr_page.maptree.mapdisplay.Show()
1608 
1609  def OnAddRaster3D(self, event):
1610  """!Add 3D raster map to the current layer tree"""
1611  self.notebook.SetSelectionByName('layers')
1612  self.curr_page.maptree.AddLayer('3d-raster')
1613 
1614  def OnAddRasterRGB(self, event):
1615  """!Add RGB raster map to the current layer tree"""
1616  self.notebook.SetSelectionByName('layers')
1617  self.curr_page.maptree.AddLayer('rgb')
1618 
1619  def OnAddRasterHIS(self, event):
1620  """!Add HIS raster map to the current layer tree"""
1621  self.notebook.SetSelectionByName('layers')
1622  self.curr_page.maptree.AddLayer('his')
1623 
1624  def OnAddRasterShaded(self, event):
1625  """!Add shaded relief raster map to the current layer tree"""
1626  self.notebook.SetSelectionByName('layers')
1627  self.curr_page.maptree.AddLayer('shaded')
1628 
1629  def OnAddRasterArrow(self, event):
1630  """!Add flow arrows raster map to the current layer tree"""
1631  self.notebook.SetSelectionByName('layers')
1632  tree = self.curr_page.maptree
1633  resolution = tree.GetMapDisplay().GetProperty('resolution')
1634  if not resolution:
1635  dlg = self.MsgDisplayResolution()
1636  if dlg.ShowModal() == wx.ID_YES:
1637  tree.GetMapDisplay().SetProperty('resolution', True)
1638  dlg.Destroy()
1639 
1640  self.curr_page.maptree.AddLayer('rastarrow')
1641 
1642  def OnAddRasterNum(self, event):
1643  """!Add cell number raster map to the current layer tree"""
1644  self.notebook.SetSelectionByName('layers')
1645  tree = self.curr_page.maptree
1646  resolution = tree.GetMapDisplay().GetProperty('resolution')
1647  if not resolution:
1648  limitText = _("Note that cell values can only be displayed for "
1649  "regions of less than 10,000 cells.")
1650  dlg = self.MsgDisplayResolution(limitText)
1651  if dlg.ShowModal() == wx.ID_YES:
1652  tree.GetMapDisplay().SetProperty('resolution', True)
1653  dlg.Destroy()
1654 
1655  # region = tree.GetMap().GetCurrentRegion()
1656  # if region['cells'] > 10000:
1657  # GMessage(message = "Cell values can only be displayed for regions of < 10,000 cells.", parent = self)
1658  self.curr_page.maptree.AddLayer('rastnum')
1659 
1660  def OnAddCommand(self, event):
1661  """!Add command line map layer to the current layer tree"""
1662  # start new map display if no display is available
1663  if not self.curr_page:
1664  self.NewDisplay(show = True)
1665 
1666  self.notebook.SetSelectionByName('layers')
1667  self.curr_page.maptree.AddLayer('command')
1668 
1669  # show map display
1670  self.curr_page.maptree.mapdisplay.Show()
1671 
1672  def OnAddGroup(self, event):
1673  """!Add layer group"""
1674  # start new map display if no display is available
1675  if not self.curr_page:
1676  self.NewDisplay(show = True)
1677 
1678  self.notebook.SetSelectionByName('layers')
1679  self.curr_page.maptree.AddLayer('group')
1680 
1681  # show map display
1682  self.curr_page.maptree.mapdisplay.Show()
1683 
1684  def OnAddGrid(self, event):
1685  """!Add grid map layer to the current layer tree"""
1686  self.notebook.SetSelectionByName('layers')
1687  self.curr_page.maptree.AddLayer('grid')
1688 
1689  def OnAddGeodesic(self, event):
1690  """!Add geodesic line map layer to the current layer tree"""
1691  self.notebook.SetSelectionByName('layers')
1692  self.curr_page.maptree.AddLayer('geodesic')
1693 
1694  def OnAddRhumb(self, event):
1695  """!Add rhumb map layer to the current layer tree"""
1696  self.notebook.SetSelectionByName('layers')
1697  self.curr_page.maptree.AddLayer('rhumb')
1698 
1699  def OnAddLabels(self, event):
1700  """!Add vector labels map layer to the current layer tree"""
1701  # start new map display if no display is available
1702  if not self.curr_page:
1703  self.NewDisplay(show = True)
1704 
1705  self.notebook.SetSelectionByName('layers')
1706  self.curr_page.maptree.AddLayer('labels')
1707 
1708  # show map display
1709  self.curr_page.maptree.mapdisplay.Show()
1710 
1711  def OnDeleteLayer(self, event):
1712  """!Remove selected map layer from the current layer Tree
1713  """
1714  if not self.curr_page or not self.curr_page.maptree.layer_selected:
1715  self.MsgNoLayerSelected()
1716  return
1717 
1718  if UserSettings.Get(group = 'manager', key = 'askOnRemoveLayer', subkey = 'enabled'):
1719  layerName = ''
1720  for item in self.curr_page.maptree.GetSelections():
1721  name = self.curr_page.maptree.GetItemText(item)
1722  idx = name.find('(' + _('opacity:'))
1723  if idx > -1:
1724  layerName += '<' + name[:idx].strip(' ') + '>,\n'
1725  else:
1726  layerName += '<' + name + '>,\n'
1727  layerName = layerName.rstrip(',\n')
1728 
1729  if len(layerName) > 2: # <>
1730  message = _("Do you want to remove map layer(s)\n%s\n"
1731  "from layer tree?") % layerName
1732  else:
1733  message = _("Do you want to remove selected map layer(s) "
1734  "from layer tree?")
1735 
1736  dlg = wx.MessageDialog (parent = self, message = message,
1737  caption = _("Remove map layer"),
1738  style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
1739 
1740  if dlg.ShowModal() != wx.ID_YES:
1741  dlg.Destroy()
1742  return
1743 
1744  dlg.Destroy()
1745 
1746  for layer in self.curr_page.maptree.GetSelections():
1747  if self.curr_page.maptree.GetPyData(layer)[0]['type'] == 'group':
1748  self.curr_page.maptree.DeleteChildren(layer)
1749  self.curr_page.maptree.Delete(layer)
1750 
1751  def OnKeyDown(self, event):
1752  """!Key pressed"""
1753  kc = event.GetKeyCode()
1754 
1755  if event.ControlDown():
1756  if kc == wx.WXK_TAB:
1757  # switch layer list / command output
1758  if self.notebook.GetSelection() == self.notebook.GetPageIndexByName('layers'):
1759  self.notebook.SetSelectionByName('output')
1760  else:
1761  self.notebook.SetSelectionByName('layers')
1762 
1763  try:
1764  ckc = chr(kc)
1765  except ValueError:
1766  event.Skip()
1767  return
1768 
1769  if event.CtrlDown():
1770  if kc == 'R':
1771  self.OnAddRaster(None)
1772  elif kc == 'V':
1773  self.OnAddVector(None)
1774 
1775  event.Skip()
1776 
1777  def OnCloseWindow(self, event):
1778  """!Cleanup when wxGUI is quitted"""
1779  # save command protocol if actived
1780  if self.goutput.btnCmdProtocol.GetValue():
1781  self.goutput.CmdProtocolSave()
1782 
1783  if not self.curr_page:
1784  self._auimgr.UnInit()
1785  self.Destroy()
1786  return
1787 
1788  # save changes in the workspace
1789  maptree = self.curr_page.maptree
1790  if self.workspaceChanged and \
1791  UserSettings.Get(group = 'manager', key = 'askOnQuit', subkey = 'enabled'):
1792  if self.workspaceFile:
1793  message = _("Do you want to save changes in the workspace?")
1794  else:
1795  message = _("Do you want to store current settings "
1796  "to workspace file?")
1797 
1798  # ask user to save current settings
1799  if maptree.GetCount() > 0:
1800  dlg = wx.MessageDialog(self,
1801  message = message,
1802  caption = _("Quit GRASS GUI"),
1803  style = wx.YES_NO | wx.YES_DEFAULT |
1804  wx.CANCEL | wx.ICON_QUESTION | wx.CENTRE)
1805  ret = dlg.ShowModal()
1806  if ret == wx.ID_YES:
1807  if not self.workspaceFile:
1808  self.OnWorkspaceSaveAs()
1809  else:
1811  elif ret == wx.ID_CANCEL:
1812  # when called from menu, it gets CommandEvent and not CloseEvent
1813  if hasattr(event, 'Veto'):
1814  event.Veto()
1815  dlg.Destroy()
1816  return
1817  dlg.Destroy()
1818 
1819  # don't ask any more...
1820  UserSettings.Set(group = 'manager', key = 'askOnQuit', subkey = 'enabled',
1821  value = False)
1822 
1823  self.OnDisplayCloseAll()
1824 
1825  self.gm_cb.DeleteAllPages()
1826 
1827  self._auimgr.UnInit()
1828  self.Destroy()
1829 
1831  """!Show dialog message 'No layer selected'"""
1832  wx.MessageBox(parent = self,
1833  message = _("No map layer selected. Operation canceled."),
1834  caption = _("Message"),
1835  style = wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
1836 
1837  def MsgDisplayResolution(self, limitText = None):
1838  """!Returns dialog for d.rast.num, d.rast.arrow
1839  when display resolution is not constrained
1840 
1841  @param limitText adds a note about cell limit
1842  """
1843  message = _("Display resolution is currently not constrained to "
1844  "computational settings. "
1845  "It's suggested to constrain map to region geometry. "
1846  "Do you want to constrain "
1847  "the resolution?")
1848  if limitText:
1849  message += "\n\n%s" % _(limitText)
1850  dlg = wx.MessageDialog(parent = self,
1851  message = message,
1852  caption = _("Constrain map to region geometry?"),
1853  style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION | wx.CENTRE)
1854  return dlg
def OnVectorCleaning
Init interactive vector cleaning.
Definition: lmgr/frame.py:1319
def GetLogWindow(self)
Get widget for command output.
Definition: lmgr/frame.py:510
def OnAddRasterHIS(self, event)
Add HIS raster map to the current layer tree.
Definition: lmgr/frame.py:1619
def OnNewDisplayWMS
Create new layer tree and map display instance.
Definition: lmgr/frame.py:1436
def RulesCmd(self, event)
Launches dialog for commands that need rules input and processes rules.
Definition: lmgr/frame.py:1175
def WorkspaceChanged(self)
Update window title.
Definition: lmgr/frame.py:321
wxGUI command interface
def OnAddOverlay(self, event)
Create decoration overlay menu.
Definition: lmgr/frame.py:1593
def OnCloseWindow(self, event)
Cleanup when wxGUI is quitted.
Definition: lmgr/frame.py:1777
def OnDisplayClose
Close current map display window.
Definition: lmgr/frame.py:1144
def SaveToWorkspaceFile(self, filename)
Save layer tree layout to workspace file.
Definition: lmgr/frame.py:1102
def OnMapsets(self, event)
Launch mapset access dialog.
Definition: lmgr/frame.py:429
Location wizard - dialogs.
def OnKeyDown(self, event)
Key pressed.
Definition: lmgr/frame.py:1751
wxGUI Graphical Modeler (base classes & read/write)
Location wizard - creates a new GRASS Location.
def OnAddGrid(self, event)
Add grid map layer to the current layer tree.
Definition: lmgr/frame.py:1684
def OnAddVector(self, event)
Add vector map to the current layer tree.
Definition: lmgr/frame.py:1562
wxGUI debugging
def __init__(self, parent, id=wx.ID_ANY, title=None, workspace=None, size=globalvar.GM_WINDOW_SIZE, style=wx.DEFAULT_FRAME_STYLE, kwargs)
Definition: lmgr/frame.py:78
def OnNewDisplay
Create new layer tree and map display instance.
Definition: lmgr/frame.py:1440
def OnAddRasterNum(self, event)
Add cell number raster map to the current layer tree.
Definition: lmgr/frame.py:1642
Layer Manager frame with notebook widget for controlling GRASS GIS.
Definition: lmgr/frame.py:71
wxGUI Interactive Python Shell for Layer Manager
def OnHistogram(self, event)
Init histogram display canvas and tools.
Definition: lmgr/frame.py:1284
def OnImportWMS
Import data from OGC WMS server.
Definition: lmgr/frame.py:1357
def OnAddVectorChart(self, event)
Add chart vector map to the current layer tree.
Definition: lmgr/frame.py:1588
GUI for ps.map.
Core GUI widgets.
def OnCBPageChanged(self, event)
Page in notebook (display) changed.
Definition: lmgr/frame.py:441
def OnAddRasterMisc(self, event)
Create misc raster popup-menu.
Definition: lmgr/frame.py:1543
def OnChangeMapset(self, event)
Definition: lmgr/frame.py:705
def OnImportGdalLayers
Convert multiple GDAL layers to GRASS raster map layers.
Definition: lmgr/frame.py:1333
Open/save workspace definition file.
GRASS Attribute Table Manager.
def OnAddGeodesic(self, event)
Add geodesic line map layer to the current layer tree.
Definition: lmgr/frame.py:1689
def OnNewVector(self, event)
Create new vector map layer.
Definition: lmgr/frame.py:724
def OnSystemInfo(self, event)
Print system information.
Definition: lmgr/frame.py:742
def RemoveNvizTools(self)
Remove nviz notebook page.
Definition: lmgr/frame.py:309
def OnUninstallExtension(self, event)
Uninstall extension.
Definition: lmgr/frame.py:1261
def AddNvizTools(self)
Add nviz notebook page.
Definition: lmgr/frame.py:286
def OnAddGroup(self, event)
Add layer group.
Definition: lmgr/frame.py:1672
def OnLinkOgrLayers
Links multiple OGR layers to GRASS vector map layers.
Definition: lmgr/frame.py:1351
def OnAboutGRASS(self, event)
Display 'About GRASS' dialog.
Definition: lmgr/frame.py:788
Nviz (3D view) module.
Various dialogs used in wxGUI.
def OnRenameDisplay(self, event)
Change Map Display name.
Definition: lmgr/frame.py:1160
def _setCopyingOfSelectedText(self)
Definition: lmgr/frame.py:236
def OnPsMap(self, event)
Launch Cartographic Composer.
Definition: lmgr/frame.py:395
Menu classes for wxGUI.
wxGUI Graphical Modeler for creating, editing, and managing models
def OnEditImageryGroups
Show dialog for creating and editing groups.
Definition: lmgr/frame.py:1248
def SetAddOnPath
Set default AddOn path.
Definition: core/utils.py:889
def MsgNoLayerSelected(self)
Show dialog message 'No layer selected'.
Definition: lmgr/frame.py:1830
def OnAddVectorTheme(self, event)
Add thematic vector map to the current layer tree.
Definition: lmgr/frame.py:1583
def OnAddRasterArrow(self, event)
Add flow arrows raster map to the current layer tree.
Definition: lmgr/frame.py:1629
def OnAddVectorMisc(self, event)
Create misc vector popup-menu.
Definition: lmgr/frame.py:1571
NvizToolWindow
Definition: nviz/main.py:35
def OnAddRasterShaded(self, event)
Add shaded relief raster map to the current layer tree.
Definition: lmgr/frame.py:1624
Georectification module for GRASS GIS.
Plotting histogram based on d.histogram.
def OnDisplayCloseAll
Close all open map display windows.
Definition: lmgr/frame.py:1150
def OnGCPManager(self, event)
Launch georectifier module.
Definition: lmgr/frame.py:383
def OnAddMaps
Add selected map layers into layer tree.
Definition: lmgr/frame.py:1496
def OnLocationWizard(self, event)
Launch location wizard.
Definition: lmgr/frame.py:329
def OnMenuCmd
Parse command selected from menu.
Definition: lmgr/frame.py:555
def OnHelp(self, event)
Show help.
Definition: lmgr/frame.py:1279
def OnProfile(self, event)
Launch profile tool.
Definition: lmgr/frame.py:1295
def _createMenuBar(self)
Creates menu bar.
Definition: lmgr/frame.py:218
def OnCBPageClosed(self, event)
Page of notebook closed Also close associated map display.
Definition: lmgr/frame.py:464
def IsPaneShown(self, name)
Check if pane (toolbar, ...) of given name is currently shown.
Definition: lmgr/frame.py:240
def OnWorkspaceSaveAs
Save workspace definition to selected file.
Definition: lmgr/frame.py:1055
def OnWorkspaceNew
Create new workspace file.
Definition: lmgr/frame.py:819
def OnWorkspaceLoadGrcFile(self, event)
Load map layers from GRC file (Tcl/Tk GUI) into map layer tree.
Definition: lmgr/frame.py:1017
def OnAddRaster3D(self, event)
Add 3D raster map to the current layer tree.
Definition: lmgr/frame.py:1609
def OnVDigit(self, event)
Start vector digitizer.
Definition: lmgr/frame.py:561
def OnSettingsChanged(self, event)
Here can be functions which have to be called after EVT_SETTINGS_CHANGED.
Definition: lmgr/frame.py:376
def LoadWorkspaceFile(self, filename)
Load layer tree definition stored in GRASS Workspace XML file (gxw)
Definition: lmgr/frame.py:885
def CreateNewVector
Create new vector map layer.
wxGUI Layer Manager - toolbars
def OnPageChanged(self, event)
Page in notebook changed.
Definition: lmgr/frame.py:453
def MsgDisplayResolution
Returns dialog for d.rast.num, d.rast.arrow when display resolution is not constrained.
Definition: lmgr/frame.py:1837
Help window.
def OnCreateMapset(self, event)
Create new mapset.
Definition: lmgr/frame.py:684
Utility classes for map layer management.
Mainframe for displaying profile of one or more raster maps.
Definition: profile.py:42
Misc utilities for wxGUI.
def OnInstallExtension(self, event)
Install extension from GRASS Addons SVN repository.
Definition: lmgr/frame.py:1255
def OnImportMenu(self, event)
Import maps menu (import, link)
Definition: lmgr/frame.py:813
def _popupMenu(self, data)
Create popup menu.
Definition: lmgr/frame.py:794
def OnLinkGdalLayers
Link multiple GDAL layers to GRASS raster map layers.
Definition: lmgr/frame.py:1339
def OnPreferences(self, event)
General GUI preferences/settings.
Definition: lmgr/frame.py:1267
User preferences dialog.
def OnMapCalculator
Init map calculator for interactive creation of mapcalc statements.
Definition: lmgr/frame.py:1305
def OnAddLabels(self, event)
Add vector labels map layer to the current layer tree.
Definition: lmgr/frame.py:1699
def OnAddRhumb(self, event)
Add rhumb map layer to the current layer tree.
Definition: lmgr/frame.py:1694
def OnGModeler(self, event)
Launch Graphical Modeler.
Definition: lmgr/frame.py:388
def _createTabMenu(self)
Creates context menu for display tabs.
Definition: lmgr/frame.py:224
def _createNoteBook(self)
Creates notebook widgets.
Definition: lmgr/frame.py:246
def OnDone(self, cmd, returncode)
Definition: lmgr/frame.py:403
def OnXTerm
Run commands that need interactive xmon.
Definition: lmgr/frame.py:1194
def OnWorkspaceClose
Close file with workspace definition.
Definition: lmgr/frame.py:1130
def OnAddCommand(self, event)
Add command line map layer to the current layer tree.
Definition: lmgr/frame.py:1660
def OnRunModel(self, event)
Run model.
Definition: lmgr/frame.py:410
def RunCommand(prog, flags="", overwrite=False, quiet=False, verbose=False, parent=None, read=False, stdin=None, getErrorMsg=False, kwargs)
Run GRASS command.
Definition: gcmd.py:633
def OnXTermNoXMon(self, event)
Run commands that need xterm.
Definition: lmgr/frame.py:1188
def OnAddRasterRGB(self, event)
Add RGB raster map to the current layer tree.
Definition: lmgr/frame.py:1614
GRASS Addons extensions management classes.
def OnImportDxfFile
Convert multiple DXF layers to GRASS vector map layers.
Definition: lmgr/frame.py:1327
def NewDisplay
Create new layer tree, which will create an associated map display frame.
Definition: lmgr/frame.py:1444
Default GUI settings.
def OnRunScript(self, event)
Run script.
Definition: lmgr/frame.py:600
def OnShowAttributeTable
Show attribute table of the given vector map layer.
Definition: lmgr/frame.py:1388
tuple range
Definition: tools.py:1406
def GetLayerTree(self)
Get current layer tree.
Definition: lmgr/frame.py:504
def RunMenuCmd
Run command selected from menu.
Definition: lmgr/frame.py:549
def OnWorkspaceOpen
Open file with workspace definition.
Definition: lmgr/frame.py:863
def OnWorkspaceSave
Save file with workspace definition.
Definition: lmgr/frame.py:1085
Command output widgets.
def decode(string)
Definition: core.py:80
def GetMenuCmd(self, event)
Get GRASS command from menu item.
Definition: lmgr/frame.py:514
def OnChangeLocation(self, event)
Definition: lmgr/frame.py:659
def OnAddRaster(self, event)
Add raster map layer.
Definition: lmgr/frame.py:1534
def OnDeleteLayer(self, event)
Remove selected map layer from the current layer Tree.
Definition: lmgr/frame.py:1711
def OnImportOgrLayers
Convert multiple OGR layers to GRASS vector map layers.
Definition: lmgr/frame.py:1345