[GRASS-SVN] r32456 -
grass/branches/develbranch_6/gui/wxpython/gui_modules
svn_grass at osgeo.org
svn_grass at osgeo.org
Sat Aug 2 07:28:09 EDT 2008
Author: martinl
Date: 2008-08-02 07:28:09 -0400 (Sat, 02 Aug 2008)
New Revision: 32456
Modified:
grass/branches/develbranch_6/gui/wxpython/gui_modules/gcmd.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/utils.py
Log:
wxGUI: optionally add created map (raster, vector) into layer tree when running command
some goutput fixes (\r) [merge from trunk, r32454]
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/gcmd.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/gcmd.py 2008-08-02 10:45:37 UTC (rev 32455)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/gcmd.py 2008-08-02 11:28:09 UTC (rev 32456)
@@ -349,11 +349,11 @@
os.linesep, os.linesep,
_("Details:"),
os.linesep,
- self.PrintModuleOutput()))
+ _("Error: ") + self.GetError()))
elif rerr == sys.stderr: # redirect message to sys
stderr.write("Execution failed: '%s'" % (' '.join(self.cmd)))
stderr.write("%sDetails:%s%s" % (os.linesep,
- self.PrintModuleOutput(),
+ _("Error: ") + self.GetError(),
os.linesep))
else:
pass # nop
@@ -408,7 +408,7 @@
if self.stderr is None:
lines = self.ReadErrOutput()
else:
- lines = self.cmdThread.rerr.strip('%s' % os.linesep). \
+ lines = self.cmdThread.error.strip('%s' % os.linesep). \
split('%s' % os.linesep)
msg = []
@@ -435,6 +435,14 @@
return msg
+ def GetError(self):
+ """Get error message or ''"""
+ for type, msg in self.__ProcessStdErr():
+ if type == 'ERROR':
+ return msg
+
+ return ''
+
def PrintModuleOutput(self, error=True, warning=False, message=False):
"""Print module errors, warnings, messages to output
@@ -480,9 +488,9 @@
self._want_abort = False
self.aborted = False
-
+
self.setDaemon(True)
-
+
# set message formatting
self.message_format = os.getenv("GRASS_MESSAGE_FORMAT")
os.environ["GRASS_MESSAGE_FORMAT"] = "gui"
@@ -511,7 +519,7 @@
if self.stdin: # read stdin if requested ...
self.module.stdin.write(self.stdin)
self.module.stdin.close()
-
+
# redirect standard outputs...
if self.stdout or self.stderr:
self.__redirect_stream()
@@ -537,14 +545,15 @@
if self._want_abort: # abort running process
self.module.kill()
self.aborted = True
- return
+ return
if self.stdout:
line = recv_some(self.module, e=0, stderr=0)
self.stdout.write(line)
if self.stderr:
line = recv_some(self.module, e=0, stderr=1)
self.stderr.write(line)
- self.rerr = line
+ if len(line) > 0:
+ self.error = line
# get the last output
if self.stdout:
@@ -554,8 +563,8 @@
line = recv_some(self.module, e=0, stderr=1)
self.stderr.write(line)
if len(line) > 0:
- self.rerr = line
-
+ self.error = line
+
def abort(self):
"""Abort running process, used by main thread to signal an abort"""
self._want_abort = True
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py 2008-08-02 10:45:37 UTC (rev 32455)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py 2008-08-02 11:28:09 UTC (rev 32456)
@@ -31,16 +31,18 @@
import globalvar
import gcmd
+import utils
from debug import Debug as Debug
wxCmdOutput, EVT_CMD_OUTPUT = NewEvent()
wxCmdProgress, EVT_CMD_PROGRESS = NewEvent()
+wxCmdRun, EVT_CMD_RUN = NewEvent()
wxCmdDone, EVT_CMD_DONE = NewEvent()
wxCmdAbort, EVT_CMD_ABORT = NewEvent()
def GrassCmd(cmd, stdout, stderr):
"""Return GRASS command thread"""
- return gcmd.CommandThread(cmd=cmd,
+ return gcmd.CommandThread(cmd,
stdout=stdout, stderr=stderr)
class CmdThread(threading.Thread):
@@ -61,7 +63,6 @@
def RunCmd(self, callable, *args, **kwds):
CmdThread.requestId += 1
- self.requestTime = time.time()
self.requestCmd = None
self.requestQ.put((CmdThread.requestId, callable, args, kwds))
@@ -70,13 +71,24 @@
def run(self):
while True:
requestId, callable, args, kwds = self.requestQ.get()
+
+ requestTime = time.time()
+ event = wxCmdRun(cmd=args[0],
+ pid=requestId)
+ wx.PostEvent(self.parent, event)
+
+ time.sleep(.1)
+
self.requestCmd = callable(*args, **kwds)
+
self.resultQ.put((requestId, self.requestCmd.run()))
event = wxCmdDone(aborted=self.requestCmd.aborted,
- time=self.requestTime,
+ time=requestTime,
pid=requestId)
+
time.sleep(.1)
+
wx.PostEvent(self.parent, event)
def abort(self):
@@ -97,7 +109,9 @@
self.parent = parent # GMFrame
self.lineWidth = 80
self.pageid = pageid
-
+ # remember position of line begining (used for '\r')
+ self.linePos = -1
+
#
# create queues
#
@@ -120,6 +134,7 @@
self.cmd_output_timer = wx.Timer(self.cmd_output, id=wx.ID_ANY)
self.cmd_output.Bind(EVT_CMD_OUTPUT, self.OnCmdOutput)
self.cmd_output.Bind(wx.EVT_TIMER, self.OnProcessPendingOutputWindowEvents)
+ self.Bind(EVT_CMD_RUN, self.OnCmdRun)
self.Bind(EVT_CMD_DONE, self.OnCmdDone)
#
@@ -240,15 +255,12 @@
except:
curr_disp = None
- if not self.requestQ.empty():
- # only one running command enabled (per GMConsole instance)
- busy = wx.BusyInfo(message=_("Unable to run the command, another command is running..."),
- parent=self)
- wx.Yield()
- time.sleep(3)
- busy.Destroy()
- return None
-
+ # switch to 'Command output'
+ # if hasattr(self.parent, "curr_page"):
+ # change notebook page only for Layer Manager
+ # if self.parent.notebook.GetSelection() != 1:
+ # self.parent.notebook.SetSelection(1)
+
# command given as a string ?
try:
cmdlist = command.strip().split(' ')
@@ -299,11 +311,9 @@
menuform.GUI().ParseCommand(cmdlist, parentframe=self)
else:
# process GRASS command with argument
- cmdPID = self.cmdThread.requestId + 1
- self.WriteCmdLog('%s' % ' '.join(cmdlist), pid=cmdPID)
-
self.cmdThread.RunCmd(GrassCmd,
- cmdlist, self.cmd_stdout, self.cmd_stderr)
+ cmdlist,
+ self.cmd_stdout, self.cmd_stderr)
self.cmd_output_timer.Start(50)
@@ -314,10 +324,6 @@
else:
# Send any other command to the shell. Send output to
# console output window
- if hasattr(self.parent, "curr_page"):
- # change notebook page only for Layer Manager
- if self.parent.notebook.GetSelection() != 1:
- self.parent.notebook.SetSelection(1)
# if command is not a GRASS command, treat it like a shell command
try:
@@ -369,7 +375,7 @@
"""Print command output"""
message = event.text
type = event.type
-
+
# message prefix
if type == 'warning':
messege = 'WARNING: ' + message
@@ -377,10 +383,10 @@
message = 'ERROR: ' + message
p1 = self.cmd_output.GetCurrentPos()
-
- message = message.replace('\r', '')
-
+ self.linePos = self.cmd_output.GetCurrentPos()
+
pc = -1
+
if '\b' in message:
pc = p1
last_c = ''
@@ -388,22 +394,26 @@
if c == '\b':
pc -= 1
else:
- self.cmd_output.SetCurrentPos(pc)
+ if c == '\r':
+ self.cmd_output.SetCurrentPos(self.linePos)
+ else:
+ self.cmd_output.SetCurrentPos(pc)
self.cmd_output.ReplaceSelection(c)
pc = self.cmd_output.GetCurrentPos()
if c != ' ':
last_c = c
if last_c not in ('0123456789'):
- self.cmd_output.AddText('\n')
+ self.cmd_output.AddTextWrapped('\n', wrap=None)
pc = -1
else:
if os.linesep not in message:
self.cmd_output.AddTextWrapped(message, wrap=60)
else:
- self.cmd_output.AddText(message)
-
+ self.cmd_output.AddTextWrapped(message, wrap=None)
+
p2 = self.cmd_output.GetCurrentPos()
self.cmd_output.StartStyling(p1, 0xff)
+
if type == 'error':
self.cmd_output.SetStyling(p2 - p1 + 1, self.cmd_output.StyleError)
elif type == 'warning':
@@ -425,7 +435,11 @@
def OnCmdAbort(self, event):
"""Abort running command"""
self.cmdThread.abort()
-
+
+ def OnCmdRun(self, event):
+ """Run command"""
+ self.WriteCmdLog('%s' % ' '.join(event.cmd), pid=event.pid)
+
def OnCmdDone(self, event):
"""Command done (or aborted)"""
if event.aborted:
@@ -465,6 +479,24 @@
dialog.btn_run.Enable(True)
+ if not event.aborted and hasattr(dialog, "addbox") and \
+ dialog.addbox.IsChecked():
+ # add new map into layer tree
+ if dialog.outputType in ('raster', 'vector'):
+ # add layer into layer tree
+ cmd = dialog.notebookpanel.createCmd(ignoreErrors = True)
+ name = utils.GetLayerNameFromCmd(cmd, fullyQualified=True, param='output')
+ mapTree = self.parent.parent.parent.parent.curr_page.maptree
+ if dialog.outputType == 'raster':
+ lcmd = ['d.rast',
+ 'map=%s' % name]
+ else:
+ lcmd = ['d.vect',
+ 'map=%s' % name]
+ mapTree.AddLayer(ltype=dialog.outputType,
+ lcmd=lcmd,
+ lname=name)
+
if dialog.get_dcmd is None and \
dialog.closebox.IsChecked():
time.sleep(1)
@@ -520,7 +552,7 @@
self.type = ''
self.message = ''
self.printMessage = False
-
+
def write(self, s):
s = s.replace('\n', os.linesep)
# remove/replace escape sequences '\b' or '\r' from stream
@@ -529,6 +561,7 @@
for line in s.split(os.linesep):
if len(line) == 0:
continue
+
if 'GRASS_INFO_PERCENT' in line:
value = int(line.rsplit(':', 1)[1].strip())
if value >= 0 and value < 100:
@@ -584,7 +617,6 @@
def __init__(self, parent, id, margin=False, wrap=None):
wx.stc.StyledTextCtrl.__init__(self, parent, id)
self.parent = parent
- self.wrap = wrap
#
# styles
@@ -606,7 +638,7 @@
self.StyleMessageSpec = "face:Courier New,size:10,fore:#000000,back:#FFFFFF"
# unknown
self.StyleUnknown = 6
- self.StyleUnknownSpec = "face:Courier New,size:10,fore:#7F0000,back:#FFFFFF"
+ self.StyleUnknownSpec = "face:Courier New,size:10,fore:#000000,back:#FFFFFF"
# default and clear => init
self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, self.StyleDefaultSpec)
@@ -657,25 +689,24 @@
String is wrapped and linesep is also added to the end
of the string"""
- if wrap is None and self.wrap:
- wrap = self.wrap
-
- if wrap is not None:
+ if wrap:
txt = textwrap.fill(txt, wrap) + os.linesep
else:
txt += os.linesep
-
- self.AddText(txt)
-
-
- def SetWrap(self, wrap):
- """Set wrapping value
-
- @param wrap wrapping value
-
- @return current wrapping value
- """
- if wrap > 0:
- self.wrap = wrap
-
- return self.wrap
+
+ if '\r' in txt:
+ self.linePos = -1
+ for seg in txt.split('\r'):
+ if self.linePos > -1:
+ self.cmd_output.SetCurrenPos()
+ self.ReplaceText(iseg) + ' ' * (self.lineWidth - len(iseg))
+ else:
+ self.AddText(iseg)
+ self.linePos = self.GetCurrentPos()
+
+ iseg += 1
+ else:
+ self.AddText(txt)
+ self.linePos = self.GetCurrentPos()
+
+
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py 2008-08-02 10:45:37 UTC (rev 32455)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py 2008-08-02 11:28:09 UTC (rev 32456)
@@ -708,6 +708,21 @@
guisizer.Add(item=btnsizer, proportion=0, flag=wx.ALIGN_CENTER)
+ if self.parent is not None:
+ self.outputType = None
+ for p in self.task.params:
+ if p.get('name', '') == 'output':
+ self.outputType = p.get('prompt', None)
+ break
+ if self.outputType:
+ # add newly created map into layer tree
+ self.addbox = wx.CheckBox(parent=self.panel,
+ label=_('Add created map into layer tree'), style = wx.NO_BORDER)
+ self.addbox.SetValue(UserSettings.Get(group='cmd', key='addNewLayer', subkey='enabled'))
+ guisizer.Add(item=self.addbox, proportion=0,
+ flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
+ border=5)
+
if self.get_dcmd is None:
# close dialog when command is terminated
self.closebox = wx.CheckBox(parent=self.panel,
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py 2008-08-02 10:45:37 UTC (rev 32455)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py 2008-08-02 11:28:09 UTC (rev 32456)
@@ -145,6 +145,9 @@
'rasterOverlay' : {
'enabled' : False
},
+ 'addNewLayer' : {
+ 'enabled' : False
+ },
},
#
# Workspace
@@ -961,6 +964,16 @@
gridSizer.Add(item=close,
pos=(row, 0), span=(1, 2))
row += 1
+ # add layer
+ add = wx.CheckBox(parent=panel, id=wx.ID_ANY,
+ label=_("Add created map into layer tree"),
+ name="IsChecked")
+ add.SetValue(self.settings.Get(group='cmd', key='addNewLayer', subkey='enabled'))
+ self.winId['cmd:addNewLayer:enabled'] = add.GetId()
+
+ gridSizer.Add(item=add,
+ pos=(row, 0), span=(1, 2))
+ row += 1
# verbosity
gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
label=_("Verbosity level:")),
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/utils.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/utils.py 2008-08-02 10:45:37 UTC (rev 32455)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/utils.py 2008-08-02 11:28:09 UTC (rev 32456)
@@ -57,12 +57,12 @@
except:
return None
-def GetLayerNameFromCmd(dcmd, fullyQualified=False):
+def GetLayerNameFromCmd(dcmd, fullyQualified=False, param=None):
"""Get map name from GRASS command
@param dcmd GRASS command (given as list)
@param fullyQualified change map name to be fully qualified
-
+ @param force parameter otherwise 'input'/'map'
@return map name
@return '' if no map name found in command
"""
@@ -78,12 +78,15 @@
mapname = dcmd[idx].split('=')[1]+' labels'
else:
for idx in range(len(dcmd)):
- if 'map=' in dcmd[idx] or \
- 'input=' in dcmd[idx] or \
- 'red=' in dcmd[idx] or \
- 'h_map=' in dcmd[idx] or \
- 'reliefmap' in dcmd[idx]:
+ if param and param in dcmd[idx]:
break
+ elif not param:
+ if 'map=' in dcmd[idx] or \
+ 'input=' in dcmd[idx] or \
+ 'red=' in dcmd[idx] or \
+ 'h_map=' in dcmd[idx] or \
+ 'reliefmap' in dcmd[idx]:
+ break
if idx < len(dcmd):
mapname = dcmd[idx].split('=')[1]
More information about the grass-commit
mailing list