[QGIS Commit] r10664 - trunk/qgis/src/plugins/grass

svn_qgis at osgeo.org svn_qgis at osgeo.org
Mon Apr 27 03:04:32 EDT 2009


Author: pcav
Date: 2009-04-27 03:04:32 -0400 (Mon, 27 Apr 2009)
New Revision: 10664

Modified:
   trunk/qgis/src/plugins/grass/CMakeLists.txt
   trunk/qgis/src/plugins/grass/qgsgrassshell.cpp
   trunk/qgis/src/plugins/grass/qgsgrassshell.h
   trunk/qgis/src/plugins/grass/qgsgrassshellbase.ui
   trunk/qgis/src/plugins/grass/qgsgrasstools.cpp
Log:
New GRASS shell - first commit - dev Lorenzo Masini

Modified: trunk/qgis/src/plugins/grass/CMakeLists.txt
===================================================================
--- trunk/qgis/src/plugins/grass/CMakeLists.txt	2009-04-27 05:39:32 UTC (rev 10663)
+++ trunk/qgis/src/plugins/grass/CMakeLists.txt	2009-04-27 07:04:32 UTC (rev 10664)
@@ -16,9 +16,9 @@
 ENDIF (NOT MSVC)
 
 IF (WIN32)
-  ADD_DEFINITIONS("\"-DGRASS_EXPORT=__declspec(dllimport)\"")
+  ADD_DEFINITIONS("\"-DHAVE_GETPT -DGRASS_EXPORT=__declspec(dllimport)\"")
 ELSE (WIN32)
-  ADD_DEFINITIONS("-DGRASS_EXPORT=")
+  ADD_DEFINITIONS("-DHAVE_POSIX_OPENPT -DGRASS_EXPORT=")
 ENDIF (WIN32)
 
 ########################################################
@@ -39,6 +39,24 @@
      qgsgrassattributes.cpp
      qgsgrassregion.cpp
      qgsgrassutils.cpp
+     qtermwidget/BlockArray.cpp
+     qtermwidget/Emulation.cpp
+     qtermwidget/Filter.cpp
+     qtermwidget/History.cpp
+     qtermwidget/KeyboardTranslator.cpp
+     qtermwidget/Pty.cpp
+     qtermwidget/Screen.cpp
+     qtermwidget/ScreenWindow.cpp
+     qtermwidget/Session.cpp
+     qtermwidget/ShellCommand.cpp
+     qtermwidget/TerminalCharacterDecoder.cpp
+     qtermwidget/TerminalDisplay.cpp
+     qtermwidget/Vt102Emulation.cpp
+     qtermwidget/k3process.cpp
+     qtermwidget/k3processcontroller.cpp
+     qtermwidget/konsole_wcwidth.cpp
+     qtermwidget/kpty.cpp
+     qtermwidget/qtermwidget.cpp
 )
 
 SET (GRASS_PLUGIN_UIS
@@ -48,7 +66,6 @@
      qgsgrassmapcalcbase.ui
      qgsgrassmodulebase.ui
      qgsgrassnewmapsetbase.ui
-     qgsgrassshellbase.ui
      qgsgrassattributesbase.ui
      qgsgrassregionbase.ui
      ../../ui/qgsprojectionselectorbase.ui
@@ -69,6 +86,16 @@
      qgsgrassregion.h
      qgsgrassutils.h
      qgsgrassedittools.h
+     qtermwidget/Emulation.h
+     qtermwidget/Filter.h
+     qtermwidget/Pty.h
+     qtermwidget/ScreenWindow.h
+     qtermwidget/Session.h
+     qtermwidget/TerminalDisplay.h
+     qtermwidget/Vt102Emulation.h
+     qtermwidget/k3process.h
+     qtermwidget/k3processcontroller.h
+     qtermwidget/qtermwidget.h
 )
 
 SET (GRASS_PLUGIN_RCCS  qgsgrass_plugin.qrc)
@@ -106,9 +133,9 @@
      ${GRASS_INCLUDE_DIR}
      ${GDAL_INCLUDE_DIR}
      ${PROJ_INCLUDE_DIR}
+     qtermwidget
 )
 
