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