Salome HOME
Initial version
[modules/gui.git] / src / LogWindow / LogWindow.cxx
1 //  KERNEL SALOME_Event : Define event posting mechanism
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
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. 
10 // 
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. 
15 // 
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 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21
22 #include "LogWindow.h"
23
24 #include <qfile.h>
25 #include <qlayout.h>
26 #include <qaction.h>
27 #include <qpopupmenu.h>
28 #include <qtextbrowser.h>
29 #include <qapplication.h>
30
31 #include <SUIT_Tools.h>
32 #include <SUIT_FileDlg.h>
33 #include <SUIT_Session.h>
34 #include <SUIT_MessageBox.h>
35 #include <SUIT_ResourceMgr.h>
36
37 #define DEFAULT_SEPARATOR "***"
38
39 //****************************************************************
40 static QString plainText( const QString& richText )
41 {
42   QString aText = richText;
43   int startTag = aText.find('<');
44   while ( 1 ) {
45     if ( startTag < 0 )
46       break;
47     int finishTag = aText.find('>',startTag);
48     if (finishTag < 0)
49       break;
50     aText = aText.remove(startTag, finishTag-startTag+1);
51     startTag = aText.find('<');
52   }
53   return aText;
54 }
55
56 //****************************************************************
57
58 LogWindow::LogWindow( QWidget* parent )
59 : QFrame( parent ),
60 SUIT_PopupClient()
61 {
62   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
63
64   QString fntSet = resMgr ? resMgr->stringValue( "Log Window", "font", QString::null ) : QString::null;
65
66   setFont( SUIT_Tools::stringToFont( fntSet ) );
67
68   myView = new QTextBrowser(this,"myView");
69 #if QT_VERSION>0x030007
70   myView->setTextFormat( Qt::LogText );
71 #endif
72   myView->viewport()->installEventFilter( this );
73
74   QVBoxLayout* main = new QVBoxLayout( this );
75   main->addWidget( myView );
76
77   myBannerSize = 0;
78   myBanner = "<b>Message Log</b>\n********************";
79   mySeparator = DEFAULT_SEPARATOR;
80
81   clear();
82
83   createActions();
84 }
85
86 LogWindow::~LogWindow()
87 {
88 }
89
90 bool LogWindow::eventFilter( QObject* o, QEvent* e )
91 {
92   if ( o == myView->viewport() && e->type() == QEvent::ContextMenu )
93   {
94     contextMenuRequest( (QContextMenuEvent*)e );
95     return true;
96   }
97   return QFrame::eventFilter( o, e );
98 }
99
100 void LogWindow::setBanner( const QString& banner )
101 {
102   myBanner = banner;
103
104   clear( false );
105 }
106
107 void LogWindow::setSeparator( const QString& separator )
108 {
109   mySeparator = separator;
110
111   clear( false );
112 }
113
114 void LogWindow::putMessage( const QString& message, bool addSeparator )
115 {
116   myView->append( message );
117   myHistory.append( plainText( message ) );
118
119   if ( addSeparator && !mySeparator.isNull() )
120   {
121     myView->append( mySeparator );   // add separator
122     myHistory.append( plainText( mySeparator ) );
123   }
124   myView->scrollToBottom();
125 }
126
127 void LogWindow::clear( bool clearHistory )
128 {
129   myView->clear();
130   if ( clearHistory )
131     myHistory.clear();
132
133   if ( !myBanner.isEmpty() )
134   {
135     myView->append( myBanner );
136     myBannerSize = myView->paragraphs();
137   }
138   else
139     myBannerSize = 0;
140 }
141
142 bool LogWindow::saveLog( const QString& fileName )
143 {
144   QFile file( fileName );
145   if ( !file.open( IO_WriteOnly ) )
146     return false;
147
148   QTextStream stream( &file );
149
150   stream << "*****************************************"   << endl;
151   stream << "Message Log"                                 << endl;
152   stream << QDate::currentDate().toString( "dd.MM:yyyy" ) << "  ";
153   stream << QTime::currentTime().toString( "hh:mm:ss" )   << endl;
154   stream << "*****************************************"   << endl;
155
156   for ( uint i = 0; i < myHistory.count(); i++ )
157     stream << myHistory[ i ] << endl;
158
159   file.close();
160   return true;
161 }
162
163 void LogWindow::createActions()
164 {
165   QAction* a = new QAction( "", tr( "&Copy" ), 0, this );
166   a->setStatusTip( tr( "&Copy" ) );
167   connect( a, SIGNAL( activated() ), SLOT( onCopy()));
168   myActions.insert( CopyId, a );
169
170   a = new QAction( "", tr( "Clea&r" ), 0, this );
171   a->setStatusTip( tr( "Clea&r" ) );
172   connect( a, SIGNAL( activated() ), SLOT( onClear()));
173   myActions.insert( ClearId, a );
174
175   a = new QAction( "", tr( "Select &All" ), 0, this );
176   a->setStatusTip( tr( "Select &All" ) );
177   connect( a, SIGNAL( activated() ), SLOT( onSelectAll()));
178   myActions.insert( SelectAllId, a );
179
180   a = new QAction( "", tr( "&Save log to file..." ), 0, this );
181   a->setStatusTip( tr( "&Save log to file..." ) );
182   connect( a, SIGNAL( activated() ), SLOT( onSaveToFile()));
183   myActions.insert( SaveToFileId, a );
184 }
185
186 void LogWindow::contextMenuPopup( QPopupMenu* popup )
187 {
188   myActions[ CopyId ]->addTo( popup );
189   myActions[ ClearId ]->addTo( popup );
190   
191   popup->insertSeparator();
192   
193   myActions[ SelectAllId ]->addTo( popup );
194   
195   popup->insertSeparator();
196   
197   myActions[ SaveToFileId ]->addTo( popup );
198
199   updateActions();
200 }
201
202 void LogWindow::updateActions()
203 {
204   int paraFrom, paraTo, indexFrom, indexTo;
205   myView->getSelection( &paraFrom, &indexFrom, &paraTo, &indexTo );
206   bool allSelected = myView->hasSelectedText() &&
207                      !paraFrom && paraTo == myView->paragraphs() - 1 && 
208                      !indexFrom && indexTo == myView->paragraphLength( paraTo );
209   myActions[ CopyId ]->setEnabled( myView->hasSelectedText() );
210   myActions[ ClearId ]->setEnabled( myView->paragraphs() > myBannerSize );
211   myActions[ SelectAllId ]->setEnabled( !allSelected );
212   myActions[ SaveToFileId ]->setEnabled( myHistory.count() > 0 );
213 }
214
215 void LogWindow::onSaveToFile()
216 {
217   QString aUsedFilter;
218   QString aName = QFileDialog::getSaveFileName( QString::null, QString( "*.log" ), this,
219                                                 0, QString::null, &aUsedFilter );
220   if ( aName.isNull() ) 
221     return;
222
223   int aStart = aUsedFilter.find('*');
224   int aEnd = aUsedFilter.find(')', aStart + 1);
225   QString aExt = aUsedFilter.mid(aStart + 1, aEnd - aStart - 1);
226   if ( aExt.contains('*') == 0 )
227   {
228     if ( aName.contains( aExt, false ) == 0 )
229       aName += aExt;
230   }
231
232
233   if ( !aName.isNull() )
234   {
235     QApplication::setOverrideCursor( Qt::waitCursor );
236     
237     bool bOk = saveLog( aName );
238
239     QApplication::restoreOverrideCursor();
240
241     if ( !bOk )
242       SUIT_MessageBox::error1( this, tr( "Error" ), tr( "Can't save file" ), tr( "OK" ) );
243   }
244 }
245
246 void LogWindow::onSelectAll()
247 {
248   if ( myView )
249     myView->selectAll();
250 }
251
252 void LogWindow::onClear()
253 {
254   clear( false );
255 }
256
257 void LogWindow::onCopy()
258 {
259   if ( myView )
260     myView->copy();
261 }