2 @package gmodeler.model
4 @brief wxGUI Graphical Modeler (base classes & read/write)
11 - model::ModelRelation
14 - model::ModelCondition
15 - model::ProcessModelFile
16 - model::WriteModelFile
17 - model::WritePythonFile
18 - model::ModelParamDialog
20 (C) 2010-2012 by the GRASS Development Team
22 This program is free software under the GNU General Public License
23 (>=v2). Read the file COPYING that comes with GRASS for details.
25 @author Martin Landa <landa.martin gmail.com>
35 import xml.etree.ElementTree
as etree
37 import elementtree.ElementTree
as etree
40 from wx.lib
import ogl
42 from core
import globalvar
43 from core
import utils
44 from core.gcmd import GMessage, GException, GError, RunCommand, EncodeString, GWarning, GetDefaultEncoding
46 from gui_core.forms
import GUI, CmdPanel
53 """!Class representing the model"""
59 'description' : _(
"Script generated by wxGUI Graphical Modeler."),
60 'author' : getpass.getuser() }
68 """!Get canvas or None"""
72 """!Get list of model items
74 @param objType Object type to filter model objects
80 for item
in self.
items:
81 if isinstance(item, objType):
87 """!Get item of given id
91 @return Model* instance
92 @return None if no item found
96 if item.GetId() == aId:
102 """!Get number of items"""
104 return len(self.
GetItems(objType = ModelAction))
109 """!Get next id (data ignored)
111 @return next id to be used (default: 1)
113 if len(self.
items) < 1:
116 currId = self.
items[-1].GetId()
123 """!Get model properties"""
127 """!Get model variables"""
134 """!Set model variables"""
142 """!Remove item from model
144 @return list of related items to remove/update
149 if not isinstance(item, ModelData):
150 self.items.remove(item)
152 if isinstance(item, ModelAction):
153 for rel
in item.GetRelations():
156 if len(data.GetRelations()) < 2:
161 elif isinstance(item, ModelData):
162 for rel
in item.GetRelations():
164 if rel.GetFrom() == self:
165 relList.append(rel.GetTo())
167 relList.append(rel.GetFrom())
169 elif isinstance(item, ModelLoop):
170 for rel
in item.GetRelations():
173 action.UnSetBlock(item)
175 return relList, upList
178 """!Find action by id"""
179 alist = self.
GetItems(objType = ModelAction)
181 if action.GetId() == aId:
187 """!Get list of data items"""
189 dataItems = self.
GetItems(objType = ModelData)
191 for action
in self.
GetItems(objType = ModelAction):
192 for rel
in action.GetRelations():
193 dataItem = rel.GetData()
194 if dataItem
not in result:
195 result.append(dataItem)
196 if dataItem
in dataItems:
197 dataItems.remove(dataItem)
206 """!Find data item in the model
211 @return ModelData instance
212 @return None if not found
215 if data.GetValue() == value
and \
216 data.GetPrompt() == prompt:
222 """!Load model definition stored in GRASS Model XML file (gxm)
224 @todo Validate against DTD
226 Raise exception on error.
228 dtdFilename = os.path.join(globalvar.ETCWXDIR,
"xml",
"grass-gxm.dtd")
233 except StandardError, e:
237 win = self.canvas.parent
239 win.SetPosition(gxmXml.pos)
241 win.SetSize(gxmXml.size)
248 for action
in gxmXml.actions:
250 x = action[
'pos'][0],
251 y = action[
'pos'][1],
252 width = action[
'size'][0],
253 height = action[
'size'][1],
254 task = action[
'task'],
257 if action[
'disabled']:
258 actionItem.Enable(
False)
262 actionItem.SetValid(actionItem.GetTask().get_options())
266 for data
in gxmXml.data:
270 width = data[
'size'][0],
271 height = data[
'size'][1],
272 prompt = data[
'prompt'],
273 value = data[
'value'])
274 dataItem.SetIntermediate(data[
'intermediate'])
276 for rel
in data[
'rels']:
278 if rel[
'dir'] ==
'from':
279 relation =
ModelRelation(parent = self, fromShape = dataItem,
280 toShape = actionItem, param = rel[
'name'])
282 relation =
ModelRelation(parent = self, fromShape = actionItem,
283 toShape = dataItem, param = rel[
'name'])
284 relation.SetControlPoints(rel[
'points'])
285 actionItem.AddRelation(relation)
286 dataItem.AddRelation(relation)
292 for loop
in gxmXml.loops:
296 width = loop[
'size'][0],
297 height = loop[
'size'][1],
303 for condition
in gxmXml.conditions:
305 x = condition[
'pos'][0],
306 y = condition[
'pos'][1],
307 width = condition[
'size'][0],
308 height = condition[
'size'][1],
309 text = condition[
'text'],
310 id = condition[
'id'])
314 for loop
in gxmXml.loops:
316 for aId
in loop[
'items']:
320 loopItem = self.
GetItem(loop[
'id'])
321 loopItem.SetItems(alist)
323 for action
in loopItem.GetItems():
324 action.SetBlock(loopItem)
326 for condition
in gxmXml.conditions:
327 conditionItem = self.
GetItem(condition[
'id'])
328 for b
in condition[
'items'].keys():
330 for aId
in condition[
'items'][b]:
333 conditionItem.SetItems(alist, branch = b)
335 items = conditionItem.GetItems()
336 for b
in items.keys():
337 for action
in items[b]:
338 action.SetBlock(conditionItem)
341 """!Add item to the list"""
342 iId = newItem.GetId()
345 for item
in self.
items:
346 if item.GetId() > iId:
347 self.items.insert(i, newItem)
351 self.items.append(newItem)
354 """Return True if model is valid"""
361 """!Validate model, return None if model is valid otherwise
366 pattern = re.compile(
r'(.*)(%.+\s?)(.*)')
367 for action
in self.
GetItems(objType = ModelAction):
368 cmd = action.GetLog(string =
False)
370 task = GUI(show =
None).ParseCommand(cmd = cmd)
371 errList += map(
lambda x: cmd[0] +
': ' + x, task.get_cmd_error())
377 key, value = opt.split(
'=', 1)
378 sval = pattern.search(value)
380 var = sval.group(2).strip()[1:]
381 if var
not in variables:
383 for item
in filter(
lambda x: isinstance(x, ModelLoop), action.GetBlock()):
384 if var
in item.GetText():
388 errList.append(cmd[0] +
": " + _(
"undefined variable '%s'") % var)
394 def _substituteFile(self, item, params = None, checkOnly = False):
395 """!Subsitute variables in command file inputs
397 @param checkOnly tuble - True to check variable, don't touch files
399 @return list of undefined variables
406 for p
in item.GetParams()[
'params']:
407 if p.get(
'element',
'') ==
'file' and \
408 p.get(
'prompt',
'') ==
'input' and \
409 p.get(
'age',
'') ==
'old_file':
410 filename = p.get(
'value', p.get(
'default',
''))
412 mimetypes.guess_type(filename)[0] ==
'text/plain':
417 fd = open(finput,
"r")
419 data = self.
fileInput[finput] = fd.read()
426 for variable
in variables:
427 pattern = re.compile(
'%' + variable)
429 if params
and 'variables' in params:
430 for p
in params[
'variables'][
'params']:
431 if variable == p.get(
'name',
''):
432 if p.get(
'type',
'string') ==
'string':
433 value = p.get(
'value',
'')
435 value = str(p.get(
'value',
''))
439 value = variables[variable].get(
'value',
'')
441 data = pattern.sub(value, data)
445 pattern = re.compile(
r'(.*)(%.+\s?)(.*)')
446 sval = pattern.search(data)
448 var = sval.group(2).strip()[1:]
449 cmd = item.GetLog(string =
False)[0]
450 errList.append(cmd +
": " + _(
"undefined variable '%s'") % var)
454 fd = open(finput,
"w")
467 def RunAction(self, item, params, log, onDone, onPrepare = None, statusbar = None):
470 @param item action item
471 @param params parameters dict
472 @param log logging window
473 @param onDone on-done method
474 @param onPrepare on-prepare method
475 @param statusbar wx.StatusBar instance or None
477 name = item.GetName()
479 paramsOrig = item.GetParams(dcopy =
True)
480 item.MergeParams(params[name])
483 statusbar.SetStatusText(_(
'Running model...'), 0)
485 data = {
'item' : item,
486 'params' : copy.deepcopy(params) }
487 log.RunCmd(command = item.GetLog(string =
False, substitute = params),
488 onDone = onDone, onPrepare = self.
OnPrepare, userData = data)
491 item.SetParams(paramsOrig)
493 def Run(self, log, onDone, parent = None):
496 @param log logging window (see goutput.GMConsole)
497 @param onDone on-done method
498 @param parent window for messages or None
501 GMessage(parent = parent,
502 message = _(
'Model is empty. Nothing to run.'))
506 if isinstance(parent, wx.Frame):
507 statusbar = parent.GetStatusBar()
511 statusbar.SetStatusText(_(
'Validating model...'), 0)
514 statusbar.SetStatusText(
'', 0)
516 dlg = wx.MessageDialog(parent = parent,
517 message = _(
'Model is not valid. Do you want to '
518 'run the model anyway?\n\n%s') %
'\n'.join(errList),
519 caption = _(
"Run model?"),
520 style = wx.YES_NO | wx.NO_DEFAULT |
521 wx.ICON_QUESTION | wx.CENTRE)
522 ret = dlg.ShowModal()
535 ret = dlg.ShowModal()
540 err = dlg.GetErrors()
541 delInterData = dlg.DeleteIntermediateData()
544 GError(parent = parent, message = unicode(
'\n'.join(err)))
548 for key, item
in params.iteritems():
549 for p
in item[
'params']:
550 if p.get(
'value',
'') ==
'':
551 err.append((key, p.get(
'name',
''), p.get(
'description',
'')))
553 GError(parent = parent,
554 message = _(
"Variables below not defined:") + \
555 "\n\n" + unicode(
'\n'.join(map(
lambda x:
"%s: %s (%s)" % (x[0], x[1], x[2]), err))))
558 log.cmdThread.SetId(-1)
560 if not item.IsEnabled():
562 if isinstance(item, ModelAction):
563 if item.GetBlockId():
565 self.
RunAction(item, params, log, onDone)
566 elif isinstance(item, ModelLoop):
567 cond = item.GetText()
570 for variable
in variables:
571 pattern = re.compile(
'%' + variable)
572 if pattern.search(cond):
574 if params
and 'variables' in params:
575 for p
in params[
'variables'][
'params']:
576 if variable == p.get(
'name',
''):
577 value = p.get(
'value',
'')
581 value = variables[variable].get(
'value',
'')
586 vtype = variables[variable].get(
'type',
'string')
587 if vtype ==
'string':
588 value =
'"' + value +
'"'
589 cond = pattern.sub(value, cond)
592 condVar, condText = map(
lambda x: x.strip(), re.split(
'\s*in\s*', cond))
593 pattern = re.compile(
'%' + condVar)
595 if condText[0] ==
'`' and condText[-1] ==
'`':
602 vlist = ret.splitlines()
604 vlist = eval(condText)
606 if 'variables' not in params:
607 params[
'variables'] = {
'params' : [] }
608 varDict = {
'name' : condVar,
'value' :
'' }
609 params[
'variables'][
'params'].append(varDict)
612 for action
in item.GetItems():
613 if not isinstance(action, ModelAction)
or \
614 not action.IsEnabled():
617 varDict[
'value'] = var
619 self.
RunAction(item = action, params = params,
620 log = log, onDone = onDone)
621 params[
'variables'][
'params'].remove(varDict)
628 for item
in params.itervalues():
629 for p
in item[
'params']:
633 """!Detele intermediate data"""
637 log.RunCmd([
'g.remove',
'rast=%s' %
','.join(rast)])
639 log.RunCmd([
'g.remove',
'rast3d=%s' %
','.join(rast3d)])
641 log.RunCmd([
'g.remove',
'vect=%s' %
','.join(vect)])
644 """!Get info about intermediate data"""
649 if not data.IsIntermediate():
651 name = data.GetValue()
652 prompt = data.GetPrompt()
653 if prompt ==
'raster':
655 elif prompt ==
'vector':
657 elif prompt ==
'rast3d':
662 msg +=
'\n\n%s: ' % _(
'Raster maps')
663 msg +=
', '.join(rast)
665 msg +=
'\n\n%s: ' % _(
'3D raster maps')
666 msg +=
', '.join(rast3d)
668 msg +=
'\n\n%s: ' % _(
'Vector maps')
669 msg +=
', '.join(vect)
671 return rast, vect, rast3d, msg
675 for item
in self.
items:
679 """!Return True if model is parameterized"""
686 """!Return parameterized options"""
691 result[
"variables"] = {
'flags' : list(),
694 for name, values
in self.variables.iteritems():
695 gtype = values.get(
'type',
'string')
696 if gtype
in (
'raster',
'vector',
'mapset',
'file'):
699 if gtype ==
'raster':
709 params.append({
'gisprompt' : gisprompt,
711 'description' : values.get(
'description',
''),
712 'guidependency' :
'',
716 'value' : values.get(
'value',
''),
721 'parameterized' :
False,
722 'values_desc' : list(),
730 for action
in self.
GetItems(objType = ModelAction):
731 if not action.IsEnabled():
733 name = action.GetName()
734 params = action.GetParams()
735 for f
in params[
'flags']:
736 if f.get(
'parameterized',
False):
737 if name
not in result:
738 result[name] = {
'flags' : list(),
741 result[name][
'flags'].append(f)
742 for p
in params[
'params']:
743 if p.get(
'parameterized',
False):
744 if name
not in result:
745 result[name] = {
'flags' : list(),
748 result[name][
'params'].append(p)
772 """!Record new relation
774 self.rels.append(rel)
777 """!Get list of relations
779 @param fdir True for 'from'
785 for rel
in self.
rels:
787 if rel.GetFrom() == self:
790 if rel.GetTo() == self:
796 """!Get True if action is enabled, otherwise False"""
800 """!Enable/disable action"""
808 """!Add object to the block (loop/condition)
810 @param item reference to ModelLoop or ModelCondition which
811 defines loops/condition
813 if item
not in self.inBlock:
814 self.inBlock.append(item)
817 """!Remove object from the block (loop/consition)
819 @param item reference to ModelLoop or ModelCondition which
820 defines loops/codition
823 self.inBlock.remove(item)
826 """!Get list of related ModelObject(s) which defines block
829 @return list of ModelObjects
834 """!Get list of related ids which defines block
840 ret.append(mo.GetId())
845 """!Action class (GRASS module)"""
846 def __init__(self, parent, x, y, id = -1, cmd = None, task = None, width = None, height = None):
847 ModelObject.__init__(self, id)
853 width = UserSettings.Get(group=
'modeler', key=
'action', subkey=(
'size',
'width'))
855 height = UserSettings.Get(group=
'modeler', key=
'action', subkey=(
'size',
'height'))
857 if cmd
and cmd[0]
in (
'r.mapcalc',
'v.type'):
861 self.
task = GUI(show =
None).ParseCommand(cmd = cmd)
875 if self.parent.GetCanvas():
876 ogl.RectangleShape.__init__(self, width, height)
878 self.SetCanvas(self.
parent)
881 self.SetPen(wx.BLACK_PEN)
887 self.
SetValid(self.task.get_options())
889 def _setBrush(self, running = False):
892 color = UserSettings.Get(group=
'modeler', key=
'action',
893 subkey=(
'color',
'running'))
895 color = UserSettings.Get(group=
'modeler', key=
'disabled',
898 color = UserSettings.Get(group=
'modeler', key=
'action',
899 subkey=(
'color',
'valid'))
901 color = UserSettings.Get(group=
'modeler', key=
'action',
902 subkey=(
'color',
'invalid'))
904 wxColor = wx.Colour(color[0], color[1], color[2])
905 self.SetBrush(wx.Brush(wxColor))
910 width = int(UserSettings.Get(group=
'modeler', key=
'action',
911 subkey=(
'width',
'parameterized')))
913 width = int(UserSettings.Get(group=
'modeler', key=
'action',
914 subkey=(
'width',
'default')))
922 cmd = self.task.get_cmd(ignoreErrors =
True)
923 if cmd
and len(cmd) > 0:
925 self.AddText(
'(%d) %s' % (self.
id, cmd[0]))
927 self.AddText(
'(%d) <<%s>>' % (self.
id, _(
"unknown")))
930 """!Record properties dialog"""
931 self.task.params = params[
'params']
932 self.task.flags = params[
'flags']
936 """!Get properties dialog"""
939 def GetLog(self, string = True, substitute = None):
942 @param string True to get cmd as a string otherwise a list
943 @param substitute dictionary of parameter to substitute or None
945 cmd = self.task.get_cmd(ignoreErrors =
True, ignoreRequired =
True,
946 ignoreDefault =
False)
951 if 'variables' in substitute:
952 for p
in substitute[
'variables'][
'params']:
953 variables.append(p.get(
'name',
''))
955 variables = self.parent.GetVariables()
956 for variable
in variables:
957 pattern= re.compile(
'%' + variable)
959 if substitute
and 'variables' in substitute:
960 for p
in substitute[
'variables'][
'params']:
961 if variable == p.get(
'name',
''):
962 if p.get(
'type',
'string') ==
'string':
963 value = p.get(
'value',
'')
965 value = str(p.get(
'value',
''))
969 value = variables[variable].get(
'value',
'')
974 for idx
in range(len(cmd)):
975 if pattern.search(cmd[idx]):
976 cmd[idx] = pattern.sub(value, cmd[idx])
990 cmd = self.task.get_cmd(ignoreErrors =
True)
991 if cmd
and len(cmd) > 0:
997 """!Get dictionary of parameters"""
999 return copy.deepcopy(self.task.get_options())
1001 return self.task.get_options()
1004 """!Get grassTask instance"""
1008 """!Set dictionary of parameters"""
1009 self.task.params = params[
'params']
1010 self.task.flags = params[
'flags']
1013 """!Merge dictionary of parameters"""
1014 if 'flags' in params:
1015 for f
in params[
'flags']:
1016 self.task.set_flag(f[
'name'],
1017 f.get(
'value',
False))
1018 if 'params' in params:
1019 for p
in params[
'params']:
1020 self.task.set_param(p[
'name'],
1024 """!Set validity for action
1026 @param options dictionary with flags and params (gtask)
1031 for f
in options[
'flags']:
1032 if f.get(
'parameterized',
False):
1036 for p
in options[
'params']:
1037 if self.
isValid and p.get(
'required',
False)
and \
1038 p.get(
'value',
'') ==
'' and \
1039 p.get(
'default',
'') ==
'':
1044 if self.parent.GetCanvas():
1049 """!Check validity (all required parameters set)"""
1053 """!Check if action is parameterized"""
1057 """!Find data item by name"""
1059 data = rel.GetData()
1060 if name == rel.GetName()
and name
in data.GetName():
1066 """!Update action"""
1074 """!Draw action in canvas"""
1077 ogl.RectangleShape.Recentre(self, dc)
1078 ogl.RectangleShape.OnDraw(self, dc)
1081 def __init__(self, parent, x, y, value = '', prompt = '', width = None, height = None):
1084 @param parent window parent
1085 @param x, y position of the shape
1086 @param fname, tname list of parameter names from / to
1088 @param prompt type of GIS element
1089 @param width,height dimension of the shape
1091 ModelObject.__init__(self)
1099 width = UserSettings.Get(group=
'modeler', key=
'data', subkey=(
'size',
'width'))
1101 height = UserSettings.Get(group=
'modeler', key=
'data', subkey=(
'size',
'height'))
1103 if self.parent.GetCanvas():
1104 ogl.EllipseShape.__init__(self, width, height)
1106 self.SetCanvas(self.
parent)
1109 self.SetPen(wx.BLACK_PEN)
1115 """!Checks if data item is intermediate"""
1119 """!Set intermediate flag"""
1126 pen.SetStyle(wx.SHORT_DASH)
1128 pen.SetStyle(wx.SOLID)
1131 ogl.EllipseShape.OnDraw(self, dc)
1134 """!Get logging info"""
1137 name.append(rel.GetName())
1139 return '/'.join(name) +
'=' + self.
value +
' (' + self.
prompt +
')'
1144 """!Get list of names"""
1147 name.append(rel.GetName())
1173 for direction
in (
'from',
'to'):
1175 if direction ==
'from':
1176 action = rel.GetTo()
1178 action = rel.GetFrom()
1180 task = GUI(show =
None).ParseCommand(cmd = action.GetLog(string =
False))
1181 task.set_param(rel.GetName(), self.
value)
1182 action.SetParams(params = task.get_options())
1185 """!Get properties dialog"""
1189 """!Get properties dialog"""
1192 def _setBrush(self):
1194 if self.
prompt ==
'raster':
1195 color = UserSettings.Get(group =
'modeler', key =
'data',
1196 subkey = (
'color',
'raster'))
1197 elif self.
prompt ==
'raster3d':
1198 color = UserSettings.Get(group =
'modeler', key =
'data',
1199 subkey = (
'color',
'raster3d'))
1200 elif self.
prompt ==
'vector':
1201 color = UserSettings.Get(group =
'modeler', key =
'data',
1202 subkey = (
'color',
'vector'))
1204 color = UserSettings.Get(group =
'modeler', key =
'action',
1205 subkey = (
'color',
'invalid'))
1206 wxColor = wx.Colour(color[0], color[1], color[2])
1207 self.SetBrush(wx.Brush(wxColor))
1211 isParameterized =
False
1213 if rel.GetTo().IsParameterized():
1214 isParameterized =
True
1216 if not isParameterized:
1218 if rel.GetFrom().IsParameterized():
1219 isParameterized =
True
1223 width = int(UserSettings.Get(group =
'modeler', key =
'action',
1224 subkey = (
'width',
'parameterized')))
1226 width = int(UserSettings.Get(group =
'modeler', key =
'action',
1227 subkey = (
'width',
'default')))
1237 name.append(rel.GetName())
1238 self.AddText(
'/'.join(name))
1240 self.AddText(self.
value)
1242 self.AddText(_(
'<not defined>'))
1245 """!Update action"""
1251 """!Data - action relation"""
1252 def __init__(self, parent, fromShape, toShape, param = ''):
1260 if self.parent.GetCanvas():
1261 ogl.LineShape.__init__(self)
1264 if self
in self.fromShape.rels:
1265 self.fromShape.rels.remove(self)
1266 if self
in self.toShape.rels:
1267 self.toShape.rels.remove(self)
1270 """!Get id of 'from' shape"""
1274 """!Get id of 'to' shape"""
1278 """!Get related ModelData instance
1280 @return ModelData instance
1281 @return None if not found
1283 if isinstance(self.
fromShape, ModelData):
1285 elif isinstance(self.
toShape, ModelData):
1291 """!Get parameter name"""
1295 """!Reset related objects"""
1296 self.fromShape.ResetControlPoints()
1297 self.toShape.ResetControlPoints()
1298 self.ResetControlPoints()
1301 """!Set control points"""
1305 """!Get list of control points"""
1312 pen.SetStyle(wx.SOLID)
1316 """!Draw relation"""
1318 ogl.LineShape.OnDraw(self, dc)
1324 def __init__(self, parent, x, y, id = -1, width = None, height = None, text = '', items = []):
1325 """!Abstract class for loops and conditions"""
1326 ModelObject.__init__(self, id)
1332 """!Get loop text"""
1336 """!Get items (id)"""
1344 """!Set loop text (condition)"""
1347 self.AddText(
'(' + str(self.
id) +
') ' + self.
text)
1352 return _(
"Condition: ") + self.
text
1354 return _(
"Condition: not defined")
1357 """!Record relation"""
1358 self.rels.append(rel)
1361 """!Clear object, remove rels"""
1365 def __init__(self, parent, x, y, id = -1, width = None, height = None, text = '', items = []):
1366 """!Defines a loop"""
1367 ModelItem.__init__(self, parent, x, y, id, width, height, text, items)
1370 width = UserSettings.Get(group=
'modeler', key=
'loop', subkey=(
'size',
'width'))
1372 height = UserSettings.Get(group=
'modeler', key=
'loop', subkey=(
'size',
'height'))
1374 if self.parent.GetCanvas():
1375 ogl.RectangleShape.__init__(self, width, height)
1377 self.SetCanvas(self.
parent)
1380 self.SetPen(wx.BLACK_PEN)
1381 self.SetCornerRadius(100)
1383 self.AddText(
'(' + str(self.
id) +
') ' + text)
1385 self.AddText(
'(' + str(self.
id) +
')')
1389 def _setBrush(self):
1392 color = UserSettings.Get(group=
'modeler', key=
'disabled',
1395 color = UserSettings.Get(group=
'modeler', key=
'loop',
1396 subkey=(
'color',
'valid'))
1398 wxColor = wx.Colour(color[0], color[1], color[2])
1399 self.SetBrush(wx.Brush(wxColor))
1402 """!Enable/disable action"""
1403 for item
in self.
items:
1404 if not isinstance(item, ModelAction):
1406 item.Enable(enabled)
1408 ModelObject.Enable(self, enabled)
1418 """!Set items (id)"""
1422 """!Draw loop in canvas"""
1424 ogl.RectangleShape.Recentre(self, dc)
1425 ogl.RectangleShape.OnDraw(self, dc)
1428 def __init__(self, parent, x, y, id = -1, width = None, height = None, text = '',
1429 items = {
'if' : [],
'else' : [] }):
1430 """!Defines a if-else condition"""
1431 ModelItem.__init__(self, parent, x, y, id, width, height, text, items)
1434 self.
width = UserSettings.Get(group=
'modeler', key=
'if-else', subkey=(
'size',
'width'))
1438 self.
height = UserSettings.Get(group=
'modeler', key=
'if-else', subkey=(
'size',
'height'))
1442 if self.parent.GetCanvas():
1443 ogl.PolygonShape.__init__(self)
1445 points = [(0, - self.
height / 2),
1446 (self.
width / 2, 0),
1448 (- self.
width / 2, 0)]
1451 self.SetCanvas(self.
parent)
1454 self.SetPen(wx.BLACK_PEN)
1456 self.AddText(
'(' + str(self.
id) +
') ' + text)
1458 self.AddText(
'(' + str(self.
id) +
')')
1465 """!Get object width"""
1469 """!Get object height"""
1475 @param items list of items
1476 @param branch 'if' / 'else'
1478 if branch
in [
'if',
'else']:
1479 self.
items[branch] = items
1482 """!Process GRASS model file (gxm)"""
1484 """!A ElementTree handler for the GXM XML file, as defined in
1504 def _filterValue(self, value):
1509 value = value.replace(
'<',
'<')
1510 value = value.replace(
'>',
'>')
1514 def _getNodeText(self, node, tag, default = ''):
1515 """!Get node text"""
1525 def _processWindow(self):
1526 """!Process window properties"""
1527 node = self.root.find(
'window')
1534 def _processProperties(self):
1535 """!Process model properties"""
1536 node = self.root.find(
'properties')
1539 for key
in (
'name',
'description',
'author'):
1542 for f
in node.findall(
'flag'):
1543 name = f.get(
'name',
'')
1544 if name ==
'overwrite':
1547 def _processProperty(self, pnode, name):
1548 """!Process given property"""
1549 node = pnode.find(name)
1550 if node
is not None:
1555 def _processVariables(self):
1556 """!Process model variables"""
1557 vnode = self.root.find(
'variables')
1560 for node
in vnode.findall(
'variable'):
1561 name = node.get(
'name',
'')
1564 self.
variables[name] = {
'type' : node.get(
'type',
'string') }
1565 for key
in (
'description',
'value'):
1568 def _processVariable(self, pnode, name, key):
1569 """!Process given variable"""
1570 node = pnode.find(key)
1571 if node
is not None:
1575 def _processItems(self):
1576 """!Process model items (actions, loops, conditions)"""
1581 def _processActions(self):
1582 """!Process model file"""
1583 for action
in self.root.findall(
'action'):
1584 pos, size = self.
_getDim(action)
1587 task = action.find(
'task')
1588 if task
is not None:
1589 if task.find(
'disabled')
is not None:
1595 aId = int(action.get(
'id', -1))
1597 self.actions.append({
'pos' : pos,
1601 'disabled' : disabled })
1603 def _getDim(self, node):
1604 """!Get position and size of shape"""
1606 posAttr = node.get(
'pos',
None)
1608 posVal = map(int, posAttr.split(
','))
1610 pos = (posVal[0], posVal[1])
1614 sizeAttr = node.get(
'size',
None)
1616 sizeVal = map(int, sizeAttr.split(
','))
1618 size = (sizeVal[0], sizeVal[1])
1624 def _processData(self):
1625 """!Process model file"""
1626 for data
in self.root.findall(
'data'):
1627 pos, size = self.
_getDim(data)
1628 param = data.find(
'data-parameter')
1629 prompt = value =
None
1630 if param
is not None:
1631 prompt = param.get(
'prompt',
None)
1634 if data.find(
'intermediate')
is None:
1635 intermediate =
False
1640 for rel
in data.findall(
'relation'):
1641 defrel = {
'id' : int(rel.get(
'id', -1)),
1642 'dir' : rel.get(
'dir',
'to'),
1643 'name' : rel.get(
'name',
'') }
1645 for point
in rel.findall(
'point'):
1648 points.append((float(x), float(y)))
1649 defrel[
'points'] = points
1652 self.data.append({
'pos' : pos,
1656 'intermediate' : intermediate,
1659 def _processTask(self, node):
1662 @return grassTask instance
1663 @return None on error
1666 parameterized = list()
1668 name = node.get(
'name',
None)
1675 for f
in node.findall(
'flag'):
1676 flag = f.get(
'name',
'')
1677 if f.get(
'parameterized',
'0') ==
'1':
1678 parameterized.append((
'flag', flag))
1679 if f.get(
'value',
'1') ==
'0':
1682 cmd.append(
'--' + flag)
1684 cmd.append(
'-' + flag)
1686 for p
in node.findall(
'parameter'):
1687 name = p.get(
'name',
'')
1688 if p.find(
'parameterized')
is not None:
1689 parameterized.append((
'param', name))
1690 cmd.append(
'%s=%s' % (name,
1693 task, err = GUI(show =
None, checkError =
True).ParseCommand(cmd = cmd)
1695 GWarning(os.linesep.join(err))
1697 for opt, name
in parameterized:
1699 task.set_flag(name,
True, element =
'parameterized')
1701 task.set_param(name,
True, element =
'parameterized')
1705 def _processLoops(self):
1706 """!Process model loops"""
1707 for node
in self.root.findall(
'loop'):
1708 pos, size = self.
_getDim(node)
1711 for anode
in node.findall(
'item'):
1713 aid.append(int(anode.text))
1717 self.loops.append({
'pos' : pos,
1720 'id' : int(node.get(
'id', -1)),
1723 def _processConditions(self):
1724 """!Process model conditions"""
1725 for node
in self.root.findall(
'if-else'):
1726 pos, size = self.
_getDim(node)
1728 aid = {
'if' : list(),
1730 for b
in aid.keys():
1731 bnode = node.find(b)
1734 for anode
in bnode.findall(
'item'):
1736 aid[b].append(int(anode.text))
1740 self.conditions.append({
'pos' : pos,
1743 'id' : int(node.get(
'id', -1)),
1747 """!Generic class for writing model file"""
1765 for action
in model.GetItems(objType = ModelAction):
1766 for rel
in action.GetRelations():
1767 dataItem = rel.GetData()
1768 if dataItem
not in dataList:
1769 dataList.append(dataItem)
1770 self.
_data(dataList)
1774 def _filterValue(self, value):
1775 """!Make value XML-valid"""
1776 value = value.replace(
'<',
'<')
1777 value = value.replace(
'>',
'>')
1783 self.fd.write(
'<?xml version="1.0" encoding="%s"?>\n' %
GetDefaultEncoding(forceUTF8 =
True))
1784 self.fd.write(
'<!DOCTYPE gxm SYSTEM "grass-gxm.dtd">\n')
1785 self.fd.write(
'%s<gxm>\n' % (
' ' * self.
indent))
1791 self.fd.write(
'%s</gxm>\n' % (
' ' * self.
indent))
1794 """!Write window properties"""
1795 canvas = self.model.GetCanvas()
1799 pos = win.GetPosition()
1800 size = win.GetSize()
1801 self.fd.write(
'%s<window pos="%d,%d" size="%d,%d" />\n' % \
1802 (
' ' * self.
indent, pos[0], pos[1], size[0], size[1]))
1804 def _properties(self):
1805 """!Write model properties"""
1806 self.fd.write(
'%s<properties>\n' % (
' ' * self.
indent))
1811 self.fd.write(
'%s<description>%s</description>\n' % (
' ' * self.
indent,
1814 self.fd.write(
'%s<author>%s</author>\n' % (
' ' * self.
indent,
1819 self.fd.write(
'%s<flag name="overwrite" />\n' % (
' ' * self.
indent))
1821 self.fd.write(
'%s</properties>\n' % (
' ' * self.
indent))
1823 def _variables(self):
1824 """!Write model variables"""
1827 self.fd.write(
'%s<variables>\n' % (
' ' * self.
indent))
1829 for name, values
in self.variables.iteritems():
1830 self.fd.write(
'%s<variable name="%s" type="%s">\n' % \
1833 if 'value' in values:
1834 self.fd.write(
'%s<value>%s</value>\n' % \
1836 if 'description' in values:
1837 self.fd.write(
'%s<description>%s</description>\n' % \
1840 self.fd.write(
'%s</variable>\n' % (
' ' * self.
indent))
1842 self.fd.write(
'%s</variables>\n' % (
' ' * self.
indent))
1845 """!Write actions/loops/conditions"""
1846 for item
in self.
items:
1847 if isinstance(item, ModelAction):
1849 elif isinstance(item, ModelLoop):
1851 elif isinstance(item, ModelCondition):
1854 def _action(self, action):
1855 """!Write actions"""
1856 self.fd.write(
'%s<action id="%d" name="%s" pos="%d,%d" size="%d,%d">\n' % \
1857 (
' ' * self.
indent, action.GetId(), action.GetName(), action.GetX(), action.GetY(),
1858 action.GetWidth(), action.GetHeight()))
1860 self.fd.write(
'%s<task name="%s">\n' % (
' ' * self.
indent, action.GetLog(string =
False)[0]))
1862 if not action.IsEnabled():
1863 self.fd.write(
'%s<disabled />\n' % (
' ' * self.
indent))
1864 for key, val
in action.GetParams().iteritems():
1867 if f.get(
'value',
False)
or f.get(
'parameterized',
False):
1868 if f.get(
'parameterized',
False):
1869 if f.get(
'value',
False) ==
False:
1870 self.fd.write(
'%s<flag name="%s" value="0" parameterized="1" />\n' %
1871 (
' ' * self.
indent, f.get(
'name',
'')))
1873 self.fd.write(
'%s<flag name="%s" parameterized="1" />\n' %
1874 (
' ' * self.
indent, f.get(
'name',
'')))
1876 self.fd.write(
'%s<flag name="%s" />\n' %
1877 (
' ' * self.
indent, f.get(
'name',
'')))
1880 if not p.get(
'value',
'')
and not p.get(
'parameterized',
False):
1882 self.fd.write(
'%s<parameter name="%s">\n' %
1883 (
' ' * self.
indent, p.get(
'name',
'')))
1885 if p.get(
'parameterized',
False):
1886 self.fd.write(
'%s<parameterized />\n' % (
' ' * self.
indent))
1887 self.fd.write(
'%s<value>%s</value>\n' %
1890 self.fd.write(
'%s</parameter>\n' % (
' ' * self.
indent))
1892 self.fd.write(
'%s</task>\n' % (
' ' * self.
indent))
1894 self.fd.write(
'%s</action>\n' % (
' ' * self.
indent))
1896 def _data(self, dataList):
1898 for data
in dataList:
1899 self.fd.write(
'%s<data pos="%d,%d" size="%d,%d">\n' % \
1900 (
' ' * self.
indent, data.GetX(), data.GetY(),
1901 data.GetWidth(), data.GetHeight()))
1903 self.fd.write(
'%s<data-parameter prompt="%s">\n' % \
1904 (
' ' * self.
indent, data.GetPrompt()))
1906 self.fd.write(
'%s<value>%s</value>\n' %
1909 self.fd.write(
'%s</data-parameter>\n' % (
' ' * self.
indent))
1911 if data.IsIntermediate():
1912 self.fd.write(
'%s<intermediate />\n' % (
' ' * self.
indent))
1915 for ft
in (
'from',
'to'):
1916 for rel
in data.GetRelations(ft):
1918 aid = rel.GetTo().GetId()
1920 aid = rel.GetFrom().GetId()
1921 self.fd.write(
'%s<relation dir="%s" id="%d" name="%s">\n' % \
1922 (
' ' * self.
indent, ft, aid, rel.GetName()))
1924 for point
in rel.GetLineControlPoints()[1:-1]:
1925 self.fd.write(
'%s<point>\n' % (
' ' * self.
indent))
1928 self.fd.write(
'%s<x>%d</x>\n' % (
' ' * self.
indent, int(x)))
1929 self.fd.write(
'%s<y>%d</y>\n' % (
' ' * self.
indent, int(y)))
1931 self.fd.write(
'%s</point>\n' % (
' ' * self.
indent))
1933 self.fd.write(
'%s</relation>\n' % (
' ' * self.
indent))
1936 self.fd.write(
'%s</data>\n' % (
' ' * self.
indent))
1938 def _loop(self, loop):
1940 self.fd.write(
'%s<loop id="%d" pos="%d,%d" size="%d,%d">\n' % \
1941 (
' ' * self.
indent, loop.GetId(), loop.GetX(), loop.GetY(),
1942 loop.GetWidth(), loop.GetHeight()))
1943 text = loop.GetText()
1946 self.fd.write(
'%s<condition>%s</condition>\n' %
1948 for item
in loop.GetItems():
1949 self.fd.write(
'%s<item>%d</item>\n' %
1950 (
' ' * self.
indent, item.GetId()))
1952 self.fd.write(
'%s</loop>\n' % (
' ' * self.
indent))
1954 def _condition(self, condition):
1955 """!Write conditions"""
1956 bbox = condition.GetBoundingBoxMin()
1957 self.fd.write(
'%s<if-else id="%d" pos="%d,%d" size="%d,%d">\n' % \
1958 (
' ' * self.
indent, condition.GetId(), condition.GetX(), condition.GetY(),
1960 text = condition.GetText()
1963 self.fd.write(
'%s<condition>%s</condition>\n' %
1965 items = condition.GetItems()
1966 for b
in items.keys():
1967 if len(items[b]) < 1:
1969 self.fd.write(
'%s<%s>\n' % (
' ' * self.
indent, b))
1971 for item
in items[b]:
1972 self.fd.write(
'%s<item>%d</item>\n' %
1973 (
' ' * self.
indent, item.GetId()))
1975 self.fd.write(
'%s</%s>\n' % (
' ' * self.
indent, b))
1978 self.fd.write(
'%s</if-else>\n' % (
' ' * self.
indent))
1982 """!Class for exporting model to Python script
1984 @param fd file desciptor
1992 def _writePython(self):
1993 """!Write model to file"""
1994 properties = self.model.GetProperties()
1997 r"""#!/usr/bin/env python
2013 EncodeString(
'\n# '.join(properties[
'description'].splitlines())),
2023 import grass.script as grass
2027 rast, vect, rast3d, msg = self.model.GetIntermediateData()
2034 r""" grass.run_command('g.remove',
2036 """ %
','.join(map(
lambda x:
"'" + x +
"'", rast)))
2039 r""" grass.run_command('g.remove',
2041 """ %
','.join(map(
lambda x:
"'" + x +
"'", vect)))
2044 r""" grass.run_command('g.remove',
2046 """ %
','.join(map(
lambda x:
"'" + x +
"'", rast3d)))
2047 if not rast
and not vect
and not rast3d:
2048 self.fd.write(
' pass\n')
2050 self.fd.write(
"\ndef main():\n")
2051 for item
in self.model.GetItems():
2054 self.fd.write(
"\n return 0\n")
2058 if __name__ == "__main__":
2059 options, flags = grass.parser()
2060 atexit.register(cleanup)
2064 def _writePythonItem(self, item, ignoreBlock = True, variables = []):
2065 """!Write model object to Python file"""
2066 if isinstance(item, ModelAction):
2067 if ignoreBlock
and item.GetBlockId():
2070 elif isinstance(item, ModelLoop)
or isinstance(item, ModelCondition):
2072 variables = self.model.GetVariables()
2073 cond = item.GetText()
2074 for variable
in variables:
2075 pattern = re.compile(
'%' + variable)
2076 if pattern.search(cond):
2077 value = variables[variable].get(
'value',
'')
2078 if variables[variable].get(
'type',
'string') ==
'string':
2079 value =
'"' + value +
'"'
2080 cond = pattern.sub(value, cond)
2081 if isinstance(item, ModelLoop):
2082 condVar, condText = map(
lambda x: x.strip(), re.split(
'\s*in\s*', cond))
2083 cond =
"%sfor %s in " % (
' ' * self.
indent, condVar)
2084 if condText[0] ==
'`' and condText[-1] ==
'`':
2085 task = GUI(show =
None).ParseCommand(cmd =
utils.split(condText[1:-1]))
2086 cond +=
"grass.read_command("
2087 cond += self.
_getPythonActionCmd(task, len(cond), variables = [condVar]) +
".splitlines()"
2090 self.fd.write(
'%s:\n' % cond)
2092 for action
in item.GetItems():
2096 self.fd.write(
'%sif %s:\n' % (
' ' * self.
indent, cond))
2098 condItems = item.GetItems()
2099 for action
in condItems[
'if']:
2101 if condItems[
'else']:
2103 self.fd.write(
'%selse:\n' % (
' ' * self.
indent))
2105 for action
in condItems[
'else']:
2109 def _writePythonAction(self, item, variables = []):
2110 """!Write model action to Python file"""
2111 task = GUI(show =
None).ParseCommand(cmd = item.GetLog(string =
False, substitute = self.model.GetVariables()))
2112 strcmd =
"%sgrass.run_command(" % (
' ' * self.
indent)
2115 def _getPythonActionCmd(self, task, cmdIndent, variables = []):
2116 opts = task.get_options()
2122 for f
in opts[
'flags']:
2123 if f.get(
'value',
False):
2124 name = f.get(
'name',
'')
2126 params.append(
'%s = True' % name)
2130 for p
in opts[
'params']:
2131 name = p.get(
'name',
None)
2132 value = p.get(
'value',
None)
2134 ptype = p.get(
'type',
'string')
2136 params.append(
"%s = %s" % (name, value[1:]))
2137 elif ptype ==
'string':
2138 params.append(
'%s = "%s"' % (name, value))
2140 params.append(
"%s = %s" % (name, value))
2142 ret +=
'"%s"' % task.get_name()
2144 ret +=
",\n%sflags = '%s'" % (
' ' * cmdIndent, flags)
2147 for opt
in params[:-1]:
2148 ret +=
"%s%s,\n" % (
' ' * cmdIndent, opt)
2149 ret +=
"%s%s)" % (
' ' * cmdIndent, params[-1])
2156 def __init__(self, parent, params, id = wx.ID_ANY, title = _(
"Model parameters"),
2157 style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
2158 """!Model parameters dialog
2164 wx.Dialog.__init__(self, parent = parent, id = id, title = title, style = style, **kwargs)
2167 style = globalvar.FNPageDStyle)
2170 wx.CallAfter(self.notebook.SetSelection, 0)
2173 self.
interData = wx.CheckBox(parent = self, label = _(
"Delete intermediate data when finish"))
2174 self.interData.SetValue(
True)
2175 rast, vect, rast3d, msg = self.parent.GetModel().GetIntermediateData()
2176 if not rast
and not vect
and not rast3d:
2177 self.interData.Hide()
2179 self.
btnCancel = wx.Button(parent = self, id = wx.ID_CANCEL)
2180 self.
btnRun = wx.Button(parent = self, id = wx.ID_OK,
2182 self.btnRun.SetDefault()
2186 size = self.GetBestSize()
2187 self.SetMinSize(size)
2188 self.SetSize((size.width, size.height +
2189 panel.constrained_size[1] -
2190 panel.panelMinHeight))
2193 btnSizer = wx.StdDialogButtonSizer()
2195 btnSizer.AddButton(self.
btnRun)
2198 mainSizer = wx.BoxSizer(wx.VERTICAL)
2199 mainSizer.Add(item = self.
notebook, proportion = 1,
2201 if self.interData.IsShown():
2202 mainSizer.Add(item = self.
interData, proportion = 0,
2203 flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
2205 mainSizer.Add(item = wx.StaticLine(parent = self, id = wx.ID_ANY,
2206 style = wx.LI_HORIZONTAL),
2208 flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 5)
2210 mainSizer.Add(item = btnSizer, proportion = 0,
2211 flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
2213 self.SetSizer(mainSizer)
2216 def _createPages(self):
2217 """!Create for each parameterized module its own page"""
2218 nameOrdered = [
''] * len(self.params.keys())
2219 for name, params
in self.params.iteritems():
2220 nameOrdered[params[
'idx']] = name
2221 for name
in nameOrdered:
2222 params = self.
params[name]
2224 if name ==
'variables':
2225 name = _(
'Variables')
2226 self.notebook.AddPage(page = panel, text = name)
2230 def _createPage(self, name, params):
2231 """!Define notebook page"""
2232 if name
in globalvar.grassCmd:
2233 task = gtask.grassTask(name)
2235 task = gtask.grassTask()
2236 task.flags = params[
'flags']
2237 task.params = params[
'params']
2239 panel = CmdPanel(parent = self, id = wx.ID_ANY, task = task)
2240 self.tasks.append(task)
2245 """!Check for errors, get list of messages"""
2247 for task
in self.
tasks:
2248 errList += task.get_cmd_error()
2253 """!Check if to detele intermediate data"""
2254 if self.interData.IsShown()
and self.interData.IsChecked():
def CmdToTuple
Convert command list to tuple for gcmd.RunCommand()
def GetItems
Get list of model items.
def _processActions
Process model file.
def normalize_whitespace
Remove redundant whitespace from a string.
def EncodeString
Return encoded string using system locales.
def _writePython
Write model to file.
def GetPropDialog
Get properties dialog.
def _processVariable
Process given variable.
def Clear
Clear object, remove rels.
def IsEnabled
Get True if action is enabled, otherwise False.
def _filterValue
Make value XML-valid.
def _properties
Write model properties.
def DeleteIntermediateData
Check if to detele intermediate data.
def __init__
Model parameters dialog.
def SetText
Set loop text (condition)
Generic class for writing model file.
def _getDim
Get position and size of shape.
def SetParams
Set dictionary of parameters.
def FindData
Find data item by name.
def _processConditions
Process model conditions.
Action class (GRASS module)
def GetPropDialog
Get properties dialog.
def SetVariables
Set model variables.
def GetParams
Get dictionary of parameters.
def GetNumItems
Get number of items.
def _processProperties
Process model properties.
def _processWindow
Process window properties.
def _processLoops
Process model loops.
def GetRelations
Get list of relations.
Class representing the model.
def ResetShapes
Reset related objects.
def GetItems
Get items (id)
def _createPage
Define notebook page.
def __init__
Abstract class for loops and conditions.
def _items
Write actions/loops/conditions.
def GetBlock
Get list of related ModelObject(s) which defines block (loop/condition)
def __init__
Defines a loop.
def Parameterize
Return parameterized options.
def GetText
Get loop text.
def RunAction
Run given action.
def GetLog
Get logging info.
def __init__
Class for exporting model to Python script.
def FindData
Find data item in the model.
def SetProperties
Record properties dialog.
def Enable
Enable/disable action.
def Validate
Validate model, return None if model is valid otherwise error string.
def GetTo
Get id of 'to' shape.
def IsIntermediate
Checks if data item is intermediate.
def GetBlockId
Get list of related ids which defines block.
def SetControlPoints
Set control points.
def split
Platform spefic shlex.split.
def AddRelation
Record relation.
def _processData
Process model file.
def _substituteFile
Subsitute variables in command file inputs.
def _condition
Write conditions.
def IsParameterized
Return True if model is parameterized.
def GetHeight
Get object height.
def GetIntermediateData
Get info about intermediate data.
def RemoveItem
Remove item from model.
def SetIntermediate
Set intermediate flag.
def Enable
Enable/disable action.
def SetBlock
Add object to the block (loop/condition)
def OnDraw
Draw loop in canvas.
def GetLog
Get logging info.
def LoadModel
Load model definition stored in GRASS Model XML file (gxm)
def EncodeString
Return encoded string using system locales.
def _processItems
Process model items (actions, loops, conditions)
def AddItem
Add item to the list.
def _processProperty
Process given property.
def SetItems
Set items (id)
def SetPropDialog
Get properties dialog.
def GetErrors
Check for errors, get list of messages.
def GetDefaultEncoding
Get default system encoding.
def GetData
Get related ModelData instance.
def GetNextId
Get next id (data ignored)
def _processTask
Process task.
def AddRelation
Record new relation.
def MergeParams
Merge dictionary of parameters.
def GetControlPoints
Get list of control points.
def _filterValue
Filter value.
def SetValid
Set validity for action.
def __init__
A ElementTree handler for the GXM XML file, as defined in grass-gxm.dtd.
def GetName
Get list of names.
def _processVariables
Process model variables.
def GetName
Get parameter name.
def OnDraw
Draw action in canvas.
def _action
Write actions.
def _writePythonItem
Write model object to Python file.
def IsValid
Check validity (all required parameters set)
Process GRASS model file (gxm)
def GetCanvas
Get canvas or None.
def _createPages
Create for each parameterized module its own page.
def GetData
Get list of data items.
def _variables
Write model variables.
def _window
Write window properties.
def GetTask
Get grassTask instance.
def GetItem
Get item of given id.
def DeleteIntermediateData
Detele intermediate data.
def GetVariables
Get model variables.
def GetProperties
Get model properties.
def FindAction
Find action by id.
def SetItems
Set items (id)
def RunCommand
Run GRASS command.
def _writePythonAction
Write model action to Python file.
def UnSetBlock
Remove object from the block (loop/consition)
def GetWidth
Get object width.
def _getNodeText
Get node text.
def GetFrom
Get id of 'from' shape.