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