[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