2 @package gui_core.forms
4 @brief Construct simple wxPython GUI from a GRASS command interface
15 This program is just a coarse approach to automatically build a GUI
16 from a xml-based GRASS user interface description.
18 You need to have Python 2.4, wxPython 2.8 and python-xml.
20 The XML stream is read from executing the command given in the
21 command line, thus you may call it for instance this way:
23 python <this file.py> r.basins.fill
25 Or you set an alias or wrap the call up in a nice shell script, GUI
26 environment ... please contribute your idea.
28 Updated to wxPython 2.8 syntax and contrib widgets. Methods added to
29 make it callable by gui. Method added to automatically re-run with
33 - verify option value types
35 Copyright(C) 2000-2012 by the GRASS Development Team
37 This program is free software under the GPL(>=v2) Read the file
38 COPYING coming with GRASS for details.
40 @author Jan-Oliver Wagner <jan@intevation.de>
41 @author Bernhard Reiter <bernhard@intevation.de>
42 @author Michael Barton, Arizona State University
43 @author Daniel Calvelo <dca.gis@gmail.com>
44 @author Martin Landa <landa.martin@gmail.com>
45 @author Luca Delucchi <lucadeluge@gmail.com>
55 from threading
import Thread
59 gisbase = os.getenv(
"GISBASE")
61 print >>sys.stderr,
"We don't seem to be properly installed, or we are being run outside GRASS. Expect glitches."
62 gisbase = os.path.join(os.path.dirname(sys.argv[0]), os.path.pardir)
65 wxbase = os.path.join(gisbase,
'etc',
'wxpython')
67 sys.path.append(wxbase)
69 from core
import globalvar
72 import wx.lib.agw.flatnotebook
as FN
74 import wx.lib.flatnotebook
as FN
75 import wx.lib.colourselect
as csel
76 import wx.lib.filebrowsebutton
as filebrowse
77 from wx.lib.newevent
import NewEvent
80 import xml.etree.ElementTree
as etree
82 import elementtree.ElementTree
as etree
89 from gui_core
import gselect
91 from core
import utils
95 wxUpdateDialog, EVT_DIALOG_UPDATE = NewEvent()
99 str2rgb = {
'aqua': (100, 128, 255),
102 'brown': (180, 77, 25),
103 'cyan': (0, 255, 255),
104 'gray': (128, 128, 128),
105 'green': (0, 255, 0),
106 'grey': (128, 128, 128),
107 'indigo': (0, 128, 255),
108 'magenta': (255, 0, 255),
109 'orange': (255, 128, 0),
110 'purple': (128, 0, 128),
112 'violet': (128, 0, 255),
113 'white': (255, 255, 255),
114 'yellow': (255, 255, 0)}
116 for (s,r)
in str2rgb.items():
119 """!Hide some options in the GUI"""
120 _blackList = {
'enabled' :
False,
121 'items' : {
'd.legend' : {
'flags' : [
'm'] } }
125 if len(color) > 0
and color[0]
in "0123456789":
126 rgb = tuple(map(int, color.split(
':')))
131 rgb = str2rgb[ color ]
135 label = _(
'Select Color')
140 Make really long texts shorter, clean up whitespace and
141 remove trailing punctuation.
151 """!Escapes ampersands with additional ampersand for GUI"""
152 return string.replace(text,
"&",
"&&")
155 """!Update dialog widgets in the thread"""
157 Thread.__init__(self)
171 for p
in self.task.params:
172 if p.get(
'gisprompt',
False) ==
False:
174 prompt = p.get(
'element',
'')
175 if prompt ==
'vector':
176 name = p.get(
'name',
'')
177 if name
in (
'map',
'input'):
182 p = self.task.get_param(self.
eventId, element =
'wxId', raiseError =
False)
183 if not p
or 'wxId-bind' not in p:
187 pType = p.get(
'prompt',
'')
192 pMap = self.task.get_param(
'map', raiseError =
False)
195 pMap = self.task.get_param(
'input', raiseError =
False)
198 map = pMap.get(
'value',
'')
204 cparams[map] = {
'dbInfo' :
None,
208 for uid
in p[
'wxId-bind']:
209 win = self.parent.FindWindowById(uid)
214 pBind = self.task.get_param(uid, element =
'wxId', raiseError =
False)
218 if name ==
'LayerSelect':
219 if map
in cparams
and not cparams[map][
'layers']:
220 win.InsertLayers(vector = map)
222 cparams[map][
'layers'] = win.GetItems()
224 elif name ==
'TableSelect':
225 pDriver = self.task.get_param(
'dbdriver', element=
'prompt', raiseError=
False)
228 driver = pDriver[
'value']
229 pDb = self.task.get_param(
'dbname', element=
'prompt', raiseError=
False)
233 self.
data[win.InsertTables] = {
'driver' : driver,
236 elif name ==
'ColumnSelect':
237 pLayer = self.task.get_param(
'layer', element=
'element', raiseError=
False)
239 if pLayer.get(
'value',
'') !=
'':
240 layer = pLayer.get(
'value',
'')
242 layer = pLayer.get(
'default',
'')
248 if not cparams[map][
'dbInfo']:
250 self.
data[win.InsertColumns] = {
'vector' : map,
'layer' : layer,
251 'dbInfo' : cparams[map][
'dbInfo'] }
254 pDriver = self.task.get_param(
'dbdriver', element=
'prompt', raiseError=
False)
256 driver = pDriver.get(
'value',
None)
257 pDb = self.task.get_param(
'dbname', element=
'prompt', raiseError=
False)
259 db = pDb.get(
'value',
None)
260 pTable = self.task.get_param(
'dbtable', element=
'element', raiseError=
False)
262 pTable.get(
'value',
'') !=
'':
264 self.
data[win.InsertTableColumns] = {
'table' : pTable.get(
'value'),
268 self.
data[win.InsertTableColumns] = {
'table' : pTable.get(
'value') }
270 elif name ==
'SubGroupSelect':
271 self.
data[win.Insert] = {
'group' : p.get(
'value',
'')}
273 elif name ==
'LocationSelect':
274 pDbase = self.task.get_param(
'dbase', element =
'element', raiseError =
False)
276 self.
data[win.UpdateItems] = {
'dbase' : pDbase.get(
'value',
'')}
278 elif name ==
'MapsetSelect':
279 pDbase = self.task.get_param(
'dbase', element =
'element', raiseError =
False)
280 pLocation = self.task.get_param(
'location', element =
'element', raiseError =
False)
281 if pDbase
and pLocation:
282 self.
data[win.UpdateItems] = {
'dbase' : pDbase.get(
'value',
''),
283 'location' : pLocation.get(
'value',
'')}
285 elif name ==
'ProjSelect':
286 pDbase = self.task.get_param(
'dbase', element =
'element', raiseError =
False)
287 pLocation = self.task.get_param(
'location', element =
'element', raiseError =
False)
288 pMapset = self.task.get_param(
'mapset', element =
'element', raiseError =
False)
289 if pDbase
and pLocation
and pMapset:
290 self.
data[win.UpdateItems] = {
'dbase' : pDbase.get(
'value',
''),
291 'location' : pLocation.get(
'value',
''),
292 'mapset' : pMapset.get(
'value',
'')}
298 """!Update dialog widgets in the thread"""
300 def __init__(self, parent, requestQ, resultQ, **kwds):
301 Thread.__init__(self, **kwds)
311 def Update(self, callable, *args, **kwds):
312 UpdateQThread.requestId += 1
315 self.requestQ.put((UpdateQThread.requestId, callable, args, kwds))
317 return UpdateQThread.requestId
321 requestId, callable, args, kwds = self.requestQ.get()
323 requestTime = time.time()
325 self.
request = callable(*args, **kwds)
327 self.resultQ.put((requestId, self.request.run()))
330 event = wxUpdateDialog(data = self.request.data)
331 wx.PostEvent(self.
parent, event)
334 """!This is the Frame containing the dialog for options input.
336 The dialog is organized in a notebook according to the guisections
337 defined by each GRASS command.
339 If run with a parent, it may Apply, Ok or Cancel; the latter two
340 close the dialog. The former two trigger a callback.
342 If run standalone, it will allow execution of the command.
344 The command is checked and sent to the clipboard when clicking
347 def __init__(self, parent, ID, task_description,
348 get_dcmd =
None, layer =
None):
353 if parent
and parent.GetName() ==
'Modeler':
359 if self.task.name.split(
'.')[-1]
in (
'py',
'sh'):
360 title = str(self.task.name.rsplit(
'.',1)[0])
362 title = self.task.name
364 if self.task.keywords != [
'']:
365 title +=
" [" +
', '.join(self.task.keywords) +
"]"
369 wx.Frame.__init__(self, parent = parent, id = ID, title = title,
370 pos = wx.DefaultPosition, style = wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL,
373 self.
locale = wx.Locale(language = wx.LANGUAGE_DEFAULT)
375 self.
panel = wx.Panel(parent = self, id = wx.ID_ANY)
378 self.CreateStatusBar()
381 self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR,
'grass_dialog.ico'), wx.BITMAP_TYPE_ICO))
383 guisizer = wx.BoxSizer(wx.VERTICAL)
392 topsizer = wx.BoxSizer(wx.HORIZONTAL)
396 bitmap = wx.Bitmap(name = os.path.join(globalvar.ETCIMGDIR,
398 type = wx.BITMAP_TYPE_PNG))
399 topsizer.Add(item = self.
logo, proportion = 0, border = 3,
400 flag = wx.ALL | wx.ALIGN_CENTER_VERTICAL)
404 module_desc = self.task.label +
' ' + self.task.description
406 module_desc = self.task.description
409 topsizer.Add(item = self.
description, proportion = 1, border = 5,
410 flag = wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND)
412 guisizer.Add(item = topsizer, proportion = 0, flag = wx.EXPAND)
414 self.panel.SetSizerAndFit(guisizer)
422 guisizer.Add(item = self.
notebookpanel, proportion = 1, flag = wx.EXPAND)
425 status_text = _(
"Enter parameters for '") + self.task.name +
"'"
430 self.SetStatusText(status_text)
433 btnsizer = wx.BoxSizer(orient = wx.HORIZONTAL)
436 self.btn_cancel.SetToolTipString(_(
"Close this window without executing the command (Ctrl+Q)"))
437 btnsizer.Add(item = self.
btn_cancel, proportion = 0, flag = wx.ALL | wx.ALIGN_CENTER, border = 10)
438 self.btn_cancel.Bind(wx.EVT_BUTTON, self.
OnCancel)
441 btn_apply = wx.Button(parent = self.
panel, id = wx.ID_APPLY)
442 btn_ok = wx.Button(parent = self.
panel, id = wx.ID_OK)
445 btnsizer.Add(item = btn_apply, proportion = 0,
446 flag = wx.ALL | wx.ALIGN_CENTER,
448 btnsizer.Add(item = btn_ok, proportion = 0,
449 flag = wx.ALL | wx.ALIGN_CENTER,
452 btn_apply.Bind(wx.EVT_BUTTON, self.
OnApply)
453 btn_ok.Bind(wx.EVT_BUTTON, self.
OnOK)
456 self.
btn_run = wx.Button(parent = self.
panel, id = wx.ID_OK, label = _(
"&Run"))
457 self.btn_run.SetToolTipString(_(
"Run the command (Ctrl+R)"))
458 self.btn_run.SetDefault()
459 self.btn_run.SetForegroundColour(wx.Colour(35, 142, 35))
463 self.btn_clipboard.SetToolTipString(_(
"Copy the current command string to the clipboard (Ctrl+C)"))
465 btnsizer.Add(item = self.
btn_run, proportion = 0,
466 flag = wx.ALL | wx.ALIGN_CENTER,
470 flag = wx.ALL | wx.ALIGN_CENTER,
473 self.btn_run.Bind(wx.EVT_BUTTON, self.
OnRun)
474 self.btn_clipboard.Bind(wx.EVT_BUTTON, self.
OnCopy)
477 self.btn_help.SetToolTipString(_(
"Show manual page of the command (Ctrl+H)"))
478 self.btn_help.Bind(wx.EVT_BUTTON, self.
OnHelp)
479 if self.notebookpanel.notebook.GetPageIndexByName(
'manual') < 0:
483 btnsizer.Add(item = self.
btn_help, proportion = 0, flag = wx.ALL | wx.ALIGN_CENTER, border = 10)
485 guisizer.Add(item = btnsizer, proportion = 0, flag = wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT,
490 for p
in self.task.params:
491 if p.get(
'age',
'old') ==
'new' and \
492 p.get(
'prompt',
'')
in (
'raster',
'vector',
'3d-raster'):
498 label = _(
'Add created map(s) into layer tree'), style = wx.NO_BORDER)
499 self.addbox.SetValue(UserSettings.Get(group =
'cmd', key =
'addNewLayer', subkey =
'enabled'))
500 guisizer.Add(item = self.
addbox, proportion = 0,
501 flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
505 for p
in self.task.params:
506 if p.get(
'age',
'old') ==
'new':
510 if self.
get_dcmd is None and hasNew:
513 label = _(
'Close dialog on finish'), style = wx.NO_BORDER)
514 self.closebox.SetValue(UserSettings.Get(group =
'cmd', key =
'closeDlg', subkey =
'enabled'))
515 self.closebox.SetToolTipString(_(
"Close dialog when command is successfully finished. "
516 "Change this settings in Preferences dialog ('Command' tab)."))
517 guisizer.Add(item = self.
closebox, proportion = 0,
518 flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
521 self.Bind(wx.EVT_CLOSE, self.
OnCancel)
522 self.Bind(wx.EVT_KEY_UP, self.
OnKeyUp)
526 self.panel.SetAutoLayout(
True)
527 self.panel.SetSizerAndFit(guisizer)
529 sizeFrame = self.GetBestSize()
530 self.SetMinSize(sizeFrame)
531 self.SetSize(wx.Size(sizeFrame[0], sizeFrame[1] + 0.33 *
max(self.notebookpanel.panelMinHeight,
532 self.notebookpanel.constrained_size[1])))
543 width, height = self.GetSizeTuple()
544 self.SetSize(wx.Size(
min(width, 650),
549 self.goutput.SetSashPosition(int(self.GetSize()[1] * .75))
552 """!Update status bar data"""
553 self.SetStatusText(
' '.join(self.notebookpanel.createCmd(ignoreErrors =
True)))
558 """!Key released (check hot-keys)"""
560 kc = chr(event.GetKeyCode())
565 if not event.ControlDown():
583 """!This function is launched from OnRun() when command is
586 @param returncode command's return code (0 for success)
588 if not self.
parent or returncode != 0:
590 if self.parent.GetName()
not in (
'LayerTree',
'LayerManager'):
593 if self.parent.GetName() ==
'LayerTree':
594 display = self.parent.GetMapDisplay()
597 tree = self.parent.GetLayerTree()
599 display = tree.GetMapDisplay()
601 if not display
or not display.IsAutoRendered():
604 mapLayers = map(
lambda x: x.GetName(),
605 display.GetMap().GetListOfLayers(l_type =
'raster') +
606 display.GetMap().GetListOfLayers(l_type =
'vector'))
608 task =
GUI(show =
None).ParseCommand(cmd)
609 for p
in task.get_options()[
'params']:
610 if p.get(
'prompt',
'')
not in (
'raster',
'vector'):
612 mapName = p.get(
'value',
'')
613 if '@' not in mapName:
614 mapName = mapName +
'@' + grass.gisenv()[
'MAPSET']
615 if mapName
in mapLayers:
616 display.GetWindow().UpdateMap(render =
True)
620 """!OK button pressed"""
622 if cmd
is not None and self.
get_dcmd is not None:
626 """!Apply the command"""
628 cmd = self.
createCmd(ignoreErrors =
True, ignoreRequired =
True)
632 if cmd
is not None and self.
get_dcmd is not None:
635 "flags" : self.task.flags},
643 """!Run the command"""
646 if not cmd
or len(cmd) < 1:
652 self.notebookpanel.notebook.SetSelectionByName(
'output')
656 self.goutput.RunCmd(cmd, onDone = self.
OnDone)
657 except AttributeError, e:
658 print >> sys.stderr,
"%s: Probably not running in wxgui.py session?" % (e)
659 print >> sys.stderr,
"parent window is: %s" % (str(self.
parent))
671 """!Abort running command"""
673 event = wxCmdAbort(aborted =
True)
674 wx.PostEvent(self.
goutput, event)
677 """!Copy the command"""
678 cmddata = wx.TextDataObject()
680 cmdstring =
' '.join(self.
createCmd(ignoreErrors =
True))
681 cmddata.SetText(cmdstring)
682 if wx.TheClipboard.Open():
684 wx.TheClipboard.SetData(cmddata)
685 wx.TheClipboard.Close()
686 self.SetStatusText(_(
"'%s' copied to clipboard") % \
690 """!Cancel button pressed"""
691 self.MakeModal(
False)
695 self.parent.GetName()
in (
'LayerTree',
699 if self.task.name
in [
'd.barscale',
'd.legend',
'd.histogram'] \
700 or len(self.parent.GetPyData(self.
layer)[0][
'cmd']) >= 1:
703 elif len(self.parent.GetPyData(self.
layer)[0][
'cmd']) < 1:
704 self.parent.Delete(self.
layer)
711 """!Show manual page (switch to the 'Manual' notebook page)"""
712 if self.notebookpanel.notebook.GetPageIndexByName(
'manual') > -1:
713 self.notebookpanel.notebook.SetSelectionByName(
'manual')
714 self.notebookpanel.OnPageChange(
None)
719 def createCmd(self, ignoreErrors = False, ignoreRequired = False):
720 """!Create command string (python list)"""
721 return self.notebookpanel.createCmd(ignoreErrors = ignoreErrors,
722 ignoreRequired = ignoreRequired)
725 """!A panel containing a notebook dividing in tabs the different
726 guisections of the GRASS cmd.
728 def __init__(self, parent, task, id = wx.ID_ANY, frame = None, *args, **kwargs):
735 wx.Panel.__init__(self, parent, id = id, *args, **kwargs)
740 not_hidden = [ p
for p
in self.task.params + self.task.flags
if not p.get(
'hidden',
False) ==
True ]
744 self.Bind(wx.EVT_SIZE, self.
OnSize)
746 for task
in not_hidden:
747 if task.get(
'required',
False):
749 task[
'guisection'] = _(
'Required')
750 if task.get(
'guisection',
'') ==
'':
752 task[
'guisection'] = _(
'Optional')
753 if task[
'guisection']
not in is_section:
755 is_section[task[
'guisection']] = 1
756 sections.append(task[
'guisection'])
758 is_section[ task[
'guisection'] ] += 1
762 for (newidx,content)
in [ (0,_(
'Required')), (len(sections)-1,_(
'Optional')) ]:
763 if content
in sections:
764 idx = sections.index(content)
765 sections[idx:idx+1] = []
766 sections[newidx:newidx] = [content]
768 panelsizer = wx.BoxSizer(orient = wx.VERTICAL)
771 self.
notebook = GNotebook(self, style = globalvar.FNPageStyle | FN.FNB_NO_X_BUTTON )
772 self.notebook.SetTabAreaColour(globalvar.FNPageColor)
773 self.notebook.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.
OnPageChange)
777 for section
in sections:
778 tab[section] = ScrolledPanel(parent = self.
notebook)
779 tab[section].SetScrollRate(10, 10)
780 tabsizer[section] = wx.BoxSizer(orient = wx.VERTICAL)
781 self.notebook.AddPage(page = tab[section], text = section)
785 if self.parent.GetName() ==
"MainFrame" and self.parent.get_dcmd
is None:
787 self.
goutput = GMConsole(parent = self, margin =
False)
788 self.
outpage = self.notebook.AddPage(page = self.
goutput, text = _(
"Command output"), name =
'output')
792 self.
manualTab = HelpPanel(parent = self, command = self.task.name)
793 if not self.manualTab.GetFile():
794 self.manualTab.Hide()
796 self.notebook.AddPage(page = self.
manualTab, text = _(
"Manual"), name =
'manual')
798 self.notebook.SetSelection(0)
800 panelsizer.Add(item = self.
notebook, proportion = 1, flag = wx.EXPAND)
805 text_style = wx.FONTWEIGHT_NORMAL
806 visible_flags = [ f
for f
in self.task.flags
if not f.get(
'hidden',
False) ==
True ]
807 for f
in visible_flags:
808 which_sizer = tabsizer[ f[
'guisection'] ]
809 which_panel = tab[ f[
'guisection'] ]
811 if f.get(
'label',
'') !=
'':
817 title_sizer = wx.BoxSizer(wx.HORIZONTAL)
818 rtitle_txt = wx.StaticText(parent = which_panel,
819 label =
'(' + f[
'name'] +
')')
820 chk = wx.CheckBox(parent = which_panel, label = title, style = wx.NO_BORDER)
821 self.label_id.append(chk.GetId())
823 chk.SetToolTipString(tooltip)
824 chk.SetValue(f.get(
'value',
False))
825 title_sizer.Add(item = chk, proportion = 1,
827 title_sizer.Add(item = rtitle_txt, proportion = 0,
828 flag = wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
829 which_sizer.Add(item = title_sizer, proportion = 0,
830 flag = wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, border = 5)
831 f[
'wxId'] = [ chk.GetId(), ]
834 if self.parent.GetName() ==
'MainFrame' and self.parent.modeler:
835 parChk = wx.CheckBox(parent = which_panel, id = wx.ID_ANY,
836 label = _(
"Parameterized in model"))
837 parChk.SetName(
'ModelParam')
838 parChk.SetValue(f.get(
'parameterized',
False))
840 f[
'wxId'].append(parChk.GetId())
842 f[
'wxId'] = [ parChk.GetId() ]
844 which_sizer.Add(item = parChk, proportion = 0,
845 flag = wx.LEFT, border = 20)
847 if f[
'name']
in (
'verbose',
'quiet'):
849 vq = UserSettings.Get(group =
'cmd', key =
'verbosity', subkey =
'selection')
853 elif f[
'name'] ==
'overwrite' and 'value' not in f:
854 chk.SetValue(UserSettings.Get(group =
'cmd', key =
'overwrite', subkey =
'enabled'))
855 f[
'value'] = UserSettings.Get(group =
'cmd', key =
'overwrite', subkey =
'enabled')
860 visible_params = [ p
for p
in self.task.params
if not p.get(
'hidden',
False) ==
True ]
863 first_param = visible_params[0]
867 for p
in visible_params:
868 which_sizer = tabsizer[ p[
'guisection'] ]
869 which_panel = tab[ p[
'guisection'] ]
872 if p.get(
'label',
'') !=
'':
881 if not p.get(
'required',
False):
882 text_style = wx.FONTWEIGHT_NORMAL
884 text_style = wx.FONTWEIGHT_BOLD
887 if (len(p.get(
'values', [])) > 0)
and \
888 p.get(
'multiple',
False)
and \
889 p.get(
'gisprompt',
False) ==
False and \
890 p.get(
'type',
'') ==
'string':
891 title_txt = wx.StaticBox(parent = which_panel, id = wx.ID_ANY)
893 title_sizer = wx.BoxSizer(wx.HORIZONTAL)
894 title_txt = wx.StaticText(parent = which_panel)
896 ltype =
','.join(p[
'key_desc'])
899 rtitle_txt = wx.StaticText(parent = which_panel,
900 label =
'(' + p[
'name'] +
'=' + ltype +
')')
901 title_sizer.Add(item = title_txt, proportion = 1,
902 flag = wx.LEFT | wx.TOP | wx.EXPAND, border = 5)
903 title_sizer.Add(item = rtitle_txt, proportion = 0,
904 flag = wx.ALIGN_RIGHT | wx.RIGHT | wx.TOP, border = 5)
905 which_sizer.Add(item = title_sizer, proportion = 0,
907 self.label_id.append(title_txt.GetId())
910 if p.get(
'multiple',
False)
and len(p.get(
'values',
'')) == 0:
911 title = _(
"[multiple]") +
" " + title
912 if p.get(
'value',
'') ==
'' :
913 p[
'value'] = p.get(
'default',
'')
915 if (len(p.get(
'values', [])) > 0):
916 valuelist = map(str, p.get(
'values',[]))
917 valuelist_desc = map(unicode, p.get(
'values_desc',[]))
919 if p.get(
'multiple',
False)
and \
920 p.get(
'gisprompt',
False) ==
False and \
921 p.get(
'type',
'') ==
'string':
922 title_txt.SetLabel(
" %s: (%s, %s) " % (title, p[
'name'], p[
'type']))
924 hSizer = wx.StaticBoxSizer(box = title_txt, orient = wx.VERTICAL)
926 hSizer = wx.StaticBoxSizer(box = title_txt, orient = wx.HORIZONTAL)
930 p[
'value'] = p.get(
'default',
'')
932 for defval
in p.get(
'value',
'').
split(
','):
933 isEnabled[ defval ] =
'yes'
938 for val
in valuelist:
940 label = valuelist_desc[idx]
944 chkbox = wx.CheckBox(parent = which_panel,
946 p[
'wxId' ].append(chkbox.GetId())
948 chkbox.SetValue(
True)
949 hSizer.Add(item = chkbox, proportion = 0,
950 flag = wx.ADJUST_MINSIZE | wx.ALL, border = 1)
954 which_sizer.Add(item = hSizer, proportion = 0,
955 flag = wx.EXPAND | wx.TOP | wx.RIGHT | wx.LEFT, border = 5)
956 elif p.get(
'gisprompt',
False) ==
False:
957 if len(valuelist) == 1:
958 title_txt.SetLabel(
"%s (%s %s):" % (title, _(
'valid range'),
961 if p.get(
'type',
'') ==
'integer' and \
962 not p.get(
'multiple',
False):
966 minValue, maxValue = map(int, valuelist[0].
split(
'-'))
970 txt2 = wx.SpinCtrl(parent = which_panel, id = wx.ID_ANY, size = globalvar.DIALOG_SPIN_SIZE,
971 min = minValue, max = maxValue)
972 txt2.SetName(
"SpinCtrl")
973 style = wx.BOTTOM | wx.LEFT
975 txt2 = wx.TextCtrl(parent = which_panel, value = p.get(
'default',
''))
976 txt2.SetName(
"TextCtrl")
977 style = wx.EXPAND | wx.BOTTOM | wx.LEFT
982 if txt2.GetName() ==
"SpinCtrl":
983 txt2.SetValue(int(value))
987 which_sizer.Add(item = txt2, proportion = 0,
988 flag = style, border = 5)
990 p[
'wxId'] = [ txt2.GetId(), ]
993 title_txt.SetLabel(title +
':')
996 if p[
'name'] ==
'icon':
997 bitmap = wx.Bitmap(os.path.join(globalvar.ETCSYMBOLDIR, value) +
'.png')
998 bb = wx.BitmapButton(parent = which_panel, id = wx.ID_ANY,
1000 iconLabel = wx.StaticText(parent = which_panel, id = wx.ID_ANY)
1001 iconLabel.SetLabel(value)
1003 p[
'wxId'] = [bb.GetId(), iconLabel.GetId()]
1005 this_sizer = wx.BoxSizer(wx.HORIZONTAL)
1006 this_sizer.Add(item = bb, proportion = 0,
1007 flag = wx.ADJUST_MINSIZE | wx.BOTTOM | wx.LEFT, border = 5)
1008 this_sizer.Add(item = iconLabel, proportion = 0,
1009 flag = wx.ADJUST_MINSIZE | wx.BOTTOM | wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border = 5)
1010 which_sizer.Add(item = this_sizer, proportion = 0,
1011 flag = wx.ADJUST_MINSIZE, border = 0)
1014 cb = wx.ComboBox(parent = which_panel, id = wx.ID_ANY, value = p.get(
'default',
''),
1015 size = globalvar.DIALOG_COMBOBOX_SIZE,
1016 choices = valuelist, style = wx.CB_DROPDOWN)
1019 which_sizer.Add(item = cb, proportion = 0,
1020 flag = wx.ADJUST_MINSIZE | wx.BOTTOM | wx.LEFT, border = 5)
1021 p[
'wxId'] = [cb.GetId(),]
1026 if (p.get(
'type',
'string')
in (
'string',
'integer',
'float')
1027 and len(p.get(
'values',[])) == 0
1028 and p.get(
'gisprompt',
False) ==
False
1029 and p.get(
'prompt',
'') !=
'color'):
1031 title_txt.SetLabel(title +
':')
1032 if p.get(
'multiple',
False)
or \
1033 p.get(
'type',
'string') ==
'string' or \
1034 len(p.get(
'key_desc', [])) > 1:
1035 txt3 = wx.TextCtrl(parent = which_panel, value = p.get(
'default',
''))
1040 txt3.SetValue(str(value))
1043 style = wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT
1047 if p.get(
'type',
'') ==
'integer':
1048 txt3 = wx.SpinCtrl(parent = which_panel, value = p.get(
'default',
''),
1049 size = globalvar.DIALOG_SPIN_SIZE,
1050 min = minValue, max = maxValue)
1051 style = wx.BOTTOM | wx.LEFT | wx.RIGHT
1055 txt3.SetValue(int(value))
1059 txt3 = wx.TextCtrl(parent = which_panel, value = p.get(
'default',
''),
1060 validator = FloatValidator())
1061 style = wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT
1065 txt3.SetValue(str(value))
1069 which_sizer.Add(item = txt3, proportion = 0,
1070 flag = style, border = 5)
1071 p[
'wxId'] = [ txt3.GetId(), ]
1076 if p.get(
'gisprompt',
False) ==
True:
1077 title_txt.SetLabel(title +
':')
1079 if p.get(
'prompt',
'')
not in (
'color',
1092 p.get(
'element',
'') !=
'file':
1093 multiple = p.get(
'multiple',
False)
1094 if p.get(
'age',
'') ==
'new':
1095 mapsets = [grass.gisenv()[
'MAPSET'],]
1098 if self.task.name
in (
'r.proj',
'v.proj') \
1099 and p.get(
'name',
'') ==
'input':
1100 if self.task.name ==
'r.proj':
1105 isRaster = isRaster)
1106 p[
'wxId'] = [ selection.GetId(), ]
1107 selection.Bind(wx.EVT_COMBOBOX, self.
OnSetValue)
1111 size = globalvar.DIALOG_GSELECT_SIZE,
1112 type = p.get(
'element',
''),
1113 multiple = multiple, nmaps = len(p.get(
'key_desc', [])),
1114 mapsets = mapsets, fullyQualified = p.get(
'age',
'old') ==
'old')
1119 textWin = selection.GetTextCtrl()
1120 p[
'wxId'] = [ textWin.GetId(), ]
1125 selection.SetValue(value)
1127 which_sizer.Add(item=selection, proportion=0,
1128 flag=wx.ADJUST_MINSIZE| wx.BOTTOM | wx.LEFT | wx.RIGHT, border=5)
1130 if p.get(
'prompt',
'')
in (
'vector',
'group'):
1133 elif p.get(
'prompt',
'') ==
'subgroup':
1135 p[
'wxId'] = [ selection.GetId() ]
1136 selection.Bind(wx.EVT_COMBOBOX, self.
OnSetValue)
1138 which_sizer.Add(item = selection, proportion = 0,
1139 flag = wx.ADJUST_MINSIZE | wx.BOTTOM | wx.LEFT | wx.RIGHT | wx.TOP | wx.ALIGN_CENTER_VERTICAL,
1143 elif p.get(
'prompt',
'')
in (
'dbdriver',
1153 if p.get(
'multiple',
'no') ==
'yes':
1154 win = wx.TextCtrl(parent = which_panel, value = p.get(
'default',
''),
1155 size = globalvar.DIALOG_TEXTCTRL_SIZE)
1160 if p.get(
'prompt',
'')
in (
'layer',
1164 if p.get(
'age',
'old_layer') ==
'old_layer':
1166 if p.get(
'prompt',
'') ==
'layer_all':
1167 initial.insert(0,
'-1')
1168 elif p.get(
'prompt',
'') ==
'layer_zero':
1169 initial.insert(0,
'0')
1170 lyrvalue = p.get(
'default')
1172 if lyrvalue
not in initial:
1173 initial.append(str(lyrvalue))
1174 lyrvalue = p.get(
'value')
1176 if lyrvalue
not in initial:
1177 initial.append(str(lyrvalue))
1181 default = p[
'default'])
1182 p[
'wxGetValue'] = win.GetStringSelection
1185 win.SetValue(str(value))
1187 win = wx.SpinCtrl(parent = which_panel, id = wx.ID_ANY,
1188 min = 1, max = 100, initial = int(p[
'default']))
1190 win.SetValue(int(value))
1192 elif p.get(
'prompt',
'') ==
'dbdriver':
1194 choices = p.get(
'values', []),
1196 p[
'wxGetValue'] = win.GetStringSelection
1199 elif p.get(
'prompt',
'') ==
'dbname':
1205 elif p.get(
'prompt',
'') ==
'dbtable':
1206 if p.get(
'age',
'old_dbtable') ==
'old_dbtable':
1209 p[
'wxGetValue'] = win.GetStringSelection
1213 win = wx.TextCtrl(parent = which_panel, value = p.get(
'default',
''),
1214 size = globalvar.DIALOG_TEXTCTRL_SIZE)
1216 elif p.get(
'prompt',
'') ==
'dbcolumn':
1223 elif p.get(
'prompt',
'') ==
'location':
1229 elif p.get(
'prompt',
'') ==
'mapset':
1235 elif p.get(
'prompt',
'') ==
'dbase':
1239 p[
'wxId'] = [ win.GetChildren()[1].GetId() ]
1243 p[
'wxId'] = [ win.GetId(), ]
1244 except AttributeError:
1247 which_sizer.Add(item = win, proportion = 0,
1248 flag = wx.ADJUST_MINSIZE | wx.BOTTOM | wx.LEFT, border = 5)
1250 elif p.get(
'prompt',
'')
in (
'color',
1252 default_color = (200,200,200)
1253 label_color = _(
"Select Color")
1254 if p.get(
'default',
'') !=
'':
1256 if p.get(
'value',
'') !=
'' and p.get(
'value',
'') !=
'none':
1258 if p.get(
'prompt',
'') ==
'color_none' or p.get(
'multiple',
False):
1259 this_sizer = wx.BoxSizer(orient = wx.HORIZONTAL)
1261 this_sizer = which_sizer
1266 p[
'wxId'] = [
None] * 3
1267 if p.get(
'multiple',
False):
1268 txt = wx.TextCtrl(parent = which_panel, id = wx.ID_ANY)
1269 this_sizer.Add(item = txt, proportion = 1,
1270 flag = wx.ADJUST_MINSIZE | wx.LEFT | wx.TOP, border = 5)
1274 p[
'wxId'][1] = txt.GetId()
1275 which_sizer.Add(this_sizer, flag = wx.EXPAND | wx.RIGHT, border = 5)
1277 btn_colour = csel.ColourSelect(parent = which_panel, id = wx.ID_ANY,
1278 label = label_color, colour = default_color,
1279 pos = wx.DefaultPosition, size = (colorSize,-1))
1280 this_sizer.Add(item = btn_colour, proportion = 0,
1281 flag = wx.ADJUST_MINSIZE | wx.BOTTOM | wx.LEFT, border = 5)
1283 p[
'wxId'][0] = btn_colour.GetId()
1285 if p.get(
'prompt',
'') ==
'color_none':
1286 none_check = wx.CheckBox(which_panel, wx.ID_ANY, _(
"Transparent"))
1287 if p.get(
'value',
'') !=
'' and p.get(
'value',[
''])[0] ==
"none":
1288 none_check.SetValue(
True)
1290 none_check.SetValue(
False)
1291 this_sizer.Add(item = none_check, proportion = 0,
1292 flag = wx.ADJUST_MINSIZE | wx.LEFT | wx.RIGHT | wx.TOP, border = 5)
1293 which_sizer.Add(this_sizer)
1295 p[
'wxId'][2] = none_check.GetId()
1298 elif p.get(
'prompt',
'') !=
'color' and p.get(
'element',
'') ==
'file':
1299 if p.get(
'age',
'new_file') ==
'new_file':
1303 fbb = filebrowse.FileBrowseButton(parent = which_panel, id = wx.ID_ANY, fileMask =
'*',
1304 size = globalvar.DIALOG_GSELECT_SIZE, labelText =
'',
1305 dialogTitle = _(
'Choose %s') % \
1306 p.get(
'description',_(
'File')),
1307 buttonText = _(
'Browse'),
1308 startDirectory = os.getcwd(), fileMode = fmode,
1313 which_sizer.Add(item = fbb, proportion = 0,
1314 flag = wx.EXPAND | wx.RIGHT, border = 5)
1319 p[
'wxId'] = [ fbb.GetChildren()[1].GetId() ]
1320 if p.get(
'age',
'new_file') ==
'old_file' and \
1321 UserSettings.Get(group=
'cmd', key=
'interactiveInput', subkey=
'enabled'):
1323 ifbb = wx.TextCtrl(parent = which_panel, id = wx.ID_ANY,
1324 style = wx.TE_MULTILINE,
1326 if p.get(
'value',
'')
and os.path.isfile(p[
'value']):
1327 f = open(p[
'value'])
1328 ifbb.SetValue(
''.join(f.readlines()))
1333 btnLoad = wx.Button(parent = which_panel, id = wx.ID_ANY, label = _(
"&Load"))
1335 btnSave = wx.Button(parent = which_panel, id = wx.ID_SAVEAS)
1338 which_sizer.Add(item = wx.StaticText(parent = which_panel, id = wx.ID_ANY,
1339 label = _(
'or enter values interactively')),
1341 flag = wx.EXPAND | wx.RIGHT | wx.LEFT | wx.BOTTOM, border = 5)
1342 which_sizer.Add(item = ifbb, proportion = 1,
1343 flag = wx.EXPAND | wx.RIGHT | wx.LEFT, border = 5)
1344 btnSizer = wx.BoxSizer(wx.HORIZONTAL)
1345 btnSizer.Add(item = btnLoad, proportion = 0,
1346 flag = wx.ALIGN_RIGHT | wx.RIGHT, border = 10)
1347 btnSizer.Add(item = btnSave, proportion = 0,
1348 flag = wx.ALIGN_RIGHT)
1349 which_sizer.Add(item = btnSizer, proportion = 0,
1350 flag = wx.ALIGN_RIGHT | wx.RIGHT | wx.TOP, border = 5)
1352 p[
'wxId'].append(ifbb.GetId())
1353 p[
'wxId'].append(btnLoad.GetId())
1354 p[
'wxId'].append(btnSave.GetId())
1356 if self.parent.GetName() ==
'MainFrame' and self.parent.modeler:
1357 parChk = wx.CheckBox(parent = which_panel, id = wx.ID_ANY,
1358 label = _(
"Parameterized in model"))
1359 parChk.SetName(
'ModelParam')
1360 parChk.SetValue(p.get(
'parameterized',
False))
1362 p[
'wxId'].append(parChk.GetId())
1364 p[
'wxId'] = [ parChk.GetId() ]
1365 parChk.Bind(wx.EVT_CHECKBOX, self.
OnSetValue)
1366 which_sizer.Add(item = parChk, proportion = 0,
1367 flag = wx.LEFT, border = 20)
1369 if title_txt
is not None:
1371 if len(p[
'values_desc']) > 0:
1373 tooltip += 2 * os.linesep
1376 if len(p[
'values']) == len(p[
'values_desc']):
1377 for i
in range(len(p[
'values'])):
1378 tooltip += p[
'values'][i] +
': ' + p[
'values_desc'][i] + os.linesep
1379 tooltip.strip(os.linesep)
1381 title_txt.SetToolTipString(tooltip)
1383 if p == first_param:
1384 if 'wxId' in p
and len(p[
'wxId']) > 0:
1385 win = self.FindWindowById(p[
'wxId'][0])
1402 for p
in self.task.params:
1403 if p.get(
'gisprompt',
False) ==
False:
1406 prompt = p.get(
'element',
'')
1407 if prompt
in (
'cell',
'vector'):
1408 name = p.get(
'name',
'')
1409 if name
in (
'map',
'input'):
1411 elif prompt ==
'layer':
1413 elif prompt ==
'dbcolumn':
1415 elif prompt ==
'dbdriver':
1417 elif prompt ==
'dbname':
1419 elif prompt ==
'dbtable':
1421 elif prompt ==
'group':
1423 elif prompt ==
'subgroup':
1425 elif prompt ==
'dbase':
1427 elif prompt ==
'location':
1429 elif prompt ==
'mapset':
1434 pColumnIds += p[
'wxId']
1437 pLayerIds += p[
'wxId']
1440 pMap[
'wxId-bind'] = copy.copy(pColumnIds)
1442 pMap[
'wxId-bind'] += pLayerIds
1445 p[
'wxId-bind'] = copy.copy(pColumnIds)
1447 if pDriver
and pTable:
1448 pDriver[
'wxId-bind'] = pTable[
'wxId']
1450 if pDatabase
and pTable:
1451 pDatabase[
'wxId-bind'] = pTable[
'wxId']
1453 if pTable
and pColumnIds:
1454 pTable[
'wxId-bind'] = pColumnIds
1456 if pGroup
and pSubGroup:
1457 pGroup[
'wxId-bind'] = pSubGroup[
'wxId']
1459 if pDbase
and pLocation:
1460 pDbase[
'wxId-bind'] = pLocation[
'wxId']
1462 if pLocation
and pMapset:
1463 pLocation[
'wxId-bind'] = pMapset[
'wxId']
1465 if pLocation
and pMapset
and pMap:
1466 pLocation[
'wxId-bind'] += pMap[
'wxId']
1467 pMapset[
'wxId-bind'] = pMap[
'wxId']
1473 for section
in sections:
1474 tab[section].SetSizer(tabsizer[section])
1475 tabsizer[section].Fit(tab[section])
1476 tab[section].Layout()
1477 minsecsizes = tabsizer[section].GetSize()
1478 maxsizes = map(
lambda x:
max(maxsizes[x], minsecsizes[x]), (0, 1))
1483 for section
in sections:
1486 if self.manualTab.IsLoaded():
1489 self.SetSizer(panelsizer)
1494 def _getValue(self, p):
1495 """!Get value or default value of given parameter
1497 @param p parameter directory
1499 if p.get(
'value',
'') !=
'':
1501 return p.get(
'default',
'')
1504 """!Load file to interactive input"""
1507 for p
in self.task.params:
1508 if 'wxId' in p
and me
in p[
'wxId']:
1509 win[
'file'] = self.FindWindowById(p[
'wxId'][0])
1510 win[
'text'] = self.FindWindowById(p[
'wxId'][1])
1519 message = _(
"Nothing to load."))
1532 """!Save interactive input to the file"""
1535 for p
in self.task.params:
1536 if wId
in p.get(
'wxId', []):
1537 win[
'file'] = self.FindWindowById(p[
'wxId'][0])
1538 win[
'text'] = self.FindWindowById(p[
'wxId'][1])
1547 message = _(
"Nothing to save."))
1550 dlg = wx.FileDialog(parent = self,
1551 message = _(
"Save input as..."),
1552 defaultDir = os.getcwd(),
1553 style = wx.SAVE | wx.FD_OVERWRITE_PROMPT)
1555 if dlg.ShowModal() == wx.ID_OK:
1556 path = dlg.GetPath()
1559 f.write(text + os.linesep)
1568 """File input interactively entered"""
1569 text = event.GetString()
1570 p = self.task.get_param(value = event.GetId(), element =
'wxId', raiseError =
False)
1573 win = self.FindWindowById(p[
'wxId'][0])
1575 filename = win.GetValue()
1578 filename = grass.tempfile()
1579 win.SetValue(filename)
1581 f = open(filename,
"w")
1584 if text[-1] != os.linesep:
1592 for fn, kwargs
in event.data.iteritems():
1595 self.parent.updateValuesHook()
1598 """!Verbosity level changed"""
1599 verbose = self.FindWindowById(self.task.get_flag(
'verbose')[
'wxId'][0])
1600 quiet = self.FindWindowById(self.task.get_flag(
'quiet')[
'wxId'][0])
1601 if event.IsChecked():
1602 if event.GetId() == verbose.GetId():
1603 if quiet.IsChecked():
1604 quiet.SetValue(
False)
1605 self.task.get_flag(
'quiet')[
'value'] =
False
1607 if verbose.IsChecked():
1608 verbose.SetValue(
False)
1609 self.task.get_flag(
'verbose')[
'value'] =
False
1615 sel = self.notebook.GetSelection()
1617 sel = event.GetSelection()
1619 idx = self.notebook.GetPageIndexByName(
'manual')
1620 if idx > -1
and sel == idx:
1623 if not self.manualTab.IsLoaded():
1625 self.manualTab.LoadPage()
1630 myId = event.GetId()
1631 for p
in self.task.params:
1632 if 'wxId' in p
and myId
in p[
'wxId']:
1633 multiple = p[
'wxId'][1]
is not None
1634 hasTransp = p[
'wxId'][2]
is not None
1637 colorchooser = wx.FindWindowById(p[
'wxId'][0])
1638 new_color = colorchooser.GetValue()[:]
1639 new_label = rgb2str.get(new_color,
':'.join(map(str, new_color)))
1640 textCtrl = wx.FindWindowById(p[
'wxId'][1])
1641 val = textCtrl.GetValue()
1643 if val
and val[-1] != sep:
1646 textCtrl.SetValue(val)
1648 elif hasTransp
and wx.FindWindowById(p[
'wxId'][2]).
GetValue():
1649 p[
'value' ] =
'none'
1651 colorchooser = wx.FindWindowById(p[
'wxId'][0])
1652 new_color = colorchooser.GetValue()[:]
1655 new_label = rgb2str.get(new_color,
':'.join(map(str,new_color)))
1656 colorchooser.SetLabel(new_label)
1657 colorchooser.SetColour(new_color)
1658 colorchooser.Refresh()
1659 p[
'value' ] = colorchooser.GetLabel()
1663 """!If we were part of a richer interface, report back the
1664 current command being built.
1666 This method should be set by the parent of this panel if
1667 needed. It's a hook, actually. Beware of what is 'self' in
1668 the method def, though. It will be called with no arguments.
1673 """!Fill the values as a ','-separated string according to
1674 current status of the checkboxes.
1678 for p
in self.task.params:
1679 if 'wxId' in p
and me
in p[
'wxId']:
1681 myIndex = p[
'wxId'].index(me)
1685 for isThere
in theParam.get(
'value',
'').
split(
','):
1686 currentValues[isThere] = 1
1687 theValue = theParam[
'values'][myIndex]
1690 currentValues[ theValue ] = 1
1692 del currentValues[ theValue ]
1695 currentValueList = []
1696 for v
in theParam[
'values']:
1697 if v
in currentValues:
1698 currentValueList.append(v)
1701 theParam[
'value'] =
','.join(currentValueList)
1703 self.OnUpdateValues()
1706 """!Retrieve the widget value and set the task value field
1709 Use for widgets that have a proper GetValue() method, i.e. not
1712 myId = event.GetId()
1713 me = wx.FindWindowById(myId)
1717 for porf
in self.task.params + self.task.flags:
1718 if 'wxId' not in porf:
1720 if myId
in porf[
'wxId']:
1727 if name
in (
'DriverSelect',
'TableSelect',
1728 'LocationSelect',
'MapsetSelect',
'ProjSelect'):
1729 porf[
'value'] = me.GetStringSelection()
1730 elif name ==
'GdalSelect':
1731 porf[
'value'] = event.dsn
1732 elif name ==
'ModelParam':
1733 porf[
'parameterized'] = me.IsChecked()
1734 elif name ==
'LayerSelect':
1735 porf[
'value'] = me.GetValue()
1737 porf[
'value'] = me.GetValue()
1744 """!Shows dialog for symbol selection"""
1745 myId = event.GetId()
1747 for p
in self.task.params:
1748 if 'wxId' in p
and myId
in p[
'wxId']:
1750 dlg = SymbolDialog(self, symbolPath = globalvar.ETCSYMBOLDIR,
1751 currentSymbol = p[
'value'])
1752 if dlg.ShowModal() == wx.ID_OK:
1753 img = dlg.GetSelectedSymbolPath()
1754 p[
'value'] = dlg.GetSelectedSymbolName()
1756 bitmapButton = wx.FindWindowById(p[
'wxId'][0])
1757 label = wx.FindWindowById(p[
'wxId'][1])
1759 bitmapButton.SetBitmapLabel(wx.Bitmap(img +
'.png'))
1760 label.SetLabel(p[
'value'])
1767 """!Update dialog (layers, tables, columns, etc.)
1769 if not hasattr(self.
parent,
"updateThread"):
1774 self.parent.updateThread.Update(UpdateDialog,
1780 self.parent.updateThread.Update(UpdateDialog,
1786 def createCmd(self, ignoreErrors = False, ignoreRequired = False):
1787 """!Produce a command line string (list) or feeding into GRASS.
1789 @param ignoreErrors True then it will return whatever has been
1790 built so far, even though it would not be a correct command
1794 cmd = self.task.get_cmd(ignoreErrors = ignoreErrors,
1795 ignoreRequired = ignoreRequired)
1796 except ValueError, err:
1797 dlg = wx.MessageDialog(parent = self,
1798 message = unicode(err),
1799 caption = _(
"Error in %s") % self.task.name,
1800 style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
1808 width = event.GetSize()[0]
1809 fontsize = self.GetFont().GetPointSize()
1810 text_width =
max(width / (fontsize - 3), 70)
1813 win = self.FindWindowById(id)
1814 label = win.GetLabel()
1815 label_new =
'\n'.join(textwrap.wrap(label, text_width))
1816 win.SetLabel(label_new)
1821 def __init__(self, parent = None, show = True, modal = False,
1822 centreOnParent =
False, checkError =
False):
1823 """!Parses GRASS commands when module is imported and used from
1837 _blackList[
'enabled'] =
True
1839 _blackList[
'enabled'] =
False
1842 """!Get validated command"""
1848 Note: cmd is given as list
1850 If command is given with options, return validated cmd list:
1851 - add key name for first parameter if not given
1852 - change mapname to mapname@mapset
1856 if completed ==
None:
1861 get_dcmd = completed[0]
1862 layer = completed[1]
1864 dcmd_params.update(completed[2])
1870 blackList = _blackList)
1871 except (grass.ScriptError, ValueError), e:
1875 if completed
is not None:
1876 if 'params' in dcmd_params:
1877 self.grass_task.params = dcmd_params[
'params']
1878 if 'flags' in dcmd_params:
1879 self.grass_task.flags = dcmd_params[
'flags']
1885 cmd_validated = [cmd[0]]
1886 for option
in cmd[1:]:
1887 if option[0] ==
'-':
1888 if option[1] ==
'-':
1889 self.grass_task.set_flag(option[2:],
True)
1891 self.grass_task.set_flag(option[1],
True)
1892 cmd_validated.append(option)
1895 key, value = option.split(
'=', 1)
1897 params = self.grass_task.get_options()[
'params']
1900 key = params[0][
'name']
1903 raise gcmd.GException, _(
"Unable to parse command '%s'") %
' '.join(cmd)
1907 element = self.grass_task.get_param(key, raiseError =
False)
1909 err.append(_(
"%(cmd)s: parameter '%(key)s' not available") % \
1913 element = element[
'element']
1915 if element
in [
'cell',
'vector']:
1917 if '@' not in value:
1918 mapset = grass.find_file(value, element)[
'mapset']
1919 curr_mapset = grass.gisenv()[
'MAPSET']
1920 if mapset
and mapset != curr_mapset:
1921 value = value +
'@' + mapset
1923 self.grass_task.set_param(key, value)
1924 cmd_validated.append(key +
'=' + value)
1930 if self.
show is not None:
1933 get_dcmd = get_dcmd, layer = layer)
1937 if get_dcmd
is not None:
1939 get_dcmd(dcmd =
None, layer = layer, params =
None,
1942 if self.
show is not None:
1943 self.mf.notebookpanel.OnUpdateSelection(
None)
1944 if self.
show is True:
1946 self.mf.CentreOnParent()
1948 self.mf.CenterOnScreen()
1949 self.mf.Show(self.
show)
1950 self.mf.MakeModal(self.
modal)
1952 self.mf.OnApply(
None)
1962 """!Get parameter key for input raster/vector map
1964 @param cmd module name
1966 @return parameter key
1967 @return None on failure
1971 enc = locale.getdefaultlocale()[1]
1972 if enc
and enc.lower() ==
"cp932":
1973 p = re.compile(
'encoding="' + enc +
'"', re.IGNORECASE)
1974 tree = etree.fromstring(p.sub(
'encoding="utf-8"',
1975 gtask.get_interface_description(cmd).
decode(enc).encode(
'utf-8')))
1977 tree = etree.fromstring(gtask.get_interface_description(cmd))
1978 self.
grass_task = gtask.processTask(tree).get_task()
1980 for p
in self.grass_task.params:
1981 if p.get(
'name',
'')
in (
'input',
'map'):
1982 age = p.get(
'age',
'')
1983 prompt = p.get(
'prompt',
'')
1984 element = p.get(
'element',
'')
1985 if age ==
'old' and \
1986 element
in (
'cell',
'grid3',
'vector')
and \
1987 prompt
in (
'raster',
'3d-raster',
'vector'):
1988 return p.get(
'name',
None)
1992 """!Stand-alone GRASS command GUI
1996 wx.App.__init__(self,
False)
1999 msg = self.grass_task.get_error_msg()
2001 gcmd.GError(msg +
'\n\nTry to set up GRASS_ADDON_PATH variable.')
2005 self.mf.CentreOnScreen()
2007 self.SetTopWindow(self.
mf)
2011 if __name__ ==
"__main__":
2013 gettext.install(
'grasswxpy', os.path.join(os.getenv(
"GISBASE"),
'locale'), unicode =
True)
2015 if len(sys.argv) == 1:
2016 sys.exit(_(
"usage: %s <grass command>") % sys.argv[0])
2018 if sys.argv[1] !=
'test':
2022 task.set_options(cmd[1:])
2027 if os.getenv(
"GISBASE")
is not None:
2028 task = gtask.grassTask(
"d.vect")
2029 task.get_param(
'map')[
'value'] =
"map_name"
2030 task.get_flag(
'v')[
'value'] =
True
2031 task.get_param(
'layer')[
'value'] = 1
2032 task.get_param(
'bcolor')[
'value'] =
"red"
2033 assert ' '.join(task.get_cmd()) ==
"d.vect -v map = map_name layer = 1 bcolor = red"
2036 task = gtask.grassTask()
2037 task.name =
"TestTask"
2038 task.description =
"This is an artificial grassTask() object intended for testing purposes."
2039 task.keywords = [
"grass",
"test",
"task"]
2043 "description" :
"Descriptions go into tooltips if labels are present, like this one",
2044 "label" :
"Enter some text",
2046 "name" :
"hidden_text",
2047 "description" :
"This text should not appear in the form",
2050 "name" :
"text_default",
2051 "description" :
"Enter text to override the default",
2052 "default" :
"default text"
2054 "name" :
"text_prefilled",
2055 "description" :
"You should see a friendly welcome message here",
2056 "value" :
"hello, world"
2058 "name" :
"plain_color",
2059 "description" :
"This is a plain color, and it is a compulsory parameter",
2064 "name" :
"transparent_color",
2065 "description" :
"This color becomes transparent when set to none",
2066 "guisection" :
"tab",
2071 "description" :
"A multiple selection",
2072 'default':
u'red,green,blue',
2074 'guisection':
'tab',
2078 'values': [
'red',
'green',
u'yellow',
u'blue',
u'purple',
u'other']
2081 "description" :
"A single multiple-choice selection",
2082 'values': [
'red',
'green',
u'yellow',
u'blue',
u'purple',
u'other'],
2083 "guisection" :
"tab"
2085 "name" :
"large_multi",
2086 "description" :
"A large multiple selection",
2087 "gisprompt" :
False,
2090 "values" : str2rgb.keys() + map(str, str2rgb.values())
2093 "description" :
"A file selector",
2101 "description" :
"Some flag, will appear in Main since it is required",
2105 "description" :
"pre-filled flag, will appear in options since it is not required",
2108 "name" :
"hidden_flag",
2109 "description" :
"hidden flag, should not be changeable",
def normalize_whitespace
Remove redundant whitespace from a string.
Creates combo box for selecting data layers defined for vector.
Various dialogs used in wxGUI.
def GetRealCmd
Return real command name - only for MS Windows.
def split
Platform spefic shlex.split.
Widget for selecting input raster/vector map used by r.proj/v.proj modules.
Creates combo box for selecting attribute tables from the database.
Widget for selecting GRASS Database.
Creates combo box for selecting database driver.
Widget for selecting GRASS location.
Run command in separate thread.
Widget for selecting GRASS mapset.
Widget for selecting subgroups.
Creates combo box for selecting columns in the attribute table for a vector map.
Creates combo box for selecting database driver.
Class providing information about attribute tables linked to a vector map.
tuple fn
if textDict['border'] != 'none' and not rot: units = UnitConversion(self) borderWidth = units...