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