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