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