[GRASS-SVN] r42280 -
grass/branches/develbranch_6/gui/wxpython/gui_modules
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue May 18 05:04:38 EDT 2010
Author: martinl
Date: 2010-05-18 05:04:38 -0400 (Tue, 18 May 2010)
New Revision: 42280
Modified:
grass/branches/develbranch_6/gui/wxpython/gui_modules/ghelp.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/gmodeler.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py
Log:
wxGUI/modeler: parametrization implemented (including model file
settings)
(merge r42272 from trunk)
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/ghelp.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/ghelp.py 2010-05-18 06:56:03 UTC (rev 42279)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/ghelp.py 2010-05-18 09:04:38 UTC (rev 42280)
@@ -195,6 +195,11 @@
desc = self.cmdPrompt.GetCommandDesc(cmd)
if self.showTip:
self.searchTip.SetLabel(desc)
+
+ def Reset(self):
+ """!Reset widget"""
+ self.searchBy.SetSelection(0)
+ self.search.SetValue('')
class MenuTreeWindow(wx.Panel):
"""!Show menu tree"""
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/gmodeler.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/gmodeler.py 2010-05-18 06:56:03 UTC (rev 42279)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/gmodeler.py 2010-05-18 09:04:38 UTC (rev 42280)
@@ -16,7 +16,8 @@
- WriteModelFile
- PreferencesDialog
- PropertiesDialog
-
+ - ModelParamDialog
+
(C) 2010 by the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.
@@ -32,6 +33,8 @@
import getpass
import stat
import textwrap
+import tempfile
+import copy
try:
import xml.etree.ElementTree as etree
@@ -133,7 +136,7 @@
y = action['pos'][1],
width = action['size'][0],
height = action['size'][1],
- cmd = action['cmd'])
+ task = action['task'])
actionItem.SetId(action['id'])
self.actions.append(actionItem)
@@ -243,7 +246,35 @@
for data in self.data:
data.Update()
+
+ def IsParametrized(self):
+ """!Return True if model is parametrized"""
+ if self.Parametrize():
+ return True
+
+ return False
+ def Parametrize(self):
+ """!Return parametrized options"""
+ result = dict()
+ for action in self.actions:
+ name = action.GetName()
+ params = action.GetParams()
+ for f in params['flags']:
+ if f.get('parametrized', False):
+ if not result.has_key(name):
+ result[name] = { 'flags' : list(),
+ 'params': list() }
+ result[name]['flags'].append(f)
+ for p in params['params']:
+ if p.get('parametrized', False):
+ if not result.has_key(name):
+ result[name] = { 'flags' : list(),
+ 'params': list() }
+ result[name]['params'].append(p)
+
+ return result
+
class ModelFrame(wx.Frame):
def __init__(self, parent, id = wx.ID_ANY,
title = _("GRASS GIS Graphical Modeler"), **kwargs):
@@ -571,12 +602,34 @@
if ret != wx.ID_YES:
return
+ params = self.model.Parametrize()
+ if params:
+ dlg = ModelParamDialog(parent = self,
+ params = params)
+ dlg.CenterOnParent()
+
+ ret = dlg.ShowModal()
+ if ret != wx.ID_OK:
+ dlg.Destroy()
+ return
+
self.goutput.cmdThread.SetId(-1)
for action in self.model.GetActions():
+ name = action.GetName()
+ if params.has_key(name):
+ paramsOrig = action.GetParams(dcopy = True)
+ action.MergeParams(params[name])
+
self.SetStatusText(_('Running model...'), 0)
self.goutput.RunCmd(command = action.GetLog(string = False),
onDone = self.OnDone)
+
+ if params.has_key(name):
+ action.SetParams(paramsOrig)
+ if params:
+ dlg.Destroy()
+
def OnDone(self, returncode):
"""!Computation finished"""
self.SetStatusText('', 0)
@@ -836,12 +889,13 @@
# show properties dialog
win = action.GetPropDialog()
- if not win:
+ if not win and action.GetLog(string = False):
module = menuform.GUI().ParseCommand(action.GetLog(string = False),
completed = (self.GetOptData, action, action.GetParams()),
parentframe = self, show = True)
- elif not win.IsShown():
+ elif win and not win.IsShown():
win.Show()
+
if win:
win.Raise()
@@ -949,7 +1003,7 @@
self.canvas.Refresh()
if dcmd:
- layer.SetProperties(dcmd, params, propwin)
+ layer.SetProperties(params, propwin)
self.SetStatusText(layer.GetLog(), 0)
@@ -1009,13 +1063,24 @@
self.canvas.Refresh(True)
def WriteModelFile(self, filename):
- """!Save model to model file
+ """!Save model to model file, recover original file on error.
@return True on success
@return False on failure
"""
+ tmpfile = tempfile.TemporaryFile(mode='w+b')
try:
- file = open(filename, "w")
+ WriteModelFile(fd = tmpfile, actions = self.model.GetActions(), data = self.model.GetData())
+ except StandardError:
+ GMessage(parent = self,
+ message = _("Writing current settings to model file failed."))
+ return False
+
+ try:
+ mfile = open(filename, "w")
+ tmpfile.seek(0)
+ for line in tmpfile.readlines():
+ mfile.write(line)
except IOError:
wx.MessageBox(parent = self,
message = _("Unable to open file <%s> for writing.") % filename,
@@ -1023,18 +1088,8 @@
style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
return False
- try:
- WriteModelFile(fd = file, actions = self.model.GetActions(), data = self.model.GetData())
- except StandardError:
- file.close()
-
- GMessage(parent = self,
- message = _("Writing current settings to model file failed."))
-
- return False
+ mfile.close()
- file.close()
-
return True
class ModelCanvas(ogl.ShapeCanvas):
@@ -1074,20 +1129,23 @@
class ModelAction(ogl.RectangleShape):
"""!Action class (GRASS module)"""
- def __init__(self, parent, x, y, cmd = None, width = None, height = None):
+ def __init__(self, parent, x, y, cmd = None, task = None, width = None, height = None):
self.parent = parent
- self.cmd = cmd
+ self.task = task
if not width:
width = UserSettings.Get(group='modeler', key='action', subkey=('size', 'width'))
if not height:
height = UserSettings.Get(group='modeler', key='action', subkey=('size', 'height'))
- if self.cmd:
- task = menuform.GUI().ParseCommand(cmd = self.cmd,
- show = None)
- self.params = task.get_options()
+ if cmd:
+ self.task = menuform.GUI().ParseCommand(cmd = self.cmd,
+ show = None)
else:
- self.params = None
+ if task:
+ self.task = task
+ else:
+ self.task = None
+
self.propWin = None
self.id = -1 # used for gxm file
@@ -1103,10 +1161,11 @@
self.SetY(y)
self.SetPen(wx.BLACK_PEN)
self._setBrush(False)
- if self.cmd and len(self.cmd) > 0:
- self.AddText(self.cmd[0])
+ cmd = self.task.getCmd(ignoreErrors = False)
+ if cmd and len(cmd) > 0:
+ self.AddText(cmd[0])
else:
- self.AddText('<<module>>')
+ self.AddText('<<%s>>' % _("module"))
def _setBrush(self, isvalid):
"""!Set brush"""
@@ -1130,10 +1189,10 @@
"""!Set id"""
self.id = id
- def SetProperties(self, dcmd, params, propwin):
+ def SetProperties(self, params, propwin):
"""!Record properties dialog"""
- self.cmd = dcmd
- self.params = params
+ self.task.params = params['params']
+ self.task.flags = params['flags']
self.propWin = propwin
def GetPropDialog(self):
@@ -1142,30 +1201,44 @@
def GetLog(self, string = True):
"""!Get logging info"""
+ cmd = self.task.getCmd(ignoreErrors = True)
if string:
- if self.cmd is None:
+ if cmd is None:
return ''
else:
- return ' '.join(self.cmd)
+ return ' '.join(cmd)
- return self.cmd
+ return cmd
def GetName(self):
"""!Get name"""
- if self.cmd and len(self.cmd) > 0:
- return self.cmd[0]
+ cmd = self.task.getCmd(ignoreErrors = True)
+ if cmd and len(cmd) > 0:
+ return cmd[0]
return _('unknown')
- def GetParams(self):
+ def GetParams(self, dcopy = False):
"""!Get dictionary of parameters"""
- return self.params
+ if dcopy:
+ return copy.deepcopy(self.task.get_options())
+
+ return self.task.get_options()
- def SetParams(self, params, cmd):
+ def SetParams(self, params):
"""!Set dictionary of parameters"""
- self.params = params
- self.cmd = cmd
-
+ self.task.params = params['params']
+ self.task.flags = params['flags']
+
+ def MergeParams(self, params):
+ """!Merge dictionary of parameters"""
+ for f in params['flags']:
+ self.task.set_flag(f['name'],
+ f.get('value', False))
+ for p in params['params']:
+ self.task.set_param(p['name'],
+ p.get('value', ''))
+
def SetValid(self, isvalid):
"""!Set instance to be valid/invalid"""
self.isValid = isvalid
@@ -1277,9 +1350,8 @@
task = menuform.GUI().ParseCommand(cmd = action.GetLog(string = False),
show = None)
task.set_param(self.name, self.value)
- action.SetParams(params = task.get_options(),
- cmd = task.getCmd(ignoreErrors = True))
-
+ action.SetParams(params = task.get_options())
+
def GetActions(self, direction):
"""!Get related actions
@@ -1546,6 +1618,10 @@
self.btnCancel = wx.Button(self.panel, wx.ID_CANCEL)
self.btnOk = wx.Button(self.panel, wx.ID_OK)
self.btnOk.SetDefault()
+ self.btnOk.Enable(False)
+
+ self.cmd_prompt.Bind(wx.EVT_KEY_UP, self.OnText)
+ self.Bind(wx.EVT_BUTTON, self.OnOk, self.btnOk)
self._layout()
@@ -1589,11 +1665,37 @@
def OnOk(self, event):
self.btnOk.SetFocus()
+ cmd = self.GetCmd()
+ if len(cmd) < 1:
+ GMessage(parent = self,
+ message = _("Command not defined.\n\n"
+ "Unable to add new action to the model."))
+ return
+
+ if cmd[0] not in globalvar.grassCmd['all']:
+ GMessage(parent = self,
+ message = _("'%s' is not a GRASS module.\n\n"
+ "Unable to add new action to the model.") % cmd[0])
+ return
+
+ self.EndModal(wx.ID_OK)
+
+ def OnText(self, event):
+ if self.cmd_prompt.AutoCompActive():
+ return
+
+ entry = self.cmd_prompt.GetTextLeft()
+ if len(entry) > 0:
+ self.btnOk.Enable()
+ else:
+ self.btnOk.Enable(False)
+
+ event.Skip()
+
def Reset(self):
"""!Reset dialog"""
- self.searchBy.SetSelection(0)
- self.search.SetValue('')
+ self.search.Reset()
self.cmd_prompt.OnCmdErase(None)
class ModelRelation(ogl.LineShape):
@@ -1653,16 +1755,16 @@
task = action.find('task')
if task:
- cmd = self._processTask(task)
+ task = self._processTask(task)
else:
- cmd = None
-
+ task = None
+
aId = int(action.get('id', -1))
- self.actions.append({ 'pos' : pos,
- 'size': size,
- 'cmd' : cmd,
- 'id' : aId })
+ self.actions.append({ 'pos' : pos,
+ 'size' : size,
+ 'task' : task,
+ 'id' : aId })
def _getDim(self, node):
"""!Get position and size of shape"""
@@ -1720,25 +1822,49 @@
'from' : fromDir })
def _processTask(self, node):
- """!Process task"""
+ """!Process task
+
+ @return grassTask instance
+ @return None on error
+ """
cmd = list()
+ parametrized = list()
+
name = node.get('name', None)
if not name:
- return cmd
+ return None
+
cmd.append(name)
# flags
- for p in node.findall('flag'):
- flag = p.get('name', '')
+ for f in node.findall('flag'):
+ flag = f.get('name', '')
+ if f.get('parametrized', '0') == '1':
+ parametrized.append(('flag', flag))
+ if f.get('value', '1') == '0':
+ continue
if len(flag) > 1:
cmd.append('--' + flag)
else:
cmd.append('-' + flag)
# parameters
for p in node.findall('parameter'):
- cmd.append('%s=%s' % (p.get('name', ''),
+ name = p.get('name', '')
+ if p.find('parametrized') is not None:
+ parametrized.append(('param', name))
+ cmd.append('%s=%s' % (name,
self._filterValue(self._getNodeText(p, 'value'))))
- return cmd
+
+ task = menuform.GUI().ParseCommand(cmd = cmd,
+ show = None)
+
+ for opt, name in parametrized:
+ if opt == 'flag':
+ task.set_flag(name, True, element = 'parametrized')
+ else:
+ task.set_param(name, True, element = 'parametrized')
+
+ return task
class WriteModelFile:
"""!Generic class for writing model file"""
@@ -1788,9 +1914,17 @@
for key, val in action.GetParams().iteritems():
if key == 'flags':
for f in val:
- if f.get('value', False):
- self.fd.write('%s<flag name="%s" />\n' %
- (' ' * self.indent, f.get('name', '')))
+ if f.get('value', False) or f.get('parametrized', False):
+ if f.get('parametrized', False):
+ if f.get('value', False) == False:
+ self.fd.write('%s<flag name="%s" value="0" parametrized="1" />\n' %
+ (' ' * self.indent, f.get('name', '')))
+ else:
+ self.fd.write('%s<flag name="%s" parametrized="1" />\n' %
+ (' ' * self.indent, f.get('name', '')))
+ else:
+ self.fd.write('%s<flag name="%s" />\n' %
+ (' ' * self.indent, f.get('name', '')))
else: # parameter
for p in val:
if not p.get('value', ''):
@@ -1798,6 +1932,8 @@
self.fd.write('%s<parameter name="%s">\n' %
(' ' * self.indent, p.get('name', '')))
self.indent += 4
+ if p.get('parametrized', False):
+ self.fd.write('%s<parametrized />\n' % (' ' * self.indent))
self.fd.write('%s<value>%s</value>\n' %
(' ' * self.indent, self._filterValue(p.get('value', ''))))
self.indent -= 4
@@ -2200,7 +2336,71 @@
self.name.SetValue(prop['name'])
self.desc.SetValue(prop['desc'])
self.author.SetValue(prop['author'])
+
+class ModelParamDialog(wx.Dialog):
+ def __init__(self, parent, params, id = wx.ID_ANY, title = _("Model parameters"),
+ style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
+ """!Model parameters dialog
+ """
+ self.parent = parent
+ self.params = params
+ wx.Dialog.__init__(self, parent = parent, id = id, title = title, style = style, **kwargs)
+
+ self.notebook = FN.FlatNotebook(self, id = wx.ID_ANY,
+ style = FN.FNB_FANCY_TABS |
+ FN.FNB_BOTTOM |
+ FN.FNB_NO_NAV_BUTTONS |
+ FN.FNB_NO_X_BUTTON)
+ panel = self._createPages()
+ wx.CallAfter(self.notebook.SetSelection, 0)
+
+ self.btnCancel = wx.Button(parent = self, id = wx.ID_CANCEL)
+ self.btnRun = wx.Button(parent = self, id = wx.ID_OK,
+ label = _("&Run"))
+ self.btnRun.SetDefault()
+
+ self._layout()
+
+ size = self.GetBestSize()
+ self.SetMinSize(size)
+ self.SetSize((size.width, size.height +
+ panel.constrained_size[1] -
+ panel.panelMinHeight))
+
+ def _layout(self):
+ btnSizer = wx.StdDialogButtonSizer()
+ btnSizer.AddButton(self.btnCancel)
+ btnSizer.AddButton(self.btnRun)
+ btnSizer.Realize()
+
+ mainSizer = wx.BoxSizer(wx.VERTICAL)
+ mainSizer.Add(item = self.notebook, proportion = 1,
+ flag = wx.EXPAND)
+ mainSizer.Add(item=btnSizer, proportion=0,
+ flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
+
+ self.SetSizer(mainSizer)
+ mainSizer.Fit(self)
+
+ def _createPages(self):
+ """!Create for each parametrized module its own page"""
+ for name, params in self.params.iteritems():
+ panel = self._createPage(name, params)
+ self.notebook.AddPage(panel, text = name)
+
+ return panel
+
+ def _createPage(self, name, params):
+ """!Define notebook page"""
+ task = menuform.grassTask(name)
+ task.flags = params['flags']
+ task.params = params['params']
+
+ panel = menuform.cmdPanel(parent = self, id = wx.ID_ANY, task = task)
+
+ return panel
+
def main():
app = wx.PySimpleApp()
wx.InitAllImageHandlers()
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py 2010-05-18 06:56:03 UTC (rev 42279)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py 2010-05-18 09:04:38 UTC (rev 42280)
@@ -188,12 +188,11 @@
if prompt == 'vector':
name = p.get('name', '')
if name in ('map', 'input'):
- self.eventId = p['wxId']
+ self.eventId = p['wxId'][0]
if self.eventId is None:
return
p = self.task.get_param(self.eventId, element='wxId', raiseError=False)
-
if not p or \
not p.has_key('wxId-bind'):
return
@@ -347,22 +346,30 @@
def get_param(self, value, element='name', raiseError=True):
"""!Find and return a param by name."""
- for p in self.params:
- if p[element] is None:
- continue
- if type(value) == types.StringType:
- if p[element][:len(value)] == value:
- return p
- else:
- if p[element] == value:
- return p
+ try:
+ for p in self.params:
+ val = p[element]
+ if val is None:
+ continue
+ if type(val) in (types.ListType, types.TupleType):
+ if value in val:
+ return p
+ elif type(val) == types.StringType:
+ if p[element][:len(value)] == value:
+ return p
+ else:
+ if p[element] == value:
+ return p
+ except KeyError:
+ pass
+
if raiseError:
- raise ValueError, _("Parameter not found: %s") % \
- value
+ raise ValueError, _("Parameter element '%(element)s' not found: '%(value)s'") % \
+ { 'element' : element, 'value' : value }
else:
return None
-
- def set_param(self, aParam, aValue):
+
+ def set_param(self, aParam, aValue, element = 'value'):
"""
Set param value/values.
"""
@@ -371,7 +378,7 @@
except ValueError:
return
- param['value'] = aValue
+ param[element] = aValue
def get_flag(self, aFlag):
"""
@@ -382,7 +389,7 @@
return f
raise ValueError, _("Flag not found: %s") % aFlag
- def set_flag(self, aFlag, aValue):
+ def set_flag(self, aFlag, aValue, element = 'value'):
"""
Enable / disable flag.
"""
@@ -391,7 +398,7 @@
except ValueError:
return
- param['value'] = aValue
+ param[element] = aValue
def getCmdError(self):
"""!Get error string produced by getCmd(ignoreErrors = False)
@@ -573,12 +580,17 @@
The command is checked and sent to the clipboard when clicking
'Copy'.
"""
- def __init__(self, parent, ID, task_description, get_dcmd=None, layer=None):
+ def __init__(self, parent, ID, task_description,
+ get_dcmd = None, layer = None):
self.get_dcmd = get_dcmd
- self.layer = layer
- self.task = task_description
- self.parent = parent # LayerTree | None
-
+ self.layer = layer
+ self.task = task_description
+ self.parent = parent # LayerTree | Modeler | None | ...
+ if parent and parent.GetName() == 'Modeler':
+ self.modeler = self.parent
+ else:
+ self.modeler = None
+
# module name + keywords
if self.task.name.split('.')[-1] in ('py', 'sh'):
title = str(self.task.name.rsplit('.',1)[0])
@@ -591,7 +603,8 @@
pass
wx.Frame.__init__(self, parent=parent, id=ID, title=title,
- pos=wx.DefaultPosition, style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)
+ pos=wx.DefaultPosition, style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL,
+ name = "MainFrame")
self.locale = wx.Locale(language = wx.LANGUAGE_DEFAULT)
@@ -607,7 +620,7 @@
# set apropriate output window
if self.parent:
- self.standalone = False
+ self.standalone = False
else:
self.standalone = True
@@ -640,10 +653,8 @@
self.Layout()
# notebooks
- self.notebookpanel = cmdPanel (parent=self.panel, task=self.task, standalone=self.standalone,
- mainFrame=self)
- ### add 'command output' tab also for dialog open from menu
- # if self.standalone:
+ self.notebookpanel = cmdPanel(parent = self.panel, task = self.task,
+ mainFrame = self)
self.goutput = self.notebookpanel.goutput
self.notebookpanel.OnUpdateValues = self.updateValuesHook
guisizer.Add (item=self.notebookpanel, proportion=1, flag=wx.EXPAND)
@@ -718,7 +729,7 @@
guisizer.Add(item=btnsizer, proportion=0, flag=wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT,
border = 30)
- if self.parent and self.parent.GetName() != 'Modeler':
+ if self.parent and not self.modeler:
addLayer = False
for p in self.task.params:
if p.get('age', 'old') == 'new' and \
@@ -774,10 +785,10 @@
self.Layout()
#keep initial window size limited for small screens
- width,height = self.GetSizeTuple()
+ width, height = self.GetSizeTuple()
if width > 640: width = 640
if height > 480: height = 480
- self.SetSize((width,height))
+ self.SetSize((width, height))
# fix goutput's pane size
if self.goutput:
@@ -820,7 +831,7 @@
def OnApply(self, event):
"""!Apply the command"""
- if self.parent and self.parent.GetName() == 'Modeler':
+ if self.modeler:
cmd = self.createCmd(ignoreErrors = True)
else:
cmd = self.createCmd()
@@ -919,16 +930,18 @@
return self.notebookpanel.createCmd(ignoreErrors=ignoreErrors)
class cmdPanel(wx.Panel):
+ """!A panel containing a notebook dividing in tabs the different
+ guisections of the GRASS cmd.
"""
- A panel containing a notebook dividing in tabs the different guisections of the GRASS cmd.
- """
- def __init__( self, parent, task, standalone, mainFrame, *args, **kwargs ):
- wx.Panel.__init__( self, parent, *args, **kwargs )
-
- self.parent = mainFrame
+ def __init__(self, parent, task, id = wx.ID_ANY, mainFrame = None, *args, **kwargs):
+ if mainFrame:
+ self.parent = mainFrame
+ else:
+ self.parent = parent
self.task = task
- fontsize = 10
+ wx.Panel.__init__(self, parent, id = id, *args, **kwargs)
+
# Determine tab layout
sections = []
is_section = {}
@@ -978,7 +991,7 @@
# are we running from command line?
### add 'command output' tab regardless standalone dialog
- if self.parent.get_dcmd is None:
+ if self.parent.GetName() == "MainFrame" and self.parent.get_dcmd is None:
self.goutput = goutput.GMConsole(parent=self, margin=False,
pageid=self.notebook.GetPageCount())
self.goutputId = self.notebook.GetPageCount()
@@ -1028,8 +1041,22 @@
flag=wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
which_sizer.Add(item=title_sizer, proportion=0,
flag=wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, border=5)
- f['wxId'] = chk.GetId()
+ f['wxId'] = [ chk.GetId(), ]
chk.Bind(wx.EVT_CHECKBOX, self.OnSetValue)
+
+ if self.parent.GetName() == 'MainFrame' and self.parent.modeler:
+ parChk = wx.CheckBox(parent = which_panel, id = wx.ID_ANY,
+ label = _("Parametrized in model"))
+ parChk.SetName('ModelParam')
+ parChk.SetValue(f.get('parametrized', False))
+ if f.has_key('wxId'):
+ f['wxId'].append(parChk.GetId())
+ else:
+ f['wxId'] = [ parChk.GetId() ]
+ parChk.Bind(wx.EVT_CHECKBOX, self.OnSetValue)
+ which_sizer.Add(item = parChk, proportion = 0,
+ flag = wx.LEFT, border = 20)
+
if f['name'] in ('verbose', 'quiet'):
chk.Bind(wx.EVT_CHECKBOX, self.OnVerbosity)
vq = UserSettings.Get(group='cmd', key='verbosity', subkey='selection')
@@ -1115,7 +1142,7 @@
isEnabled[ defval ] = 'yes'
# for multi checkboxes, this is an array of all wx IDs
# for each individual checkbox
- p[ 'wxId' ] = []
+ p['wxId'] = list()
idx = 0
for val in valuelist:
try:
@@ -1125,7 +1152,7 @@
chkbox = wx.CheckBox( parent=which_panel,
label = text_beautify(label))
- p[ 'wxId' ].append( chkbox.GetId() )
+ p['wxId'].append( chkbox.GetId() )
if isEnabled.has_key(val):
chkbox.SetValue( True )
hSizer.Add( item=chkbox, proportion=0,
@@ -1169,7 +1196,7 @@
which_sizer.Add(item=txt2, proportion=0,
flag=style, border=5)
- p['wxId'] = txt2.GetId()
+ p['wxId'] = [ txt2.GetId(), ]
txt2.Bind(wx.EVT_TEXT, self.OnSetValue)
else:
# list of values (combo)
@@ -1181,7 +1208,7 @@
cb.SetValue(p['value']) # parameter previously set
which_sizer.Add( item=cb, proportion=0,
flag=wx.ADJUST_MINSIZE | wx.BOTTOM | wx.LEFT, border=5)
- p['wxId'] = cb.GetId()
+ p['wxId'] = [ cb.GetId(), ]
cb.Bind( wx.EVT_COMBOBOX, self.OnSetValue)
cb.Bind(wx.EVT_TEXT, self.OnSetValue)
@@ -1237,7 +1264,7 @@
which_sizer.Add(item=txt3, proportion=0,
flag=style, border=5)
- p['wxId'] = txt3.GetId()
+ p['wxId'] = [ txt3.GetId(), ]
#
# element selection tree combobox (maps, icons, regions, etc.)
@@ -1276,7 +1303,7 @@
# A select.Select is a combobox with two children: a textctl and a popupwindow;
# we target the textctl here
- p['wxId'] = selection.GetChildren()[0].GetId()
+ p['wxId'] = [ selection.GetChildren()[0].GetId(), ]
selection.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnSetValue)
if p.get('prompt', '') in ('vector', 'group'):
selection.Bind(wx.EVT_TEXT, self.OnUpdateSelection)
@@ -1354,7 +1381,7 @@
### win.Bind(wx.EVT_COMBOBOX, self.OnSetValue)
win.Bind(wx.EVT_TEXT, self.OnSetValue)
- p['wxId'] = win.GetId()
+ p['wxId'] = [ win.GetId(), ]
which_sizer.Add(item=win, proportion=0,
flag=wx.ADJUST_MINSIZE | wx.BOTTOM | wx.LEFT, border=5)
@@ -1386,7 +1413,6 @@
none_check.SetValue(True)
else:
none_check.SetValue(False)
- # none_check.SetFont( wx.Font( fontsize, wx.FONTFAMILY_DEFAULT, wx.NORMAL, text_style, 0, ''))
this_sizer.Add(item=none_check, proportion=0,
flag=wx.ADJUST_MINSIZE | wx.LEFT | wx.RIGHT | wx.TOP, border=5)
which_sizer.Add( this_sizer )
@@ -1410,8 +1436,21 @@
# A file browse button is a combobox with two children:
# a textctl and a button;
# we have to target the button here
- p['wxId'] = fbb.GetChildren()[1].GetId()
-
+ p['wxId'] = [ fbb.GetChildren()[1].GetId(), ]
+
+ if self.parent.GetName() == 'MainFrame' and self.parent.modeler:
+ parChk = wx.CheckBox(parent = which_panel, id = wx.ID_ANY,
+ label = _("Parametrized in model"))
+ parChk.SetName('ModelParam')
+ parChk.SetValue(p.get('parametrized', False))
+ if p.has_key('wxId'):
+ p['wxId'].append(parChk.GetId())
+ else:
+ p['wxId'] = [ parChk.GetId() ]
+ parChk.Bind(wx.EVT_CHECKBOX, self.OnSetValue)
+ which_sizer.Add(item = parChk, proportion = 0,
+ flag = wx.LEFT, border = 20)
+
if title_txt is not None:
# create tooltip if given
if len(p['values_desc']) > 0:
@@ -1428,7 +1467,7 @@
if p == first_param:
if type(p['wxId']) == type(1):
- self.FindWindowById(p['wxId']).SetFocus()
+ self.FindWindowById(p['wxId'][0]).SetFocus()
#
# set widget relations for OnUpdateSelection
@@ -1468,10 +1507,10 @@
pColumnIds = []
for p in pColumn:
- pColumnIds.append(p['wxId'])
+ pColumnIds += p['wxId']
pLayerIds = []
for p in pLayer:
- pLayerIds.append(p['wxId'])
+ pLayerIds += p['wxId']
if pMap:
pMap['wxId-bind'] = copy.copy(pColumnIds)
@@ -1482,10 +1521,10 @@
p['wxId-bind'] = copy.copy(pColumnIds)
if pDriver and pTable:
- pDriver['wxId-bind'] = [pTable['wxId'], ]
+ pDriver['wxId-bind'] = pTable['wxId']
if pDatabase and pTable:
- pDatabase['wxId-bind'] = [pTable['wxId'], ]
+ pDatabase['wxId-bind'] = pTable['wxId']
if pTable and pColumnIds:
pTable['wxId-bind'] = pColumnIds
@@ -1522,7 +1561,7 @@
self.hasMain = tab.has_key( _('Required') ) # publish, to enclosing Frame for instance
self.Bind(EVT_DIALOG_UPDATE, self.OnUpdateDialog)
-
+
def OnUpdateDialog(self, event):
for fn, kwargs in event.data.iteritems():
fn(**kwargs)
@@ -1564,7 +1603,7 @@
def OnColorChange( self, event ):
myId = event.GetId()
for p in self.task.params:
- if 'wxId' in p and type( p['wxId'] ) == type( [] ) and myId in p['wxId']:
+ if 'wxId' in p and myId in p['wxId']:
has_button = p['wxId'][1] is not None
if has_button and wx.FindWindowById( p['wxId'][1] ).GetValue() == True:
p[ 'value' ] = 'none'
@@ -1596,7 +1635,7 @@
me = event.GetId()
theParam = None
for p in self.task.params:
- if 'wxId' in p and type( p['wxId'] ) == type( [] ) and me in p['wxId']:
+ if 'wxId' in p and me in p['wxId']:
theParam = p
myIndex = p['wxId'].index( me )
@@ -1631,11 +1670,24 @@
"""
myId = event.GetId()
me = wx.FindWindowById( myId )
+ name = me.GetName()
for porf in self.task.params + self.task.flags:
- if 'wxId' in porf and type( porf[ 'wxId' ] ) == type( 1 ) and porf['wxId'] == myId:
- if porf.has_key('wxGetValue') and porf['wxGetValue']:
- porf['value'] = porf['wxGetValue']()
+ if not porf.has_key('wxId'):
+ continue
+ found = False
+ for id in porf['wxId']:
+ if id == myId:
+ found = True
+ break
+
+ if found:
+ if name in ('LayerSelect', 'DriverSelect', 'TableSelect'):
+ porf['value'] = me.GetStringSelection()
+ elif name == 'GdalSelect':
+ porf['value'] = event.dsn
+ elif name == 'ModelParam':
+ porf['parametrized'] = me.IsChecked()
else:
porf['value'] = me.GetValue()
@@ -1753,12 +1805,12 @@
return processTask(tree).GetTask()
- def ParseCommand(self, cmd, gmpath=None, completed=None, parentframe=None,
- show=True, modal=False):
+ def ParseCommand(self, cmd, gmpath = None, completed = None, parentframe = None,
+ show = True, modal = False):
"""!Parse command
-
+
Note: cmd is given as list
-
+
If command is given with options, return validated cmd list:
- add key name for first parameter if not given
- change mapname to mapname at mapset
@@ -1776,17 +1828,17 @@
dcmd_params.update(completed[2])
self.parent = parentframe
-
+
# parse the interface decription
self.grass_task = self.ParseInterface(cmd)
-
+
# if layer parameters previously set, re-insert them into dialog
if completed is not None:
if 'params' in dcmd_params:
self.grass_task.params = dcmd_params['params']
if 'flags' in dcmd_params:
self.grass_task.flags = dcmd_params['flags']
-
+
# update parameters if needed && validate command
if len(cmd) > 1:
i = 0
@@ -1808,14 +1860,19 @@
else:
raise ValueError, _("Unable to parse command %s") % ' '.join(cmd)
- if self.grass_task.get_param(key)['element'] in ['cell', 'vector']:
+ element = self.grass_task.get_param(key)['element']
+ if element in ['cell', 'vector']:
# mapname -> mapname at mapset
if '@' not in value:
- value = value + '@' + grass.gisenv()['MAPSET']
+ mapset = grass.find_file(value, element)['mapset']
+ curr_mapset = grass.gisenv()['MAPSET']
+ if mapset and mapset != curr_mapset:
+ value = value + '@' + mapset
+
self.grass_task.set_param(key, value)
cmd_validated.append(key + '=' + value)
i = i + 1
-
+
# update original command list
cmd = cmd_validated
@@ -1830,7 +1887,7 @@
# update only propwin reference
get_dcmd(dcmd=None, layer=layer, params=None,
propwin=self.mf)
-
+
if show is not None:
self.mf.notebookpanel.OnUpdateSelection(None)
if show is True:
@@ -1844,7 +1901,7 @@
self.cmd = cmd
return self.grass_task
-
+
def GetCommandInputMapParamKey(self, cmd):
"""!Get parameter key for input raster/vector map
More information about the grass-commit
mailing list