Salome HOME
Merge branch 'master' into V7_5_BR
[modules/gui.git] / src / PyConsole / PyConsole_Editor.cxx
index adb5a6d7ae9b72da5b2098272464734ee04d20ed..aeb61f965e0cc5dd56d67116a539bd09eb3d5050 100644 (file)
@@ -138,14 +138,20 @@ bool DumpCommandsFileValidator::canSave(const QString& file, bool permissions)
 
 void staticCallbackStdout( void* data, char* c )
 {
-  if(!((PyConsole_Editor*)data)->isSuppressOutput())
-    QApplication::postEvent( (PyConsole_Editor*)data, new PrintEvent( c, false ) );
+  if(!((PyConsole_Editor*)data)->isSuppressOutput()) {
+    PyConsole_Editor* e = (PyConsole_Editor*)data;
+    e->putLog( QString::fromUtf8(c) );
+    QApplication::postEvent( e, new PrintEvent( QString::fromUtf8(c), false ) );
+  }
 }
 
 void staticCallbackStderr( void* data, char* c )
 {
-  if(!((PyConsole_Editor*)data)->isSuppressOutput())
-    QApplication::postEvent( (PyConsole_Editor*)data, new PrintEvent( c, true ) );
+  if(!((PyConsole_Editor*)data)->isSuppressOutput()) {
+    PyConsole_Editor* e = (PyConsole_Editor*)data;
+    e->putLog( QString::fromUtf8(c) );
+    QApplication::postEvent( e, new PrintEvent( QString::fromUtf8(c), true ) );
+  }
 }
 
 
@@ -163,7 +169,7 @@ PyConsole_Editor::PyConsole_Editor( PyConsole_Interp* theInterp,
   myCmdInHistory( -1 ),
   myEventLoop( 0 ),
   myShowBanner( true ),
-  myIsSync( false ),
+  myIsSync( true ),
   myIsSuppressOutput( false )
 {
   QString fntSet( "" );
@@ -185,16 +191,20 @@ PyConsole_Editor::PyConsole_Editor( PyConsole_Interp* theInterp,
 
 /*!
   \brief Destructor.
-
-  Does nothing for the moment.
 */
 PyConsole_Editor::~PyConsole_Editor()
 {
-  myInterp->destroy();
-  delete myInterp;
   myInterp = 0;
 }
 
+/*!
+  \brief Get Python interpreter
+*/
+PyConsole_Interp* PyConsole_Editor::getInterp() const
+{
+  return myInterp;
+}
+
 /*!
   \brief Get synchronous mode flag value.
   
@@ -272,6 +282,17 @@ void PyConsole_Editor::setIsShowBanner( const bool on )
   }
 }
 
+/*!
+  \brief Check if trace logging is switched on.
+  
+  \sa startLog(), stopLog()
+  \return \c true if trace logging is switched on
+*/
+bool PyConsole_Editor::isLogging() const
+{
+  return !myLogFile.isEmpty();
+}
+
 /*!
   \brief Get size hint for the Python console window
   \return size hint value
@@ -342,6 +363,7 @@ void PyConsole_Editor::exec( const QString& command )
     if ( !lines[i].trimmed().isEmpty() )
       myHistory.push_back( lines[i] );
     addText( ( i == 0 ? READY_PROMPT : DOTS_PROMPT ) + lines[i], i != 0 );
+    putLog( QString( "%1%2\n" ).arg( i == 0 ? READY_PROMPT : DOTS_PROMPT ).arg( lines[i] ) );
   }
   // IPAL20182
   addText( "", true );
@@ -378,14 +400,21 @@ void PyConsole_Editor::execAndWait( const QString& command )
     return;
 
   // create new event loop
-  myEventLoop = new QEventLoop( this );
+  bool sync = isSync();
+  if ( !sync ) {
+    myEventLoop = new QEventLoop( this );
+  }
+
   // execute command
   exec( command );
-  // run event loop
-  myEventLoop->exec();
-  // delete event loop after command is processed
-  delete myEventLoop;
-  myEventLoop = 0;
+
+  if ( !sync ) {
+    // run event loop
+    myEventLoop->exec();
+    // delete event loop after command is processed
+    delete myEventLoop;
+    myEventLoop = 0;
+  }
 }
 
 /*!
@@ -411,6 +440,7 @@ void PyConsole_Editor::handleReturn()
   // add command to the history
   if ( !cmd.trimmed().isEmpty() )
     myHistory.push_back( cmd );
+  putLog( QString( "%1%2\n" ).arg( myPrompt ).arg( cmd ) );
 
   // IPAL19397
   addText( "", true ); 
@@ -1116,18 +1146,90 @@ void PyConsole_Editor::dump()
   aFilters.append( tr( "PYTHON_FILES_FILTER" ) );
   
   QString fileName = SUIT_FileDlg::getFileName( this, QString(),
-                                    aFilters, tr( "TOT_DUMP_PYCOMMANDS" ),
-                                    false, true, new DumpCommandsFileValidator( this ) );
-  if ( fileName != "" ) {
+                                               aFilters, tr( "TOT_DUMP_PYCOMMANDS" ),
+                                               false, true, new DumpCommandsFileValidator( this ) );
+  if ( !fileName.isEmpty() ) {
     QFile file( fileName ); 
     if ( !file.open( QFile::WriteOnly ) )
       return;
 
     QTextStream out (&file);
   
-    for( int i=0; i<myHistory.count(); i++ ) {
-         out<<myHistory[i]<<endl;
+    for ( int i=0; i<myHistory.count(); i++ ) {
+      out << myHistory[i] << endl;
+    }
+    file.close();
+  }
+}
+/*!
+  \brief "Start log" operation.
+ */
+void PyConsole_Editor::startLog()
+{
+  QStringList aFilters;
+  aFilters.append( tr( "LOG_FILES_FILTER" ) );
+
+  while (1) {
+    QString fileName = SUIT_FileDlg::getFileName( this, QString(),
+                                                 aFilters, tr( "TOT_SAVE_PYLOG" ),
+                                                 false, true );
+    if ( !fileName.isEmpty() ) {
+      if ( startLog( fileName ) ) {
+       break;
+      }
+      else {
+       SUIT_MessageBox::critical( this,
+                                  QObject::tr("ERR_ERROR"),
+                                  QObject::tr("ERR_FILE_NOT_WRITABLE") );
+      }
+    }
+    else {
+      break;
+    }
+  }
+}
+
+/*!
+  \brief Start python trace logging
+  \param fileName the path to the log file
+  \sa stopLog()
+ */
+bool PyConsole_Editor::startLog( const QString& fileName )
+{
+  bool ok = false;
+  if ( !fileName.isEmpty() ) {
+    QFile file( fileName );
+    if ( file.open( QFile::WriteOnly ) ) {
+      file.close();
+      myLogFile = fileName;
+      ok = true;
     }
+  }
+  return ok;
+}
+
+/*!
+  \brief "Stop log" operation.
+  \sa startLog()
+ */
+void PyConsole_Editor::stopLog()
+{
+  myLogFile = QString();
+}
+
+/*!
+  \brief Put string to the log file
+ */
+void PyConsole_Editor::putLog( const QString& s )
+{
+  if ( !myLogFile.isEmpty() ) {
+    QFile file( myLogFile );
+    if ( !file.open( QFile::Append ) )
+      return;
+    
+    QTextStream out (&file);
+    out << s;
+    
     file.close();
   }
 }