1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // KERNEL SALOME_Event : Define event posting mechanism
23 // File : LogWindow.cxx
24 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
26 #include "LogWindow.h"
29 #include <QApplication>
34 #include <QTextStream>
36 #include <QVBoxLayout>
38 #include <SUIT_MessageBox.h>
39 #include <SUIT_ResourceMgr.h>
40 #include <SUIT_Session.h>
41 #include <SUIT_Tools.h>
43 #define DEFAULT_SEPARATOR "***"
46 \brief Convert rich text to plain text.
48 \param richText rich text string
49 \return converted plain text string
51 static QString plainText( const QString& richText )
53 QString aText = richText;
54 int startTag = aText.indexOf( '<' );
60 int finishTag = aText.indexOf( '>', startTag );
64 aText = aText.remove( startTag, finishTag - startTag + 1 );
65 startTag = aText.indexOf( '<' );
72 \brief Widget, displaying log messages.
74 The log messages window provides operations like:
76 - display timestamps at the message beginning
77 - color messages according to their purposes (e.g., errors/warning)
79 - copy messages to clipvoard
80 - save message log to to the text file
86 Creates new messages log window widget.
87 \param parent parent widget
89 LogWindow::LogWindow( QWidget* parent )
93 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
95 QString fntSet = resMgr ? resMgr->stringValue( "Log Window", "font", QString() ) : QString();
97 setFont( SUIT_Tools::stringToFont( fntSet ) );
99 myView = new QTextEdit( this );
100 myView->setReadOnly( true );
101 myView->viewport()->installEventFilter( this );
103 QVBoxLayout* main = new QVBoxLayout( this );
104 main->setMargin( 0 );
105 main->addWidget( myView );
108 myBanner = "<b>Message Log</b>\n********************";
109 mySeparator = DEFAULT_SEPARATOR;
119 Does nothing for the moment.
121 LogWindow::~LogWindow()
126 \brief Get current banner (message log window header text).
127 \return string representing the current banner
129 QString LogWindow::banner() const
135 \brief Get current separator (text which is printed between messages).
136 \return string representing the current separator
138 QString LogWindow::separator() const
144 \brief Set current banner (message log window header text).
145 \param banner new banner
147 void LogWindow::setBanner( const QString& banner )
155 Set current separator (text which is printed between messages).
156 \param separator new separator
158 void LogWindow::setSeparator( const QString& separator )
160 mySeparator = separator;
166 \brief Custom event handler.
168 Process context popup menu request event.
172 \return True if the event is processed and further processing should be stopped
174 bool LogWindow::eventFilter( QObject* o, QEvent* e )
176 if ( o == myView->viewport() && e->type() == QEvent::ContextMenu )
178 contextMenuRequest( (QContextMenuEvent*)e );
181 return QWidget::eventFilter( o, e );
185 \brief Put new message to the log window.
186 \param message text of the message
187 \param flags ORed flags which define how the message should be printed
189 void LogWindow::putMessage( const QString& message, const int flags )
191 putMessage( message, QColor(), flags );
195 \brief Put new message to the log window.
196 \param message text of the message
197 \param color text color of the message
198 \param flags ORed flags which define how the message should be printed
200 void LogWindow::putMessage( const QString& message, const QColor& color, const int flags )
202 QString msg = message;
206 bool noColor = flags & DisplayNoColor;
208 if ( color.isValid() )
209 msg = QString( "<font color=\"%1\">%2</font>" ).arg( color.name() ).arg( msg );
212 if ( flags & DisplayDate )
214 dStr = QDate::currentDate().toString( Qt::SystemLocaleDate );
216 dStr = QString( "<font color=\"#003380\">%1</font>" ).arg( dStr );
220 if ( flags & DisplayTime )
222 tStr = QTime::currentTime().toString( Qt::SystemLocaleDate );
224 tStr = QString( "<font color=\"#008033\">%1</font>" ).arg( tStr );
227 QString dateTime = QString( "%1 %2" ).arg( dStr ).arg( tStr ).trimmed();
228 if ( !dateTime.isEmpty() )
229 msg = QString( "[%1] %2" ).arg( dateTime ).arg( msg );
231 myView->append( msg );
232 myHistory.append( plainText( message ) );
234 if ( flags & DisplaySeparator && !mySeparator.isEmpty() )
236 myView->append( mySeparator ); // add separator
237 myHistory.append( plainText( mySeparator ) );
239 myView->moveCursor( QTextCursor::End );
243 \brief Clear message log.
244 \param clearHistory if True, clear also the messages history
246 void LogWindow::clear( bool clearHistory )
252 if ( !myBanner.isEmpty() )
254 myView->append( myBanner );
255 myBannerSize = myView->document()->blockCount();
262 \brief Save messages log to the file.
263 \param fileName name of the file
264 \return \c true on success and \c false on error
266 bool LogWindow::saveLog( const QString& fileName )
268 QFile file( fileName );
269 if ( !file.open( QFile::WriteOnly ) )
272 QTextStream stream( &file );
274 stream << "*****************************************" << endl;
275 stream << "Message Log" << endl;
276 stream << QDate::currentDate().toString( "dd.MM:yyyy" ) << " ";
277 stream << QTime::currentTime().toString( "hh:mm:ss" ) << endl;
278 stream << "*****************************************" << endl;
280 for ( int i = 0; i < myHistory.count(); i++ )
281 stream << myHistory[ i ] << endl;
288 \brief Create context popup menu actions.
290 void LogWindow::createActions()
292 QAction* a = new QAction( tr( "EDIT_COPY_CMD" ), this );
293 a->setStatusTip( tr( "EDIT_COPY_CMD" ) );
294 connect( a, SIGNAL( triggered( bool ) ), SLOT( onCopy() ) );
295 myActions.insert( CopyId, a );
297 a = new QAction( tr( "EDIT_CLEAR_CMD" ), this );
298 a->setStatusTip( tr( "EDIT_CLEAR_CMD" ) );
299 connect( a, SIGNAL( triggered( bool ) ), SLOT( onClear() ) );
300 myActions.insert( ClearId, a );
302 a = new QAction( tr( "EDIT_SELECTALL_CMD" ), this );
303 a->setStatusTip( tr( "EDIT_SELECTALL_CMD" ) );
304 connect( a, SIGNAL( triggered( bool ) ), SLOT( onSelectAll() ) );
305 myActions.insert( SelectAllId, a );
307 a = new QAction( tr( "EDIT_SAVETOFILE_CMD" ), this );
308 a->setStatusTip( tr( "EDIT_SAVETOFILE_CMD" ) );
309 connect( a, SIGNAL( triggered( bool ) ), SLOT( onSaveToFile() ) );
310 myActions.insert( SaveToFileId, a );
314 \brief Create the context popup menu.
316 Fill in the popup menu with the commands.
318 \param menu context popup menu
320 void LogWindow::contextMenuPopup( QMenu* popup )
322 popup->addAction( myActions[ CopyId ] );
323 popup->addAction( myActions[ ClearId ] );
324 popup->addSeparator();
325 popup->addAction( myActions[ SelectAllId ] );
326 popup->addSeparator();
327 popup->addAction( myActions[ SaveToFileId ] );
329 Qtx::simplifySeparators( popup );
335 \brief Update menu actions.
337 Update context popup menu action state.
339 void LogWindow::updateActions()
341 myActions[CopyId]->setEnabled( myView->textCursor().hasSelection() );
342 myActions[ ClearId ]->setEnabled( myView->document()->blockCount() > myBannerSize );
343 myActions[SelectAllId]->setEnabled( !myView->document()->isEmpty() );
344 myActions[ SaveToFileId ]->setEnabled( myHistory.count() > 0 );
348 \brief Called when user selects "Save To File" command in the popup menu.
350 void LogWindow::onSaveToFile()
352 SUIT_Application* app = SUIT_Session::session()->activeApplication();
356 // call application-specific "Save file" dialog box
357 QString aName = app->getFileName( false, QString(), QString( "*.log" ), QString(), 0 );
358 if ( aName.isNull() )
361 QApplication::setOverrideCursor( Qt::WaitCursor );
363 bool bOk = saveLog( aName );
365 QApplication::restoreOverrideCursor();
368 SUIT_MessageBox::critical( this, tr( "ERR_ERROR" ), tr( "ERR_CANT_SAVE_FILE" ) );
372 \brief Called when user selects "Select all" command in the popup menu.
374 void LogWindow::onSelectAll()
381 \brief Called when user click "Clear" command in the popup menu.
383 void LogWindow::onClear()
389 \brief Called when user click "Copy" command in the popup menu.
391 void LogWindow::onCopy()
398 \brief Set actions to be visible in the context popup menu.
400 Actions, which IDs are set in \a flags parameter, will be shown in the
401 context popup menu. Other actions will not be shown.
403 \param flags ORed together actions flags
405 void LogWindow::setMenuActions( const int flags )
407 myActions[CopyId]->setVisible( flags & CopyId );
408 myActions[ClearId]->setVisible( flags & ClearId );
409 myActions[SelectAllId]->setVisible( flags & SelectAllId );
410 myActions[SaveToFileId]->setVisible( flags & SaveToFileId );
414 \brief Get menu actions which are currently visible in the context popup menu.
415 \return ORed together actions flags
418 int LogWindow::menuActions() const
421 ret = ret | ( myActions[CopyId]->isVisible() ? CopyId : 0 );
422 ret = ret | ( myActions[ClearId]->isVisible() ? ClearId : 0 );
423 ret = ret | ( myActions[SelectAllId]->isVisible() ? SelectAllId : 0 );
424 ret = ret | ( myActions[SaveToFileId]->isVisible() ? SaveToFileId : 0 );
429 \fn virtual QString LogWindow::popupClientType() const;
430 \brief Get popup client symbolic name, used in popup menu management system.
431 \return symbolic name