[GRASS-SVN] r40053 - in grass/branches/develbranch_6/gui/wxpython: . gui_modules

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Dec 19 00:58:46 EST 2009


Author: cmbarton
Date: 2009-12-19 00:58:44 -0500 (Sat, 19 Dec 2009)
New Revision: 40053

Modified:
   grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/prompt.py
   grass/branches/develbranch_6/gui/wxpython/wxgui.py
Log:
Adds advanced command console with separate input and output areas, autocompletion of commands and input files, calltips of command syntax, and command history.

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py	2009-12-18 20:29:56 UTC (rev 40052)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py	2009-12-19 05:58:44 UTC (rev 40053)
@@ -24,6 +24,8 @@
 import time
 import threading
 import Queue
+import shlex
+import keyword
 
 import wx
 import wx.stc
@@ -36,6 +38,8 @@
 import utils
 import preferences
 import menuform
+import prompt
+
 from debug import Debug as Debug
 from preferences import globalSettings as UserSettings
 
@@ -145,6 +149,7 @@
             self._notebook = self.parent.notebook
         self.lineWidth       = 80
         self.pageid          = pageid
+                        
         # remember position of line begining (used for '\r')
         self.linePos         = -1
         
@@ -162,7 +167,7 @@
                                             style=wx.GA_HORIZONTAL)
         self.console_progressbar.Bind(EVT_CMD_PROGRESS, self.OnCmdProgress)
         # abort
-        self.btn_abort = wx.Button(parent=self, id=wx.ID_STOP)
+        self.btn_abort = wx.Button(self, -1, "Abort command", size=(125,-1))
         self.btn_abort.SetToolTipString(_("Abort the running command"))
         self.btn_abort.Bind(wx.EVT_BUTTON, self.OnCmdAbort)
         self.btn_abort.Enable(False)
@@ -179,6 +184,11 @@
         self.Bind(EVT_CMD_DONE, self.OnCmdDone)
         
         #
+        # command prompt
+        #
+        self.cmd_prompt = prompt.GPrompt(self, id=wx.ID_ANY)
+
+        #
         # stream redirection
         #
         self.cmd_stdout = GMStdout(self)
@@ -192,8 +202,10 @@
         #
         # buttons
         #
-        self.console_clear = wx.Button(parent=self, id=wx.ID_CLEAR)
-        self.console_save  = wx.Button(parent=self, id=wx.ID_SAVE)
+        self.console_clear = wx.Button(self, -1, "Clear output", size=(125,-1))
+        self.cmd_clear = wx.Button(self, -1, "Clear command", size=(125,-1))
+        self.console_save  = wx.Button(self, -1, "Save output", size=(125,-1))
+        self.Bind(wx.EVT_BUTTON, self.cmd_prompt.OnCmdErase, self.cmd_clear)
         self.Bind(wx.EVT_BUTTON, self.ClearHistory, self.console_clear)
         self.Bind(wx.EVT_BUTTON, self.SaveHistory,  self.console_save)
 
@@ -204,27 +216,31 @@
     def __layout(self):
         """!Do layout"""
         boxsizer1 = wx.BoxSizer(wx.VERTICAL)
