]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
0022652: [CEA 1194] Redirect the traces from embedded Python console in a log file
authorvsr <vsr@opencascade.com>
Mon, 22 Sep 2014 13:59:44 +0000 (17:59 +0400)
committervsr <vsr@opencascade.com>
Mon, 22 Sep 2014 13:59:44 +0000 (17:59 +0400)
Additional changes:
- Implement Start/Stop Log commands to save run-time log instead of saving static snapshot of the log.

src/PyConsole/PyConsole_Console.cxx
src/PyConsole/PyConsole_Console.h
src/PyConsole/PyConsole_Editor.cxx
src/PyConsole/PyConsole_Editor.h
src/PyConsole/resources/PyConsole_msg_en.ts
src/PyConsole/resources/PyConsole_msg_fr.ts
src/PyConsole/resources/PyConsole_msg_ja.ts

index c613866d1e10cadf7cec28eb0739f42e6a8eba8e..f386ebfdb6ee77588d7a0af85fcc0f2df911ce49 100644 (file)
@@ -248,7 +248,10 @@ void PyConsole_Console::contextMenuPopup( QMenu* menu )
   menu->addAction( myActions[SelectAllId] );
   menu->addSeparator();
   menu->addAction( myActions[DumpCommandsId] );
-  menu->addAction( myActions[SaveLogId] );
+  if ( !myEditor->isLogging() )
+    menu->addAction( myActions[StartLogId] );
+  else
+    menu->addAction( myActions[StopLogId] );
 
   Qtx::simplifySeparators( menu );
 
@@ -270,7 +273,8 @@ void PyConsole_Console::setMenuActions( const int flags )
   myActions[ClearId]->setVisible( flags & ClearId );
   myActions[SelectAllId]->setVisible( flags & SelectAllId );
   myActions[DumpCommandsId]->setVisible( flags & DumpCommandsId );
