[GRASS-SVN] r72333 - grass/branches/releasebranch_7_4/gui/wxpython/gmodeler
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Mar 9 03:26:53 PST 2018
Author: martinl
Date: 2018-03-09 03:26:53 -0800 (Fri, 09 Mar 2018)
New Revision: 72333
Modified:
grass/branches/releasebranch_7_4/gui/wxpython/gmodeler/frame.py
grass/branches/releasebranch_7_4/gui/wxpython/gmodeler/giface.py
grass/branches/releasebranch_7_4/gui/wxpython/gmodeler/model.py
Log:
wxGUI/gmodeler: print command finished message
print model computation finished message
delete intermediate data when model finished
implement display data functionality
(merge r72300:72302,r72308,r72313:72314 from trunk)
Modified: grass/branches/releasebranch_7_4/gui/wxpython/gmodeler/frame.py
===================================================================
--- grass/branches/releasebranch_7_4/gui/wxpython/gmodeler/frame.py 2018-03-08 13:00:42 UTC (rev 72332)
+++ grass/branches/releasebranch_7_4/gui/wxpython/gmodeler/frame.py 2018-03-09 11:26:53 UTC (rev 72333)
@@ -11,7 +11,7 @@
- frame::ItemPanel
- frame::PythonPanel
-(C) 2010-2014 by the GRASS Development Team
+(C) 2010-2018 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.
@@ -38,7 +38,8 @@
import wx.lib.agw.flatnotebook as FN
else:
import wx.lib.flatnotebook as FN
-
+from wx.lib.newevent import NewEvent
+
from core.utils import _
from gui_core.widgets import GNotebook
from core.gconsole import GConsole, \
@@ -61,6 +62,8 @@
from gmodeler.model import *
from gmodeler.dialogs import *
+wxModelDone, EVT_MODEL_DONE = NewEvent()
+
from grass.script.utils import try_remove
from grass.script import core as grass
@@ -148,7 +151,8 @@
# rewrite default method to avoid hiding progress bar
self._gconsole.Bind(EVT_CMD_DONE, self.OnCmdDone)
self.Bind(EVT_CMD_PREPARE, self.OnCmdPrepare)
-
+ self.Bind(EVT_MODEL_DONE, self.OnModelDone)
+
self.notebook.AddPage(page=self.canvas, text=_('Model'), name='model')
self.notebook.AddPage(
page=self.itemPanel,
@@ -288,11 +292,37 @@
def OnCmdDone(self, event):
"""Command done (or aborted)"""
- self.goutput.GetProgressBar().SetValue(0)
+ def time_elapsed(etime):
+ try:
+ ctime = time.time() - etime
+ if ctime < 60:
+ stime = _("%d sec") % int(ctime)
+ else:
+ mtime = int(ctime / 60)
+ stime = _("%(min)d min %(sec)d sec") % {
+ 'min': mtime, 'sec': int(ctime - (mtime * 60))}
+ except KeyError:
+ # stopped deamon
+ stime = _("unknown")
+
+ return stime
+
+ self.goutput.GetProgressBar().SetValue(0)
+ self.goutput.WriteCmdLog('({}) {} ({})'.format(
+ str(time.ctime()), _("Command finished"), time_elapsed(event.time)),
+ notification=event.notification)
+
try:
action = self.GetModel().GetItems()[event.pid]
if hasattr(action, "task"):
action.Update(running=True)
+ if event.pid == self._gconsole.cmdThread.GetId() - 1:
+ self.goutput.WriteCmdLog('({}) {} ({})'.format(
+ str(time.ctime()), _("Model computation finished"), time_elapsed(self.start_time)),
+ notification=event.notification)
+ event = wxModelDone()
+ wx.PostEvent(self, event)
+
except IndexError:
pass
@@ -357,6 +387,22 @@
dlg.Destroy()
+ def _deleteIntermediateData(self):
+ """Delete intermediate data"""
+ rast, vect, rast3d, msg = self.model.GetIntermediateData()
+ if rast:
+ self._gconsole.RunCmd(['g.remove', '-f', 'type=raster',
+ 'name=%s' % ','.join(rast)])
+ if rast3d:
+ self._gconsole.RunCmd(['g.remove', '-f', 'type=raster_3d',
+ 'name=%s' % ','.join(rast3d)])
+ if vect:
+ self._gconsole.RunCmd(['g.remove', '-f', 'type=vector',
+ 'name=%s' % ','.join(vect)])
+
+ self.SetStatusText(_("%d intermediate maps deleted from current mapset") %
+ int(len(rast) + len(rast3d) + len(vect)))
+
def OnDeleteData(self, event):
"""Delete intermediate data"""
rast, vect, rast3d, msg = self.model.GetIntermediateData()
@@ -375,25 +421,10 @@
style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
ret = dlg.ShowModal()
+ dlg.Destroy()
if ret == wx.ID_YES:
- dlg.Destroy()
+ self._deleteIntermediateData()
- if rast:
- self._gconsole.RunCmd(['g.remove', '-f', 'type=raster',
- 'name=%s' % ','.join(rast)])
- if rast3d:
- self._gconsole.RunCmd(['g.remove', '-f', 'type=raster_3d',
- 'name=%s' % ','.join(rast3d)])
- if vect:
- self._gconsole.RunCmd(['g.remove', '-f', 'type=vector',
- 'name=%s' % ','.join(vect)])
-
- self.SetStatusText(_("%d maps deleted from current mapset") %
- int(len(rast) + len(rast3d) + len(vect)))
- return
-
- dlg.Destroy()
-
def OnModelNew(self, event):
"""Create new model"""
Debug.msg(4, "ModelFrame.OnModelNew():")
@@ -580,15 +611,14 @@
def OnRunModel(self, event):
"""Run entire model"""
- self.model.Run(self._gconsole, self.OnDone, parent=self)
+ self.start_time = time.time()
+ self.model.Run(self._gconsole, self.OnModelDone, parent=self)
- def OnDone(self, event):
+ def OnModelDone(self, event):
"""Computation finished
-
- .. todo::
- not called -- must be fixed
"""
self.SetStatusText('', 0)
+
# restore original files
if hasattr(self.model, "fileInput"):
for finput in self.model.fileInput:
@@ -603,6 +633,25 @@
fd.close()
del self.model.fileInput
+ # delete intermediate data
+ self._deleteIntermediateData()
+
+ # display data if required
+ for data in self.model.GetData():
+ if not data.HasDisplay():
+ continue
+
+ # remove existing map layers first
+ layers = self._giface.GetLayerList().GetLayersByName(data.GetValue())
+ if layers:
+ for layer in layers:
+ self._giface.GetLayerList().DeleteLayer(layer)
+
+ # add new map layer
+ self._giface.GetLayerList().AddLayer(
+ ltype=data.GetPrompt(), name=data.GetValue(), checked=True,
+ cmd=data.GetDisplayCmd())
+
def OnValidateModel(self, event, showMsg=True):
"""Validate entire model"""
if self.model.GetNumItems() < 1:
@@ -1434,7 +1483,7 @@
if not hasattr(self, "popupID"):
self.popupID = dict()
for key in ('remove', 'enable', 'addPoint',
- 'delPoint', 'intermediate', 'props', 'id',
+ 'delPoint', 'intermediate', 'display', 'props', 'id',
'label', 'comment'):
self.popupID[key] = wx.NewId()
@@ -1496,20 +1545,38 @@
if len(shape.GetLineControlPoints()) == 2:
popupMenu.Enable(self.popupID['delPoint'], False)
- if isinstance(shape, ModelData) and '@' not in shape.GetValue():
+ if isinstance(shape, ModelData):
popupMenu.AppendSeparator()
- popupMenu.Append(
- self.popupID['intermediate'],
- text=_('Intermediate'),
- kind=wx.ITEM_CHECK)
- if self.GetShape().IsIntermediate():
- popupMenu.Check(self.popupID['intermediate'], True)
+ if '@' not in shape.GetValue() and \
+ len(self.GetShape().GetRelations('from')) > 0:
+ popupMenu.Append(
+ self.popupID['intermediate'],
+ text=_('Intermediate'),
+ kind=wx.ITEM_CHECK)
+ if self.GetShape().IsIntermediate():
+ popupMenu.Check(self.popupID['intermediate'], True)
- self.frame.Bind(
- wx.EVT_MENU,
- self.OnIntermediate,
- id=self.popupID['intermediate'])
+ self.frame.Bind(
+ wx.EVT_MENU,
+ self.OnIntermediate,
+ id=self.popupID['intermediate'])
+ if self.frame._giface.GetMapDisplay():
+ popupMenu.Append(
+ self.popupID['display'],
+ text=_('Display'),
+ kind=wx.ITEM_CHECK)
+ if self.GetShape().HasDisplay():
+ popupMenu.Check(self.popupID['display'], True)
+
+ self.frame.Bind(
+ wx.EVT_MENU,
+ self.OnHasDisplay,
+ id=self.popupID['display'])
+
+ if self.GetShape().IsIntermediate():
+ popupMenu.Enable(self.popupID['display'], False)
+
if isinstance(shape, ModelData) or \
isinstance(shape, ModelAction) or \
isinstance(shape, ModelLoop):
@@ -1614,6 +1681,29 @@
shape.SetIntermediate(event.IsChecked())
self.frame.canvas.Refresh()
+ def OnHasDisplay(self, event):
+ """Mark data to be displayed"""
+ self.frame.ModelChanged()
+ shape = self.GetShape()
+ shape.SetHasDisplay(event.IsChecked())
+ self.frame.canvas.Refresh()
+
+ try:
+ if event.IsChecked():
+ # add map layer to display
+ self.frame._giface.GetLayerList().AddLayer(
+ ltype=shape.GetPrompt(), name=shape.GetValue(), checked=True,
+ cmd=shape.GetDisplayCmd())
+ else:
+ # remove map layer(s) from display
+ layers = self.frame._giface.GetLayerList().GetLayersByName(shape.GetValue())
+ for layer in layers:
+ self.frame._giface.GetLayerList().DeleteLayer(layer)
+
+ except GException as e:
+ GError(parent=self,
+ message='{}'.format(e))
+
def OnRemove(self, event):
"""Remove shape
"""
Modified: grass/branches/releasebranch_7_4/gui/wxpython/gmodeler/giface.py
===================================================================
--- grass/branches/releasebranch_7_4/gui/wxpython/gmodeler/giface.py 2018-03-08 13:00:42 UTC (rev 72332)
+++ grass/branches/releasebranch_7_4/gui/wxpython/gmodeler/giface.py 2018-03-09 11:26:53 UTC (rev 72333)
@@ -6,7 +6,7 @@
Classes:
- giface::GraphicalModelerGrassInterface
-(C) 2013-2014 by the GRASS Development Team
+(C) 2013-2018 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.
Modified: grass/branches/releasebranch_7_4/gui/wxpython/gmodeler/model.py
===================================================================
--- grass/branches/releasebranch_7_4/gui/wxpython/gmodeler/model.py 2018-03-08 13:00:42 UTC (rev 72332)
+++ grass/branches/releasebranch_7_4/gui/wxpython/gmodeler/model.py 2018-03-09 11:26:53 UTC (rev 72333)
@@ -18,7 +18,7 @@
- model::WritePythonFile
- model::ModelParamDialog
-(C) 2010-2016 by the GRASS Development Team
+(C) 2010-2018 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.
@@ -354,6 +354,7 @@
prompt=data['prompt'],
value=data['value'])
dataItem.SetIntermediate(data['intermediate'])
+ dataItem.SetHasDisplay(data['display'])
for rel in data['rels']:
actionItem = self.FindAction(rel['id'])
@@ -569,7 +570,7 @@
def OnPrepare(self, item, params):
self._substituteFile(item, params, checkOnly=False)
- def RunAction(self, item, params, log, onDone,
+ def RunAction(self, item, params, log, onDone=None,
onPrepare=None, statusbar=None):
"""Run given action
@@ -683,7 +684,7 @@
if isinstance(item, ModelAction):
if item.GetBlockId():
continue
- self.RunAction(item, params, log, onDone)
+ self.RunAction(item, params, log)
elif isinstance(item, ModelLoop):
cond = item.GetLabel()
@@ -743,7 +744,7 @@
varDict['value'] = var
self.RunAction(item=action, params=params,
- log=log, onDone=onDone)
+ log=log)
params['variables']['params'].remove(varDict)
if delInterData:
@@ -1346,6 +1347,7 @@
self.value = value
self.prompt = prompt
self.intermediate = False
+ self.display = False
self.propWin = None
if not width:
width = UserSettings.Get(
@@ -1374,6 +1376,14 @@
"""Set intermediate flag"""
self.intermediate = im
+ def HasDisplay(self):
+ """Checks if data item is marked to be displayed"""
+ return self.display
+
+ def SetHasDisplay(self, tbd):
+ """Set to-be-displayed flag"""
+ self.display = tbd
+
def OnDraw(self, dc):
self._setPen()
@@ -1506,7 +1516,21 @@
self._setPen()
self.SetLabel()
+ def GetDisplayCmd(self):
+ """Get display command as list"""
+ cmd = []
+ if self.prompt == 'raster':
+ cmd.append('d.rast')
+ elif self.prompt == 'vector':
+ cmd.append('d.vect')
+ else:
+ raise GException("Unsupported display prompt: {}".format(
+ self.prompt))
+ cmd.append('map=' + self.value)
+
+ return cmd
+
class ModelRelation(ogl.LineShape):
"""Data - action relation"""
@@ -2018,11 +2042,10 @@
prompt = param.get('prompt', None)
value = self._filterValue(self._getNodeText(param, 'value'))
- if data.find('intermediate') is None:
- intermediate = False
- else:
- intermediate = True
+ intermediate = False if data.find('intermediate') is None else True
+ display = False if data.find('display') is None else True
+
rels = list()
for rel in data.findall('relation'):
defrel = {'id': int(rel.get('id', -1)),
@@ -2041,6 +2064,7 @@
'prompt': prompt,
'value': value,
'intermediate': intermediate,
+ 'display': display,
'rels': rels})
def _processTask(self, node):
@@ -2381,6 +2405,8 @@
if data.IsIntermediate():
self.fd.write('%s<intermediate />\n' % (' ' * self.indent))
+ if data.HasDisplay():
+ self.fd.write('%s<display />\n' % (' ' * self.indent))
# relations
for ft in ('from', 'to'):
More information about the grass-commit
mailing list