-SET( QT_USE_QT3SUPPORT TRUE )
 INCLUDE( ${QT_USE_FILE} )
 
 TARGET_LINK_LIBRARIES(grassplugin

Modified: trunk/qgis/src/plugins/grass/qgsgrassshell.cpp
===================================================================
--- trunk/qgis/src/plugins/grass/qgsgrassshell.cpp	2009-04-27 05:39:32 UTC (rev 10663)
+++ trunk/qgis/src/plugins/grass/qgsgrassshell.cpp	2009-04-27 07:04:32 UTC (rev 10664)
@@ -1,9 +1,9 @@
 /***************************************************************************
      qgsgrassshell.cpp
      --------------------------------------
-    Date                 : Sun Sep 16 12:06:10 AKDT 2007
-    Copyright            : (C) 2007 by Gary E. Sherman
-    Email                : sherman at mrcc dot com
+    Date                 : Thu Apr 23 08:35:43 CEST 2009
+    Copyright            : (C) 2009 by Lorenzo "Il Rugginoso" Masini
+    Email                : lorenxo86 at gmail.com
  ***************************************************************************
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -12,944 +12,102 @@
  *   (at your option) any later version.                                   *
  *                                                                         *
  ***************************************************************************/
-#include <vector>
+#include <QTabWidget>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QShortcut>
+#include <QKeySequence>
+#include <QSizePolicy>
 
-#include <qstring.h>
-#include <qapplication.h>
-#include <qpushbutton.h>
-#include <qwidget.h>
-#include <q3textedit.h>
-#include <q3process.h>
-#include <qmessagebox.h>
-#include <q3cstring.h>
-#include <qfile.h>
-#include <qdatastream.h>
-#include <qstringlist.h>
-#include <qsocketnotifier.h>
-#include <q3socket.h>
-#include <q3socketdevice.h>
-#include <qevent.h>
-#include <q3textbrowser.h>
-#include <qregexp.h>
-#include <qcursor.h>
-#include <qlayout.h>
-#include <qclipboard.h>
-#include <qfontmetrics.h>
-#include <q3progressbar.h>
-
+#include "qgsgrasstools.h"
+#include "qtermwidget/qtermwidget.h"
 #include "qgsapplication.h"
 
 #include "qgsgrassshell.h"
-//Added by qt3to4:
-#include <QGridLayout>
-#include <QKeyEvent>
-#include <QResizeEvent>
-#include <QMouseEvent>
-#include "qgslogger.h"
 
-extern "C"
-{
-#include <stdio.h>
+extern "C" {
 #include <stdlib.h>
-#ifndef _MSC_VER
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-
-#ifndef WIN32
-#ifdef Q_OS_MACX
-#include <util.h>
-#else
-#ifdef __NetBSD__
-#include <util.h>
-#else
-#ifdef __FreeBSD__
-#include <termios.h>
-#include <libutil.h>
-#else
-#include <pty.h>
-#endif
-#endif
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/wait.h>
-#endif //!WIN32
 }
 
-QgsGrassShell::QgsGrassShell( QgsGrassTools *tools,
-                              QTabWidget * parent, const char * name ):
-    QDialog( parent ), QgsGrassShellBase(), mTools( tools )
+QgsGrassShell::QgsGrassShell(QgsGrassTools *tools, QTabWidget *parent, const char *name)
+        : QFrame(parent)
 {
-  mValid = false;
-  mSkipLines = 2;
-  mTabWidget = parent;
+    mTools = tools;
+    mTabWidget = parent;
 
-#ifdef WIN32
-  QMessageBox::warning( 0, "Warning",
-                        "GRASS Shell is not supported on Windows." );
-  return;
-#else
+    QVBoxLayout *mainLayout = new QVBoxLayout(this);
+    QTermWidget *mTerminal = new QTermWidget(0, this);
+    initTerminal(mTerminal);
+    QPushButton *closeButton = new QPushButton(tr("Close"), this);
+    QShortcut *pasteShortcut = new QShortcut(QKeySequence(tr("Ctrl+Shift+V")), mTerminal);
+    QShortcut *copyShortcut = new QShortcut(QKeySequence(tr("Ctrl+Shift+C")), mTerminal);
 
-  setupUi( this );
+    mainLayout->addWidget(mTerminal);
+    mainLayout->addWidget(closeButton);
+    setLayout(mainLayout);
 
-  QGridLayout *layout = new QGridLayout( mTextFrame, 1, 1 );
-  mText = new QgsGrassShellText( this, mTextFrame );
-  layout->addWidget( mText, 0, 0 );
-  mText->show();
+    connect(closeButton, SIGNAL(clicked()), this, SLOT(closeShell()));
+    connect(mTerminal, SIGNAL(finished()), this, SLOT(closeShell()));
+    connect(pasteShortcut, SIGNAL(activated()), mTerminal, SLOT(pasteClipboard()));
+    connect(copyShortcut, SIGNAL(activated()), mTerminal, SLOT(copyClipboard()));
 
-  connect( mCloseButton, SIGNAL( clicked() ), this, SLOT( closeShell() ) );
-
-  mFont = QFont( "Courier", 10 );
-
-  mAppDir = mTools->appDir();
-
-#ifndef Q_WS_MAC
-  // Qt4.3.2/Mac Q3TextEdit readOnly property causes keys to be processed as keyboard actions
-  mText->setReadOnly( TRUE );
-#endif
-  //mText->setFocusPolicy ( QWidget::NoFocus ); // To get key press directly
-
-#ifndef HAVE_OPENPTY
-  mText->append( "GRASS shell is not supported" );
-  return;
-#endif
-
-  // TODO set cursor IbeamCursor
-  // This does not work - the cursor is used for scrollbars -> disabled
-  //mText->setCursor ( QCursor(Qt::IbeamCursor) );
-  mParagraph = -1; // first will be 0
-  mIndex = -1;
-
-  mNewLine = true;
-
-  for ( int i = 0; i < ModeCount; i++ )
-  {
-    resetMode( i );
-  }
-
-  int uid;
-  seteuid( uid = getuid() ); /* Run unprivileged */
-
-  // Get and open pseudo terminal
-  // Note: 0 (stdin), 1 (stdout) or 2 (stderr)
-  int fdSlave; // slave file descriptor
-  seteuid( 0 );
-  int ret =  openpty( &mFdMaster, &fdSlave, NULL, NULL, NULL );
-  if ( ret != 0 )
-  {
-    QMessageBox::warning( 0, "Warning", "Cannot open pseudo terminal" );
-    return;
-  }
-  fchown( fdSlave, uid, ( gid_t ) - 1 );
-  fchmod( fdSlave, S_IRUSR | S_IWUSR );
-  seteuid( uid );
-
-  QgsDebugMsg( QString( "mFdMaster = %1" ).arg( mFdMaster ) );
-  QgsDebugMsg( QString( "fdSlave = %1" ).arg( fdSlave ) );
-
-  fcntl( mFdMaster, F_SETFL, O_NDELAY );
-  //fcntl( fdSlave, F_SETFL, O_NDELAY); // enable?
-
-  QString slaveName = ttyname( fdSlave );
-  QgsDebugMsg( QString( "master ttyname = %1" ).arg( ttyname( mFdMaster ) ) );
-  QgsDebugMsg( QString( "slave ttyname = %1" ).arg( ttyname( fdSlave ) ) );
-
-  //::close( fdSlave ); // -> crash
-
-  // Fork slave and open shell
-  int pid = fork();
-  QgsDebugMsg( QString( "pid = %1" ).arg( pid ) );
-  if ( pid == -1 )
-  {
-    QMessageBox::warning( 0, "Warning", "Cannot fork shell" );
-    return;
-  }
-
-  // Child - slave
-  if ( pid == 0 )
-  {
-    QgsDebugMsg( "child ->" );
-
-    // TODO close all opened file descriptors - close(0)???
-    ::close( mFdMaster );
-
-    //::close( fdSlave ); // -> freeze
-
-    setsid();
-    seteuid( 0 );
-
-    int fd = ::open(( char* ) slaveName.ascii(), O_RDWR );
-    if ( fd < 0 )
-    {
-      QMessageBox::warning( 0, "Warning", "Cannot open slave file "
-                            "in child process" );
-      return;
-    }
-
-    fchown( fd, uid, ( gid_t ) - 1 );
-    fchmod( fd, S_IRUSR | S_IWUSR );
-    setuid( uid );
-
-    dup2( fd, 0 ); /* stdin */
-    dup2( fd, 1 ); /* stdout */
-    dup2( fd, 2 ); /* stderr */
-
-    // TODO: test if shell is available
-    QString shell = ( getenv( "SHELL" ) );
-    if ( shell.isEmpty() )
-    {
-      shell = "/bin/bash";
-    }
-
-    const char *norc = "";
-    QFileInfo si( shell );
-    if ( si.fileName() ==  "bash" || si.fileName() ==  "sh" )
-    {
-      norc = "--norc";
-    }
-    else if ( si.fileName() ==  "tcsh" || si.fileName() ==  "csh" )
-    {
-      norc = "-f";
-    }
-
-    // Warning: execle + --norc will not inherit not given variables
-    // -> overwrite here
-    const char *env = "GRASS_MESSAGE_FORMAT=gui";
-    char *envstr = new char[strlen( env )+1];
-    strcpy( envstr, env );
-    putenv( envstr );
-
-    putenv(( char * ) "GISRC_MODE_MEMORY" );  // unset
-
-    env = "PS1=GRASS > ";
-    envstr = new char[strlen( env )+1];
-    strcpy( envstr, env );
-    putenv( envstr );
-
-    env = "TERM=vt100";
-    envstr = new char[strlen( env )+1];
-    strcpy( envstr, env );
-    putenv( envstr );
-
-    //char *envar[] = { "PS1=GRASS > ", "TERM=vt100", "GISRC_MODE_MEMORY=",
-    //                  "GRASS_MESSAGE_FORMAT=gui", (char *)0 };
-
-    //execle ( (char*)shell.ascii(), (char *)si.fileName().ascii(),
-    //         norc, (char *) 0, envar);
-    execl(( char* )shell.ascii(), ( char * )si.fileName().ascii(),
-          norc, ( char * ) 0 );
-
-    // Failed (QMessageBox here does not work)
-    fprintf( stderr, "GRASS_INFO_ERROR(1,1): Cannot start shell %s\n",
-             ( char* )shell.ascii() );
-    exit( 1 );
-  }
-
-  mPid = pid;
-
-  // Create socket notifier
-  mOutNotifier = new QSocketNotifier( mFdMaster, QSocketNotifier::Read, this );
-
-  QObject::connect( mOutNotifier, SIGNAL( activated( int ) ),
-                    this, SLOT( readStdout( int ) ) );
-
-  // Set tab stops ???
-  mTabStop.resize( 200 );
-  for ( int i = 0 ; i * 8 < ( int )mTabStop.size(); i++ )
-  {
-    mTabStop[i*8] = true;
-  }
-
-  // Set trap to write history on SIGUSR1
-  //QString trap = "trap 'history -w' SIGUSR1\015\012";
-  QString trap = "trap 'history -w' SIGUSR1\015";
-  write( mFdMaster, trap.ascii(), trap.length() );
-  mText->clear();
-
-  resizeTerminal();
-  mValid = true;
-#endif // !WIN32
+    mTerminal->startShellProgram();
+    mTerminal->setFocus(Qt::MouseFocusReason);
 }
 
 QgsGrassShell::~QgsGrassShell()
 {
-  QgsDebugMsg( "entered." );
-
-#ifndef WIN32
-  // This was old trick to write history
-  /*
-  write( mFdMaster, "exit\015\012", 6);
-  while ( 1 )
-  {
-  readStdout(0);
-
-  int status;
-  if ( waitpid ( mPid, &status, WNOHANG ) > 0 ) break;
-
-  struct timespec t, r;
-  t.tv_sec = 0;
-  t.tv_nsec = 10000000; // 0.01 s
-  nanosleep ( &t, &r );
-  }
-  */
-
-  // Write history
-  if ( kill( mPid, SIGUSR1 ) == -1 )
-  {
-    QgsDebugMsg( QString( "cannot write history (signal SIGUSR1 to pid = %1)" ).arg( mPid ) );
-  }
-
-  QgsDebugMsg( QString( "kill shell pid = %1" ).arg( mPid ) );
-  if ( kill( mPid, SIGTERM ) == -1 )
-  {
-    QgsDebugMsg( QString( "cannot kill shell pid = %1" ).arg( mPid ) );
-  }
-#endif
 }
 
-void QgsGrassShell::keyPressEvent( QKeyEvent * e )
-{
-  QgsDebugMsg( "entered." );
 
-  char s[10];
-  int length = 0;
-  int ret = 0;
-
-  if ( !mValid ) return;
-
-  mProgressBar->setProgress( 0, 100 );
-
-  char c = ( char ) e->ascii();
-  QgsDebugMsg( QString( "c = %1 key = %2 text = %3" ).arg(( int )c ).arg( e->key() ).arg( e->text().local8Bit().data() ) );
-  s[0] = c;
-  length = 1;
-
-  // Set key down
-  if ( e->key() == Qt::Key_Control ) mKeyDown[DownControl] = true;
-  else if ( e->key() == Qt::Key_Shift ) mKeyDown[DownShift] = true;
-  else if ( e->key() == Qt::Key_Alt ) mKeyDown[DownAlt] = true;
-  else if ( e->key() == Qt::Key_Meta ) mKeyDown[DownMeta] = true;
-
-  if ( c == 0 )
-  {
-    switch ( e->key() )
-    {
-      case Qt::Key_Up :
-        strcpy( s, "\033[A" );
-        length = 3;
-        break;
-
-      case Qt::Key_Down :
-        strcpy( s, "\033[B" );
-        length = 3;
-        break;
-
-      case Qt::Key_Right :
-        strcpy( s, "\033[C" );
-        length = 3;
-        break;
-
-      case Qt::Key_Left :
-        strcpy( s, "\033[D" );
-        length = 3;
-        break;
-    }
-  }
-
-  ret = write( mFdMaster, s, length );
-  QgsDebugMsg( QString( "write ret = %1" ).arg( ret ) );
-}
-
-void QgsGrassShell::keyReleaseEvent( QKeyEvent * e )
+/* TODO: Implement something that resizes the terminal without
+ *       crashes.
+void QgsGrassShell::resizeTerminal()
 {
-#ifdef QGISDEBUG
-  // QgsDebugMsg("entered.");
-#endif
-
-  // Reset key down
-  if ( e->key() == Qt::Key_Control ) mKeyDown[DownControl] = false;
-  else if ( e->key() == Qt::Key_Shift ) mKeyDown[DownShift] = false;
-  else if ( e->key() == Qt::Key_Alt ) mKeyDown[DownAlt] = false;
-  else if ( e->key() == Qt::Key_Meta ) mKeyDown[DownMeta] = false;
+    //mTerminal->setSize(80, 25);
+    //mTerminal->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
 }
+*/
 
-void QgsGrassShell::readStdout( int socket )
+void QgsGrassShell::closeShell()
 {
-#ifdef QGISDEBUG
-// QgsDebugMsg("entered.");
-#endif
-
-  char buf[4097];
-  int len;
-  while (( len = read( mFdMaster, buf, 4096 ) ) > 0 )
-  {
-    // Terminate string
-    buf[len] = '\0';
-
-    mStdoutBuffer.append( buf );
-  }
-
-  printStdout();
+    int index = mTabWidget->indexOf(this);
+    mTabWidget->removeTab(index);
+    delete this;
 }
 
-void QgsGrassShell::printStdout()
+void QgsGrassShell::initTerminal(QTermWidget *terminal)
 {
-  // Debug
-#ifdef QGISDEBUG
-  QString str;
-  for ( int i = 0; i < ( int )mStdoutBuffer.length(); i++ )
-  {
-    int c = mStdoutBuffer[i];
-    QString s = "";
-    if ( c > '\037' && c != '\177' ) // control characters
+    QStringList args("");
+    QStringList env("");
+    // Set the shell program
+    QString shell = ::getenv("SHELL");
+    if (shell.isEmpty() || shell.isNull())
     {
-      str += c;
+        // if the shell isn't specified use the default one (/bin/bash)
+        terminal->setShellProgram(shell);
     }
-    else
-    {
-      str += "(c=" + QString::number( c, 8 ) + ")";
-    }
-  }
-  QgsDebugMsg( "****** buffer ******" );
-  QgsDebugMsg( QString( "-->%1<--" ).arg( str.toLocal8Bit().constData() ) );
-#endif
 
-  eraseCursor();
-  // To make it faster we want to print maximum lenght blocks from buffer
-  while ( mStdoutBuffer.length() > 0 )
-  {
-    QgsDebugMsg( "------ cycle ------" );
-
-    // Search control character
-    int control = -1;
-    for ( int i = 0; i < ( int )mStdoutBuffer.length(); i++ )
+    // Set shell program arguments
+    QFileInfo shellInfo(shell);
+    if (shellInfo.fileName() == "bash" || shellInfo.fileName() == "sh")
     {
-      int c = mStdoutBuffer[i];
-      if ( c < '\037' || c == '\177' )
-      {
-        control = i;
-        break;
-      }
+        args << "--norc";
     }
-    QgsDebugMsg( QString( "control = %1" ).arg( control ) );
-
-    // Process control character if found at index 0
-    if ( control == 0 )
+    else if (shellInfo.fileName() == "tcsh" || shellInfo.fileName() == "csh")
     {
-      int c = mStdoutBuffer[0];
-      QgsDebugMsg( QString( "c = %1" ).arg( QString::number( c, 8 ).local8Bit().data() ) );
-
-      // control sequence
-      if ( c == '\033' )
-      {
-// QgsDebugMsg("control sequence");
-
-        bool found = false;
-
-        // It is sequence, so it should be at least one more character
-        // wait for more data
-        if ( mStdoutBuffer.length() < 2 ) break;
-        if ( mStdoutBuffer[1] == ']' && mStdoutBuffer.length() < 3 ) break;
-
-        // ESC ] Ps ; Pt BEL    (xterm title hack)
-        QRegExp rx( "\\](\\d+);([^\\a]+)\\a" );
-        if ( rx.search( mStdoutBuffer, 1 ) == 1 )
-        {
-          int mlen = rx.matchedLength();
-          QgsDebugMsg( QString( "ESC(set title): %1" ).arg( rx.cap( 2 ).local8Bit().data() ) );
-          mStdoutBuffer.remove( 0, mlen + 1 );
-          found = true;
-        }
-
-        if ( !found )
-        {
-          //    ESC [ Pn ; Pn FINAL
-          // or ESC [ = Pn ; Pn FINAL
-          // or ESC [ = Pn ; Pn FINAL
-          // TODO: QRegExp captures only last of repeated patterns
-          //       ( ; separated nums - (;\\d+)* )
-          rx.setPattern( "\\[([?=])*(\\d+)*(;\\d+)*([A-z])" );
-          if ( rx.search( mStdoutBuffer, 1 ) == 1 )
-          {
-            int mlen = rx.matchedLength();
-            char final = rx.cap( 4 ).at( 0 ).latin1();
-
-            QgsDebugMsg( QString( "final = %1" ).arg( final ) );
-// QgsDebugMsg(QString("ESC: %1").arg(rx.cap(0)));
-
-            switch ( final )
-            {
-              case 'l' : // RM - Reset Mode
-              case 'h' : // SM - Set Mode
-              {
-                int mode = -1;
-                switch ( rx.cap( 2 ).toInt() )
-                {
-                  case 4 :
-                    mode = Insert;
-                    break;
-
-                  default:
-                    QgsDebugMsg( QString( "ESC ignored: %1" ).arg( rx.cap( 0 ).local8Bit().data() ) );
-                    break;
-                }
-                if ( mode >= 0 )
-                {
-                  if ( final == 'l' )
-                    resetMode( mode );
-                  else
-                    setMode( mode );
-                }
-                break;
-              }
-
-              case 'm' : // SGR - Select Graphic Rendition
-                if ( rx.cap( 2 ).isEmpty() || rx.cap( 2 ).toInt() == 0 )
-                {
-                  for ( int i = 0; i < RendetionCount; i++ )
-                  {
-                    mRendetion[i] = false;
-                  }
-                }
-                else
-                {
-                  QgsDebugMsg( QString( "ESC SGR ignored: %1" ).arg( rx.cap( 0 ).local8Bit().data() ) );
-                }
-                break;
-
-              case 'P' : // DCH - Delete Character
-              {
-                int n = rx.cap( 2 ).toInt();
-                mText->setSelection( mParagraph, mIndex, mParagraph, mIndex + n, 0 );
-                mText->removeSelectedText( 0 );
-                break;
-              }
-
-              case 'K' : // EL - Erase In Line
-                if ( rx.cap( 2 ).isEmpty() || rx.cap( 2 ).toInt() == 0 )
-                {
-                  //mText->setSelectionAttributes ( 1, QColor(255,255,255), true );
-                  mText->setSelection( mParagraph, mIndex, mParagraph,
-                                       mText->paragraphLength( mParagraph ), 0 );
-                  mText->removeSelectedText( 0 );
-                }
-                break;
-
-                // TODO: multiple tab stops
-              case 'H' : // Horizontal Tabulation Set (HTS)
-                mTabStop[mIndex] = true;
-                QgsDebugMsg( QString( "TAB set on %1" ).arg( mIndex ) );
-                break;
-
-              case 'g' : // Tabulation Clear (TBC)
-                // ESC [ g  Clears tab stop at the cursor
-                // ESC [ 2 g  Clears all tab stops in the line
-                // ESC [ 3 g  Clears all tab stops in the Page
-                QgsDebugMsg( "TAB reset" );
-                if ( rx.cap( 2 ).isEmpty() || rx.cap( 2 ).toInt() == 0 )
-                {
-                  mTabStop[mIndex] = false;
-                }
-                else
-                {
-                  for ( int i = 0; i < ( int )mTabStop.size(); i++ )
-                    mTabStop[mIndex] = false;
-                }
-                break;
-
-              default:
-                QgsDebugMsg( QString( "ESC ignored: %1" ).arg( rx.cap( 0 ).local8Bit().data() ) );
-                break;
-            }
-
-            mStdoutBuffer.remove( 0, mlen + 1 );
-            found = true;
-          }
-        }
-
-        if ( !found )
-        {
-          // ESC # DIGIT
-          rx.setPattern( "#(\\d)" );
-          if ( rx.search( mStdoutBuffer, 1 ) == 1 )
-          {
-            QgsDebugMsg( QString( "ESC ignored: %1" ).arg( rx.cap( 0 ).local8Bit().data() ) );
-            mStdoutBuffer.remove( 0, 3 );
-            found = true;
-          }
-        }
-
-        if ( !found )
-        {
-          // ESC CHARACTER
-          rx.setPattern( "[A-z<>=]" );
-          if ( rx.search( mStdoutBuffer, 1 ) == 1 )
-          {
-            QgsDebugMsg( QString( "ESC ignored: %1" ).arg( rx.cap( 0 ).local8Bit().data() ) );
-            mStdoutBuffer.remove( 0, 2 );
-            found = true;
-          }
-        }
-
-        // TODO: it can happen that the sequence is not complete ->
-        //       no match -> how to distinguish unknown sequence from
-        //       missing characters
-        if ( !found )
-        {
-          // For now move forward
-          QgsDebugMsg( QString( "Unknown ESC ignored: %1" ).arg( mStdoutBuffer.mid( 1, 5 ).data() ) );
-          mStdoutBuffer.remove( 0, 1 );
-        }
-      }
-      else
-      {
-        // control character
-        switch ( c )
-        {
-          case '\015' : // CR
-// QgsDebugMsg("CR");
-            mStdoutBuffer.remove( 0, 1 );
-            // TODO : back tab stops?
-            mIndex = 0;
-            break;
-
-          case '\012' : // NL
-// QgsDebugMsg("NL");
-            newLine();
-            mStdoutBuffer.remove( 0, 1 );
-            break;
-
-          case '\010' : // BS
-// QgsDebugMsg("BS");
-            mIndex--;
-            mStdoutBuffer.remove( 0, 1 );
-            break;
-
-          case '\011' : // HT (tabulator)
-          {
-// QgsDebugMsg("HT");
-            QString space;
-            for ( int i = mIndex; i < ( int )mTabStop.size(); i++ )
-            {
-              space.append( " " );
-              if ( mTabStop[i] ) break;
-            }
-            insert( space );
-            mStdoutBuffer.remove( 0, 1 );
-            break;
-          }
-
-          case '>' : // Keypad Numeric Mode
-            QgsDebugMsg( QString( "Keypad Numeric Mode ignored: %1" ).arg( QString::number( c, 8 ).local8Bit().data() ) );
-            mStdoutBuffer.remove( 0, 2 );
-            break;
-
-          default : // unknown control, do nothing
-            QgsDebugMsg( QString( "Unknown control char ignored: %1" ).arg( QString::number( c, 8 ).local8Bit().data() ) );
-            mStdoutBuffer.remove( 0, 1 );
-            break;
-        }
-      }
-      continue;
+        args << "-f";
     }
+    terminal->setArgs(args);
 
-    // GRASS messages. GRASS messages start with GRASS_INFO_
-    // and stop with \015\012 (\n)
+    // Set shell program enviroment variables
+    env << "GRASS_MESSAGE_FORMAT=";
+    env << "GRASS_UI_TERM=1";
+    env << "GISRC_MODE_MEMORY";
+    env << "PS1=GRASS > ";
+    env << "TERM=vt100";
+    terminal->setEnvironment(env);
 
-    // first info
-    QRegExp rxinfo( "GRASS_INFO_" );
-    int message = rxinfo.search( mStdoutBuffer );
-
-    if ( message == 0 ) // Info found at index 0
-    {
-      // First try percent
-      QRegExp rxpercent( "GRASS_INFO_PERCENT: (\\d+)\\015\\012" );
-      if ( rxpercent.search( mStdoutBuffer ) == 0 )
-      {
-        int mlen = rxpercent.matchedLength();
-        int progress = rxpercent.cap( 1 ).toInt();
-        mProgressBar->setProgress( progress, 100 );
-        mStdoutBuffer.remove( 0, mlen );
-        continue;
-      }
-
-      QRegExp rxwarning( "GRASS_INFO_WARNING\\(\\d+,\\d+\\): ([^\\015]*)\\015\\012" );
-      QRegExp rxerror( "GRASS_INFO_ERROR\\(\\d+,\\d+\\): ([^\\015]*)\\015\\012" );
-      QRegExp rxend( "GRASS_INFO_END\\(\\d+,\\d+\\)\\015\\012" );
-
-      int mlen = 0;
-      QString msg;
-      QString img;
-      if ( rxwarning.search( mStdoutBuffer ) == 0 )
-      {
-        mlen = rxwarning.matchedLength();
-        msg = rxwarning.cap( 1 );
-        img = QgsApplication::pkgDataPath() + "/themes/default/grass/grass_module_warning.png";
-      }
-      else if ( rxerror.search( mStdoutBuffer ) == 0 )
-      {
-        mlen = rxerror.matchedLength();
-        msg = rxerror.cap( 1 );
-        img = QgsApplication::pkgDataPath() + "/themes/default/grass/grass_module_error.png";
-      }
-
-      if ( mlen > 0 ) // found error or warning
-      {
-        QgsDebugMsg( QString( "MSG: %1" ).arg( msg.local8Bit().data() ) );
-
-        // Delete all previous empty paragraphs.
-        // Messages starts with \n (\015\012) which is previously interpreted
-        // as new line, so it is OK delete it, but it is not quite correct
-        // to delete more  because it can be regular module output
-        // but it does not look nice to have empty rows before
-        removeEmptyParagraphs();
-
-        msg.replace( "&", "&amp;" );
-        msg.replace( "<", "&lt;" );
-        msg.replace( ">", "&gt;" );
-        msg.replace( " ", "&nbsp;" );
-
-        mText->setTextFormat( Qt::RichText );
-        mText->append( "<img src=\"" + img + "\">" + msg );
-        mParagraph++;
-        mNewLine = true;
-        mStdoutBuffer.remove( 0, mlen );
-        continue;
-      }
-
-      if ( rxend.search( mStdoutBuffer ) == 0 )
-      {
-        mlen = rxend.matchedLength();
-        mStdoutBuffer.remove( 0, mlen );
-        continue;
-      }
-
-      // No complete message found => wait for input
-      // TODO: 1) Sleep for a moment because GRASS writes
-      //          1 character in loop
-      //       2) Fix GRASS to write longer strings
-      break;
-    }
-
-    // Print plain text
-    int length = mStdoutBuffer.length();
-    if ( control >= 0 ) length = control;
-    if ( message >= 0 && ( control == -1 || control > message ) )
-    {
-      length = message;
-    }
-
-    if ( length > 0 )
-    {
-      QString out = mStdoutBuffer.left( length ) ;
-      QgsDebugMsg( QString( "TXT: '%1'" ).arg( out.local8Bit().data() ) );
-
-      insert( out );
-
-      mStdoutBuffer.remove( 0, length );
-    }
-  }
-
-  showCursor();
-  mText->ensureCursorVisible();
+    // Look & Feel
+    terminal->setScrollBarPosition(QTermWidget::ScrollBarRight);
 }
-
-void QgsGrassShell::removeEmptyParagraphs()
-{
-  while ( mParagraph >= 0
-          && mText->text( mParagraph ).stripWhiteSpace().length() <= 0 )
-  {
-    mText->removeParagraph( mParagraph );
-    mParagraph--;
-  }
-  mIndex = mText->paragraphLength( mParagraph );
-}
-
-void QgsGrassShell::insert( QString s )
-{
-  QgsDebugMsg( "insert()" );
-
-  if ( s.isEmpty() ) return;
-
-  // In theory mParagraph == mText->paragrephs()-1
-  // but if something goes wrong (more paragraphs) we want to write
-  // at the end
-  if ( mParagraph > -1 && mParagraph != mText->paragraphs() - 1 )
-  {
-    QgsDebugMsg( "WRONG mParagraph!" );
-    mNewLine = true;
-  }
-
-  // Bug?: QTextEdit::setOverwriteMode does not work, always 'insert'
-  //       -> if Insert mode is not set, delete first the string
-  //          to the right
-  // mText->setOverwriteMode ( !mMode[Insert] ); // does not work
-  if ( !mMode[Insert] && !mNewLine && mParagraph >= 0 &&
-       mText->paragraphLength( mParagraph ) > mIndex )
-  {
-    QgsDebugMsg( QString( "erase old %1 chars " ).arg( mIndex + s.length() ) );
-    mText->setSelection( mParagraph, mIndex, mParagraph, mIndex + s.length(), 0 );
-    mText->removeSelectedText( 0 );
-  }
-
-  if ( mNewLine )
-  {
-    // Start new paragraph
-    mText->setTextFormat( Qt::PlainText );
-    mText->setCurrentFont( mFont );
-    mText->append( s );
-    mIndex = s.length();
-    //mParagraph++;
-    mParagraph = mText->paragraphs() - 1;
-    mNewLine = false;
-  }
-  else
-  {
-    // Append to existing paragraph
-    mText->setCursorPosition( mParagraph, mIndex );
-    mText->setTextFormat( Qt::PlainText );
-    mText->setCurrentFont( mFont );
-    mText->insert( s );
-
-    mIndex += s.length();
-  }
-}
-
-void QgsGrassShell::newLine()
-{
-  if ( mSkipLines > 0 )
-  {
-    mText->clear();
-    mSkipLines--;
-  }
-  if ( mNewLine )
-  {
-    mText->setTextFormat( Qt::PlainText );
-    mText->setCurrentFont( mFont );
-    mText->append( " " );
-    //mParagraph++;
-    // To be sure that we are at the end
-    mParagraph = mText->paragraphs() - 1;
-    mIndex = 0;
-  }
-  mNewLine = true;
-}
-
-void QgsGrassShell::eraseCursor()
-{
-  // Remove space representing cursor from the end of current paragraph
-  if ( !mNewLine && mCursorSpace && mParagraph >= 0 )
-  {
-    mText->setSelection( mParagraph, mIndex, mParagraph, mIndex + 1, 0 );
-    mText->removeSelectedText( 0 );
-  }
-  mCursorSpace = false;
-}
-
-void QgsGrassShell::showCursor()
-{
-  // Do not highlite cursor if last printed paragraph was GRASS message
-  if ( mNewLine ) return;
-
-  // If cursor is at the end of paragraph add space
-  if ( mParagraph >= 0 && mIndex > mText->paragraphLength( mParagraph ) - 1 )
-  {
-    mText->setCursorPosition( mParagraph, mIndex );
-    mText->setCursorPosition( mParagraph, mIndex );
-    mText->insert( " " );
-    // Warning: do not increase mIndex,
-    // the space if after current position
-    mCursorSpace = true;
-  }
-
-  // Selection 1 is used as cursor highlite
-  mText->setSelection( mParagraph, mIndex, mParagraph, mIndex + 1, 1 );
-  mText->setSelectionAttributes( 1, QColor( 0, 0, 0 ), true );
-}
-
-void QgsGrassShell::mousePressEvent( QMouseEvent* e )
-{
-  QgsDebugMsg( "mousePressEvent()" );
-
-  if ( !mValid ) return;
-
-  // paste clipboard
-  if ( e->button() == Qt::MidButton )
-  {
-    QClipboard *cb = QApplication::clipboard();
-    QString text = cb->text( QClipboard::Selection );
-    write( mFdMaster, ( char* ) text.ascii(), text.length() );
-  }
-}
-
-void QgsGrassShell::resizeTerminal()
-{
-#ifndef WIN32
-  int width = mText->visibleWidth();
-  int height = mText->visibleHeight();
-
-  QFontMetrics fm( mFont );
-  int col = ( int )( width / fm.width( "x" ) );
-  int row = ( int )( height / fm.height() );
-
-  struct winsize winSize;
-  memset( &winSize, 0, sizeof( winSize ) );
-  winSize.ws_row = row;
-  winSize.ws_col = col;
-
-  ioctl( mFdMaster, TIOCSWINSZ, ( char * )&winSize );
-#endif
-}
-
-void QgsGrassShell::readStderr()
-{
-}
-
-void QgsGrassShell::closeShell()
-{
-  QgsDebugMsg( "entered." );
-
-  mTabWidget->removePage( this );
-  delete this;
-}
-
-
-QgsGrassShellText::QgsGrassShellText( QgsGrassShell *gs,
-                                      QWidget * parent, const char *name )
-    : Q3TextEdit( parent, name ),
-    mShell( gs )
-{
-}
-
-QgsGrassShellText::~QgsGrassShellText() {}
-
-void QgsGrassShellText::contentsMousePressEvent( QMouseEvent* e )
-{
-  QgsDebugMsg( "entered." );
-  mShell->mousePressEvent( e );
-  Q3TextEdit::contentsMousePressEvent( e );
-}
-
-void QgsGrassShellText::keyPressEvent( QKeyEvent * e )
-{
-  QgsDebugMsg( "entered." );
-  mShell->keyPressEvent( e );
-}
-
-void QgsGrassShellText::keyReleaseEvent( QKeyEvent * e )
-{
-  QgsDebugMsg( "entered." );
-  mShell->keyReleaseEvent( e );
-}
-
-void QgsGrassShellText::resizeEvent( QResizeEvent *e )
-{
-  QgsDebugMsg( "resizeEvent()" );
-  mShell->resizeTerminal();
-  Q3TextEdit::resizeEvent( e );
-}

Modified: trunk/qgis/src/plugins/grass/qgsgrassshell.h
===================================================================
--- trunk/qgis/src/plugins/grass/qgsgrassshell.h	2009-04-27 05:39:32 UTC (rev 10663)
+++ trunk/qgis/src/plugins/grass/qgsgrassshell.h	2009-04-27 07:04:32 UTC (rev 10664)
@@ -1,9 +1,10 @@
 /***************************************************************************
      qgsgrassshell.h
      --------------------------------------
-    Date                 : Sun Sep 16 12:06:16 AKDT 2007
-    Copyright            : (C) 2007 by Gary E. Sherman
-    Email                : sherman at mrcc dot com
+    Date                 : Thu Apr 23 08:35:43 CEST 2009
+    Copyright            : (C) 2009 by Lorenzo "Il Rugginoso" Masini
+    Email                : lorenxo86 at gmail.com
+
  ***************************************************************************
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -12,228 +13,33 @@
  *   (at your option) any later version.                                   *
  *                                                                         *
  ***************************************************************************/
+#include <QFrame>
 
-#include <Q3CString>
-#include <Q3Process>
-#include <Q3TextEdit>
-#include <QDialog>
-#include <QKeyEvent>
-#include <QMessageBox>
-#include <QMouseEvent>
-#include <QResizeEvent>
-#include <QSocketNotifier>
-#include <QString>
-
-#include "qgsgrasstools.h"
-#include "ui_qgsgrassshellbase.h"
-
+class QgsGrassTools;
 class QTabWidget;
+class QTermWidget;
 
-class QgsGrassShellText;
-
-extern "C"
+class QgsGrassShell : public QFrame
 {
-#include <stdio.h>
-}
-
-/* QgsGrassShellBase is simple pseudo terminal implementing
- * very limited subset of VT100. OTOH it parses GUI format of
- * messages printed by GRASS modules and adds icons for
- * WARNING and ERROR and it also resets progress bar if a module
- * uses G_percent() function.
- *
- * On UNIX pseudo terminal is represented by a pair of files
- * called master and slave which are connected.
- * On LINUX the files are called /dev/ptmx (master)
- * and /dev/pts/<number> (slave). The application emulating terminal
- * is connected master and the program running in terminal
- * (usually shell like bash,tcsh,sh) is connected to slave.
- *
- * There is no support for pseudo terminals in Qt. Everything
- * must be written using relatively low level C functions
- *
- * Input (LINUX):
- * keyboard -> X -> Qt -> QgsGrassShellBase::keyPressEvent()
- * -> /dev/ptmx -> /dev/pts/<number> -> shell
- *
- * Output (LINUX):
- * shell -> /dev/pts/<number> -> /dev/ptmx
- * -> QgsGrassShell::readStdout() -> QCString ->
- * -> QgsGrassShell::printStdout() -> QTextEdit
- *
- * Reading/printing of shel output is bease on two prerrequisites:
- *   1) Lines printed by shell are not endless
- *   2) GRASS GUI messages are always available complete on output
- * thus we read everything on output to buffer in cycle untill
- * we reach either EOF (no more data available) or NL (new line).
- * Then the data from buffer are printed to output QTextEdit.
- * Control characters, control sequences and GRASS GUI messages
- * are transformed to appropriate output written to QTextEdit.
- */
-
-class QgsGrassShell: public QDialog, private Ui::QgsGrassShellBase
-{
     Q_OBJECT
 
-  public:
-    QgsGrassShell( QgsGrassTools *tools,
-                   QTabWidget * parent = 0, const char * name = 0 );
-    ~QgsGrassShell();
+public:
+    QgsGrassShell(QgsGrassTools *tools, QTabWidget *parent = 0, const char *name = 0);
+    virtual ~QgsGrassShell();
 
-    // Modes
-    enum Mode
-    {
-      Origin = 0,
-      Wrap,
-      Insert,
-      Screen,
-      Cursor,
-      NewLine,
-      ModeCount
-    };
-
-    // Graphic Rendition
-    enum Rendition
-    {
-      Bold = 0,
-      Underline,
-      Blink,
-      Reverse,
-      RendetionCount
-    };
-
-    // Pressed key
-    enum KeyDown
-    {
-      DownControl = 0,
-      DownShift,
-      DownAlt,
-      DownMeta,
-      KeyDownCount
-    };
-
-    // Print maximum form standard input buffer
-    void printStdout();
-
-    // Print maximum form standard error buffer
-    void printStderr();
-
-    // Set / reset mode
-    void setMode( int m ) { mMode[m] = true; }
-    void resetMode( int m ) { mMode[m] = false; }
-
-    // Insert text on current cursor position according to Insert mode
-    void insert( QString );
-
-    // Start new line
-    void newLine();
-
-    // Erase cursor highlight (space)
-    void eraseCursor( void );
-
-    // Highlite cursor
-    void showCursor( void );
-
-    // Reset pseudoterminal size
+/* TODO: Implement something that resizes the terminal without
+ *       crashes.
+public slots:
     void resizeTerminal();
+*/
 
-    // Remove empty (or with whitespaces) paragraphs
-    void removeEmptyParagraphs();
-
-    // Reset cursor to current position
-    //void setCursorPosition();
-
-  public slots:
-    void readStdout( int socket );
-    void readStderr();
-    void keyPressEvent( QKeyEvent * e );
-    void keyReleaseEvent( QKeyEvent * e );
-    void mousePressEvent( QMouseEvent* e );
+private slots:
     void closeShell();
 
-  signals:
+private:
+    void initTerminal(QTermWidget *terminal);
 
-  private:
-    //QProcess *mProcess;
-    // Master file descriptor
-    int mFdMaster;
-
-    /**
-     *    * The socket descriptors for stdout.
-     *       */
-    int out[2];
-
-    QSocketNotifier *mOutNotifier;
-
-    // Buffer for data read form shell stdout
-    Q3CString mStdoutBuffer;
-
-    // Buffer for data read form shell stderr
-    Q3CString mStderrBuffer;
-
-    // Shell process PID
-    int mPid;
-
-    // Modes
-    bool mMode[ModeCount];
-
-    // Flag for space if it was added at the end of paragraph to
-    // visualize the cursor
-    bool mCursorSpace;
-
-    // Current cursor position
-    int mParagraph;
-    int mIndex;
-
-    // Text widget
-    QgsGrassShellText *mText;
-
-    // Default text font
-    QFont mFont;
-
-    // Rendetion
-    bool mRendetion[RendetionCount];
-
-    // Pressed keys
-    bool mKeyDown[KeyDownCount];
-
-    // Application directory
-    QString mAppDir;
-
-    // GRASS Tools
+    QTermWidget *mTerminal;
     QgsGrassTools *mTools;
-
-    // Create new line in nex insert
-    // This must be used because QTextEdit will remove all empty
-    // paragraphs
-    bool mNewLine;
-
-    // Is it successfuly opened
-    bool mValid;
-
-    // Horizontal tabulator stop
-    std::vector<bool> mTabStop;
-
-    // How many lines to skip, used to skip output of first commands sent to shell
-    int mSkipLines;
-
-    // pointer to tab widget in which is the shell
-    QTabWidget* mTabWidget;
+    QTabWidget *mTabWidget;
 };
-
-class QgsGrassShellText : public Q3TextEdit
-{
-    Q_OBJECT
-  public:
-    QgsGrassShellText( QgsGrassShell *,
-                       QWidget * parent = 0, const char * name = 0 );
-    ~QgsGrassShellText();
-  public slots:
-    void contentsMousePressEvent( QMouseEvent * );
-    void resizeEvent( QResizeEvent * );
-    void keyPressEvent( QKeyEvent * e );
-    void keyReleaseEvent( QKeyEvent * e );
-  private:
-    QgsGrassShell *mShell;
-};
-

Modified: trunk/qgis/src/plugins/grass/qgsgrassshellbase.ui
===================================================================
--- trunk/qgis/src/plugins/grass/qgsgrassshellbase.ui	2009-04-27 05:39:32 UTC (rev 10663)
+++ trunk/qgis/src/plugins/grass/qgsgrassshellbase.ui	2009-04-27 07:04:32 UTC (rev 10664)
@@ -1,75 +0,0 @@
-<ui version="4.0" >
- <class>QgsGrassShellBase</class>
- <widget class="QWidget" name="QgsGrassShellBase" >
-  <property name="geometry" >
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>600</width>
-    <height>434</height>
-   </rect>
-  </property>
-  <property name="minimumSize" >
-   <size>
-    <width>600</width>
-    <height>400</height>
-   </size>
-  </property>
-  <property name="windowTitle" >
-   <string>GRASS Shell</string>
-  </property>
-  <layout class="QVBoxLayout" >
-   <item>
-    <widget class="Q3Frame" name="mTextFrame" >
-     <property name="sizePolicy" >
-      <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="frameShape" >
-      <enum>QFrame::StyledPanel</enum>
-     </property>
-     <property name="frameShadow" >
-      <enum>QFrame::Raised</enum>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" >
-     <item>
-      <widget class="Q3ProgressBar" name="mProgressBar" />
-     </item>
-     <item>
-      <widget class="QPushButton" name="mCloseButton" >
-       <property name="focusPolicy" >
-        <enum>Qt::ClickFocus</enum>
-       </property>
-       <property name="text" >
-        <string>Close</string>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-  </layout>
- </widget>
- <layoutdefault spacing="6" margin="11" />
- <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
- <customwidgets>
-  <customwidget>
-   <class>Q3Frame</class>
-   <extends>QFrame</extends>
-   <header>Qt3Support/Q3Frame</header>
-   <container>1</container>
-  </customwidget>
-  <customwidget>
-   <class>Q3ProgressBar</class>
-   <extends>QFrame</extends>
-   <header>Qt3Support/Q3ProgressBar</header>
-   <container>1</container>
-  </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>

Modified: trunk/qgis/src/plugins/grass/qgsgrasstools.cpp
===================================================================
--- trunk/qgis/src/plugins/grass/qgsgrasstools.cpp	2009-04-27 05:39:32 UTC (rev 10663)
+++ trunk/qgis/src/plugins/grass/qgsgrasstools.cpp	2009-04-27 07:04:32 UTC (rev 10664)
@@ -214,9 +214,13 @@
 
   // We must call resize to reset COLUMNS enviroment variable
   // used by bash !!!
+
+/* TODO: Implement something that resizes the terminal without
+ *       crashes.
 #ifndef WIN32
   if ( sh ) sh->resizeTerminal();
 #endif
+*/
 }
 
 bool QgsGrassTools::loadConfig( QString filePath )



More information about the QGIS-commit mailing list