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 def __init__(self, parent, x, y, id = -1, width = None, height = None, text = '',
1423 items = {
'if' : [],
'else' : [] }):
1424 """!Defines a if-else condition"""
1425 ModelItem.__init__(self, parent, x, y, id, width, height, text, items)
1428 self.
width = UserSettings.Get(group=
'modeler', key=
'if-else', subkey=(
'size',
'width'))
1432 self.
height = UserSettings.Get(group=
'modeler', key=
'if-else', subkey=(
'size',
'height'))
1436 if self.parent.GetCanvas():
1437 ogl.PolygonShape.__init__(self)
1439 points = [(0, - self.
height / 2),
1440 (self.
width / 2, 0),
1442 (- self.
width / 2, 0)]
1445 self.SetCanvas(self.
parent)
1448 self.SetPen(wx.BLACK_PEN)
1450 self.AddText(
'(' + str(self.
id) +
') ' + text)
1452 self.AddText(
'(' + str(self.
id) +
')')
1459 """!Get object width"""
1463 """!Get object height"""
1469 @param items list of items
1470 @param branch 'if' / 'else'
1472 if branch
in [
'if',
'else']:
1473 self.
items[branch] = items
1476 """!Process GRASS model file (gxm)"""
1478 """!A ElementTree handler for the GXM XML file, as defined in
1498 def _filterValue(self, value):
1503 value = value.replace(
'<',
'<')
1504 value = value.replace(
'>',
'>')
1508 def _getNodeText(self, node, tag, default = ''):
1509 """!Get node text"""
1519 def _processWindow(self):
1520 """!Process window properties"""
1521 node = self.root.find(
'window')
1528 def _processProperties(self):
1529 """!Process model properties"""
1530 node = self.root.find(
'properties')
1533 for key
in (
'name',
'description',
'author'):
1536 for f
in node.findall(
'flag'):
1537 name = f.get(
'name',
'')
1538 if name ==
'overwrite':
1541 def _processProperty(self, pnode, name):
1542 """!Process given property"""
1543 node = pnode.find(name)
1544 if node
is not None:
1549 def _processVariables(self):
1550 """!Process model variables"""
1551 vnode = self.root.find(
'variables')
1554 for node
in vnode.findall(
'variable'):
1555 name = node.get(
'name',
'')
1558 self.
variables[name] = {
'type' : node.get(
'type',
'string') }
1559 for key
in (
'description',
'value'):
1562 def _processVariable(self, pnode, name, key):
1563 """!Process given variable"""
1564 node = pnode.find(key)
1565 if node
is not None:
1569 def _processItems(self):
1570 """!Process model items (actions, loops, conditions)"""
1575 def _processActions(self):
1576 """!Process model file"""
1577 for action
in self.root.findall(
'action'):
1578 pos, size = self.
_getDim(action)
1581 task = action.find(
'task')
1582 if task
is not None:
1583 if task.find(
'disabled')
is not None:
1589 aId = int(action.get(
'id', -1))
1591 self.actions.append({
'pos' : pos,
1595 'disabled' : disabled })
1597 def _getDim(self, node):
1598 """!Get position and size of shape"""
1600 posAttr = node.get(
'pos',
None)
1602 posVal = map(int, posAttr.split(
','))
1604 pos = (posVal[0], posVal[1])
1608 sizeAttr = node.get(
'size',
None)
1610 sizeVal = map(int, sizeAttr.split(
','))
1612 size = (sizeVal[0], sizeVal[1])
1618 def _processData(self):
1619 """!Process model file"""
1620 for data
in self.root.findall(
'data'):
1621 pos, size = self.
_getDim(data)
1622 param = data.find(
'data-parameter')
1623 prompt = value =
None
1624 if param
is not None:
1625 prompt = param.get(
'prompt',
None)
1628 if data.find(
'intermediate')
is None:
1629 intermediate =
False
1634 for rel
in data.findall(
'relation'):
1635 defrel = {
'id' : int(rel.get(
'id', -1)),
1636 'dir' : rel.get(
'dir',
'to'),
1637 'name' : rel.get(
'name',
'') }
1639 for point
in rel.findall(
'point'):
1642 points.append((float(x), float(y)))
1643 defrel[
'points'] = points
1646 self.data.append({
'pos' : pos,
1650 'intermediate' : intermediate,
1653 def _processTask(self, node):
1656 @return grassTask instance
1657 @return None on error
1660 parameterized = list()
1662 name = node.get(
'name',
None)
1669 for f
in node.findall(
'flag'):
1670 flag = f.get(
'name',
'')
1671 if f.get(
'parameterized',
'0') ==
'1':
1672 parameterized.append((
'flag', flag))
1673 if f.get(
'value',
'1') ==
'0':
1676 cmd.append(
'--' + flag)
1678 cmd.append(
'-' + flag)
1680 for p
in node.findall(
'parameter'):
1681 name = p.get(
'name',
'')
1682 if p.find(
'parameterized')
is not None:
1683 parameterized.append((
'param', name))
1684 cmd.append(
'%s=%s' % (name,
1687 task, err = GUI(show =
None, checkError =
True).ParseCommand(cmd = cmd)
1689 GWarning(os.linesep.join(err))
1691 for opt, name
in parameterized:
1693 task.set_flag(name,
True, element =
'parameterized')
1695 task.set_param(name,
True, element =
'parameterized')
1699 def _processLoops(self):
1700 """!Process model loops"""
1701 for node
in self.root.findall(
'loop'):
1702 pos, size = self.
_getDim(node)
1705 for anode
in node.findall(
'item'):
1707 aid.append(int(anode.text))
1711 self.loops.append({
'pos' : pos,
1714 'id' : int(node.get(
'id', -1)),
1717 def _processConditions(self):
1718 """!Process model conditions"""
1719 for node
in self.root.findall(
'if-else'):
1720 pos, size = self.
_getDim(node)
1722 aid = {
'if' : list(),
1724 for b
in aid.keys():
1725 bnode = node.find(b)
1728 for anode
in bnode.findall(
'item'):
1730 aid[b].append(int(anode.text))
1734 self.conditions.append({
'pos' : pos,
1737 'id' : int(node.get(
'id', -1)),
1741 """!Generic class for writing model file"""
1759 for action
in model.GetItems(objType = ModelAction):
1760 for rel
in action.GetRelations():
1761 dataItem = rel.GetData()
1762 if dataItem
not in dataList:
1763 dataList.append(dataItem)
1764 self.
_data(dataList)
1768 def _filterValue(self, value):
1769 """!Make value XML-valid"""
1770 value = value.replace(
'<',
'<')
1771 value = value.replace(
'>',
'>')
1777 self.fd.write(
'<?xml version="1.0" encoding="%s"?>\n' %
GetDefaultEncoding(forceUTF8 =
True))
1778 self.fd.write(
'<!DOCTYPE gxm SYSTEM "grass-gxm.dtd">\n')
1779 self.fd.write(
'%s<gxm>\n' % (
' ' * self.
indent))
1785 self.fd.write(
'%s</gxm>\n' % (
' ' * self.
indent))
1788 """!Write window properties"""
1789 canvas = self.model.GetCanvas()
1793 pos = win.GetPosition()
1794 size = win.GetSize()
1795 self.fd.write(
'%s<window pos="%d,%d" size="%d,%d" />\n' % \
1796 (
' ' * self.
indent, pos[0], pos[1], size[0], size[1]))
1798 def _properties(self):
1799 """!Write model properties"""
1800 self.fd.write(
'%s<properties>\n' % (
' ' * self.
indent))
1805 self.fd.write(
'%s<description>%s</description>\n' % (
' ' * self.
indent,
1808 self.fd.write(
'%s<author>%s</author>\n' % (
' ' * self.
indent,
1813 self.fd.write(
'%s<flag name="overwrite" />\n' % (
' ' * self.
indent))
1815 self.fd.write(
'%s</properties>\n' % (
' ' * self.
indent))
1817 def _variables(self):
1818 """!Write model variables"""
1821 self.fd.write(
'%s<variables>\n' % (
' ' * self.
indent))
1823 for name, values
in self.variables.iteritems():
1824 self.fd.write(
'%s<variable name="%s" type="%s">\n' % \
1827 if 'value' in values:
1828 self.fd.write(
'%s<value>%s</value>\n' % \
1830 if 'description' in values:
1831 self.fd.write(
'%s<description>%s</description>\n' % \
1834 self.fd.write(
'%s</variable>\n' % (
' ' * self.
indent))
1836 self.fd.write(
'%s</variables>\n' % (
' ' * self.
indent))
1839 """!Write actions/loops/conditions"""
1840 for item
in self.
items:
1841 if isinstance(item, ModelAction):
1843 elif isinstance(item, ModelLoop):
1845 elif isinstance(item, ModelCondition):
1848 def _action(self, action):
1849 """!Write actions"""
1850 self.fd.write(
'%s<action id="%d" name="%s" pos="%d,%d" size="%d,%d">\n' % \
1851 (
' ' * self.
indent, action.GetId(), action.GetName(), action.GetX(), action.GetY(),
1852 action.GetWidth(), action.GetHeight()))
1854 self.fd.write(
'%s<task name="%s">\n' % (
' ' * self.
indent, action.GetLog(string =
False)[0]))
1856 if not action.IsEnabled():
1857 self.fd.write(
'%s<disabled />\n' % (
' ' * self.
indent))
1858 for key, val
in action.GetParams().iteritems():
1861 if f.get(
'value',
False)
or f.get(
'parameterized',
False):
1862 if f.get(
'parameterized',
False):
1863 if f.get(
'value',
False) ==
False:
1864 self.fd.write(
'%s<flag name="%s" value="0" parameterized="1" />\n' %
1865 (
' ' * self.
indent, f.get(
'name',
'')))
1867 self.fd.write(
'%s<flag name="%s" parameterized="1" />\n' %
1868 (
' ' * self.
indent, f.get(
'name',
'')))
1870 self.fd.write(
'%s<flag name="%s" />\n' %
1871 (
' ' * self.
indent, f.get(
'name',
'')))
1874 if not p.get(
'value',
'')
and not p.get(
'parameterized',
False):
1876 self.fd.write(
'%s<parameter name="%s">\n' %
1877 (
' ' * self.
indent, p.get(
'name',
'')))
1879 if p.get(
'parameterized',
False):
1880 self.fd.write(
'%s<parameterized />\n' % (
' ' * self.
indent))
1881 self.fd.write(
'%s<value>%s</value>\n' %
1884 self.fd.write(
'%s</parameter>\n' % (
' ' * self.
indent))
1886 self.fd.write(
'%s</task>\n' % (
' ' * self.
indent))
1888 self.fd.write(
'%s</action>\n' % (
' ' * self.
indent))
1890 def _data(self, dataList):
1892 for data
in dataList:
1893 self.fd.write(
'%s<data pos="%d,%d" size="%d,%d">\n' % \
1894 (
' ' * self.
indent, data.GetX(), data.GetY(),
1895 data.GetWidth(), data.GetHeight()))
1897 self.fd.write(
'%s<data-parameter prompt="%s">\n' % \
1898 (
' ' * self.
indent, data.GetPrompt()))
1900 self.fd.write(
'%s<value>%s</value>\n' %
1903 self.fd.write(
'%s</data-parameter>\n' % (
' ' * self.
indent))
1905 if data.IsIntermediate():
1906 self.fd.write(
'%s<intermediate />\n' % (
' ' * self.
indent))
1909 for ft
in (
'from',
'to'):
1910 for rel
in data.GetRelations(ft):
1912 aid = rel.GetTo().GetId()
1914 aid = rel.GetFrom().GetId()
1915 self.fd.write(
'%s<relation dir="%s" id="%d" name="%s">\n' % \
1916 (
' ' * self.
indent, ft, aid, rel.GetName()))
1918 for point
in rel.GetLineControlPoints()[1:-1]:
1919 self.fd.write(
'%s<point>\n' % (
' ' * self.
indent))
1922 self.fd.write(
'%s<x>%d</x>\n' % (
' ' * self.
indent, int(x)))
1923 self.fd.write(
'%s<y>%d</y>\n' % (
' ' * self.
indent, int(y)))
1925 self.fd.write(
'%s</point>\n' % (
' ' * self.
indent))
1927 self.fd.write(
'%s</relation>\n' % (
' ' * self.
indent))
1930 self.fd.write(
'%s</data>\n' % (
' ' * self.
indent))
1932 def _loop(self, loop):
1934 self.fd.write(
'%s<loop id="%d" pos="%d,%d" size="%d,%d">\n' % \
1935 (
' ' * self.
indent, loop.GetId(), loop.GetX(), loop.GetY(),
1936 loop.GetWidth(), loop.GetHeight()))
1937 text = loop.GetText()
1940 self.fd.write(
'%s<condition>%s</condition>\n' %
1942 for item
in loop.GetItems():
1943 self.fd.write(
'%s<item>%d</item>\n' %
1944 (
' ' * self.
indent, item.GetId()))
1946 self.fd.write(
'%s</loop>\n' % (
' ' * self.
indent))
1948 def _condition(self, condition):
1949 """!Write conditions"""
1950 bbox = condition.GetBoundingBoxMin()
1951 self.fd.write(
'%s<if-else id="%d" pos="%d,%d" size="%d,%d">\n' % \
1952 (
' ' * self.
indent, condition.GetId(), condition.GetX(), condition.GetY(),
1954 text = condition.GetText()
1957 self.fd.write(
'%s<condition>%s</condition>\n' %
1959 items = condition.GetItems()
1960 for b
in items.keys():
1961 if len(items[b]) < 1:
1963 self.fd.write(
'%s<%s>\n' % (
' ' * self.
indent, b))
1965 for item
in items[b]:
1966 self.fd.write(
'%s<item>%d</item>\n' %
1967 (
' ' * self.
indent, item.GetId()))
1969 self.fd.write(
'%s</%s>\n' % (
' ' * self.
indent, b))
1972 self.fd.write(
'%s</if-else>\n' % (
' ' * self.
indent))
1976 """!Class for exporting model to Python script
1978 @param fd file desciptor
1986 def _writePython(self):
1987 """!Write model to file"""
1988 properties = self.model.GetProperties()
1991 r"""#!/usr/bin/env python
2007 EncodeString(
'\n# '.join(properties[
'description'].splitlines())),
2017 import grass.script as grass
2021 rast, vect, rast3d, msg = self.model.GetIntermediateData()
2028 r""" grass.run_command('g.remove',
2030 """ %
','.join(map(
lambda x:
"'" + x +
"'", rast)))
2033 r""" grass.run_command('g.remove',
2035 """ %
','.join(map(
lambda x:
"'" + x +
"'", vect)))
2038 r""" grass.run_command('g.remove',
2040 """ %
','.join(map(
lambda x:
"'" + x +
"'", rast3d)))
2041 if not rast
and not vect
and not rast3d:
2042 self.fd.write(
' pass\n')
2044 self.fd.write(
"\ndef main():\n")
2045 for item
in self.model.GetItems():
2048 self.fd.write(
"\n return 0\n")
2052 if __name__ == "__main__":
2053 options, flags = grass.parser()
2054 atexit.register(cleanup)
2058 def _writePythonItem(self, item, ignoreBlock = True, variables = []):
2059 """!Write model object to Python file"""
2060 if isinstance(item, ModelAction):
2061 if ignoreBlock
and item.GetBlockId():
2064 elif isinstance(item, ModelLoop)
or isinstance(item, ModelCondition):
2066 variables = self.model.GetVariables()
2067 cond = item.GetText()
2068 for variable
in variables:
2069 pattern = re.compile(
'%' + variable)
2070 if pattern.search(cond):
2071 value = variables[variable].get(
'value',
'')
2072 if variables[variable].get(
'type',
'string') ==
'string':
2073 value =
'"' + value +
'"'
2074 cond = pattern.sub(value, cond)
2075 if isinstance(item, ModelLoop):
2076 condVar, condText = map(
lambda x: x.strip(), re.split(
'\s*in\s*', cond))
2077 cond =
"%sfor %s in " % (
' ' * self.
indent, condVar)
2078 if condText[0] ==
'`' and condText[-1] ==
'`':
2079 task = GUI(show =
None).ParseCommand(cmd =
utils.split(condText[1:-1]))
2080 cond +=
"grass.read_command("
2081 cond += self.
_getPythonActionCmd(task, len(cond), variables = [condVar]) +
".splitlines()"
2084 self.fd.write(
'%s:\n' % cond)
2086 for action
in item.GetItems():
2090 self.fd.write(
'%sif %s:\n' % (
' ' * self.
indent, cond))
2092 condItems = item.GetItems()
2093 for action
in condItems[
'if']:
2095 if condItems[
'else']:
2097 self.fd.write(
'%selse:\n' % (
' ' * self.
indent))
2099 for action
in condItems[
'else']:
2103 def _writePythonAction(self, item, variables = []):
2104 """!Write model action to Python file"""
2105 task = GUI(show =
None).ParseCommand(cmd = item.GetLog(string =
False, substitute = self.model.GetVariables()))
2106 strcmd =
"%sgrass.run_command(" % (
' ' * self.
indent)
2109 def _getPythonActionCmd(self, task, cmdIndent, variables = []):
2110 opts = task.get_options()
2116 for f
in opts[
'flags']:
2117 if f.get(
'value',
False):
2118 name = f.get(
'name',
'')
2120 params.append(
'%s = True' % name)
2124 for p
in opts[
'params']:
2125 name = p.get(
'name',
None)
2126 value = p.get(
'value',
None)
2128 ptype = p.get(
'type',
'string')
2130 params.append(
"%s = %s" % (name, value[1:]))
2131 elif ptype ==
'string':
2132 params.append(
'%s = "%s"' % (name, value))
2134 params.append(
"%s = %s" % (name, value))
2136 ret +=
'"%s"' % task.get_name()
2138 ret +=
",\n%sflags = '%s'" % (
' ' * cmdIndent, flags)
2141 for opt
in params[:-1]:
2142 ret +=
"%s%s,\n" % (
' ' * cmdIndent, opt)
2143 ret +=
"%s%s)" % (
' ' * cmdIndent, params[-1])
2150 def __init__(self, parent, params, id = wx.ID_ANY, title = _(
"Model parameters"),
2151 style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
2152 """!Model parameters dialog
2158 wx.Dialog.__init__(self, parent = parent, id = id, title = title, style = style, **kwargs)
2161 style = globalvar.FNPageDStyle)
2164 wx.CallAfter(self.notebook.SetSelection, 0)
2167 self.
interData = wx.CheckBox(parent = self, label = _(
"Delete intermediate data when finish"))
2168 self.interData.SetValue(
True)
2169 rast, vect, rast3d, msg = self.parent.GetModel().GetIntermediateData()
2170 if not rast
and not vect
and not rast3d:
2171 self.interData.Hide()
2173 self.
btnCancel = wx.Button(parent = self, id = wx.ID_CANCEL)
2174 self.
btnRun = wx.Button(parent = self, id = wx.ID_OK,
2176 self.btnRun.SetDefault()
2180 size = self.GetBestSize()
2181 self.SetMinSize(size)
2182 self.SetSize((size.width, size.height +
2183 panel.constrained_size[1] -
2184 panel.panelMinHeight))
2187 btnSizer = wx.StdDialogButtonSizer()
2189 btnSizer.AddButton(self.
btnRun)
2192 mainSizer = wx.BoxSizer(wx.VERTICAL)
2193 mainSizer.Add(item = self.
notebook, proportion = 1,
2195 if self.interData.IsShown():
2196 mainSizer.Add(item = self.
interData, proportion = 0,
2197 flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
2199 mainSizer.Add(item = wx.StaticLine(parent = self, id = wx.ID_ANY,
2200 style = wx.LI_HORIZONTAL),
2202 flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 5)
2204 mainSizer.Add(item = btnSizer, proportion = 0,
2205 flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
2207 self.SetSizer(mainSizer)
2210 def _createPages(self):
2211 """!Create for each parameterized module its own page"""
2212 nameOrdered = [
''] * len(self.params.keys())
2213 for name, params
in self.params.iteritems():
2214 nameOrdered[params[
'idx']] = name
2215 for name
in nameOrdered:
2216 params = self.
params[name]
2218 if name ==
'variables':
2219 name = _(
'Variables')
2220 self.notebook.AddPage(page = panel, text = name)
2224 def _createPage(self, name, params):
2225 """!Define notebook page"""
2226 if name
in globalvar.grassCmd:
2227 task = gtask.grassTask(name)
2229 task = gtask.grassTask()
2230 task.flags = params[
'flags']
2231 task.params = params[
'params']
2233 panel = CmdPanel(parent = self, id = wx.ID_ANY, task = task)
2234 self.tasks.append(task)
2239 """!Check for errors, get list of messages"""
2241 for task
in self.
tasks:
2242 errList += task.get_cmd_error()
2247 """!Check if to detele intermediate data"""
2248 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 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.