-        gridsizer1 = wx.GridSizer(rows=1, cols=2, vgap=0, hgap=0)
+        gridsizer1 = wx.GridSizer(rows=1, cols=4, vgap=0, hgap=0)
+        
         boxsizer1.Add(item=self.cmd_output, proportion=1,
-                      flag=wx.EXPAND | wx.ADJUST_MINSIZE, border=0)
+                      flag=wx.EXPAND | wx.ALIGN_BOTTOM, border=0)
+        boxsizer1.Add(item=self.cmd_prompt, proportion=0,
+                      flag=wx.EXPAND | wx.FIXED_MINSIZE | wx.ALIGN_BOTTOM, border=0)
+                                            
         gridsizer1.Add(item=self.console_clear, proportion=0,
-                       flag=wx.ALIGN_CENTER_HORIZONTAL | wx.ADJUST_MINSIZE, border=0)
+                       flag=wx.ALIGN_CENTER_HORIZONTAL | wx.FIXED_MINSIZE, border=0)
         gridsizer1.Add(item=self.console_save, proportion=0,
-                       flag=wx.ALIGN_CENTER_HORIZONTAL | wx.ADJUST_MINSIZE, border=0)
-
-
+                       flag=wx.ALIGN_CENTER_HORIZONTAL | wx.FIXED_MINSIZE, border=0)
+        gridsizer1.Add(item=self.cmd_clear, proportion=0,
+                       flag=wx.ALIGN_CENTER_HORIZONTAL | wx.FIXED_MINSIZE, border=0)
+        gridsizer1.Add(item=self.btn_abort, proportion=0,
+                       flag=wx.ALIGN_CENTER_HORIZONTAL | wx.FIXED_MINSIZE, border=0)
         boxsizer1.Add(item=gridsizer1, proportion=0,
                       flag=wx.EXPAND | wx.ALIGN_CENTRE_VERTICAL | wx.TOP | wx.BOTTOM,
                       border=5)
+                      
         boxsizer2 = wx.BoxSizer(wx.HORIZONTAL)
         boxsizer2.Add(item=self.console_progressbar, proportion=1,
                       flag=wx.EXPAND | wx.ALIGN_CENTRE_VERTICAL)
-        boxsizer2.Add(item=self.btn_abort, proportion=0,
-                      flag=wx.ALIGN_CENTRE_VERTICAL | wx.LEFT,
-                      border = 5)
         boxsizer1.Add(item=boxsizer2, proportion=0,
-                      flag=wx.EXPAND | wx.ALIGN_CENTRE_VERTICAL | wx.ALL,
-                      border=5)
+                      flag=wx.EXPAND | wx.ALIGN_CENTRE_VERTICAL | wx.LEFT | wx.RIGHT |
+                      wx.TOP, border=5)
         
         boxsizer1.Fit(self)
         boxsizer1.SetSizeHints(self)
@@ -232,6 +248,7 @@
         # layout
         self.SetAutoLayout(True)
         self.SetSizer(boxsizer1)
