GRASS Programmer's Manual  6.4.4(2014)-r
gui_core/dialogs.py
Go to the documentation of this file.
1 """!
2 @package gui_core.dialogs
3 
4 @brief Various dialogs used in wxGUI.
5 
6 List of classes:
7  - dialogs::ElementDialog
8  - dialogs::LocationDialog
9  - dialogs::MapsetDialog
10  - dialogs::NewVectorDialog
11  - dialogs::SavedRegion
12  - dialogs::DecorationDialog
13  - dialogs::TextLayerDialog
14  - dialogs::GroupDialog
15  - dialogs::MapLayersDialog
16  - dialogs::ImportDialog
17  - dialogs::GdalImportDialog
18  - dialogs::DxfImportDialog
19  - dialogs::LayersList (used by MultiImport)
20  - dialogs::SetOpacityDialog
21  - dialogs::ImageSizeDialog
22 
23 (C) 2008-2011 by the GRASS Development Team
24 
25 This program is free software under the GNU General Public License
26 (>=v2). Read the file COPYING that comes with GRASS for details.
27 
28 @author Martin Landa <landa.martin gmail.com>
29 @author Anna Kratochvilova <kratochanna gmail.com> (GroupDialog)
30 """
31 
32 import os
33 import sys
34 import re
35 from bisect import bisect
36 
37 import wx
38 import wx.lib.filebrowsebutton as filebrowse
39 import wx.lib.mixins.listctrl as listmix
40 from wx.lib.newevent import NewEvent
41 
42 from grass.script import core as grass
43 from grass.script import task as gtask
44 
45 from core import globalvar
46 from core.gcmd import GError, RunCommand, GMessage
47 from gui_core.gselect import ElementSelect, LocationSelect, MapsetSelect, Select, GdalSelect
48 from gui_core.forms import GUI
49 from gui_core.widgets import SingleSymbolPanel, EVT_SYMBOL_SELECTION_CHANGED
50 from core.utils import GetListOfMapsets, GetLayerNameFromCmd, GetValidLayerName
51 from core.settings import UserSettings
52 from core.debug import Debug
53 
54 wxApplyOpacity, EVT_APPLY_OPACITY = NewEvent()
55 
56 class ElementDialog(wx.Dialog):
57  def __init__(self, parent, title, label, id = wx.ID_ANY,
58  etype = False, style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
59  **kwargs):
60  """!General dialog to choose given element (location, mapset, vector map, etc.)
61 
62  @param parent window
63  @param title window title
64  @param label element label
65  @param etype show also ElementSelect
66  """
67  wx.Dialog.__init__(self, parent, id, title, style = style, **kwargs)
68 
69  self.etype = etype
70  self.label = label
71 
72  self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
73 
74  self.btnCancel = wx.Button(parent = self.panel, id = wx.ID_CANCEL)
75  self.btnOK = wx.Button(parent = self.panel, id = wx.ID_OK)
76  self.btnOK.SetDefault()
77  self.btnOK.Enable(False)
78 
79  if self.etype:
80  self.typeSelect = ElementSelect(parent = self.panel,
81  size = globalvar.DIALOG_GSELECT_SIZE)
82  self.typeSelect.Bind(wx.EVT_CHOICE, self.OnType)
83 
84  self.element = None # must be defined
85 
86  self.__layout()
87 
88  def PostInit(self):
89  self.element.SetFocus()
90  self.element.Bind(wx.EVT_TEXT, self.OnElement)
91 
92  def OnType(self, event):
93  """!Select element type"""
94  if not self.etype:
95  return
96  evalue = self.typeSelect.GetValue(event.GetString())
97  self.element.SetType(evalue)
98 
99  def OnElement(self, event):
100  """!Name for vector map layer given"""
101  if len(event.GetString()) > 0:
102  self.btnOK.Enable(True)
103  else:
104  self.btnOK.Enable(False)
105 
106  def __layout(self):
107  """!Do layout"""
108  self.sizer = wx.BoxSizer(wx.VERTICAL)
109 
110  self.dataSizer = wx.BoxSizer(wx.VERTICAL)
111 
112  if self.etype:
113  self.dataSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
114  label = _("Type of element:")),
115  proportion = 0, flag = wx.ALL, border = 1)
116  self.dataSizer.Add(item = self.typeSelect,
117  proportion = 0, flag = wx.ALL, border = 1)
118 
119  self.dataSizer.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
120  label = self.label),
121  proportion = 0, flag = wx.ALL, border = 1)
122 
123  # buttons
124  btnSizer = wx.StdDialogButtonSizer()
125  btnSizer.AddButton(self.btnCancel)
126  btnSizer.AddButton(self.btnOK)
127  btnSizer.Realize()
128 
129  self.sizer.Add(item = self.dataSizer, proportion = 1,
130  flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
131 
132  self.sizer.Add(item = btnSizer, proportion = 0,
133  flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
134 
135  def GetElement(self):
136  """!Return (mapName, overwrite)"""
137  return self.element.GetValue()
138 
139  def GetType(self):
140  """!Get element type"""
141  return self.element.tcp.GetType()
142 
144  """!Dialog used to select location"""
145  def __init__(self, parent, title = _("Select GRASS location and mapset"), id = wx.ID_ANY):
146  ElementDialog.__init__(self, parent, title, label = _("Name of GRASS location:"))
147 
148  self.element = LocationSelect(parent = self.panel, id = wx.ID_ANY,
149  size = globalvar.DIALOG_GSELECT_SIZE)
150 
151  self.element1 = MapsetSelect(parent = self.panel, id = wx.ID_ANY,
152  size = globalvar.DIALOG_GSELECT_SIZE,
153  setItems = False, skipCurrent = True)
154 
155  self.PostInit()
156 
157  self._layout()
158  self.SetMinSize(self.GetSize())
159 
160  def _layout(self):
161  """!Do layout"""
162  self.dataSizer.Add(self.element, proportion = 0,
163  flag = wx.EXPAND | wx.ALL, border = 1)
164 
165  self.dataSizer.Add(wx.StaticText(parent = self.panel, id = wx.ID_ANY,
166  label = _("Name of mapset:")), proportion = 0,
167  flag = wx.EXPAND | wx.ALL, border = 1)
168 
169  self.dataSizer.Add(self.element1, proportion = 0,
170  flag = wx.EXPAND | wx.ALL, border = 1)
171 
172  self.panel.SetSizer(self.sizer)
173  self.sizer.Fit(self)
174 
175  def OnElement(self, event):
176  """!Select mapset given location name"""
177  location = event.GetString()
178 
179  if location:
180  dbase = grass.gisenv()['GISDBASE']
181  self.element1.UpdateItems(dbase = dbase, location = location)
182  self.element1.SetSelection(0)
183  mapset = self.element1.GetStringSelection()
184 
185  if location and mapset:
186  self.btnOK.Enable(True)
187  else:
188  self.btnOK.Enable(False)
189 
190  def GetValues(self):
191  """!Get location, mapset"""
192  return (self.GetElement(), self.element1.GetStringSelection())
193 
195  """!Dialog used to select mapset"""
196  def __init__(self, parent, title = _("Select mapset in GRASS location"),
197  location = None, id = wx.ID_ANY):
198  ElementDialog.__init__(self, parent, title, label = _("Name of mapset:"))
199  if location:
200  self.SetTitle(self.GetTitle() + ' <%s>' % location)
201  else:
202  self.SetTitle(self.GetTitle() + ' <%s>' % grass.gisenv()['LOCATION_NAME'])
203 
204  self.element = MapsetSelect(parent = self.panel, id = wx.ID_ANY, skipCurrent = True,
205  size = globalvar.DIALOG_GSELECT_SIZE)
206 
207  self.PostInit()
208 
209  self.__Layout()
210  self.SetMinSize(self.GetSize())
211 
212  def __Layout(self):
213  """!Do layout"""
214  self.dataSizer.Add(self.element, proportion = 0,
215  flag = wx.EXPAND | wx.ALL, border = 1)
216 
217  self.panel.SetSizer(self.sizer)
218  self.sizer.Fit(self)
219 
220  def GetMapset(self):
221  return self.GetElement()
222 
224  def __init__(self, parent, id = wx.ID_ANY, title = _('Create new vector map'),
225  disableAdd = False, disableTable = False,
226  style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, *kwargs):
227  """!Dialog for creating new vector map
228 
229  @param parent parent window
230  @param id window id
231  @param title window title
232  @param disableAdd disable 'add layer' checkbox
233  @param disableTable disable 'create table' checkbox
234  @param style window style
235  @param kwargs other argumentes for ElementDialog
236 
237  @return dialog instance
238  """
239  ElementDialog.__init__(self, parent, title, label = _("Name for new vector map:"))
240 
241  self.element = Select(parent = self.panel, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
242  type = 'vector', mapsets = [grass.gisenv()['MAPSET'],])
243 
244  self.table = wx.CheckBox(parent = self.panel, id = wx.ID_ANY,
245  label = _("Create attribute table"))
246  self.table.SetValue(True)
247  if disableTable:
248  self.table.Enable(False)
249 
250  self.keycol = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY,
251  size = globalvar.DIALOG_SPIN_SIZE)
252  self.keycol.SetValue(UserSettings.Get(group = 'atm', key = 'keycolumn', subkey = 'value'))
253  if disableTable:
254  self.keycol.Enable(False)
255 
256  self.addbox = wx.CheckBox(parent = self.panel,
257  label = _('Add created map into layer tree'), style = wx.NO_BORDER)
258  if disableAdd:
259  self.addbox.SetValue(True)
260  self.addbox.Enable(False)
261  else:
262  self.addbox.SetValue(UserSettings.Get(group = 'cmd', key = 'addNewLayer', subkey = 'enabled'))
263 
264  self.table.Bind(wx.EVT_CHECKBOX, self.OnTable)
265 
266  self.PostInit()
267 
268  self._layout()
269  self.SetMinSize(self.GetSize())
270 
271  def OnMapName(self, event):
272  """!Name for vector map layer given"""
273  self.OnElement(event)
274 
275  def OnTable(self, event):
276  self.keycol.Enable(event.IsChecked())
277 
278  def _layout(self):
279  """!Do layout"""
280  self.dataSizer.Add(self.element, proportion = 0,
281  flag = wx.EXPAND | wx.ALL, border = 1)
282 
283  self.dataSizer.Add(self.table, proportion = 0,
284  flag = wx.EXPAND | wx.ALL, border = 1)
285 
286  keySizer = wx.BoxSizer(wx.HORIZONTAL)
287  keySizer.Add(item = wx.StaticText(parent = self.panel, label = _("Key column:")),
288  proportion = 0,
289  flag = wx.ALIGN_CENTER_VERTICAL)
290  keySizer.AddSpacer(10)
291  keySizer.Add(item = self.keycol, proportion = 0,
292  flag = wx.ALIGN_RIGHT)
293  self.dataSizer.Add(item = keySizer, proportion = 1,
294  flag = wx.EXPAND | wx.ALL, border = 1)
295 
296  self.dataSizer.AddSpacer(5)
297 
298  self.dataSizer.Add(item = self.addbox, proportion = 0,
299  flag = wx.EXPAND | wx.ALL, border = 1)
300 
301  self.panel.SetSizer(self.sizer)
302  self.sizer.Fit(self)
303 
304  def GetName(self, full = False):
305  """!Get name of vector map to be created
306 
307  @param full True to get fully qualified name
308  """
309  name = self.GetElement()
310  if full:
311  if '@' in name:
312  return name
313  else:
314  return name + '@' + grass.gisenv()['MAPSET']
315 
316  return name.split('@', 1)[0]
317 
318  def GetKey(self):
319  """!Get key column name"""
320  return self.keycol.GetValue()
321 
322  def IsChecked(self, key):
323  """!Get dialog properties
324 
325  @param key window key ('add', 'table')
326 
327  @return True/False
328  @return None on error
329  """
330  if key == 'add':
331  return self.addbox.IsChecked()
332  elif key == 'table':
333  return self.table.IsChecked()
334 
335  return None
336 
337 def CreateNewVector(parent, cmd, title = _('Create new vector map'),
338  exceptMap = None, log = None, disableAdd = False, disableTable = False):
339  """!Create new vector map layer
340 
341  @param cmd (prog, **kwargs)
342  @param title window title
343  @param exceptMap list of maps to be excepted
344  @param log
345  @param disableAdd disable 'add layer' checkbox
346  @param disableTable disable 'create table' checkbox
347 
348  @return dialog instance
349  @return None on error
350  """
351  dlg = NewVectorDialog(parent, title = title,
352  disableAdd = disableAdd, disableTable = disableTable)
353 
354  if dlg.ShowModal() != wx.ID_OK:
355  dlg.Destroy()
356  return None
357 
358  outmap = dlg.GetName()
359  key = dlg.GetKey()
360  if outmap == exceptMap:
361  GError(parent = parent,
362  message = _("Unable to create vector map <%s>.") % outmap)
363  dlg.Destroy()
364  return None
365  if dlg.table.IsEnabled() and not key:
366  GError(parent = parent,
367  message = _("Invalid or empty key column.\n"
368  "Unable to create vector map <%s>.") % outmap)
369  dlg.Destroy()
370  return
371 
372  if outmap == '': # should not happen
373  dlg.Destroy()
374  return None
375 
376  # update cmd -> output name defined
377  cmd[1][cmd[2]] = outmap
378 
379  listOfVectors = grass.list_grouped('vect')[grass.gisenv()['MAPSET']]
380 
381  overwrite = False
382  if not UserSettings.Get(group = 'cmd', key = 'overwrite', subkey = 'enabled') and \
383  outmap in listOfVectors:
384  dlgOw = wx.MessageDialog(parent, message = _("Vector map <%s> already exists "
385  "in the current mapset. "
386  "Do you want to overwrite it?") % outmap,
387  caption = _("Overwrite?"),
388  style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
389  if dlgOw.ShowModal() == wx.ID_YES:
390  overwrite = True
391  else:
392  dlgOw.Destroy()
393  dlg.Destroy()
394  return None
395 
396  if UserSettings.Get(group = 'cmd', key = 'overwrite', subkey = 'enabled'):
397  overwrite = True
398 
399  ret = RunCommand(prog = cmd[0],
400  parent = parent,
401  overwrite = overwrite,
402  **cmd[1])
403  if ret != 0:
404  dlg.Destroy()
405  return None
406 
407  # create attribute table
408  if dlg.table.IsEnabled() and dlg.table.IsChecked():
409  sql = 'CREATE TABLE %s (%s INTEGER)' % (outmap, key)
410 
411  RunCommand('db.connect',
412  flags = 'c')
413 
414  Debug.msg(1, "SQL: %s" % sql)
415  RunCommand('db.execute',
416  quiet = True,
417  parent = parent,
418  input = '-',
419  stdin = sql)
420 
421  RunCommand('v.db.connect',
422  quiet = True,
423  parent = parent,
424  map = outmap,
425  table = outmap,
426  key = key,
427  layer = '1')
428 
429  # return fully qualified map name
430  if '@' not in outmap:
431  outmap += '@' + grass.gisenv()['MAPSET']
432 
433  if log:
434  log.WriteLog(_("New vector map <%s> created") % outmap)
435 
436  return dlg
437 
438 class SavedRegion(wx.Dialog):
439  def __init__(self, parent, id = wx.ID_ANY, title = "", loadsave = 'load',
440  **kwargs):
441  """!Loading and saving of display extents to saved region file
442 
443  @param loadsave load or save region?
444  """
445  wx.Dialog.__init__(self, parent, id, title, **kwargs)
446 
447  self.loadsave = loadsave
448  self.wind = ''
449 
450  sizer = wx.BoxSizer(wx.VERTICAL)
451 
452  box = wx.BoxSizer(wx.HORIZONTAL)
453  label = wx.StaticText(parent = self, id = wx.ID_ANY)
454  box.Add(item = label, proportion = 0, flag = wx.ALIGN_CENTRE | wx.ALL, border = 5)
455  if loadsave == 'load':
456  label.SetLabel(_("Load region:"))
457  selection = Select(parent = self, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
458  type = 'windows')
459  elif loadsave == 'save':
460  label.SetLabel(_("Save region:"))
461  selection = Select(parent = self, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
462  type = 'windows', mapsets = [grass.gisenv()['MAPSET']], fullyQualified = False)
463 
464  box.Add(item = selection, proportion = 0, flag = wx.ALIGN_CENTRE | wx.ALL, border = 5)
465  selection.SetFocus()
466  selection.Bind(wx.EVT_TEXT, self.OnRegion)
467 
468  sizer.Add(item = box, proportion = 0, flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL,
469  border = 5)
470 
471  line = wx.StaticLine(parent = self, id = wx.ID_ANY, size = (20, -1), style = wx.LI_HORIZONTAL)
472  sizer.Add(item = line, proportion = 0,
473  flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border = 5)
474 
475  btnsizer = wx.StdDialogButtonSizer()
476 
477  btn = wx.Button(parent = self, id = wx.ID_OK)
478  btn.SetDefault()
479  btnsizer.AddButton(btn)
480 
481  btn = wx.Button(parent = self, id = wx.ID_CANCEL)
482  btnsizer.AddButton(btn)
483  btnsizer.Realize()
484 
485  sizer.Add(item = btnsizer, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
486 
487  self.SetSizer(sizer)
488  sizer.Fit(self)
489  self.Layout()
490 
491  def OnRegion(self, event):
492  self.wind = event.GetString()
493 
494 DECOR_DIALOG_LEGEND = 0
495 DECOR_DIALOG_BARSCALE = 1
496 
497 class DecorationDialog(wx.Dialog):
498  """
499  """
500  def __init__(self, parent, title, overlayController,
501  ddstyle, **kwargs):
502 
503  wx.Dialog.__init__(self, parent, wx.ID_ANY, title, **kwargs)
504 
505  self.parent = parent # MapFrame
506  self._overlay = overlayController
507  self._ddstyle = ddstyle
508 
509  sizer = wx.BoxSizer(wx.VERTICAL)
510 
511  box = wx.BoxSizer(wx.HORIZONTAL)
512  self.chkbox = wx.CheckBox(parent = self, id = wx.ID_ANY)
513  self.chkbox.SetValue(True)
514 
515  if self._ddstyle == DECOR_DIALOG_LEGEND:
516  self.chkbox.SetLabel("Show legend")
517  else:
518  self.chkbox.SetLabel("Show scale and North arrow")
519 
520 
521  box.Add(item = self.chkbox, proportion = 0,
522  flag = wx.ALIGN_CENTRE|wx.ALL, border = 5)
523  sizer.Add(item = box, proportion = 0,
524  flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
525 
526  box = wx.BoxSizer(wx.HORIZONTAL)
527  optnbtn = wx.Button(parent = self, id = wx.ID_ANY, label = _("Set options"))
528  box.Add(item = optnbtn, proportion = 0, flag = wx.ALIGN_CENTRE|wx.ALL, border = 5)
529  sizer.Add(item = box, proportion = 0,
530  flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
531  if self._ddstyle == DECOR_DIALOG_LEGEND:
532  box = wx.BoxSizer(wx.HORIZONTAL)
533  self.resizeBtn = wx.ToggleButton(parent = self, id = wx.ID_ANY, label = _("Set size and position"))
534  self.resizeBtn.SetToolTipString(_("Click and drag on the map display to set legend "
535  "size and position and then press OK"))
536  self.resizeBtn.Disable()
537  self.resizeBtn.Bind(wx.EVT_TOGGLEBUTTON, self.OnResize)
538  box.Add(item = self.resizeBtn, proportion = 0, flag = wx.ALIGN_CENTRE|wx.ALL, border = 5)
539  sizer.Add(item = box, proportion = 0,
540  flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
541 
542  box = wx.BoxSizer(wx.HORIZONTAL)
543  if self._ddstyle == DECOR_DIALOG_LEGEND:
544  labelText = _("Drag legend object with mouse in pointer mode to position.\n"
545  "Double-click to change options.\n"
546  "Define raster map name for legend in properties dialog.")
547  else:
548  labelText = _("Drag scale object with mouse in pointer mode to position.\n"
549  "Double-click to change options.")
550 
551  label = wx.StaticText(parent = self, id = wx.ID_ANY,
552  label = labelText)
553 
554  box.Add(item = label, proportion = 0,
555  flag = wx.ALIGN_CENTRE|wx.ALL, border = 5)
556  sizer.Add(item = box, proportion = 0,
557  flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
558 
559  line = wx.StaticLine(parent = self, id = wx.ID_ANY, size = (20,-1), style = wx.LI_HORIZONTAL)
560  sizer.Add(item = line, proportion = 0,
561  flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
562 
563  # buttons
564  btnsizer = wx.StdDialogButtonSizer()
565 
566  self.btnOK = wx.Button(parent = self, id = wx.ID_OK)
567  self.btnOK.SetDefault()
568  self.btnOK.Enable(self._ddstyle != DECOR_DIALOG_LEGEND)
569  btnsizer.AddButton(self.btnOK)
570 
571  btnCancel = wx.Button(parent = self, id = wx.ID_CANCEL)
572  btnsizer.AddButton(btnCancel)
573  btnsizer.Realize()
574 
575  sizer.Add(item = btnsizer, proportion = 0,
576  flag = wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border = 5)
577 
578  #
579  # bindings
580  #
581  optnbtn.Bind(wx.EVT_BUTTON, self.OnOptions)
582  btnCancel.Bind(wx.EVT_BUTTON, lambda evt: self.CloseDialog())
583  self.btnOK.Bind(wx.EVT_BUTTON, self.OnOK)
584 
585  self.SetSizer(sizer)
586  sizer.Fit(self)
587 
588  mapName, found = GetLayerNameFromCmd(self._overlay.cmd)
589  if found:
590  # enable 'OK' and 'Resize' button
591  self.btnOK.Enable()
592  if not self.parent.IsPaneShown('3d'):
593  self.resizeBtn.Enable()
594 
595  # set title
596  self.SetTitle(_('Legend of raster map <%s>') % \
597  mapName)
598 
599  def OnOptions(self, event):
600  """!Sets option for decoration map overlays
601  """
602  if self._overlay.propwin is None:
603  # build properties dialog
604  GUI(parent = self.parent).ParseCommand(cmd = self._overlay.cmd,
605  completed = (self.GetOptData, self._overlay.name, ''))
606 
607  else:
608  if self._overlay.propwin.IsShown():
609  self._overlay.propwin.SetFocus()
610  else:
611  self._overlay.propwin.Show()
612 
613  def OnResize(self, event):
614  if event.GetInt():
615  self.parent.MapWindow.SetCursor(self.parent.cursors["cross"])
616  self.parent.MapWindow.mouse['use'] = 'legend'
617  self.parent.MapWindow.mouse['box'] = 'box'
618  self.parent.MapWindow.pen = wx.Pen(colour = 'Black', width = 2, style = wx.SHORT_DASH)
619  else:
620  self.parent.MapWindow.SetCursor(self.parent.cursors["default"])
621  self.parent.MapWindow.mouse['use'] = 'pointer'
622 
623  def CloseDialog(self):
624  """!Hide dialog"""
625  if self._ddstyle == DECOR_DIALOG_LEGEND and self.resizeBtn.GetValue():
626  self.resizeBtn.SetValue(False)
627  self.OnResize(None)
628 
629  self.Hide()
630 
631  def OnOK(self, event):
632  """!Button 'OK' pressed"""
633  # enable or disable overlay
634  self._overlay.Show(self.chkbox.IsChecked())
635 
636  # update map
637  if self.parent.IsPaneShown('3d'):
638  self.parent.MapWindow.UpdateOverlays()
639 
640  self.parent.MapWindow.UpdateMap()
641 
642  # hide dialog
643  self.CloseDialog()
644 
645  def GetOptData(self, dcmd, layer, params, propwin):
646  """!Process decoration layer data"""
647  if dcmd:
648  self._overlay.cmd = dcmd
649  self._overlay.propwin = propwin
650  if params:
651  self.btnOK.Enable()
652  if self._ddstyle == DECOR_DIALOG_LEGEND and not self.parent.IsPaneShown('3d'):
653  self.resizeBtn.Enable()
654 
655 
656 class TextLayerDialog(wx.Dialog):
657  """
658  Controls setting options and displaying/hiding map overlay decorations
659  """
660 
661  def __init__(self, parent, ovlId, title, name = 'text',
662  pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_DIALOG_STYLE):
663 
664  wx.Dialog.__init__(self, parent, wx.ID_ANY, title, pos, size, style)
665  from wx.lib.expando import ExpandoTextCtrl, EVT_ETC_LAYOUT_NEEDED
666 
667  self.ovlId = ovlId
668  self.parent = parent
669 
670  if self.ovlId in self.parent.MapWindow.textdict.keys():
671  self.currText = self.parent.MapWindow.textdict[self.ovlId]['text']
672  self.currFont = self.parent.MapWindow.textdict[self.ovlId]['font']
673  self.currClr = self.parent.MapWindow.textdict[self.ovlId]['color']
674  self.currRot = self.parent.MapWindow.textdict[self.ovlId]['rotation']
675  self.currCoords = self.parent.MapWindow.textdict[self.ovlId]['coords']
676  self.currBB = self.parent.MapWindow.textdict[self.ovlId]['bbox']
677  else:
678  self.currClr = wx.BLACK
679  self.currText = ''
680  self.currFont = self.GetFont()
681  self.currRot = 0.0
682  self.currCoords = [10, 10, 10, 10]
683  self.currBB = wx.Rect()
684 
685  self.sizer = wx.BoxSizer(wx.VERTICAL)
686  box = wx.GridBagSizer(vgap = 5, hgap = 5)
687 
688  # show/hide
689  self.chkbox = wx.CheckBox(parent = self, id = wx.ID_ANY,
690  label = _('Show text object'))
691  if self.parent.Map.GetOverlay(self.ovlId) is None:
692  self.chkbox.SetValue(True)
693  else:
694  self.chkbox.SetValue(self.parent.MapWindow.overlays[self.ovlId]['layer'].IsActive())
695  box.Add(item = self.chkbox, span = (1,2),
696  flag = wx.ALIGN_LEFT|wx.ALL, border = 5,
697  pos = (0, 0))
698 
699  # text entry
700  label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Enter text:"))
701  box.Add(item = label,
702  flag = wx.ALIGN_CENTER_VERTICAL,
703  pos = (1, 0))
704 
705  self.textentry = ExpandoTextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (300,-1))
706  self.textentry.SetFont(self.currFont)
707  self.textentry.SetForegroundColour(self.currClr)
708  self.textentry.SetValue(self.currText)
709  # get rid of unneeded scrollbar when text box first opened
710  self.textentry.SetClientSize((300,-1))
711 
712  box.Add(item = self.textentry,
713  pos = (1, 1))
714 
715  # rotation
716  label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Rotation:"))
717  box.Add(item = label,
718  flag = wx.ALIGN_CENTER_VERTICAL,
719  pos = (2, 0))
720  self.rotation = wx.SpinCtrl(parent = self, id = wx.ID_ANY, value = "", pos = (30, 50),
721  size = (75,-1), style = wx.SP_ARROW_KEYS)
722  self.rotation.SetRange(-360, 360)
723  self.rotation.SetValue(int(self.currRot))
724  box.Add(item = self.rotation,
725  flag = wx.ALIGN_RIGHT,
726  pos = (2, 1))
727 
728  # font
729  fontbtn = wx.Button(parent = self, id = wx.ID_ANY, label = _("Set font"))
730  box.Add(item = fontbtn,
731  flag = wx.ALIGN_RIGHT,
732  pos = (3, 1))
733 
734  self.sizer.Add(item = box, proportion = 1,
735  flag = wx.ALL, border = 10)
736 
737  # note
738  box = wx.BoxSizer(wx.HORIZONTAL)
739  label = wx.StaticText(parent = self, id = wx.ID_ANY,
740  label = _("Drag text with mouse in pointer mode "
741  "to position.\nDouble-click to change options"))
742  box.Add(item = label, proportion = 0,
743  flag = wx.ALIGN_CENTRE | wx.ALL, border = 5)
744  self.sizer.Add(item = box, proportion = 0,
745  flag = wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER | wx.ALL, border = 5)
746 
747  line = wx.StaticLine(parent = self, id = wx.ID_ANY,
748  size = (20,-1), style = wx.LI_HORIZONTAL)
749  self.sizer.Add(item = line, proportion = 0,
750  flag = wx.EXPAND | wx.ALIGN_CENTRE | wx.ALL, border = 5)
751 
752  btnsizer = wx.StdDialogButtonSizer()
753 
754  btn = wx.Button(parent = self, id = wx.ID_OK)
755  btn.SetDefault()
756  btnsizer.AddButton(btn)
757 
758  btn = wx.Button(parent = self, id = wx.ID_CANCEL)
759  btnsizer.AddButton(btn)
760  btnsizer.Realize()
761 
762  self.sizer.Add(item = btnsizer, proportion = 0,
763  flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
764 
765  self.SetSizer(self.sizer)
766  self.sizer.Fit(self)
767 
768  # bindings
769  self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnRefit, self.textentry)
770  self.Bind(wx.EVT_BUTTON, self.OnSelectFont, fontbtn)
771  self.Bind(wx.EVT_TEXT, self.OnText, self.textentry)
772  self.Bind(wx.EVT_SPINCTRL, self.OnRotation, self.rotation)
773 
774  def OnRefit(self, event):
775  """!Resize text entry to match text"""
776  self.sizer.Fit(self)
777 
778  def OnText(self, event):
779  """!Change text string"""
780  self.currText = event.GetString()
781 
782  def OnRotation(self, event):
783  """!Change rotation"""
784  self.currRot = event.GetInt()
785 
786  event.Skip()
787 
788  def OnSelectFont(self, event):
789  """!Change font"""
790  data = wx.FontData()
791  data.EnableEffects(True)
792  data.SetColour(self.currClr) # set colour
793  data.SetInitialFont(self.currFont)
794 
795  dlg = wx.FontDialog(self, data)
796 
797  if dlg.ShowModal() == wx.ID_OK:
798  data = dlg.GetFontData()
799  self.currFont = data.GetChosenFont()
800  self.currClr = data.GetColour()
801 
802  self.textentry.SetFont(self.currFont)
803  self.textentry.SetForegroundColour(self.currClr)
804 
805  self.Layout()
806 
807  dlg.Destroy()
808 
809  def GetValues(self):
810  """!Get text properties"""
811  return { 'text' : self.currText,
812  'font' : self.currFont,
813  'color' : self.currClr,
814  'rotation' : self.currRot,
815  'coords' : self.currCoords,
816  'active' : self.chkbox.IsChecked() }
817 
818 class GroupDialog(wx.Dialog):
819  """!Dialog for creating/editing groups"""
820  def __init__(self, parent = None, defaultGroup = None,
821  title = _("Create or edit imagery groups"),
822  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
823 
824  wx.Dialog.__init__(self, parent = parent, id = wx.ID_ANY, title = title,
825  style = style, **kwargs)
826 
827  self.parent = parent
828  self.defaultGroup = defaultGroup
830  self.groupChanged = False
831 
833 
834  # buttons
835  btnOk = wx.Button(parent = self, id = wx.ID_OK)
836  btnApply = wx.Button(parent = self, id = wx.ID_APPLY)
837  btnClose = wx.Button(parent = self, id = wx.ID_CANCEL)
838 
839  btnOk.SetToolTipString(_("Apply changes to selected group and close dialog"))
840  btnApply.SetToolTipString(_("Apply changes to selected group"))
841  btnClose.SetToolTipString(_("Close dialog, changes are not applied"))
842 
843  btnOk.SetDefault()
844 
845  # sizers & do layout
846  # btnSizer = wx.BoxSizer(wx.HORIZONTAL)
847  # btnSizer.Add(item = btnClose, proportion = 0,
848  # flag = wx.RIGHT | wx.ALIGN_RIGHT | wx.EXPAND, border = 5)
849  # btnSizer.Add(item = btnApply, proportion = 0,
850  # flag = wx.LEFT, border = 5)
851  btnSizer = wx.StdDialogButtonSizer()
852  btnSizer.AddButton(btnOk)
853  btnSizer.AddButton(btnApply)
854  btnSizer.AddButton(btnClose)
855  btnSizer.Realize()
856 
857  mainSizer = wx.BoxSizer(wx.VERTICAL)
858  mainSizer.Add(item = self.bodySizer, proportion = 1,
859  flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 10)
860  mainSizer.Add(item = wx.StaticLine(parent = self, id = wx.ID_ANY,
861  style = wx.LI_HORIZONTAL), proportion = 0,
862  flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 10)
863 
864  mainSizer.Add(item = btnSizer, proportion = 0,
865  flag = wx.ALL | wx.ALIGN_RIGHT, border = 10)
866 
867  self.SetSizer(mainSizer)
868  mainSizer.Fit(self)
869 
870  btnOk.Bind(wx.EVT_BUTTON, self.OnOk)
871  btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
872  btnClose.Bind(wx.EVT_BUTTON, self.OnClose)
873 
874  # set dialog min size
875  self.SetMinSize(self.GetSize())
876 
877  def _createDialogBody(self):
878  bodySizer = wx.BoxSizer(wx.VERTICAL)
879 
880  # group selection
881  bodySizer.Add(item = wx.StaticText(parent = self, id = wx.ID_ANY,
882  label = _("Select the group you want to edit or "
883  "enter name of new group:")),
884  flag = wx.ALIGN_CENTER_VERTICAL | wx.TOP, border = 10)
885  self.groupSelect = Select(parent = self, type = 'group',
886  mapsets = [grass.gisenv()['MAPSET']],
887  size = globalvar.DIALOG_GSELECT_SIZE) # searchpath?
888 
889  bodySizer.Add(item = self.groupSelect, flag = wx.TOP | wx.EXPAND, border = 5)
890 
891  bodySizer.AddSpacer(10)
892  # layers in group
893  bodySizer.Add(item = wx.StaticText(parent = self, label = _("Layers in selected group:")),
894  flag = wx.ALIGN_CENTER_VERTICAL | wx.BOTTOM, border = 5)
895 
896  gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
897  gridSizer.AddGrowableCol(0)
898 
899  self.layerBox = wx.ListBox(parent = self, id = wx.ID_ANY, size = (-1, 150),
900  style = wx.LB_MULTIPLE | wx.LB_NEEDED_SB)
901 
902  gridSizer.Add(item = self.layerBox, pos = (0, 0), span = (2, 1), flag = wx.EXPAND)
903 
904  self.addLayer = wx.Button(self, id = wx.ID_ADD)
905  self.addLayer.SetToolTipString(_("Select map layers and add them to the list."))
906  gridSizer.Add(item = self.addLayer, pos = (0, 1), flag = wx.EXPAND)
907 
908  self.removeLayer = wx.Button(self, id = wx.ID_REMOVE)
909  self.removeLayer.SetToolTipString(_("Remove selected layer(s) from list."))
910  gridSizer.Add(item = self.removeLayer, pos = (1, 1))
911 
912  bodySizer.Add(item = gridSizer, proportion = 1, flag = wx.EXPAND)
913 
914  self.infoLabel = wx.StaticText(parent = self, id = wx.ID_ANY)
915  bodySizer.Add(item = self.infoLabel,
916  flag = wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.BOTTOM, border = 5)
917 
918  self.subGroup = wx.CheckBox(parent = self, id = wx.ID_ANY,
919  label = _("Define also sub-group (same name as group)"))
920  bodySizer.Add(item = self.subGroup, flag = wx.BOTTOM | wx.EXPAND, border = 5)
921 
922  # bindings
923  self.groupSelect.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnGroupSelected)
924  self.addLayer.Bind(wx.EVT_BUTTON, self.OnAddLayer)
925  self.removeLayer.Bind(wx.EVT_BUTTON, self.OnRemoveLayer)
926 
927  if self.defaultGroup:
928  self.groupSelect.SetValue(self.defaultGroup)
929 
930  return bodySizer
931 
932  def OnAddLayer(self, event):
933  """!Add new layer to listbox"""
934  dlg = MapLayersDialog(parent = self, title = _("Add selected map layers into group"),
935  mapType = 'raster', selectAll = False,
936  fullyQualified = True, showFullyQualified = False)
937  if dlg.ShowModal() != wx.ID_OK:
938  dlg.Destroy()
939  return
940 
941  layers = dlg.GetMapLayers()
942  for layer in layers:
943  if layer not in self.GetLayers():
944  self.layerBox.Append(layer)
945  self.groupChanged = True
946 
947 
948  def OnRemoveLayer(self, event):
949  """!Remove layer from listbox"""
950  while self.layerBox.GetSelections():
951  sel = self.layerBox.GetSelections()[0]
952  self.layerBox.Delete(sel)
953  self.groupChanged = True
954 
955  def GetLayers(self):
956  """!Get layers"""
957  return self.layerBox.GetItems()
958 
959  def OnGroupSelected(self, event):
960  """!Text changed in group selector"""
961  # callAfter must be called to close popup before other actions
962  wx.CallAfter(self.GroupSelected)
963 
964  def GroupSelected(self):
965  """!Group was selected, check if changes were apllied"""
966  group = self.GetSelectedGroup()
967  if self.groupChanged:
968  dlg = wx.MessageDialog(self, message = _("Group <%s> was changed, "
969  "do you want to apply changes?") % self.currentGroup,
970  caption = _("Unapplied changes"),
971  style = wx.YES_NO | wx.ICON_QUESTION | wx.YES_DEFAULT)
972  if dlg.ShowModal() == wx.ID_YES:
973  self.ApplyChanges(showResult = True)
974 
975  dlg.Destroy()
976 
977 
978 
979  groups = self.GetExistGroups()
980  if group in groups:
981  self.ShowGroupLayers(self.GetGroupLayers(group))
982 
983  self.currentGroup = group
984  self.groupChanged = False
985 
986  self.ClearNotification()
987 
988  def ShowGroupLayers(self, mapList):
989  """!Show map layers in currently selected group"""
990  self.layerBox.Set(mapList)
991 
992 
993  def EditGroup(self, group):
994  """!Edit selected group"""
995  layersNew = self.GetLayers()
996  layersOld = self.GetGroupLayers(group)
997 
998  add = []
999  remove = []
1000  for layerNew in layersNew:
1001  if layerNew not in layersOld:
1002  add.append(layerNew)
1003 
1004  for layerOld in layersOld:
1005  if layerOld not in layersNew:
1006  remove.append(layerOld)
1007 
1008  kwargs = {}
1009  if self.subGroup.IsChecked():
1010  kwargs['subgroup'] = group
1011 
1012  ret = None
1013  if remove:
1014  ret = RunCommand('i.group',
1015  parent = self,
1016  group = group,
1017  flags = 'r',
1018  input = ','.join(remove),
1019  **kwargs)
1020 
1021  if add:
1022  ret = RunCommand('i.group',
1023  parent = self,
1024  group = group,
1025  input = ','.join(add),
1026  **kwargs)
1027 
1028  return ret
1029 
1030  def CreateNewGroup(self, group):
1031  """!Create new group"""
1032  layers = self.GetLayers()
1033 
1034  kwargs = {}
1035  if self.subGroup.IsChecked():
1036  kwargs['subgroup'] = group
1037 
1038  return RunCommand('i.group',
1039  parent = self,
1040  group = group,
1041  input = layers,
1042  **kwargs)
1043 
1044  def GetExistGroups(self):
1045  """!Returns existing groups in current mapset"""
1046  return grass.list_grouped('group')[grass.gisenv()['MAPSET']]
1047 
1048  def ShowResult(self, group, returnCode, create):
1049  """!Show if operation was successfull."""
1050  group += '@' + grass.gisenv()['MAPSET']
1051  if returnCode is None:
1052  label = _("No changes to apply in group <%s>.") % group
1053  elif returnCode == 0:
1054  if create:
1055  label = _("Group <%s> was successfully created.") % group
1056  else:
1057  label = _("Group <%s> was successfully changed.") % group
1058  else:
1059  if create:
1060  label = _("Creating of new group <%s> failed.") % group
1061  else:
1062  label = _("Changing of group <%s> failed.") % group
1063 
1064  self.infoLabel.SetLabel(label)
1065  wx.FutureCall(4000, self.ClearNotification)
1066 
1067  def GetSelectedGroup(self):
1068  """!Return currently selected group (without mapset)"""
1069  return self.groupSelect.GetValue().split('@')[0]
1070 
1071  def GetGroupLayers(self, group):
1072  """!Get layers in group"""
1073  res = RunCommand('i.group',
1074  parent = self,
1075  flags = 'g',
1076  group = group,
1077  read = True).strip()
1078  if res.split('\n')[0]:
1079  return res.split('\n')
1080  return []
1081 
1083  """!Clear notification string"""
1084  self.infoLabel.SetLabel("")
1085 
1086  def ApplyChanges(self, showResult):
1087  """!Create or edit group"""
1088  group = self.currentGroup
1089  if not group:
1090  GMessage(parent = self,
1091  message = _("No group selected."))
1092  return False
1093 
1094  groups = self.GetExistGroups()
1095  if group in groups:
1096  ret = self.EditGroup(group)
1097  self.ShowResult(group = group, returnCode = ret, create = False)
1098 
1099  else:
1100  ret = self.CreateNewGroup(group)
1101  self.ShowResult(group = group, returnCode = ret, create = True)
1102 
1103  self.groupChanged = False
1104 
1105  return True
1106 
1107  def OnApply(self, event):
1108  """!Apply changes"""
1109  self.ApplyChanges(showResult = True)
1110 
1111  def OnOk(self, event):
1112  """!Apply changes and close dialog"""
1113  if self.ApplyChanges(showResult = False):
1114  self.OnClose(event)
1115 
1116  def OnClose(self, event):
1117  """!Close dialog"""
1118  if not self.IsModal():
1119  self.Destroy()
1120  event.Skip()
1121 
1122 class MapLayersDialog(wx.Dialog):
1123  def __init__(self, parent, title, modeler = False,
1124  mapType = None, selectAll = True, fullyQualified = True, showFullyQualified = True,
1125  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
1126  """!Dialog for selecting map layers (raster, vector)
1127 
1128  Valid mapType values:
1129  - raster
1130  - raster3d
1131  - vector
1132 
1133  @param mapType type of map (if None: raster, vector, 3d raster, if one only: selects it and disables selection)
1134  @param selectAll all/none maps should be selected by default
1135  @param fullyQualified True if dialog should return full map names by default
1136  @param showFullyQualified True to show 'fullyQualified' checkbox, otherwise hide it
1137  """
1138  wx.Dialog.__init__(self, parent = parent, id = wx.ID_ANY, title = title,
1139  style = style, **kwargs)
1140 
1141  self.parent = parent # GMFrame or ?
1142  self.mapType = mapType
1143  self.selectAll = selectAll
1144 
1145  # dialog body
1147  # update list of layer to be loaded
1148  self.map_layers = [] # list of map layers (full list type/mapset)
1149  self.LoadMapLayers(self.GetLayerType(cmd = True),
1150  self.mapset.GetStringSelection())
1151 
1152  self.fullyQualified = wx.CheckBox(parent = self, id = wx.ID_ANY,
1153  label = _("Use fully-qualified map names"))
1154  self.fullyQualified.SetValue(fullyQualified)
1155  self.fullyQualified.Show(showFullyQualified)
1156 
1157  self.dseries = None
1158  if modeler:
1159  self.dseries = wx.CheckBox(parent = self, id = wx.ID_ANY,
1160  label = _("Dynamic series (%s)") % 'g.mlist')
1161  self.dseries.SetValue(False)
1162 
1163  # buttons
1164  btnCancel = wx.Button(parent = self, id = wx.ID_CANCEL)
1165  btnOk = wx.Button(parent = self, id = wx.ID_OK)
1166  btnOk.SetDefault()
1167 
1168  # sizers & do layout
1169  btnSizer = wx.StdDialogButtonSizer()
1170  btnSizer.AddButton(btnCancel)
1171  btnSizer.AddButton(btnOk)
1172  btnSizer.Realize()
1173 
1174  mainSizer = wx.BoxSizer(wx.VERTICAL)
1175  mainSizer.Add(item = self.bodySizer, proportion = 1,
1176  flag = wx.EXPAND | wx.ALL, border = 5)
1177  mainSizer.Add(item = self.fullyQualified, proportion = 0,
1178  flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 5)
1179  if self.dseries:
1180  mainSizer.Add(item = self.dseries, proportion = 0,
1181  flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 5)
1182 
1183  mainSizer.Add(item = btnSizer, proportion = 0,
1184  flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
1185 
1186  self.SetSizer(mainSizer)
1187  mainSizer.Fit(self)
1188 
1189  # set dialog min size
1190  self.SetMinSize(self.GetSize())
1191 
1192  def _createDialogBody(self):
1193  bodySizer = wx.GridBagSizer(vgap = 3, hgap = 3)
1194 
1195  # layer type
1196  bodySizer.Add(item = wx.StaticText(parent = self, label = _("Map type:")),
1197  flag = wx.ALIGN_CENTER_VERTICAL,
1198  pos = (0,0))
1199 
1200  self.layerType = wx.Choice(parent = self, id = wx.ID_ANY,
1201  choices = [_('raster'), _('3D raster'), _('vector')], size = (100,-1))
1202 
1203  if self.mapType:
1204  if self.mapType == 'raster':
1205  self.layerType.SetSelection(0)
1206  elif self.mapType == 'raster3d':
1207  self.layerType.SetSelection(1)
1208  elif self.mapType == 'vector':
1209  self.layerType.SetSelection(2)
1210  self.layerType.Disable()
1211  else:
1212  self.layerType.SetSelection(0)
1213 
1214  bodySizer.Add(item = self.layerType,
1215  pos = (0,1))
1216 
1217  # select toggle
1218  self.toggle = wx.CheckBox(parent = self, id = wx.ID_ANY,
1219  label = _("Select toggle"))
1220  self.toggle.SetValue(self.selectAll)
1221  bodySizer.Add(item = self.toggle,
1222  flag = wx.ALIGN_CENTER_VERTICAL,
1223  pos = (0,2))
1224 
1225  # mapset filter
1226  bodySizer.Add(item = wx.StaticText(parent = self, label = _("Mapset:")),
1227  flag = wx.ALIGN_CENTER_VERTICAL,
1228  pos = (1,0))
1229 
1230  self.mapset = MapsetSelect(parent = self, searchPath = True)
1231  self.mapset.SetStringSelection(grass.gisenv()['MAPSET'])
1232  bodySizer.Add(item = self.mapset,
1233  pos = (1,1), span = (1, 2))
1234 
1235  # map name filter
1236  bodySizer.Add(item = wx.StaticText(parent = self, label = _("Pattern:")),
1237  flag = wx.ALIGN_CENTER_VERTICAL,
1238  pos = (2,0))
1239 
1240  self.filter = wx.TextCtrl(parent = self, id = wx.ID_ANY,
1241  value = "",
1242  size = (250,-1))
1243  bodySizer.Add(item = self.filter,
1244  flag = wx.EXPAND,
1245  pos = (2,1), span = (1, 2))
1246 
1247  # layer list
1248  bodySizer.Add(item = wx.StaticText(parent = self, label = _("List of maps:")),
1249  flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_TOP,
1250  pos = (3,0))
1251  self.layers = wx.CheckListBox(parent = self, id = wx.ID_ANY,
1252  size = (250, 100),
1253  choices = [])
1254  bodySizer.Add(item = self.layers,
1255  flag = wx.EXPAND,
1256  pos = (3,1), span = (1, 2))
1257 
1258  bodySizer.AddGrowableCol(1)
1259  bodySizer.AddGrowableRow(3)
1260  # bindings
1261  self.layerType.Bind(wx.EVT_CHOICE, self.OnChangeParams)
1262  self.mapset.Bind(wx.EVT_COMBOBOX, self.OnChangeParams)
1263  self.layers.Bind(wx.EVT_RIGHT_DOWN, self.OnMenu)
1264  self.filter.Bind(wx.EVT_TEXT, self.OnFilter)
1265  self.toggle.Bind(wx.EVT_CHECKBOX, self.OnToggle)
1266 
1267  return bodySizer
1268 
1269  def LoadMapLayers(self, type, mapset):
1270  """!Load list of map layers
1271 
1272  @param type layer type ('raster' or 'vector')
1273  @param mapset mapset name
1274  """
1275  self.map_layers = grass.mlist_grouped(type = type)[mapset]
1276  self.layers.Set(self.map_layers)
1277 
1278  # check all items by default
1279  for item in range(self.layers.GetCount()):
1280 
1281  self.layers.Check(item, check = self.selectAll)
1282 
1283  def OnChangeParams(self, event):
1284  """!Filter parameters changed by user"""
1285  # update list of layer to be loaded
1286  self.LoadMapLayers(self.GetLayerType(cmd = True),
1287  self.mapset.GetStringSelection())
1288 
1289  event.Skip()
1290 
1291  def OnMenu(self, event):
1292  """!Table description area, context menu"""
1293  if not hasattr(self, "popupID1"):
1294  self.popupDataID1 = wx.NewId()
1295  self.popupDataID2 = wx.NewId()
1296  self.popupDataID3 = wx.NewId()
1297 
1298  self.Bind(wx.EVT_MENU, self.OnSelectAll, id = self.popupDataID1)
1299  self.Bind(wx.EVT_MENU, self.OnSelectInvert, id = self.popupDataID2)
1300  self.Bind(wx.EVT_MENU, self.OnDeselectAll, id = self.popupDataID3)
1301 
1302  # generate popup-menu
1303  menu = wx.Menu()
1304  menu.Append(self.popupDataID1, _("Select all"))
1305  menu.Append(self.popupDataID2, _("Invert selection"))
1306  menu.Append(self.popupDataID3, _("Deselect all"))
1307 
1308  self.PopupMenu(menu)
1309  menu.Destroy()
1310 
1311  def OnSelectAll(self, event):
1312  """!Select all map layer from list"""
1313  for item in range(self.layers.GetCount()):
1314  self.layers.Check(item, True)
1315 
1316  def OnSelectInvert(self, event):
1317  """!Invert current selection"""
1318  for item in range(self.layers.GetCount()):
1319  if self.layers.IsChecked(item):
1320  self.layers.Check(item, False)
1321  else:
1322  self.layers.Check(item, True)
1323 
1324  def OnDeselectAll(self, event):
1325  """!Select all map layer from list"""
1326  for item in range(self.layers.GetCount()):
1327  self.layers.Check(item, False)
1328 
1329  def OnFilter(self, event):
1330  """!Apply filter for map names"""
1331  if len(event.GetString()) == 0:
1332  self.layers.Set(self.map_layers)
1333  return
1334 
1335  list = []
1336  for layer in self.map_layers:
1337  try:
1338  if re.compile('^' + event.GetString()).search(layer):
1339  list.append(layer)
1340  except:
1341  pass
1342 
1343  self.layers.Set(list)
1344  self.OnSelectAll(None)
1345 
1346  event.Skip()
1347 
1348  def OnToggle(self, event):
1349  """!Select toggle (check or uncheck all layers)"""
1350  check = event.Checked()
1351  for item in range(self.layers.GetCount()):
1352  self.layers.Check(item, check)
1353 
1354  event.Skip()
1355 
1356  def GetMapLayers(self):
1357  """!Return list of checked map layers"""
1358  layerNames = []
1359  for indx in self.layers.GetSelections():
1360  # layers.append(self.layers.GetStringSelec(indx))
1361  pass
1362 
1363  fullyQualified = self.fullyQualified.IsChecked()
1364  mapset = self.mapset.GetStringSelection()
1365  for item in range(self.layers.GetCount()):
1366  if not self.layers.IsChecked(item):
1367  continue
1368  if fullyQualified:
1369  layerNames.append(self.layers.GetString(item) + '@' + mapset)
1370  else:
1371  layerNames.append(self.layers.GetString(item))
1372 
1373  return layerNames
1374 
1375  def GetLayerType(self, cmd = False):
1376  """!Get selected layer type
1377 
1378  @param cmd True for g.mlist
1379  """
1380  if not cmd:
1381  return self.layerType.GetStringSelection()
1382 
1383  sel = self.layerType.GetSelection()
1384  if sel == 0:
1385  ltype = 'rast'
1386  elif sel == 1:
1387  ltype = 'rast3d'
1388  else:
1389  ltype = 'vect'
1390 
1391  return ltype
1392 
1393  def GetDSeries(self):
1394  """!Used by modeler only
1395 
1396  @return g.mlist command
1397  """
1398  if not self.dseries or not self.dseries.IsChecked():
1399  return ''
1400 
1401  cond = 'map in `g.mlist type=%s ' % self.GetLayerType(cmd = True)
1402  patt = self.filter.GetValue()
1403  if patt:
1404  cond += 'pattern=%s ' % patt
1405  cond += 'mapset=%s`' % self.mapset.GetStringSelection()
1406 
1407  return cond
1408 
1409 class ImportDialog(wx.Dialog):
1410  """!Dialog for bulk import of various data (base class)"""
1411  def __init__(self, parent, itype,
1412  id = wx.ID_ANY, title = _("Multiple import"),
1413  style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
1414  self.parent = parent # GMFrame
1415  self.importType = itype
1416  self.options = dict() # list of options
1417 
1418  self.commandId = -1 # id of running command
1419 
1420  wx.Dialog.__init__(self, parent, id, title, style = style,
1421  name = "MultiImportDialog")
1422 
1423  self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
1424 
1425  self.layerBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
1426  label = _(" List of %s layers ") % self.importType.upper())
1427 
1428  #
1429  # list of layers
1430  #
1431  columns = [_('Layer id'),
1432  _('Layer name'),
1433  _('Name for GRASS map (editable)')]
1434  self.list = LayersList(parent = self.panel, columns = columns)
1435  self.list.LoadData()
1436 
1437  self.optionBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
1438  label = "%s" % _("Options"))
1439 
1440  cmd = self._getCommand()
1441  task = gtask.parse_interface(cmd)
1442  for f in task.get_options()['flags']:
1443  name = f.get('name', '')
1444  desc = f.get('label', '')
1445  if not desc:
1446  desc = f.get('description', '')
1447  if not name and not desc:
1448  continue
1449  if cmd == 'r.in.gdal' and name not in ('o', 'e', 'l', 'k'):
1450  continue
1451  elif cmd == 'r.external' and name not in ('o', 'e', 'r', 'h', 'v'):
1452  continue
1453  elif cmd == 'v.in.ogr' and name not in ('c', 'z', 't', 'o', 'r', 'e', 'w'):
1454  continue
1455  elif cmd == 'v.external' and name not in ('b'):
1456  continue
1457  elif cmd == 'v.in.dxf' and name not in ('e', 't', 'b', 'f', 'i'):
1458  continue
1459  self.options[name] = wx.CheckBox(parent = self.panel, id = wx.ID_ANY,
1460  label = desc)
1461 
1462  if not self.options:
1463  self.optionBox.Hide()
1464 
1465  self.overwrite = wx.CheckBox(parent = self.panel, id = wx.ID_ANY,
1466  label = _("Allow output files to overwrite existing files"))
1467  self.overwrite.SetValue(UserSettings.Get(group = 'cmd', key = 'overwrite', subkey = 'enabled'))
1468 
1469  self.add = wx.CheckBox(parent = self.panel, id = wx.ID_ANY)
1470  self.closeOnFinish = wx.CheckBox(parent = self.panel, id = wx.ID_ANY,
1471  label = _("Close dialog on finish"))
1472  self.closeOnFinish.SetValue(UserSettings.Get(group = 'cmd', key = 'closeDlg', subkey = 'enabled'))
1473 
1474  #
1475  # buttons
1476  #
1477  # cancel
1478  self.btn_close = wx.Button(parent = self.panel, id = wx.ID_CLOSE)
1479  self.btn_close.SetToolTipString(_("Close dialog"))
1480  self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose)
1481  # run
1482  self.btn_run = wx.Button(parent = self.panel, id = wx.ID_OK, label = _("&Import"))
1483  self.btn_run.SetToolTipString(_("Import selected layers"))
1484  self.btn_run.SetDefault()
1485  self.btn_run.Enable(False)
1486  self.btn_run.Bind(wx.EVT_BUTTON, self.OnRun)
1487  # run command dialog
1488  self.btn_cmd = wx.Button(parent = self.panel, id = wx.ID_ANY,
1489  label = _("Command dialog"))
1490  self.btn_cmd.Bind(wx.EVT_BUTTON, self.OnCmdDialog)
1491 
1492  def doLayout(self):
1493  """!Do layout"""
1494  dialogSizer = wx.BoxSizer(wx.VERTICAL)
1495 
1496  # dsn input
1497  dialogSizer.Add(item = self.dsnInput, proportion = 0,
1498  flag = wx.EXPAND)
1499 
1500  #
1501  # list of DXF layers
1502  #
1503  layerSizer = wx.StaticBoxSizer(self.layerBox, wx.HORIZONTAL)
1504 
1505  layerSizer.Add(item = self.list, proportion = 1,
1506  flag = wx.ALL | wx.EXPAND, border = 5)
1507 
1508  dialogSizer.Add(item = layerSizer, proportion = 1,
1509  flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 5)
1510 
1511  # options
1512  if self.optionBox.IsShown():
1513  optionSizer = wx.StaticBoxSizer(self.optionBox, wx.VERTICAL)
1514  for key in self.options.keys():
1515  optionSizer.Add(item = self.options[key], proportion = 0)
1516 
1517  dialogSizer.Add(item = optionSizer, proportion = 0,
1518  flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 5)
1519 
1520  dialogSizer.Add(item = self.overwrite, proportion = 0,
1521  flag = wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 5)
1522 
1523  dialogSizer.Add(item = self.add, proportion = 0,
1524  flag = wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 5)
1525 
1526  dialogSizer.Add(item = self.closeOnFinish, proportion = 0,
1527  flag = wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 5)
1528  #
1529  # buttons
1530  #
1531  btnsizer = wx.BoxSizer(orient = wx.HORIZONTAL)
1532 
1533  btnsizer.Add(item = self.btn_cmd, proportion = 0,
1534  flag = wx.RIGHT | wx.ALIGN_CENTER,
1535  border = 10)
1536 
1537  btnsizer.Add(item = self.btn_close, proportion = 0,
1538  flag = wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER,
1539  border = 10)
1540 
1541  btnsizer.Add(item = self.btn_run, proportion = 0,
1542  flag = wx.RIGHT | wx.ALIGN_CENTER,
1543  border = 10)
1544 
1545  dialogSizer.Add(item = btnsizer, proportion = 0,
1546  flag = wx.ALIGN_CENTER_VERTICAL | wx.BOTTOM | wx.ALIGN_RIGHT,
1547  border = 10)
1548 
1549  # dialogSizer.SetSizeHints(self.panel)
1550  self.panel.SetAutoLayout(True)
1551  self.panel.SetSizer(dialogSizer)
1552  dialogSizer.Fit(self.panel)
1553 
1554  # auto-layout seems not work here - FIXME
1555  size = wx.Size(globalvar.DIALOG_GSELECT_SIZE[0] + 225, 550)
1556  self.SetMinSize(size)
1557  self.SetSize((size.width, size.height + 100))
1558  # width = self.GetSize()[0]
1559  # self.list.SetColumnWidth(col = 1, width = width / 2 - 50)
1560  self.Layout()
1561 
1562  def _getCommand(self):
1563  """!Get command"""
1564  return ''
1565 
1566  def OnClose(self, event = None):
1567  """!Close dialog"""
1568  self.Close()
1569 
1570  def OnRun(self, event):
1571  """!Import/Link data (each layes as separate vector map)"""
1572  pass
1573 
1574  def OnCmdDialog(self, event):
1575  """!Show command dialog"""
1576  pass
1577 
1578  def AddLayers(self, returncode, cmd = None):
1579  """!Add imported/linked layers into layer tree"""
1580  if not self.add.IsChecked() or returncode != 0:
1581  return
1582 
1583  self.commandId += 1
1584  maptree = self.parent.curr_page.maptree
1585 
1586  layer, output = self.list.GetLayers()[self.commandId]
1587 
1588  if '@' not in output:
1589  name = output + '@' + grass.gisenv()['MAPSET']
1590  else:
1591  name = output
1592 
1593  # add imported layers into layer tree
1594  if self.importType == 'gdal':
1595  cmd = ['d.rast',
1596  'map=%s' % name]
1597  if UserSettings.Get(group = 'cmd', key = 'rasterOverlay', subkey = 'enabled'):
1598  cmd.append('-o')
1599 
1600  item = maptree.AddLayer(ltype = 'raster',
1601  lname = name, lchecked = False,
1602  lcmd = cmd, multiple = False)
1603  else:
1604  item = maptree.AddLayer(ltype = 'vector',
1605  lname = name, lchecked = False,
1606  lcmd = ['d.vect',
1607  'map=%s' % name],
1608  multiple = False)
1609 
1610  maptree.mapdisplay.MapWindow.ZoomToMap()
1611 
1612  def OnAbort(self, event):
1613  """!Abort running import
1614 
1615  @todo not yet implemented
1616  """
1617  pass
1618 
1619 class GdalImportDialog(ImportDialog):
1620  def __init__(self, parent, ogr = False, link = False):
1621  """!Dialog for bulk import of various raster/vector data
1622 
1623  @param parent parent window
1624  @param ogr True for OGR (vector) otherwise GDAL (raster)
1625  @param link True for linking data otherwise importing data
1626  """
1627  self.link = link
1628  self.ogr = ogr
1629 
1630  if ogr:
1631  ImportDialog.__init__(self, parent, itype = 'ogr')
1632  if link:
1633  self.SetTitle(_("Link external vector data"))
1634  else:
1635  self.SetTitle(_("Import vector data"))
1636  else:
1637  ImportDialog.__init__(self, parent, itype = 'gdal')
1638  if link:
1639  self.SetTitle(_("Link external raster data"))
1640  else:
1641  self.SetTitle(_("Import raster data"))
1642 
1643  self.dsnInput = GdalSelect(parent = self, panel = self.panel,
1644  ogr = ogr, link = link)
1645 
1646  if link:
1647  self.add.SetLabel(_("Add linked layers into layer tree"))
1648  else:
1649  self.add.SetLabel(_("Add imported layers into layer tree"))
1650 
1651  self.add.SetValue(UserSettings.Get(group = 'cmd', key = 'addNewLayer', subkey = 'enabled'))
1652 
1653  if link:
1654  self.btn_run.SetLabel(_("&Link"))
1655  self.btn_run.SetToolTipString(_("Link selected layers"))
1656  if ogr:
1657  self.btn_cmd.SetToolTipString(_('Open %s dialog') % 'v.external')
1658  else:
1659  self.btn_cmd.SetToolTipString(_('Open %s dialog') % 'r.external')
1660  else:
1661  self.btn_run.SetLabel(_("&Import"))
1662  self.btn_run.SetToolTipString(_("Import selected layers"))
1663  if ogr:
1664  self.btn_cmd.SetToolTipString(_('Open %s dialog') % 'v.in.ogr')
1665  else:
1666  self.btn_cmd.SetToolTipString(_('Open %s dialog') % 'r.in.gdal')
1667 
1668  self.doLayout()
1669 
1670  def OnRun(self, event):
1671  """!Import/Link data (each layes as separate vector map)"""
1672  self.commandId = -1
1673  data = self.list.GetLayers()
1674  if not data:
1675  GMessage(_("No layers selected. Operation canceled."),
1676  parent = self)
1677  return
1678 
1679  dsn = self.dsnInput.GetDsn()
1680  ext = self.dsnInput.GetFormatExt()
1681 
1682  # determine data driver for PostGIS links
1683  popOGR = False
1684  if self.importType == 'ogr' and \
1685  self.dsnInput.GetType() == 'db' and \
1686  self.dsnInput.GetFormat() == 'PostgreSQL' and \
1687  'GRASS_VECTOR_OGR' not in os.environ:
1688  popOGR = True
1689  os.environ['GRASS_VECTOR_OGR'] = '1'
1690 
1691  for layer, output in data:
1692  if self.importType == 'ogr':
1693  if ext and layer.rfind(ext) > -1:
1694  layer = layer.replace('.' + ext, '')
1695  if self.link:
1696  cmd = ['v.external',
1697  'dsn=%s' % dsn,
1698  'output=%s' % output,
1699  'layer=%s' % layer]
1700  else:
1701  cmd = ['v.in.ogr',
1702  'dsn=%s' % dsn,
1703  'layer=%s' % layer,
1704  'output=%s' % output]
1705  else: # gdal
1706  if self.dsnInput.GetType() == 'dir':
1707  idsn = os.path.join(dsn, layer)
1708  else:
1709  idsn = dsn
1710 
1711  if self.link:
1712  cmd = ['r.external',
1713  'input=%s' % idsn,
1714  'output=%s' % output]
1715  else:
1716  cmd = ['r.in.gdal',
1717  'input=%s' % idsn,
1718  'output=%s' % output]
1719 
1720  if self.overwrite.IsChecked():
1721  cmd.append('--overwrite')
1722 
1723  for key in self.options.keys():
1724  if self.options[key].IsChecked():
1725  cmd.append('-%s' % key)
1726 
1727  if UserSettings.Get(group = 'cmd', key = 'overwrite', subkey = 'enabled') and \
1728  '--overwrite' not in cmd:
1729  cmd.append('--overwrite')
1730 
1731  # run in Layer Manager
1732  self.parent.goutput.RunCmd(cmd, switchPage = True,
1733  onDone = self.AddLayers)
1734 
1735  if popOGR:
1736  os.environ.pop('GRASS_VECTOR_OGR')
1737 
1738  if self.closeOnFinish.IsChecked():
1739  self.Close()
1740 
1741  def _getCommand(self):
1742  """!Get command"""
1743  if self.link:
1744  if self.ogr:
1745  return 'v.external'
1746  else:
1747  return 'r.external'
1748  else:
1749  if self.ogr:
1750  return 'v.in.ogr'
1751  else:
1752  return 'r.in.gdal'
1753 
1754  return ''
1755 
1756  def OnCmdDialog(self, event):
1757  """!Show command dialog"""
1758  name = self._getCommand()
1759  GUI(parent = self, modal = False).ParseCommand(cmd = [name])
1760 
1762  """!Dialog for bulk import of DXF layers"""
1763  def __init__(self, parent):
1764  ImportDialog.__init__(self, parent, itype = 'dxf',
1765  title = _("Import DXF layers"))
1766 
1767  self.dsnInput = filebrowse.FileBrowseButton(parent = self.panel, id = wx.ID_ANY,
1768  size = globalvar.DIALOG_GSELECT_SIZE, labelText = '',
1769  dialogTitle = _('Choose DXF file to import'),
1770  buttonText = _('Browse'),
1771  startDirectory = os.getcwd(), fileMode = 0,
1772  changeCallback = self.OnSetDsn,
1773  fileMask = "DXF File (*.dxf)|*.dxf")
1774 
1775  self.add.SetLabel(_("Add imported layers into layer tree"))
1776 
1777  self.add.SetValue(UserSettings.Get(group = 'cmd', key = 'addNewLayer', subkey = 'enabled'))
1778 
1779  self.doLayout()
1780 
1781  def _getCommand(self):
1782  """!Get command"""
1783  return 'v.in.dxf'
1784 
1785  def OnRun(self, event):
1786  """!Import/Link data (each layes as separate vector map)"""
1787  data = self.list.GetLayers()
1788 
1789  # hide dialog
1790  self.Hide()
1791 
1792  inputDxf = self.dsnInput.GetValue()
1793 
1794  for layer, output in data:
1795  cmd = ['v.in.dxf',
1796  'input=%s' % inputDxf,
1797  'layers=%s' % layer,
1798  'output=%s' % output]
1799 
1800  for key in self.options.keys():
1801  if self.options[key].IsChecked():
1802  cmd.append('-%s' % key)
1803 
1804  if self.overwrite.IsChecked() or \
1805  UserSettings.Get(group = 'cmd', key = 'overwrite', subkey = 'enabled'):
1806  cmd.append('--overwrite')
1807 
1808  # run in Layer Manager
1809  self.parent.goutput.RunCmd(cmd, switchPage = True,
1810  onDone = self.AddLayers)
1811 
1812  self.OnCancel()
1813 
1814  def OnSetDsn(self, event):
1815  """!Input DXF file defined, update list of layer widget"""
1816  path = event.GetString()
1817  if not path:
1818  return
1819 
1820  data = list()
1821  ret = RunCommand('v.in.dxf',
1822  quiet = True,
1823  parent = self,
1824  read = True,
1825  flags = 'l',
1826  input = path)
1827  if not ret:
1828  self.list.LoadData()
1829  self.btn_run.Enable(False)
1830  return
1831 
1832  for line in ret.splitlines():
1833  layerId = line.split(':')[0].split(' ')[1]
1834  layerName = line.split(':')[1].strip()
1835  grassName = GetValidLayerName(layerName)
1836  data.append((layerId, layerName.strip(), grassName.strip()))
1837 
1838  self.list.LoadData(data)
1839  if len(data) > 0:
1840  self.btn_run.Enable(True)
1841  else:
1842  self.btn_run.Enable(False)
1843 
1844  def OnCmdDialog(self, event):
1845  """!Show command dialog"""
1846  GUI(parent = self, modal = True).ParseCommand(cmd = ['v.in.dxf'])
1847 
1848 class LayersList(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin,
1849  listmix.CheckListCtrlMixin, listmix.TextEditMixin):
1850  """!List of layers to be imported (dxf, shp...)"""
1851  def __init__(self, parent, columns, log = None):
1852  self.parent = parent
1853 
1854  wx.ListCtrl.__init__(self, parent, wx.ID_ANY,
1855  style = wx.LC_REPORT)
1856  listmix.CheckListCtrlMixin.__init__(self)
1857  self.log = log
1858 
1859  # setup mixins
1860  listmix.ListCtrlAutoWidthMixin.__init__(self)
1861  listmix.TextEditMixin.__init__(self)
1862 
1863  for i in range(len(columns)):
1864  self.InsertColumn(i, columns[i])
1865 
1866  if len(columns) == 3:
1867  width = (65, 200)
1868  else:
1869  width = (65, 180, 110)
1870 
1871  for i in range(len(width)):
1872  self.SetColumnWidth(col = i, width = width[i])
1873 
1874  self.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnPopupMenu) #wxMSW
1875  self.Bind(wx.EVT_RIGHT_UP, self.OnPopupMenu) #wxGTK
1876 
1877  def LoadData(self, data = None):
1878  """!Load data into list"""
1879  self.DeleteAllItems()
1880  if data is None:
1881  return
1882 
1883  for item in data:
1884  index = self.InsertStringItem(sys.maxint, str(item[0]))
1885  for i in range(1, len(item)):
1886  self.SetStringItem(index, i, "%s" % str(item[i]))
1887 
1888  # check by default only on one item
1889  if len(data) == 1:
1890  self.CheckItem(index, True)
1891 
1892  def OnPopupMenu(self, event):
1893  """!Show popup menu"""
1894  if self.GetItemCount() < 1:
1895  return
1896 
1897  if not hasattr(self, "popupDataID1"):
1898  self.popupDataID1 = wx.NewId()
1899  self.popupDataID2 = wx.NewId()
1900 
1901  self.Bind(wx.EVT_MENU, self.OnSelectAll, id = self.popupDataID1)
1902  self.Bind(wx.EVT_MENU, self.OnSelectNone, id = self.popupDataID2)
1903 
1904  # generate popup-menu
1905  menu = wx.Menu()
1906  menu.Append(self.popupDataID1, _("Select all"))
1907  menu.Append(self.popupDataID2, _("Deselect all"))
1908 
1909  self.PopupMenu(menu)
1910  menu.Destroy()
1911 
1912  def OnSelectAll(self, event):
1913  """!Select all items"""
1914  item = -1
1915 
1916  while True:
1917  item = self.GetNextItem(item)
1918  if item == -1:
1919  break
1920  self.CheckItem(item, True)
1921 
1922  event.Skip()
1923 
1924  def OnSelectNone(self, event):
1925  """!Deselect items"""
1926  item = -1
1927 
1928  while True:
1929  item = self.GetNextItem(item, wx.LIST_STATE_SELECTED)
1930  if item == -1:
1931  break
1932  self.CheckItem(item, False)
1933 
1934  event.Skip()
1935 
1936  def OnLeftDown(self, event):
1937  """!Allow editing only output name
1938 
1939  Code taken from TextEditMixin class.
1940  """
1941  x, y = event.GetPosition()
1942 
1943  colLocs = [0]
1944  loc = 0
1945  for n in range(self.GetColumnCount()):
1946  loc = loc + self.GetColumnWidth(n)
1947  colLocs.append(loc)
1948 
1949  col = bisect(colLocs, x + self.GetScrollPos(wx.HORIZONTAL)) - 1
1950 
1951  if col == self.GetColumnCount() - 1:
1952  listmix.TextEditMixin.OnLeftDown(self, event)
1953  else:
1954  event.Skip()
1955 
1956  def GetLayers(self):
1957  """!Get list of layers (layer name, output name)"""
1958  data = []
1959  item = -1
1960  while True:
1961  item = self.GetNextItem(item)
1962  if item == -1:
1963  break
1964  if not self.IsChecked(item):
1965  continue
1966  # layer / output name
1967  data.append((self.GetItem(item, 1).GetText(),
1968  self.GetItem(item, self.GetColumnCount() - 1).GetText()))
1969 
1970  return data
1971 
1972 class SetOpacityDialog(wx.Dialog):
1973  """!Set opacity of map layers"""
1974  def __init__(self, parent, id = wx.ID_ANY, title = _("Set Map Layer Opacity"),
1975  size = wx.DefaultSize, pos = wx.DefaultPosition,
1976  style = wx.DEFAULT_DIALOG_STYLE, opacity = 100):
1977 
1978  self.parent = parent # GMFrame
1979  self.opacity = opacity # current opacity
1980 
1981  super(SetOpacityDialog, self).__init__(parent, id = id, pos = pos,
1982  size = size, style = style, title = title)
1983 
1984  panel = wx.Panel(parent = self, id = wx.ID_ANY)
1985 
1986  sizer = wx.BoxSizer(wx.VERTICAL)
1987 
1988  box = wx.GridBagSizer(vgap = 5, hgap = 5)
1989  self.value = wx.Slider(panel, id = wx.ID_ANY, value = self.opacity,
1990  style = wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | \
1991  wx.SL_TOP | wx.SL_LABELS,
1992  minValue = 0, maxValue = 100,
1993  size = (350, -1))
1994 
1995  box.Add(item = self.value,
1996  flag = wx.ALIGN_CENTRE, pos = (0, 0), span = (1, 2))
1997  box.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1998  label = _("transparent")),
1999  pos = (1, 0))
2000  box.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
2001  label = _("opaque")),
2002  flag = wx.ALIGN_RIGHT,
2003  pos = (1, 1))
2004 
2005  sizer.Add(item = box, proportion = 0,
2006  flag = wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border = 5)
2007 
2008  line = wx.StaticLine(parent = panel, id = wx.ID_ANY,
2009  style = wx.LI_HORIZONTAL)
2010  sizer.Add(item = line, proportion = 0,
2011  flag = wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border = 5)
2012 
2013  # buttons
2014  btnsizer = wx.StdDialogButtonSizer()
2015 
2016  btnOK = wx.Button(parent = panel, id = wx.ID_OK)
2017  btnOK.SetDefault()
2018  btnsizer.AddButton(btnOK)
2019 
2020  btnCancel = wx.Button(parent = panel, id = wx.ID_CANCEL)
2021  btnsizer.AddButton(btnCancel)
2022 
2023  btnApply = wx.Button(parent = panel, id = wx.ID_APPLY)
2024  btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
2025  btnsizer.AddButton(btnApply)
2026  btnsizer.Realize()
2027 
2028  sizer.Add(item = btnsizer, proportion = 0,
2029  flag = wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border = 5)
2030 
2031  panel.SetSizer(sizer)
2032  sizer.Fit(panel)
2033 
2034  self.SetSize(self.GetBestSize())
2035 
2036  self.Layout()
2037 
2038  def GetOpacity(self):
2039  """!Button 'OK' pressed"""
2040  # return opacity value
2041  opacity = float(self.value.GetValue()) / 100
2042  return opacity
2043 
2044  def OnApply(self, event):
2045  event = wxApplyOpacity(value = self.GetOpacity())
2046  wx.PostEvent(self, event)
2047 
2048 def GetImageHandlers(image):
2049  """!Get list of supported image handlers"""
2050  lext = list()
2051  ltype = list()
2052  for h in image.GetHandlers():
2053  lext.append(h.GetExtension())
2054 
2055  filetype = ''
2056  if 'png' in lext:
2057  filetype += "PNG file (*.png)|*.png|"
2058  ltype.append({ 'type' : wx.BITMAP_TYPE_PNG,
2059  'ext' : 'png' })
2060  filetype += "BMP file (*.bmp)|*.bmp|"
2061  ltype.append({ 'type' : wx.BITMAP_TYPE_BMP,
2062  'ext' : 'bmp' })
2063  if 'gif' in lext:
2064  filetype += "GIF file (*.gif)|*.gif|"
2065  ltype.append({ 'type' : wx.BITMAP_TYPE_GIF,
2066  'ext' : 'gif' })
2067 
2068  if 'jpg' in lext:
2069  filetype += "JPG file (*.jpg)|*.jpg|"
2070  ltype.append({ 'type' : wx.BITMAP_TYPE_JPEG,
2071  'ext' : 'jpg' })
2072 
2073  if 'pcx' in lext:
2074  filetype += "PCX file (*.pcx)|*.pcx|"
2075  ltype.append({ 'type' : wx.BITMAP_TYPE_PCX,
2076  'ext' : 'pcx' })
2077 
2078  if 'pnm' in lext:
2079  filetype += "PNM file (*.pnm)|*.pnm|"
2080  ltype.append({ 'type' : wx.BITMAP_TYPE_PNM,
2081  'ext' : 'pnm' })
2082 
2083  if 'tif' in lext:
2084  filetype += "TIF file (*.tif)|*.tif|"
2085  ltype.append({ 'type' : wx.BITMAP_TYPE_TIF,
2086  'ext' : 'tif' })
2087 
2088  if 'xpm' in lext:
2089  filetype += "XPM file (*.xpm)|*.xpm"
2090  ltype.append({ 'type' : wx.BITMAP_TYPE_XPM,
2091  'ext' : 'xpm' })
2092 
2093  return filetype, ltype
2094 
2095 class ImageSizeDialog(wx.Dialog):
2096  """!Set size for saved graphic file"""
2097  def __init__(self, parent, id = wx.ID_ANY, title = _("Set image size"),
2098  style = wx.DEFAULT_DIALOG_STYLE, **kwargs):
2099  self.parent = parent
2100 
2101  wx.Dialog.__init__(self, parent, id = id, style = style, title = title, **kwargs)
2102 
2103  self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
2104 
2105  self.box = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
2106  label = ' % s' % _("Image size"))
2107 
2108  size = self.parent.GetWindow().GetClientSize()
2109  self.width = wx.SpinCtrl(parent = self.panel, id = wx.ID_ANY,
2110  style = wx.SP_ARROW_KEYS)
2111  self.width.SetRange(20, 1e6)
2112  self.width.SetValue(size.width)
2113  wx.CallAfter(self.width.SetFocus)
2114  self.height = wx.SpinCtrl(parent = self.panel, id = wx.ID_ANY,
2115  style = wx.SP_ARROW_KEYS)
2116  self.height.SetRange(20, 1e6)
2117  self.height.SetValue(size.height)
2118  self.template = wx.Choice(parent = self.panel, id = wx.ID_ANY,
2119  size = (125, -1),
2120  choices = [ "",
2121  "640x480",
2122  "800x600",
2123  "1024x768",
2124  "1280x960",
2125  "1600x1200",
2126  "1920x1440" ])
2127 
2128  self.btnOK = wx.Button(parent = self.panel, id = wx.ID_OK)
2129  self.btnOK.SetDefault()
2130  self.btnCancel = wx.Button(parent = self.panel, id = wx.ID_CANCEL)
2131 
2132  self.template.Bind(wx.EVT_CHOICE, self.OnTemplate)
2133 
2134  self._layout()
2135  self.SetSize(self.GetBestSize())
2136 
2137  def _layout(self):
2138  """!Do layout"""
2139  sizer = wx.BoxSizer(wx.VERTICAL)
2140 
2141  # body
2142  box = wx.StaticBoxSizer(self.box, wx.HORIZONTAL)
2143  fbox = wx.FlexGridSizer(cols = 2, vgap = 5, hgap = 5)
2144  fbox.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
2145  label = _("Width:")),
2146  flag = wx.ALIGN_CENTER_VERTICAL)
2147  fbox.Add(item = self.width)
2148  fbox.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
2149  label = _("Height:")),
2150  flag = wx.ALIGN_CENTER_VERTICAL)
2151  fbox.Add(item = self.height)
2152  fbox.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
2153  label = _("Template:")),
2154  flag = wx.ALIGN_CENTER_VERTICAL)
2155  fbox.Add(item = self.template)
2156 
2157  box.Add(item = fbox, proportion = 1,
2158  flag = wx.EXPAND | wx.ALL, border = 5)
2159  sizer.Add(item = box, proportion = 1,
2160  flag = wx.EXPAND | wx.ALL, border = 3)
2161 
2162  # buttons
2163  btnsizer = wx.StdDialogButtonSizer()
2164  btnsizer.AddButton(self.btnOK)
2165  btnsizer.AddButton(self.btnCancel)
2166  btnsizer.Realize()
2167 
2168  sizer.Add(item = btnsizer, proportion = 0,
2169  flag = wx.EXPAND | wx.ALIGN_RIGHT | wx.ALL, border = 5)
2170 
2171  self.panel.SetSizer(sizer)
2172  sizer.Fit(self.panel)
2173  self.Layout()
2174 
2175  def GetValues(self):
2176  """!Get width/height values"""
2177  return self.width.GetValue(), self.height.GetValue()
2178 
2179  def OnTemplate(self, event):
2180  """!Template selected"""
2181  sel = event.GetString()
2182  if not sel:
2183  width, height = self.parent.GetWindow().GetClientSize()
2184  else:
2185  width, height = map(int, sel.split('x'))
2186  self.width.SetValue(width)
2187  self.height.SetValue(height)
2188 
2189 class SymbolDialog(wx.Dialog):
2190  """!Dialog for GRASS symbols selection.
2191 
2192  Dialog is called in gui_core::forms module.
2193  """
2194  def __init__(self, parent, symbolPath, currentSymbol = None, title = _("Symbols")):
2195  """!Dialog constructor.
2196 
2197  It is assumed that symbolPath contains folders with symbols.
2198 
2199  @param parent dialog parent
2200  @param symbolPath absolute path to symbols
2201  @param currentSymbol currently selected symbol (e.g. 'basic/x')
2202  @param title dialog title
2203  """
2204  wx.Dialog.__init__(self, parent = parent, title = title, id = wx.ID_ANY)
2205 
2206  self.symbolPath = symbolPath
2207  self.currentSymbol = currentSymbol # default basic/x
2208  self.selected = None
2209  self.selectedDir = None
2210 
2211  self._layout()
2212 
2213  def _layout(self):
2214  mainPanel = wx.Panel(self, id = wx.ID_ANY)
2215  mainSizer = wx.BoxSizer(wx.VERTICAL)
2216  vSizer = wx.BoxSizer( wx.VERTICAL)
2217  fgSizer = wx.FlexGridSizer(rows = 2, vgap = 5, hgap = 5)
2218  self.folderChoice = wx.Choice(mainPanel, id = wx.ID_ANY, choices = os.listdir(self.symbolPath))
2219  self.folderChoice.Bind(wx.EVT_CHOICE, self.OnFolderSelect)
2220 
2221  fgSizer.Add(item = wx.StaticText(mainPanel, id = wx.ID_ANY, label = _("Symbol directory:")),
2222  proportion = 0,
2223  flag = wx.ALIGN_CENTER_VERTICAL)
2224 
2225  fgSizer.Add(item = self.folderChoice, proportion = 0,
2226  flag = wx.ALIGN_CENTER, border = 0)
2227 
2228  self.infoLabel = wx.StaticText(mainPanel, id = wx.ID_ANY)
2229  fgSizer.Add(wx.StaticText(mainPanel, id = wx.ID_ANY, label = _("Symbol name:")),
2230  flag = wx.ALIGN_CENTRE_VERTICAL)
2231  fgSizer.Add(self.infoLabel, proportion = 0,
2232  flag = wx.ALIGN_CENTRE_VERTICAL)
2233  vSizer.Add(fgSizer, proportion = 0, flag = wx.ALL, border = 5)
2234 
2235  self.panels = self._createSymbolPanels(mainPanel)
2236  for panel in self.panels:
2237  vSizer.Add(panel, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
2238  panel.Bind(EVT_SYMBOL_SELECTION_CHANGED, self.SelectionChanged)
2239 
2240  mainSizer.Add(vSizer, proportion = 1, flag = wx.ALL| wx.EXPAND, border = 5)
2241  self.btnCancel = wx.Button(parent = mainPanel, id = wx.ID_CANCEL)
2242  self.btnOK = wx.Button(parent = mainPanel, id = wx.ID_OK)
2243  self.btnOK.SetDefault()
2244  self.btnOK.Enable(False)
2245 
2246  # buttons
2247  btnSizer = wx.StdDialogButtonSizer()
2248  btnSizer.AddButton(self.btnCancel)
2249  btnSizer.AddButton(self.btnOK)
2250  btnSizer.Realize()
2251  mainSizer.Add(item = btnSizer, proportion = 0,
2252  flag = wx.EXPAND | wx.ALL, border = 5)
2253 
2254  # show panel with the largest number of images and fit size
2255  count = []
2256  for folder in os.listdir(self.symbolPath):
2257  count.append(len(os.listdir(os.path.join(self.symbolPath, folder))))
2258 
2259  index = count.index(max(count))
2260  self.folderChoice.SetSelection(index)
2261  self.OnFolderSelect(None)
2262  self.infoLabel.Show()
2263 
2264  mainPanel.SetSizerAndFit(mainSizer)
2265  self.SetSize(self.GetBestSize())
2266 
2267  # show currently selected symbol
2268  if self.currentSymbol:
2269  # set directory
2270  self.selectedDir, self.selected = os.path.split(self.currentSymbol)
2271  self.folderChoice.SetStringSelection(self.selectedDir)
2272  # select symbol
2273  panelIdx = self.folderChoice.GetSelection()
2274  for panel in self.symbolPanels[panelIdx]:
2275  if panel.GetName() == self.selected:
2276  panel.Select()
2277  else:
2278  self.folderChoice.SetSelection(0)
2279 
2280  self.OnFolderSelect(None)
2281 
2282  def _createSymbolPanels(self, parent):
2283  """!Creates multiple panels with symbols.
2284 
2285  Panels are shown/hidden according to selected folder."""
2286  folders = os.listdir(self.symbolPath)
2287 
2288  panels = []
2289  self.symbolPanels = []
2290  maxImages = 0
2291 
2292  for folder in folders:
2293  panel = wx.Panel(parent, style = wx.BORDER_RAISED)
2294  sizer = wx.GridSizer(cols = 6, vgap = 3, hgap = 3)
2295  images = self._getSymbols(path = os.path.join(self.symbolPath, folder))
2296 
2297  symbolPanels = []
2298  for img in images:
2299  iP = SingleSymbolPanel(parent = panel, symbolPath = img)
2300  sizer.Add(item = iP, proportion = 0, flag = wx.ALIGN_CENTER)
2301  symbolPanels.append(iP)
2302 
2303  panel.SetSizerAndFit(sizer)
2304  panel.Hide()
2305  panels.append(panel)
2306  self.symbolPanels.append(symbolPanels)
2307 
2308  return panels
2309 
2310  def _getSymbols(self, path):
2311  # we assume that images are in subfolders (1 level only)
2312  imageList = []
2313  for image in os.listdir(path):
2314  imageList.append(os.path.join(path, image))
2315 
2316  return sorted(imageList)
2317 
2318  def OnFolderSelect(self, event):
2319  """!Selected folder with symbols changed."""
2320  idx = self.folderChoice.GetSelection()
2321  for i in range(len(self.panels)):
2322  sizer = self.panels[i].GetContainingSizer()
2323  sizer.Show(self.panels[i], i == idx, recursive = True)
2324  sizer.Layout()
2325 
2326  if self.selectedDir == self.folderChoice.GetStringSelection():
2327  self.btnOK.Enable()
2328  self.infoLabel.SetLabel(self.selected)
2329  else:
2330  self.btnOK.Disable()
2331  self.infoLabel.SetLabel('')
2332 
2333  def SelectionChanged(self, event):
2334  """!Selected symbol changed."""
2335  if event.doubleClick:
2336  self.EndModal(wx.ID_OK)
2337  # deselect all
2338  for i in range(len(self.panels)):
2339  for panel in self.symbolPanels[i]:
2340  if panel.GetName() != event.name:
2341  panel.Deselect()
2342 
2343  self.btnOK.Enable()
2344 
2345  self.selected = event.name
2346  self.selectedDir = self.folderChoice.GetStringSelection()
2347 
2348  self.infoLabel.SetLabel(event.name)
2349 
2351  """!Returns currently selected symbol name (e.g. 'basic/x').
2352  """
2353  # separator must be '/' and not dependent on OS
2354  return self.selectedDir + '/' + self.selected
2355 
2357  """!Returns currently selected symbol full path.
2358  """
2359  return os.path.join(self.symbolPath, self.selectedDir, self.selected)
2360 
2361 class TextEntryDialog(wx.Dialog):
2362  """!Simple dialog with text field.
2363 
2364  It differs from wx.TextEntryDialog because it allows adding validator.
2365  """
2366  def __init__(self, parent, message, caption='',
2367  defaultValue='', pos=wx.DefaultPosition, validator=wx.DefaultValidator,
2368  style=wx.OK | wx.CANCEL):
2369  wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=caption, pos=pos)
2370 
2371  vbox = wx.BoxSizer(wx.VERTICAL)
2372 
2373  stline = wx.StaticText(self, id=wx.ID_ANY, label=message)
2374  vbox.Add(item=stline, proportion=0, flag=wx.EXPAND | wx.ALL, border=10)
2375 
2376  self._textCtrl = wx.TextCtrl(self, id=wx.ID_ANY, size = (300, -1),
2377  value=defaultValue, validator=validator)
2378  vbox.Add(item=self._textCtrl, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=10)
2379  self._textCtrl.SetFocus()
2380 
2381  sizer = self.CreateSeparatedButtonSizer(style)
2382  vbox.Add(item=sizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
2383 
2384  self.SetSizerAndFit(vbox)
2385 
2386  def GetValue(self):
2387  return self._textCtrl.GetValue()
2388 
2389  def SetValue(self, value):
2390  self._textCtrl.SetValue(value)
2391 
2392 
2393 class HyperlinkDialog(wx.Dialog):
2394  """!Dialog for displaying message with hyperlink."""
2395  def __init__(self, parent, title, message, hyperlink,
2396  hyperlinkLabel=None, style=wx.OK):
2397  """!Constructor
2398 
2399  @param parent gui parent
2400  @param title dialog title
2401  @param message message
2402  @param hyperlink url
2403  @param hyperlinkLabel label shown instead of url
2404  @param style button style
2405  """
2406  wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=title,
2407  style=wx.DEFAULT_DIALOG_STYLE)
2408 
2409  sizer = wx.BoxSizer(wx.VERTICAL)
2410 
2411  label = wx.StaticText(self, label=message)
2412  sizer.Add(item=label, proportion=0, flag=wx.ALIGN_CENTRE|wx.ALL, border=10)
2413  hyperlinkLabel = hyperlinkLabel if hyperlinkLabel else hyperlink
2414  hyperlinkCtrl = wx.HyperlinkCtrl(self, id=wx.ID_ANY,
2415  label=hyperlinkLabel, url=hyperlink,
2416  style=wx.HL_ALIGN_LEFT|wx.HL_CONTEXTMENU)
2417  sizer.Add(item=hyperlinkCtrl, proportion=0, flag=wx.EXPAND|wx.ALL, border=10)
2418 
2419  btnsizer = self.CreateSeparatedButtonSizer(style)
2420  sizer.Add(item=btnsizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
2421 
2422  self.SetSizer(sizer)
2423  sizer.Fit(self)
def _getCommand(self)
Get command.
def ApplyChanges(self, showResult)
Create or edit group.
Dialog for bulk import of DXF layers.
wxGUI command interface
def OnRotation(self, event)
Change rotation.
def _layout(self)
Do layout.
def OnSelectInvert(self, event)
Invert current selection.
Dialog for GRASS symbols selection.
def OnAbort(self, event)
Abort running import.
def OnClose(self, event)
Close dialog.
def GetValidLayerName(name)
Make layer name SQL compliant, based on G_str_to_sql()
Definition: core/utils.py:175
def _createSymbolPanels(self, parent)
Creates multiple panels with symbols.
def OnApply(self, event)
Apply changes.
def GetLayerType
Get selected layer type.
def GetOpacity(self)
Button 'OK' pressed.
def OnGroupSelected(self, event)
Text changed in group selector.
def GroupSelected(self)
Group was selected, check if changes were apllied.
def OnRun(self, event)
Import/Link data (each layes as separate vector map)
def OnMapName(self, event)
Name for vector map layer given.
wxGUI debugging
def OnSelectAll(self, event)
Select all map layer from list.
def IsChecked(self, key)
Get dialog properties.
def OnToggle(self, event)
Select toggle (check or uncheck all layers)
Core GUI widgets.
def EditGroup(self, group)
Edit selected group.
def GetImageHandlers(image)
Get list of supported image handlers.
def OnRemoveLayer(self, event)
Remove layer from listbox.
def LoadData
Load data into list.
def __init__(self, parent, title, overlayController, ddstyle, kwargs)
def GetMapLayers(self)
Return list of checked map layers.
def SelectionChanged(self, event)
Selected symbol changed.
Simple dialog with text field.
def GetSelectedSymbolName(self)
Returns currently selected symbol name (e.g.
def OnSelectNone(self, event)
Deselect items.
#define max(x, y)
Definition: draw2.c:69
def OnCmdDialog(self, event)
Show command dialog.
Dialog for displaying message with hyperlink.
def OnOK(self, event)
Button 'OK' pressed.
def OnCmdDialog(self, event)
Show command dialog.
def _layout(self)
Do layout.
def OnAddLayer(self, event)
Add new layer to listbox.
def OnType(self, event)
Select element type.
def OnCmdDialog(self, event)
Show command dialog.
def OnLeftDown(self, event)
Allow editing only output name.
Custom control that selects elements.
def __init__(self, parent, id=wx.ID_ANY, title=_('Create new vector map'), disableAdd=False, disableTable=False, style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, kwargs)
Dialog for creating new vector map.
Dialog for creating/editing groups.
def GetGroupLayers(self, group)
Get layers in group.
def __init__(self, parent, id=wx.ID_ANY, title="", loadsave='load', kwargs)
Loading and saving of display extents to saved region file.
def split(s)
Platform spefic shlex.split.
Definition: core/utils.py:37
def OnDeselectAll(self, event)
Select all map layer from list.
def OnRefit(self, event)
Resize text entry to match text.
def OnSelectFont(self, event)
Change font.
def GetLayerNameFromCmd
Get map name from GRASS command.
Definition: core/utils.py:73
def ClearNotification(self)
Clear notification string.
def CloseDialog(self)
Hide dialog.
def LoadMapLayers(self, type, mapset)
Load list of map layers.
def OnSelectAll(self, event)
Select all items.
def GetValues(self)
Get text properties.
Dialog for bulk import of various data (base class)
def GetLayers(self)
Get layers.
def OnRun(self, event)
Import/Link data (each layes as separate vector map)
def OnOk(self, event)
Apply changes and close dialog.
def OnClose
Close dialog.
def __init__
Dialog for bulk import of various raster/vector data.
def __init__
Dialog constructor.
def GetKey(self)
Get key column name.
def __init__(self, parent, title, modeler=False, mapType=None, selectAll=True, fullyQualified=True, showFullyQualified=True, style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, kwargs)
Dialog for selecting map layers (raster, vector)
def ShowGroupLayers(self, mapList)
Show map layers in currently selected group.
def OnRun(self, event)
Import/Link data (each layes as separate vector map)
Set size for saved graphic file.
def __init__(self, parent)
def OnChangeParams(self, event)
Filter parameters changed by user.
def GetExistGroups(self)
Returns existing groups in current mapset.
def OnMenu(self, event)
Table description area, context menu.
def __layout(self)
Do layout.
def CreateNewVector
Create new vector map layer.
def GetSelectedGroup(self)
Return currently selected group (without mapset)
def GetOptData(self, dcmd, layer, params, propwin)
Process decoration layer data.
def OnFilter(self, event)
Apply filter for map names.
def OnText(self, event)
Change text string.
List of layers to be imported (dxf, shp...)
def GetName
Get name of vector map to be created.
def OnElement(self, event)
Select mapset given location name.
def GetLayers(self)
Get list of layers (layer name, output name)
def OnElement(self, event)
Name for vector map layer given.
Misc utilities for wxGUI.
def __Layout(self)
Do layout.
def _layout(self)
Do layout.
def AddLayers
Add imported/linked layers into layer tree.
def ShowResult(self, group, returnCode, create)
Show if operation was successfull.
Set opacity of map layers.
def doLayout(self)
Do layout.
def CreateNewGroup(self, group)
Create new group.
def _getSymbols(self, path)
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 GetValues(self)
Get location, mapset.
def GetDSeries(self)
Used by modeler only.
def GetSelectedSymbolPath(self)
Returns currently selected symbol full path.
def OnFolderSelect(self, event)
Selected folder with symbols changed.
def OnTemplate(self, event)
Template selected.
Default GUI settings.
def OnSetDsn(self, event)
Input DXF file defined, update list of layer widget.
tuple range
Definition: tools.py:1406
def __init__(self, parent, title, label, id=wx.ID_ANY, etype=False, style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, kwargs)
General dialog to choose given element (location, mapset, vector map, etc.)
def OnTable(self, event)
def __init__(self, parent, id=wx.ID_ANY, title=_("Set image size"), style=wx.DEFAULT_DIALOG_STYLE, kwargs)
def OnPopupMenu(self, event)
Show popup menu.
def __init__(self, parent=None, defaultGroup=None, title=_("Create or edit imagery groups"), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, kwargs)
Dialog used to select location.
def OnRegion(self, event)
def OnOptions(self, event)
Sets option for decoration map overlays.
def GetType(self)
Get element type.
def GetElement(self)
Return (mapName, overwrite)
def GetValues(self)
Get width/height values.
Dialog used to select mapset.