-  myActions[SaveLogId]->setVisible( flags & SaveLogId );
+  myActions[StartLogId]->setVisible( flags & StartLogId );
+  myActions[StopLogId]->setVisible( flags & StopLogId );
 }
 
 /*!
@@ -286,7 +290,8 @@ int PyConsole_Console::menuActions() const
   ret = ret | ( myActions[ClearId]->isVisible() ? ClearId : 0 );
   ret = ret | ( myActions[SelectAllId]->isVisible() ? SelectAllId : 0 );
   ret = ret | ( myActions[DumpCommandsId]->isVisible() ? DumpCommandsId : 0 );
-  ret = ret | ( myActions[SaveLogId]->isVisible() ? SaveLogId : 0 );
+  ret = ret | ( myActions[StartLogId]->isVisible() ? StartLogId : 0 );
+  ret = ret | ( myActions[StopLogId]->isVisible() ? StopLogId : 0 );
   return ret;
 }
 
@@ -322,10 +327,15 @@ void PyConsole_Console::createActions()
   connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( dump() ) );
   myActions.insert( DumpCommandsId, a );
 
-  a = new QAction( tr( "EDIT_SAVELOG_CMD" ), this );
-  a->setStatusTip( tr( "EDIT_SAVELOG_CMD" ) );
-  connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( saveLog() ) );
-  myActions.insert( SaveLogId, a );
+  a = new QAction( tr( "EDIT_STARTLOG_CMD" ), this );
+  a->setStatusTip( tr( "EDIT_STARTLOG_CMD" ) );
+  connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( startLog() ) );
+  myActions.insert( StartLogId, a );
+
+  a = new QAction( tr( "EDIT_STOPLOG_CMD" ), this );
+  a->setStatusTip( tr( "EDIT_STOPLOG_CMD" ) );
+  connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( stopLog() ) );
+  myActions.insert( StopLogId, a );
 }
 
 /*!
index 783c6567a1b7cec292a18863ba329d37e6cf9f1b..de909960de54c4c6a1e27a49929abe350436917a 100644 (file)
@@ -44,13 +44,14 @@ public:
   //! Context popup menu actions flags
   enum
   {
-    CopyId         = 0x01,                                                      //!< "Copy" menu action
-    PasteId        = 0x02,                                                      //!< "Paste" menu action
-    ClearId        = 0x04,                                                      //!< "Clear" menu action
-    SelectAllId    = 0x08,                                                      //!< "Select All" menu action
-    DumpCommandsId = 0x10,                                                      //!< "DumpCommands" menu action
-    SaveLogId      = 0x20,                                                      //!< "Save log" menu action
-    All = CopyId | PasteId | ClearId | SelectAllId | DumpCommandsId | SaveLogId //!< all menu actions
+    CopyId         = 0x01,  //!< "Copy" menu action
+    PasteId        = 0x02,  //!< "Paste" menu action
+    ClearId        = 0x04,  //!< "Clear" menu action
+    SelectAllId    = 0x08,  //!< "Select All" menu action
+    DumpCommandsId = 0x10,  //!< "DumpCommands" menu action
+    StartLogId     = 0x20,  //!< "Start log" menu action
+    StopLogId      = 0x40,  //!< "Stop log" menu action
+    All            = 0xFF,  //!< all menu actions 
   };
 
 public:
index c9542464aa7ec3ab7d24d1785fc7e9233ab7e353..be9ba6b981c72efc0380d4e31dba87c2d20df411 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( QString::fromUtf8(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( QString::fromUtf8(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 ) );
+  }
 }
 
 
@@ -272,6 +278,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
@@ -339,13 +356,10 @@ void PyConsole_Editor::exec( const QString& command )
   if ( !cmd.endsWith( "\n" ) ) cmd += "\n";
   QStringList lines = command.split( "\n" );
   for ( int i = 0; i < lines.size(); i++ ) {
-    if ( !lines[i].trimmed().isEmpty() ) {
-      PyCommand aCommand;
-      aCommand.command = lines[i];
-      aCommand.prompt = i == 0 ? READY_PROMPT : DOTS_PROMPT;
-      myHistory.append( aCommand );
-    }
+    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 );
@@ -413,12 +427,9 @@ void PyConsole_Editor::handleReturn()
   // extend the command buffer with the current command 
   myCommandBuffer.append( cmd );
   // add command to the history
-  if ( !cmd.trimmed().isEmpty() ) {
-    PyCommand aCommand;
-    aCommand.command = cmd;
-    aCommand.prompt = myPrompt;
-    myHistory.append( aCommand );
-  }
+  if ( !cmd.trimmed().isEmpty() )
+    myHistory.push_back( cmd );
+  putLog( QString( "%1%2\n" ).arg( myPrompt ).arg( cmd ) );
 
   // IPAL19397
   addText( "", true ); 
@@ -604,7 +615,7 @@ void PyConsole_Editor::keyPressEvent( QKeyEvent* event )
         if ( myCmdInHistory > 0 ) {
           myCmdInHistory--;
           // get previous command in the history
-          QString previousCommand = myHistory.at( myCmdInHistory ).command;
+          QString previousCommand = myHistory.at( myCmdInHistory );
           // print previous command
           moveCursor( QTextCursor::End );
           moveCursor( QTextCursor::StartOfBlock, QTextCursor::KeepAnchor );
@@ -641,7 +652,7 @@ void PyConsole_Editor::keyPressEvent( QKeyEvent* event )
           QString nextCommand;
           if ( myCmdInHistory < myHistory.count() ) {
             // next command in history
-            nextCommand = myHistory.at( myCmdInHistory ).command;
+            nextCommand = myHistory.at( myCmdInHistory );
           }
           else {
             // end of history is reached
@@ -748,7 +759,7 @@ void PyConsole_Editor::keyPressEvent( QKeyEvent* event )
         if ( myCmdInHistory > 0 ) {
           myCmdInHistory = 0;
           // get very first command in the history
-          QString firstCommand = myHistory.at( myCmdInHistory ).command;
+          QString firstCommand = myHistory.at( myCmdInHistory );
           // print first command
           moveCursor( QTextCursor::End );
           moveCursor( QTextCursor::StartOfBlock, QTextCursor::KeepAnchor );
@@ -943,7 +954,6 @@ void PyConsole_Editor::customEvent( QEvent* event )
     {
       PrintEvent* pe=(PrintEvent*)event;
       addText( pe->text(), false, pe->isError());
-      myHistory.last().output = myHistory.last().output + pe->text();
       return;
     }
   case PyInterp_Event::ES_OK:
@@ -1135,7 +1145,7 @@ void PyConsole_Editor::dump()
     QTextStream out (&file);
   
     for ( int i=0; i<myHistory.count(); i++ ) {
-      out << myHistory.at(i).command << endl;
+      out << myHistory[i] << endl;
     }
     file.close();
   }
@@ -1143,25 +1153,57 @@ void PyConsole_Editor::dump()
 /*!
   \brief "Save log" operation.
  */