+        self.Layout()
 
     def Redirect(self):
         """!Redirect stderr
@@ -269,7 +286,8 @@
         
         # p1 = self.cmd_output.GetCurrentPos()
         p1 = self.cmd_output.GetEndStyled()
-        self.cmd_output.GotoPos(p1)
+#        self.cmd_output.GotoPos(p1)
+        self.cmd_output.DocumentEnd()
         
         for line in text.splitlines():
             # fill space
@@ -349,7 +367,10 @@
                 self.parent.cmdinput.SetHistoryItems()
             except AttributeError:
                 pass
-        
+
+        # allow writing to output window
+        self.cmd_output.SetReadOnly(False)
+                
         if cmdlist[0] in globalvar.grassCmd['all']:
             # send GRASS command without arguments to GUI command interface
             # except display commands (they are handled differently)
@@ -434,9 +455,9 @@
 
             # if command is not a GRASS command, treat it like a shell command
             try:
-                # gcmd.Command(cmdlist,
-                #             stdout=self.cmd_stdout,
-                #             stderr=self.cmd_stderr)
+#                gcmd.Command(cmdlist,
+#                         stdout=self.cmd_stdout,
+#                         stderr=self.cmd_stderr)
                 self.cmdThread.RunCmd(GrassCmd,
                                       onDone,
                                       cmdlist,
@@ -445,6 +466,9 @@
                 self.cmd_output_timer.Start(50)
             except gcmd.CmdError, e:
                 print >> sys.stderr, e
+
+        # reset output window to read only
+        self.cmd_output.SetReadOnly(True)
         
         return None
 
@@ -530,7 +554,7 @@
                 self.cmd_output.AddTextWrapped(message, wrap=60)
             else:
                 self.cmd_output.AddTextWrapped(message, wrap=None)
-	    
+
         p2 = self.cmd_output.GetCurrentPos()
         
         if p2 >= p1:
@@ -590,7 +614,7 @@
 
         # set focus on prompt
         if self.parent.GetName() == "LayerManager":
-            self.parent.cmdinput.SetFocus()
+#            self.parent.cmdinput.SetFocus()
             self.btn_abort.Enable(False)
         else:
             # updated command dialog
@@ -756,13 +780,14 @@
     def __init__(self, parent, id, margin=False, wrap=None):
         wx.stc.StyledTextCtrl.__init__(self, parent, id)
         self.parent = parent
+        self.SetUndoCollection(True)
+        self.SetReadOnly(True)
 
         #
         # styles
         #                
         self.SetStyle()
         
-
         #
         # line margins
         #
@@ -786,10 +811,10 @@
         self.SetUseHorizontalScrollBar(True)
 
         #
-        # bindins
+        # bindings
         #
         self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
-        
+                                                            
     def SetStyle(self):
         """!Set styles for styled text output windows with type face 
         and point size selected by user (Courier New 10 is default)"""
@@ -830,8 +855,8 @@
         self.StyleSetSpec(self.StyleError,   self.StyleErrorSpec)
         self.StyleSetSpec(self.StyleWarning, self.StyleWarningSpec)
         self.StyleSetSpec(self.StyleMessage, self.StyleMessageSpec)
-        self.StyleSetSpec(self.StyleUnknown, self.StyleUnknownSpec)        
-
+        self.StyleSetSpec(self.StyleUnknown, self.StyleUnknownSpec)  
+        
     def OnDestroy(self, evt):
         """!The clipboard contents can be preserved after
         the app has exited"""

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/prompt.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/prompt.py	2009-12-18 20:29:56 UTC (rev 40052)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/prompt.py	2009-12-19 05:58:44 UTC (rev 40053)
@@ -24,147 +24,400 @@
 import shlex
 
 import wx
-import wx.lib.mixins.listctrl as listmix
+import wx.stc
 
 from grass.script import core as grass
 
 import globalvar
-import utils
-import menuform
 import menudata
+import gcmd
 
-class GPrompt:
-    """!Interactive GRASS prompt"""
-    def __init__(self, parent):
-        self.parent = parent # GMFrame
+class GPrompt(wx.stc.StyledTextCtrl):
+    """!Styled GRASS prompt"""    
+    def __init__(self, parent, id, size=wx.DefaultSize, margin=False, wrap=None):
+        wx.stc.StyledTextCtrl.__init__(self, parent, id)
+        self.parent = parent
+        self.SetUndoCollection(True)        
+
+        #
+        # styles
+        #                
+        self.SetWrapMode(True)
         
-        # dictionary of modules (description, keywords, ...)
-        self.modules = self.parent.menudata.GetModules()
+        #
+        # create command and map lists for autocompletion
+        #
+        self.AutoCompSetIgnoreCase(False) 
         
-        self.panel, self.input = self.__create()
+        self.rastlist = []
+        self.vectlist = []
+        self.imglist = []
+        self.r3list = []
+        self.dblist = []
+        self.genlist = []
+        self.displist = []
         
-    def __create(self):
-        """!Create widget"""
-        cmdprompt = wx.Panel(self.parent)
+        for item in globalvar.grassCmd['all']:
+            if len(item.split('.')) > 1:
+                start,end = item.split('.',1)
+                if start == 'r': self.rastlist.append(end)
+                elif start == 'v': self.vectlist.append(end)
+                elif start == 'i': self.imglist.append(end)
+                elif start == 'r3': self.r3list.append(end)
+                elif start == 'db': self.dblist.append(end)
+                elif start == 'g': self.genlist.append(end)
+                elif start == 'd': self.displist.append(end)
+
+        self.rastlist.sort()
+        self.vectlist.sort()
+        self.imglist.sort()
+        self.r3list.sort()
+        self.dblist.sort()
+        self.genlist.sort()
+        self.displist.sort()
+                        
+        self.datatypes = []
+        self.maplists = {}
+        self.maptype = ''
+        self.datatypes = ['rast',
+                        'rast3d',
+                        'vect',
+                        'oldvect',
+                        'asciivect',
+                        'labels',
+                        'region',
+                        'region3d',
+                        'group',
+                        '3dview']
+
+        self.drastcmd = ['d.rast',
+                        'd.rgb',
+                        'd.his',
+                        'd.rast.arrow',
+                        'd.rast.num']
+                    
+        self.dvectcmd = ['d.vect',
+                        'd.vect.chart'
+                        'd.thematic.area',
+                        'd.vect.thematic']
         
+        self.rastargs = ['map',
+                        'input',
+                        'elevation',
+                        'color',
+                        'rast',
+                        'raster',
+                        'red',
+                        'green',
+                        'blue',
+                        'h_map',
+                        'i_map',
+                        's_map',
+                        'hue_input',
+                        'intensity_input',
+                        'saturation_input',
+                        'red_input',
+                        'green_input',
+                        'blue_input']
+                        
+        self.__getfiles()
+
         #
-        # search
+        # command history buffer
         #
-        searchTxt = wx.StaticText(parent = cmdprompt, id = wx.ID_ANY,
-                                  label = _("Find module:"))
-        
-        self.searchBy = wx.Choice(parent = cmdprompt, id = wx.ID_ANY,
-                             choices = [_("description"),
-                                        _("keywords")])
-        winHeight = self.searchBy.GetSize()[1]
+        self.cmdbuffer = []
+        self.cmdindex = 0
 
-        self.search = wx.TextCtrl(parent = cmdprompt, id = wx.ID_ANY,
-                             value = "", size = (-1, 25))
-        
-        label = wx.Button(parent = cmdprompt, id = wx.ID_ANY,
-                          label = _("&Cmd >"), size = (-1, winHeight))
-        label.SetToolTipString(_("Click for erasing command prompt"))
+        #
+        # line margins
+        #
+        # TODO print number only from cmdlog
+        self.SetMarginWidth(1, 0)
+        self.SetMarginWidth(2, 0)
+        if margin:
+            self.SetMarginType(0, wx.stc.STC_MARGIN_NUMBER)
+            self.SetMarginWidth(0, 30)
+        else:
+            self.SetMarginWidth(0, 0)
 
-        ### todo: fix TextCtrlAutoComplete to work also on Macs
-        ### reason: missing wx.PopupWindow()
-        try:
-            cmdinput = TextCtrlAutoComplete(parent = cmdprompt, id = wx.ID_ANY,
-                                            value = "",
-                                            style = wx.TE_LINEWRAP | wx.TE_PROCESS_ENTER,
-                                            size = (-1, winHeight),
-                                            statusbar = self.parent.statusbar)
-        except NotImplementedError:
-            # wx.PopupWindow may be not available in wxMac
-            # see http://trac.wxwidgets.org/ticket/9377
-            cmdinput = wx.TextCtrl(parent = cmdprompt, id = wx.ID_ANY,
-                                   value = "",
-                                   style=wx.TE_LINEWRAP | wx.TE_PROCESS_ENTER,
-                                   size = (-1, 25))
-            self.searchBy.Enable(False)
-            self.search.Enable(False)
+        #
+        # miscellaneous
+        #
+        self.SetViewWhiteSpace(False)
+#        self.SetTabWidth(4)
+        self.SetUseTabs(False)
+        self.UsePopUp(True)
+        self.SetSelBackground(True, "#FFFF00")
+        self.SetUseHorizontalScrollBar(True)
+
+        #
+        # bindings
+        #
+        self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
+        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
+ 
+    def __getfiles(self):   
+        for item in self.datatypes:
+            mlist = grass.read_command("g.mlist", "m", type=item).splitlines()
+            mlist.sort()
+            self.maplists[item] = mlist
+            
+    def OnKeyPressed(self, event):
+        """!Key press capture for autocompletion, tooltips, and command history"""
+        #keycodes used: "." = 46, "=" = 61, "," = 44 
+        line = ''
+        entry = ''
+        usage = ''
+        cmdtype = ''
+        cmdname = ''
+        cmd = ''
+        if event.GetKeyCode() != 44:
+            self.maptype = ''
+                            
+        # CAN CHANGE: event.ControlDown() for manual autocomplete
         
-        cmdinput.SetFont(wx.Font(10, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.NORMAL, 0, ''))
-        
-        wx.CallAfter(cmdinput.SetInsertionPoint, 0)
-        
-        # bidnings
-        label.Bind(wx.EVT_BUTTON,        self.OnCmdErase)
-        cmdinput.Bind(wx.EVT_TEXT_ENTER, self.OnRunCmd)
-        cmdinput.Bind(wx.EVT_TEXT,       self.OnUpdateStatusBar)
-        self.search.Bind(wx.EVT_TEXT,    self.OnSearchModule)
-        
-        # layout
-        sizer = wx.GridBagSizer(hgap=5, vgap=5)
-        sizer.AddGrowableRow(1)
-        sizer.AddGrowableCol(2)
+        if event.GetKeyCode() == 46 and not event.ShiftDown():
+            #GRASS command autocomplete when "." is pressed after r,v,i,g,db, or d
+            listcmds = []
+            pos = self.GetCurrentPos()
+            self.InsertText(pos,'.')
+            self.CharRight()
+            
+            entry = self.GetTextLeft()
+            if entry not in ['r.','v.','i.','g.','db.','d.']:
+                return
 
-        sizer.Add(item = searchTxt,
-                  flag = wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL,
-                  pos = (0, 0))
+            if entry == 'r.': listcmds = self.rastlist
+            elif entry == 'v.': listcmds = self.vectlist
+            elif entry == 'i.': listcmds = self.imglist
+            elif entry == 'r3.': listcmds = self.r3list
+            elif entry == 'db.': listcmds = self.dblist
+            elif entry == 'g.': listcmds = self.genlist
+            elif entry == 'd.': listcmds = self.displist
 
-        sizer.Add(item = self.searchBy,
-                  flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER,
-                  pos = (0, 1))
+            if listcmds == []:
+                return
+            else:
+                self.AutoCompShow(0, " ".join(listcmds))                    
+            
+        elif event.GetKeyCode() == wx.WXK_TAB:
+            #GRASS command calltips
+                        
+            #Must be a command to the left somewhere
+            pos = self.GetCurrentPos()
+            entry = self.GetTextLeft()
+            cmd = entry.split()[0].strip()
+            if cmd not in globalvar.grassCmd['all']:
+                return
+            
+            usage, description = self.GetCommandUsage(cmd)
+                                        
+            self.CallTipSetBackground("PALE GREEN")
+            self.CallTipSetForeground("BLACK")
+            self.CallTipShow(pos, usage+'\n\n'+description)
+            
+        elif (event.GetKeyCode() == wx.WXK_SPACE and event.ControlDown()) or \
+            event.GetKeyCode() == 61 or event.GetKeyCode() == 44:
+            #Autocompletion for map/data file name entry
+            pos = self.GetCurrentPos()
+            entry = self.GetTextLeft()
+            arg = ''
+
+            if entry.strip()[0:2] in ['r.','v.','i.','g.','db.','d.']:
+                cmdtype =  entry.strip()[0]
+                cmd = entry.split()[0].strip()
+                if cmd in globalvar.grassCmd['all']:
+                    cmdname = cmd.split('.')[1]
+                else:
+                    #No complete GRASS command found
+                    cmd = ''
+                    cmdname = ''
+            elif entry.strip()[0:4] == 'nviz':
+                cmdtype = ''
+                cmdname = cmd = 'nviz'
+            else:
+                #No partial or complete GRASS command found
+                return
+
+            cmdargs = entry.strip('=')
+            try:
+                arg = cmdargs.rsplit(' ',1)[1]
+            except:
+                arg = ''
+                
+            if event.GetKeyCode() == 61:
+                #insert the '=' and move to the end of the line, ready for a map name
+                self.InsertText(pos,'=')
+                self.CharRight()
+
+                maplist = []
+                maptype = ''
+                
+                #what kind of map/data type is desired?
+                if (((cmdtype in ['r', 'i'] or cmd in self.drastcmd) and arg in self.rastargs) or
+                  ((cmd=='nviz' or cmdtype=='r3') and (arg=='elevation' or arg=='color')) or
+                  arg=='rast' or arg=='raster'):
+                    self.maptype = 'rast'
+                elif (((cmdtype=='v' or cmd in self.dvectcmd) and arg in ['map', 'input']) or
+                  (cmdtype=='r3' and arg=='input') or
+                  arg in ['vect', 'vector', 'points']):
+                    self.maptype = 'vect'
+                elif ((cmdtype=='r3' and (arg=='map' or arg=='input')) or
+                  (cmdtype=='nviz' and arg=='volume') or arg=='rast3d'):
+                    self.maptype = 'rast3d'
+                elif arg=='labels':
+                    self.maptype ='labels'
+                elif arg=='region':
+                    self.maptype ='region'
+                elif arg=='region3d':
+                    self.maptype ='region3d'
+                elif arg=='group':
+                    self.maptype ='group'
+                elif arg=='3dview':
+                    self.maptype ='3dview'
+
+            elif event.GetKeyCode() == 44:
+                #if ctrl-comma is pressed, use the same maptype as previous for multiple map entries
+                
+                # insert the comma and move to the end of the line ready for a map name
+                self.InsertText(pos,',')
+                self.CharRight()
+                
+                #must apply to an entry where '=[string]' has already been entered
+                if '=' not in arg:
+                    return
+
+            elif event.GetKeyCode() == wx.WXK_SPACE and event.ControlDown():
+                #map entries without arguments (as in r.info [mapname]) use ctrl-shift
+                maplist = []
+                if cmdtype=='r' or cmdtype=='i':
+                    self.maptype = 'rast'
+                elif cmdtype=='v':
+                    self.maptype = 'vect'
+                elif cmdtype=='r3':
+                    self.maptype = 'rast3d'
+                    
+            if self.maptype == '': 
+                return
+            else:
+                maplist = self.maplists[self.maptype]
+                self.AutoCompShow(0, " ".join(maplist))
+                        
+        elif event.GetKeyCode() in [wx.WXK_UP,wx.WXK_DOWN] and event.ControlDown():
+            #Command history    
+            
+            if self.cmdbuffer == []: return
+            txt = ''
+
+            self.DocumentEnd()
+            
+            if event.GetKeyCode() == wx.WXK_UP:
+                self.cmdindex = self.cmdindex - 1
+            if event.GetKeyCode() == wx.WXK_DOWN:
+                self.cmdindex = self.cmdindex + 1
+            if self.cmdindex < 0:
+                self.cmdindex = 0
+            if self.cmdindex > len(self.cmdbuffer) - 1:
+                self.cmdindex = len(self.cmdbuffer) - 1
+            
+            try:
+                txt = self.cmdbuffer[self.cmdindex]
+            except:
+                pass
+                
+            self.DelLineLeft()
+            self.DelLineRight()
+            pos = self.GetCurrentPos()            
+            self.InsertText(pos,txt)
+            self.LineEnd()
+            
+        elif event.GetKeyCode() == wx.WXK_RETURN and self.AutoCompActive() == False:
+            #Run command on line when <return> is pressed    
+            print 'in command'
+            #find the command to run
+            line = str(self.GetCurLine()[0]).strip()
+            if len(line) == 0:
+                return
+                        
+            cmd = shlex.split(str(line))
+            
+            #send the command to the processor 
+            self.parent.RunCmd(cmd)
+                            
+            #add command to buffer    
+            self.cmdbuffer.append(line)
+            
+            #keep buffer to a managable size
+            if len(self.cmdbuffer) > 200:
+                del self.cmdbuffer[0]
+            self.cmdindex = len(self.cmdbuffer)
+
+        else:
+            event.Skip()
+
+    def GetTextLeft(self):
+        """!Returns all text left of the caret"""
+        entry = ''
+        pos = self.GetCurrentPos()
+        self.HomeExtend()
+        entry = self.GetSelectedText().strip()
+        self.SetCurrentPos(pos)
         
-        sizer.Add(item = self.search,
-                  flag = wx.EXPAND | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER,
-                  border = 5,
-                  pos = (0, 2))
-        
-        sizer.Add(item = label, 
-                  flag = wx.LEFT | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER,
-                  border = 5,
-                  pos = (1, 0))
-        
-        sizer.Add(item = cmdinput,
-                  flag = wx.EXPAND | wx.RIGHT,
-                  border = 5,
-                  pos = (1, 1), span = (1, 2))
-        
-        cmdprompt.SetSizer(sizer)
-        sizer.Fit(cmdprompt)
-        cmdprompt.Layout()
-        
-        return cmdprompt, cmdinput
+        return entry
 
-    def __checkKey(self, text, keywords):
-        """!Check if text is in keywords"""
-        found = 0
-        keys = text.split(',')
-        if len(keys) > 1: # -> multiple keys
-            for k in keys[:-1]:
-                k = k.strip()
-                for key in keywords: 
-                    if k == key: # full match
-                        found += 1
-                        break
-            k = keys[-1].strip()
-            for key in keywords:
-                if k in key: # partial match
-                    found +=1
+    def GetCommandUsage(self, command):
+        """!Returns the usage information for a command"""
+        usage = ''
+        description = ''
+
+        ret, out  = gcmd.RunCommand(command, 'help', getErrorMsg = True)
+               
+        if ret == 0:
+            cmdhelp = out.splitlines()
+            addline = False
+            helplist = []
+            description = ''
+            for line in cmdhelp:
+                if "Usage:" in line:
+                    addline = True
+                    continue
+                elif "Flags:" in line:
+                    addline = False
                     break
+                elif addline == True:
+                    line = line.strip()
+                    helplist.append(line)
+
+            for line in cmdhelp:
+                if "Description:" in line:
+                    addline = True
+                    continue
+                elif "Keywords:" in line:
+                    addline = False
+                    break
+                elif addline == True:
+                    description += (line + ' ')
+                
+            description = description.strip()
+
+            for line in helplist:
+                usage += line + '\n'
+
+            return usage.strip(), description
         else:
-            for key in keywords:
-                if text in key: # partial match
-                    found +=1
-                    break
+            return ''   
+
+    def OnDestroy(self, evt):
+        """!The clipboard contents can be preserved after
+        the app has exited"""
         
-        if found == len(keys):
-            return True
-        
-        return False
+        wx.TheClipboard.Flush()
+        evt.Skip()
     
-    def GetPanel(self):
-        """!Get main widget panel"""
-        return self.panel
-
-    def GetInput(self):
-        """!Get main prompt widget"""
-        return self.input
-    
     def OnCmdErase(self, event):
         """!Erase command prompt"""
-        self.input.SetValue('')
+        self.Home()
+        self.DelLineRight()
         
     def OnRunCmd(self, event):
         """!Run command"""
@@ -664,3 +917,4 @@
             self._showDropDown(False)
         
         event.Skip()
+>>>>>>> .r40052

Modified: grass/branches/develbranch_6/gui/wxpython/wxgui.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/wxgui.py	2009-12-18 20:29:56 UTC (rev 40052)
+++ grass/branches/develbranch_6/gui/wxpython/wxgui.py	2009-12-19 05:58:44 UTC (rev 40053)
@@ -1,4 +1,4 @@
-"""!
+"""
 @package wxgui.py
 
 @brief Main Python app for GRASS wxPython GUI. Main menu, layer management
@@ -119,20 +119,20 @@
         self.disp_idx      = 0            # index value for map displays and layer trees
         self.curr_page     = ''           # currently selected page for layer tree notebook
         self.curr_pagenum  = ''           # currently selected page number for layer tree notebook
+        self.encoding      = 'ISO-8859-1' # default encoding for display fonts
         self.workspaceFile = workspace    # workspace file
         self.menucmd       = dict()       # menuId / cmd
         self.georectifying = None         # reference to GCP class or None
+        
         # list of open dialogs
         self.dialogs        = dict()
         self.dialogs['preferences'] = None
         self.dialogs['atm'] = list()
         
         # creating widgets
-        # -> self.notebook, self.goutput, self.outpage
         self.notebook  = self.__createNoteBook()
         self.menubar, self.menudata = self.__createMenuBar()
         self.statusbar = self.CreateStatusBar(number=1)
-        self.cmdprompt, self.cmdinput = self.__createCommandPrompt()
         self.toolbar   = self.__createToolBar()
         
         # bindings
@@ -146,16 +146,11 @@
         self._auimgr.AddPane(self.notebook, wx.aui.AuiPaneInfo().
                              Left().CentrePane().BestSize((-1,-1)).Dockable(False).
                              CloseButton(False).DestroyOnClose(True).Row(1).Layer(0))
-        self._auimgr.AddPane(self.cmdprompt, wx.aui.AuiPaneInfo().
-                             Bottom().BestSize((-1, -1)).Dockable(False).
-                             CloseButton(False).DestroyOnClose(True).
-                             PaneBorder(False).Row(1).Layer(0).Position(0).
-                             CaptionVisible(False))
 
         self._auimgr.Update()
 
         wx.CallAfter(self.notebook.SetSelection, 0)
-        wx.CallAfter(self.cmdinput.SetFocus)
+        wx.CallAfter(self.goutput.cmd_prompt.SetFocus)
         
         # use default window layout ?
         if UserSettings.Get(group='general', key='defWindowPos', subkey='enabled') is True:
@@ -192,13 +187,7 @@
         # start with layer manager on top
         self.curr_page.maptree.mapdisplay.Raise()
         self.Raise()
-        
-    def __createCommandPrompt(self):
-        """!Creates command-line input area"""
-        p = prompt.GPrompt(self)
-
-        return p.GetPanel(), p.GetInput()
-    
+            
     def __createMenuBar(self):
         """!Creates menubar"""
 
@@ -367,7 +356,7 @@
         page = event.GetSelection()
         if page == self.goutput.pageid:
             # remove '(...)'
-            self.notebook.SetPageText(page, _("Command output"))
+            self.notebook.SetPageText(page, _("Command console"))
         
         event.Skip()
 
@@ -454,7 +443,7 @@
         if event:
             cmd = self.GetMenuCmd(event)
         self.goutput.RunCmd(cmd, switchPage=True)
-        
+
     def OnMenuCmd(self, event, cmd = ''):
         """!Parse command selected from menu"""
         if event:
@@ -548,7 +537,7 @@
     def OnAboutGRASS(self, event):
         """!Display 'About GRASS' dialog"""
         win = AboutWindow(self)
-        win.CentreOnScreen()
+        win.Centre()
         win.Show(True)  
         
     def OnWorkspace(self, event):
@@ -979,7 +968,7 @@
 
         gisbase = os.environ['GISBASE']
 
-        if sys.platform == win32:
+        if 'OS' in os.environ and os.environ['OS'] == "Windows_NT":
             runbat = os.path.join(gisbase,'etc','grass-run.bat')
             cmdlist = ["cmd.exe", "/c", 'start "%s"' % runbat, command]
         else:
@@ -1541,20 +1530,18 @@
         event.Skip()
 
     def OnQuit(self, event):
-        """!Quit GRASS session (wxGUI and shell)"""
+        """!Quit GRASS"""
         # quit wxGUI session
         self.OnCloseWindow(event)
-        
+
         # quit GRASS shell
         try:
-            pid = int(os.environ['GIS_LOCK'])
-        except (KeyError, ValueError):
-            sys.stderr.write('\n')
-            sys.stderr.write(_("WARNING: Unable to quit GRASS, uknown GIS_LOCK"))
+            pid = os.environ['GRASS_SHELL_PID']
+        except KeyError:
             return
+
+        os.kill(int(pid), signal.SIGQUIT)
         
-        os.kill(pid, signal.SIGQUIT)
-        
     def OnCloseWindow(self, event):
         """!Cleanup when wxGUI is quit"""
         if not self.curr_page:



More information about the grass-commit mailing list