Salome HOME
sources v1.2
[modules/kernel.git] / src / RegistryDisplay / RegWidget.cxx
1 //  SALOME RegistryDisplay : GUI for Registry server implementation
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 //
23 //
24 //  File   : RegWidget.cxx
25 //  Author : Pascale NOYRET, EDF
26 //  Module : SALOME
27 //  $Header$
28
29 using namespace std;
30 # include <qpushbutton.h>
31 # include <qlistview.h>
32 # include <qtabwidget.h> 
33 # include <qstatusbar.h>
34 # include <qtextview.h>
35 # include <qtimer.h>
36 # include <qinputdialog.h>
37 # include <qtoolbar.h>
38 # include <qdir.h>
39 # include <qtooltip.h>
40
41 # include "SALOME_NamingService.hxx"
42 # include "ServiceUnreachable.hxx"
43 # include "Utils_SINGLETON.hxx"
44 # include "Utils_CommException.hxx"
45
46 # include "utilities.h"
47 # include "OpUtil.hxx"
48
49 # include "RegWidget.hxx"
50 # include "HelpWindow.hxx" 
51 # include "IntervalWindow.hxx"
52
53 typedef int PIXELS;
54 RegWidget* RegWidget::myRegWidgetPtr = 0;
55
56 #define BOLD( text ) ( QString( "<b>" ) + QString( text ) + QString( "</b>" ) )
57 /*!
58   Creates components list
59 */
60 Registry::Components_var MakeRegistry( CORBA::ORB_var &orb )
61 {
62
63   const char *registryName="Registry" ;
64   
65   SALOME_NamingService &naming = *SINGLETON_<SALOME_NamingService>::Instance() ;
66   naming.init_orb( orb ) ;
67   
68   // Recuperation de la reference de l'objet
69   CORBA::Object_var object = 0 ;
70   try
71     {
72       SCRUTE(registryName) ;
73       object = naming.Resolve( registryName ) ;
74       if(CORBA::is_nil(object)) throw CommException( "unable to find the RegistryService" ) ;
75     }
76   catch( const ServiceUnreachable &ex )
77     {
78       MESSAGE( ex.what() )
79       exit( EXIT_FAILURE ) ;
80     }
81   catch( const CORBA::Exception &exx )
82     {
83       exit( EXIT_FAILURE ) ;
84     }
85   
86   // Specialisation de l'objet generique
87   
88   return Registry::Components::_narrow( object ) ;
89 }
90
91 /*!
92   Only one global registry window should exist at the moment
93   This method creates registry window if necessary and returns it
94   [ static ] 
95 */
96 RegWidget* RegWidget::GetRegWidget( CORBA::ORB_var &orb , QWidget *parent, const char *name )
97 {
98   if ( !myRegWidgetPtr ) 
99     myRegWidgetPtr = new RegWidget( orb, parent, name );
100   return myRegWidgetPtr;
101 }
102
103 /*!
104   Constructor  
105 */
106 RegWidget::RegWidget(CORBA::ORB_var &orb, QWidget *parent, const char *name ) 
107      : QMainWindow( parent, name, WType_TopLevel | WDestructiveClose ),
108        _VarComponents( MakeRegistry(orb) ),
109        _clients(0), _history(0), _parent( parent ),
110        _tabWidget(0), _refresh(0), _interval(0),
111        myInfoWindow(0), myHelpWindow(0), myIntervalWindow(0)
112 {
113   char* dir = getenv( "CSF_ResourcesDefaults" );
114   QString path( "" );
115   if ( dir ) {
116     QDir qDir( dir );
117     path = qDir.filePath( "default.png" );
118   }
119   QPixmap pm ( path );
120   if ( !pm.isNull() )
121     setIcon( pm );
122
123   // Buttons definition
124   QToolBar* topbar = new QToolBar( tr("Toolbar"), this );
125   setDockEnabled( topbar, DockTornOff, false );
126   setDockMenuEnabled( false );
127
128   _refresh = new QPushButton( tr( "Refresh" ), topbar );
129   connect( _refresh, SIGNAL( clicked() ), this, SLOT( slotListeSelect() ) );
130   QToolTip::add( _refresh, "", toolTipGroup(), tr("Immediately updates list of components") );
131   
132   QPushButton* help = new QPushButton( tr( "Help" ), topbar );
133   connect( help, SIGNAL( clicked() ), this, SLOT( slotHelp() ) );
134   QToolTip::add( help, "", toolTipGroup(), tr("Opens Help window") );
135   
136   _interval = new QPushButton( tr( "Interval" ), topbar );
137   connect( _interval, SIGNAL( clicked() ), this, SLOT( slotSelectRefresh() ) );
138   QToolTip::add( _interval, "", toolTipGroup(), tr("Changes refresh interval") );
139   
140   // Display area and associated slots definition
141   _tabWidget = new QTabWidget( this );
142   _clients   = new QListView( _tabWidget );
143   SetListe();
144   _history   = new QListView( _tabWidget );
145   SetListeHistory();
146   
147   _tabWidget->addTab( _clients, tr( "Running" ) );
148   _tabWidget->addTab( _history, tr( "History" ) );
149   connect( _tabWidget, SIGNAL( currentChanged( QWidget* )), this, SLOT( slotListeSelect() ) );
150   connect( _clients,   SIGNAL( clicked( QListViewItem* ) ),        this, SLOT( slotClientChanged( QListViewItem* ) ) );
151   connect( _history,   SIGNAL( clicked( QListViewItem* ) ),        this, SLOT( slotHistoryChanged( QListViewItem* ) ) );
152   setCentralWidget( _tabWidget );
153   
154   // Timer definition (used to automaticaly refresh the display area)
155   _counter = new QTimer( this );
156   connect( _counter, SIGNAL( timeout() ), this, SLOT( slotListeSelect() ) );
157   myRefreshInterval = 10;
158   _counter->start( myRefreshInterval * 1000 );
159   
160   PIXELS xpos    = 160 ;
161   PIXELS ypos    = 100 ;
162   PIXELS largeur = 800 ;
163   PIXELS hauteur = 350 ;
164   setGeometry( xpos, ypos, largeur, hauteur ) ;
165   setCaption( name ) ;
166   statusBar()->message("    ");
167 }
168
169 /*!
170   Destructor
171 */
172 RegWidget::~RegWidget()
173 {
174   MESSAGE("Debut du Destructeur");
175   _counter->stop();
176   myRegWidgetPtr = 0;
177 };
178
179 /*!
180   Event filter
181 */
182 bool RegWidget::eventFilter( QObject* object, QEvent* event )
183 {
184   if ( object ) {
185     if ( object == myHelpWindow && event->type() == QEvent::Close ) {
186       myHelpWindow = 0;
187     }
188     else if ( object == myInfoWindow && event->type() == QEvent::Close ) {
189       myInfoWindow = 0;
190     }
191     else if ( object == myIntervalWindow && event->type() == QEvent::Close ) {
192       myIntervalWindow = 0;
193     }
194   }
195   return QMainWindow::eventFilter( object, event );
196 }
197
198 /*!
199   Searches item in the list and returns it's index or -1 if not found
200 */
201 int RegWidget::numitem(const QString &name, const QString &pid, const QString &machine,const Registry::AllInfos *listclient)
202 {
203   BEGIN_OF("numitem");
204   for (CORBA::ULong i=0; i<listclient->length(); i++)
205     {       
206       const Registry::Infos & c_info=(*listclient)[i];
207       ASSERT( c_info.name!=NULL);
208       QString b;
209       b.setNum(int(c_info.pid));
210       if ( (name.compare(QString(c_info.name)) == 0) && 
211           (machine.compare(QString(c_info.machine)) == 0) && 
212           (pid.compare(b) == 0) )
213         {
214           END_OF("numitem");
215           return i;
216         }
217     }
218   END_OF("numitem");
219   return -1;
220 }
221
222 /*!
223   Returns text, containing information about client [ static ]
224 */
225 QString RegWidget::setlongText( const Registry::Infos &c_info)
226 {
227   BEGIN_OF("setlongText");
228   ASSERT( c_info.name != NULL );
229   QString a = QString( "<hr><h2>" ) + tr( "Code" ) + QString( " : " );
230   a.append( QString( c_info.name ) );
231   a.append( "</h1><hr><br>" );
232   a.append( tr( "Process Id" ) + QString( " : " ) );
233   a.append( BOLD( QString::number( int( c_info.pid ) ) ) );
234   a.append( QString( " " ) + tr( "on machine" ) + QString( " " ) );
235   a.append( BOLD( c_info.machine ) ); 
236   a.append( QString( " " ) + tr( "ip address" ) + QString( " : " ) );
237   a.append( BOLD( c_info.adip ) );
238   a.append( "<br>" );
239   
240   a.append( tr( "launched by user" ) + QString( " " ) );
241   a.append( BOLD( c_info.pwname ) );
242   a.append( QString( " ( " ) + tr( "pid" ) + QString( " : " ) );
243   a.append( BOLD( QString::number( int( c_info.uid ) ) ) );
244   a.append( QString( " )<br> " ) + tr( "in directory" ) + QString( " " ));
245   a.append( BOLD( c_info.cdir ) );
246   
247   a.append( QString( "<br>" ) + tr( "begins" ) + QString( " " ) );
248   char * t1 = (char * )duplicate(ctime(&c_info.tc_start));
249   t1 [strlen(t1) -1 ] = ' ';
250   a.append( BOLD( t1 ) ); 
251   delete [] t1;
252   a.append( "<br>" );
253   
254   if (c_info.tc_hello != 0 )
255     {
256       char * t2 = (char * )duplicate(ctime(&c_info.tc_hello));
257       t2 [strlen(t2) -1 ] = ' ';
258       a.append( tr( "last signal" ) + QString(" : ") ); 
259       a.append( BOLD( t2 ) ); 
260       a.append( "<br>" );
261       delete [] t2;
262     }
263   if ((c_info.tc_end - c_info.difftime) != 0)
264     {
265       char * t3 = (char * )duplicate(ctime(&c_info.tc_end));
266       t3 [strlen(t3) -1 ] = ' ';
267       a.append( tr( "ends" ) + QString( " " ) ); 
268       a.append( BOLD( t3 ) ); 
269       a.append( "<br>" );
270       delete [] t3;
271     }
272   else
273     {
274       a.append( tr( "still running" ) + QString( "<br>" ) );
275     }
276   
277   SCRUTE(c_info.difftime);
278   if (c_info.difftime!= 0)
279     {
280       a.append( QString( "(" ) + tr( "Time on" ) + QString( " " ) ); 
281       a.append( BOLD( c_info.machine ) ); 
282       a.append( QString( " " ) + tr( "differs from server's time. The difference is" ) + QString( " " )); 
283       a.append( BOLD( QString::number( int( c_info.difftime ) ) ) );
284       a.append( QString( " " ) + tr( "seconds" ) + QString( ")<br>" ) );
285     }
286   END_OF("setlongText");  
287   return a;
288   
289 }
290
291 /*!
292   Close event
293 */
294 void RegWidget::closeEvent( QCloseEvent *e)
295 {
296   BEGIN_OF("closeEvent");
297   if ( myInfoWindow )
298     myInfoWindow->close();
299   if ( myHelpWindow )
300     myHelpWindow->close();
301   if (myIntervalWindow)
302     myIntervalWindow->close();
303   e->accept();
304   END_OF("closeEvent");
305 };
306
307 /*!
308   Setups Clients list
309 */
310 void RegWidget::SetListe()
311 {
312   BEGIN_OF("SetListe");
313   _clients->addColumn( tr( "Component" ), -1);
314   _clients->addColumn( tr( "PID" ), -1 );
315   _clients->addColumn( tr( "User Name" ), -1 );
316   _clients->addColumn( tr( "Machine" ), -1 );
317   _clients->addColumn( tr( "begins" ), -1 );
318   _clients->addColumn( tr( "hello" ) , -1 );
319   _clients->setColumnAlignment( 1, Qt::AlignRight );
320   END_OF("SetListe");
321 }
322
323 /*!
324   Setups History list
325 */
326 void RegWidget::SetListeHistory()
327 {
328    BEGIN_OF("SetListeHistory")
329   _history->addColumn( tr( "Component" ), -1);
330   _history->addColumn( tr( "PID" ), -1 );
331   _history->addColumn( tr( "User Name" ), -1 );
332   _history->addColumn( tr( "Machine" ), -1 );
333   _history->addColumn( tr( "begins" ), -1 );
334   _history->addColumn( tr( "ends" ), -1 );
335   _history->setColumnAlignment( 1, Qt::AlignRight );
336    END_OF("SetListeHistory")
337 }
338
339 /*!
340   Updates History list
341 */
342 void RegWidget::InfoHistory()
343 {
344
345   BEGIN_OF("InfoHistory")
346     _history->clear();
347   try
348     {
349       _serverhistory = _VarComponents->history();
350       for (CORBA::ULong i=0; i<_serverhistory->length(); i++)
351         {       
352           const Registry::Infos & c_info=(*_serverhistory)[i];
353           ASSERT( c_info.name!=NULL);
354           QString a;
355           a.setNum(int(c_info.pid));
356           char * t1 = (char * )duplicate(ctime(&c_info.tc_start));
357           t1 [strlen(t1) -1 ] = ' ';
358           char * t2 = (char * )duplicate(ctime(&c_info.tc_end));
359           t2 [strlen(t2) -1 ] = ' ';
360           QListViewItem * item = new QListViewItem(_history, QString(c_info.name),\
361                                                    a, QString(c_info.pwname), QString(c_info.machine), \
362                                                    QString(t1), QString(t2));
363           item=0 ;
364           delete [] t1;
365           delete [] t2;
366           
367         }
368     }
369   catch( ... )
370     {
371       _interval->setDisabled( TRUE ) ;
372       _refresh->setDisabled( TRUE ) ;
373       _counter->stop();
374       MESSAGE("Sorry, No more Registry Server") ;
375       statusBar()->message( tr( "Sorry, No more Registry Server" ) ) ;
376     }
377   END_OF("InfoHistory")
378 }
379
380 /*!
381   Updates clients list
382 */
383 void RegWidget::InfoReg()
384 {
385   BEGIN_OF("InfoReg")
386   _clients->clear();
387   try
388     {
389       _serverclients = _VarComponents->getall();
390       for (CORBA::ULong i=0; i<_serverclients->length(); i++)
391         {       
392           const Registry::Infos & c_info=(*_serverclients)[i];
393           ASSERT( c_info.name!=NULL);
394           QString a;
395           a.setNum(int(c_info.pid));
396           char * t1 = (char * )duplicate(ctime(&c_info.tc_start));
397           t1 [strlen(t1) -1 ] = ' ';
398           char * t2 = (char * )duplicate(ctime(&c_info.tc_hello));
399           t2 [strlen(t2) -1 ] = ' ';
400           QListViewItem * item = new QListViewItem(_clients, QString(c_info.name),\
401                                                    a, QString(c_info.pwname), QString(c_info.machine), \
402                                                    QString(t1), QString(t2));
403           item=0 ;
404           delete [] t1;
405           delete [] t2;
406           
407         }
408     }
409   catch( ... )
410     {
411       _interval->setDisabled( TRUE ) ;
412       _refresh->setDisabled( TRUE ) ;
413       _counter->stop();
414       MESSAGE("Sorry, No more Registry Server") ;
415       statusBar()->message( tr( "Sorry, No more Registry Server" ) ) ;
416     }
417   END_OF("InfoReg")
418 }
419
420 /*!
421   Called when <Refresh> button is clicked
422 */
423 void RegWidget::slotListeSelect()
424 {
425   try
426     {
427       ASSERT(_tabWidget->currentPage() != NULL);
428       if (_tabWidget->currentPage () == _clients) InfoReg();
429       else if (_tabWidget->currentPage () == _history) InfoHistory();
430     }
431   catch( ... )
432     {
433       MESSAGE("Sorry, No more Registry Server") ;
434       statusBar()->message( tr( "Sorry, No more Registry Server" ) ) ;
435     }
436 }
437
438 /*!
439   Called when <Interval> button is clicked (changing refresh interval)
440 */
441 void RegWidget::slotSelectRefresh()
442 {
443   BEGIN_OF("slotSelectRefresh");
444   myIntervalWindow = new IntervalWindow(this);
445   myIntervalWindow->installEventFilter( this );
446   myIntervalWindow->setValue(myRefreshInterval);
447   myIntervalWindow->show();
448   connect( myIntervalWindow->Cancel(), SIGNAL( clicked() ), myIntervalWindow, SLOT( reject() ) );
449   connect( myIntervalWindow->Ok(), SIGNAL( clicked() ), this, SLOT( slotIntervalOk() ) );
450   END_OF("slotSelectRefresh");
451 }
452
453 void RegWidget::slotIntervalOk()
454 {
455   BEGIN_OF("slotIntervalOk");
456   myRefreshInterval = myIntervalWindow->getValue();
457   _counter->changeInterval( myRefreshInterval * 1000 );
458   SCRUTE(myRefreshInterval);
459   myIntervalWindow->close();
460   END_OF("slotIntervalOk");
461 }
462 /*!
463   Called when <Help> button is clicked
464 */
465 void RegWidget::slotHelp()
466 {
467   BEGIN_OF("slotHelp()");
468
469   if ( !myHelpWindow ) {
470     myHelpWindow  = new HelpWindow( this );
471     myHelpWindow->installEventFilter( this );
472   }
473   myHelpWindow->show();
474   myHelpWindow->raise();
475   myHelpWindow->setActiveWindow();
476   
477   END_OF("slotHelp()") ;
478 }
479
480 /*!
481   Called when user clicks on item in <Running> list
482 */
483 void RegWidget::slotClientChanged( QListViewItem* item )
484 {
485   BEGIN_OF("slotClientChanged()") ;
486
487   if ( item <= 0)
488     return;
489
490   blockSignals( true ); // for sure that item will not be deleted when refreshing
491
492   int numeroItem = numitem(item->text(0), item->text(1), item->text(3), _serverclients);
493   SCRUTE(numeroItem) ;
494   SCRUTE(item->text(1)) ;
495   
496   ASSERT(numeroItem>=0) ;
497   ASSERT((size_t)numeroItem<_serverclients->length()) ;
498   const Registry::Infos & c_info=(*_serverclients)[numeroItem];
499   ASSERT( c_info.name!=NULL);
500   
501   if ( !myInfoWindow ) {
502     myInfoWindow  = new InfoWindow( this );
503     myInfoWindow->installEventFilter( this );
504   }
505   QString a = tr( "More about" ) + QString( " " ) + QString( c_info.name );
506   myInfoWindow->setCaption(a);
507   myInfoWindow->setText( RegWidget::setlongText( c_info) );
508   myInfoWindow->show();
509   myInfoWindow->raise();
510   myInfoWindow->setActiveWindow();
511
512   blockSignals( false ); // enabling signals again
513
514   END_OF("slotClientChanged()") ;
515   return ;
516 }
517
518 /*!
519   Called when user clicks on item in <History> list
520 */
521 void RegWidget::slotHistoryChanged( QListViewItem* item )
522 {
523
524   BEGIN_OF("slotHistoryChanged()") ;
525   
526   if ( item <= 0)
527     return;
528
529   blockSignals( true ); // for sure that item will not be deleted when refreshing
530
531   int numeroItem = numitem(item->text(0), item->text(1), item->text(3), _serverhistory);
532   
533   SCRUTE(numeroItem) ;
534   SCRUTE(item->text(1)) ;
535   ASSERT(numeroItem>=0) ;
536   ASSERT((size_t)numeroItem<_serverhistory->length()) ;
537   const Registry::Infos & c_info=(*_serverhistory)[numeroItem];
538   ASSERT( c_info.name!=NULL);
539   
540   if ( !myInfoWindow ) {
541     myInfoWindow  = new InfoWindow( this );
542     myInfoWindow->installEventFilter( this );
543   }
544   QString a = tr( "More about" ) + QString( " " ) + QString( c_info.name );
545   myInfoWindow->setCaption(a);
546   myInfoWindow->setText( RegWidget::setlongText( c_info ) );
547   myInfoWindow->show();
548   myInfoWindow->raise();
549   myInfoWindow->setActiveWindow();
550
551   blockSignals( false ); // enabling signals again
552
553   END_OF("slotHistoryChanged()") ;
554   return ;
555 }
556
557 /*!
558   Constructor
559 */
560 InfoWindow::InfoWindow( QWidget* parent, const char* name )
561      : QMainWindow( parent, name, WType_TopLevel | WDestructiveClose )
562 {
563   BEGIN_OF("InfoWindow");
564   myTextView = new QTextView( this, "myTextView" );
565   setCentralWidget( myTextView );
566   setMinimumSize( 450, 250 );
567   END_OF("InfoWindow");
568 }
569
570 /*!
571   Sets text
572 */
573 void InfoWindow::setText( const QString& text )
574 {
575   myTextView->setText( text );
576 }