-void PyConsole_Editor::saveLog()
+void PyConsole_Editor::startLog()
 {
   QStringList aFilters;
   aFilters.append( tr( "LOG_FILES_FILTER" ) );
 
-  QString fileName = SUIT_FileDlg::getFileName( this, QString(),
-                                               aFilters, tr( "TOT_SAVE_PYLOG" ),
-                                               false, true );
-  if ( !fileName.isEmpty() ) {
-    QFile file( fileName );
-    if ( !file.open( QFile::WriteOnly ) )
-      return;
+  while (1) {
+    QString fileName = SUIT_FileDlg::getFileName( this, QString(),
+                                                 aFilters, tr( "TOT_SAVE_PYLOG" ),
+                                                 false, true );
+    if ( !fileName.isEmpty() ) {
+      QFile file( fileName );
+      if ( file.open( QFile::WriteOnly ) ) {
+       file.close();
+       myLogFile = fileName;
+       break;
+      }
+      else {
+       SUIT_MessageBox::critical( this,
+                                  QObject::tr("ERR_ERROR"),
+                                  QObject::tr("ERR_FILE_NOT_WRITABLE") );
+      }
+    }
+    else {
+      break;
+    }
+  }
+}
 
-    QTextStream out (&file);
 
-     for( int i = 0; i < myHistory.count(); i++ ) {
-      out << myHistory.at(i).prompt << myHistory.at(i).command << endl;
-      out << myHistory.at(i).output;
-    }
+/*!
+  \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();
   }
 }
index 994be9db658238f8d1f2fa0add2b1ea9d74ecee9..650712a8f52c5db012996b5ad79016d4640d5a16 100644 (file)
@@ -35,10 +35,6 @@ class PyConsole_Interp;
 class PyInterp_Request;
 class QEventLoop;
 
-typedef struct {
-  QString command, output, prompt;
-} PyCommand;
-
 class PYCONSOLE_EXPORT PyConsole_Editor : public QTextEdit
 {
   Q_OBJECT;
@@ -62,6 +58,8 @@ public:
   bool           isShowBanner() const;
   void           setIsShowBanner( const bool );
 
+  bool           isLogging() const;
+
   virtual QSize  sizeHint() const;
 
 public slots:
@@ -71,7 +69,9 @@ public slots:
     void           handleReturn();
     void           onPyInterpChanged( PyConsole_Interp* );
     void           dump();
-    void           saveLog();
+    void           startLog();
+    void           stopLog();
+    void           putLog( const QString& );
 
 protected:
   virtual void   dropEvent( QDropEvent* event );
@@ -90,7 +90,8 @@ protected:
   QString           myCurrentCommand;   //!< currently being printed command
   QString           myPrompt;           //!< current command line prompt
   int               myCmdInHistory;     //!< current history command index
-  QList<PyCommand>  myHistory;          //!< commands history buffer
+  QString           myLogFile;          //!< current output log
+  QStringList       myHistory;          //!< commands history buffer
   QEventLoop*       myEventLoop;        //!< internal event loop
   QString           myBanner;           //!< current banner
   bool              myShowBanner;       //!< 'show banner' flag
index a4818b95b4006b77a11058add4b65fe29dc54e0b..3a3b89bd94a077e4af5f6f7e2b2a10674d86dfbf 100644 (file)
     </message>
     <message>
         <source>EDIT_DUMPCOMMANDS_CMD</source>
-        <translation>D&amp;ump commands</translation>
+        <translation>D&amp;ump Commands</translation>
     </message>
     <message>
-        <source>EDIT_SAVELOG_CMD</source>
-        <translation>&amp;Save log</translation>
+      <source>EDIT_STARTLOG_CMD</source>
+        <translation>Start &amp;Log</translation>
+    </message>
+    <message>
+      <source>EDIT_STOPLOG_CMD</source>
+        <translation>Stop &amp;Log</translation>
     </message>
 </context>
 <context>
@@ -50,5 +54,9 @@
         <source>LOG_FILES_FILTER</source>
         <translation>Log files (*.log *.txt)</translation>
     </message>
+    <message>
+        <source>ERR_FILE_NOT_WRITABLE</source>
+        <translation>File is not writable!</translation>
+    </message>
 </context>
 </TS>
index 92dd76dde25fda0e4c073ee4dfe68b9da93228b2..4446aa9bdd2857109409b613bdc82733cd76cb74 100755 (executable)
         <translation>&amp;Générer le script des commandes</translation>
     </message>
     <message>
-        <source>EDIT_SAVELOG_CMD</source>
-        <translation type="unfinished">&amp;Save log</translation>
+        <source>EDIT_STARTLOG_CMD</source>
+        <translation type="unfinished">Start &amp;Log</translation>
+    </message>
+    <message>
+        <source>EDIT_STOPLOG_CMD</source>
+        <translation type="unfinished">Stop &amp;Log</translation>
     </message>
 </context>
 <context>
@@ -50,5 +54,9 @@
         <source>LOG_FILES_FILTER</source>
         <translation type="unfinished">Log files (*.log *.txt)</translation>
     </message>
+    <message>
+        <source>ERR_FILE_NOT_WRITABLE</source>
+        <translation type="unfinished">File is not writable!</translation>
+    </message>
 </context>
 </TS>
index 23de7907ed0fc8badc5514afb736452ad4c7f983..c993c7cc5e3b735b80514c4e0f1eec75eb837cc6 100644 (file)
       <translation>スクリプト コマンドを生成します。(&amp;u)</translation>
     </message>
     <message>
-        <source>EDIT_SAVELOG_CMD</source>
-        <translation type="unfinished">&amp;Save log</translation>
+        <source>EDIT_STARTLOG_CMD</source>
+        <translation type="unfinished">Start &amp;Log</translation>
+    </message>
+    <message>
+        <source>EDIT_STOPLOG_CMD</source>
+        <translation type="unfinished">Stop &amp;Log</translation>
     </message>
   </context>
   <context>
@@ -50,5 +54,9 @@
         <source>LOG_FILES_FILTER</source>
         <translation type="unfinished">Log files (*.log *.txt)</translation>
     </message>
+    <message>
+        <source>ERR_FILE_NOT_WRITABLE</source>
+        <translation type="unfinished">File is not writable!</translation>
+    </message>
   </context>
 </TS>