1 // SALOME RegistryDisplay : GUI for Registry server implementation
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : RegWidget.cxx
25 // Author : Pascale NOYRET, EDF
29 # include <qpushbutton.h>
30 # include <qlistview.h>
31 # include <qtabwidget.h>
32 # include <qstatusbar.h>
33 # include <qtextview.h>
35 # include <qinputdialog.h>
36 # include <qtoolbar.h>
38 # include <qtooltip.h>
40 # include "SALOME_NamingService.hxx"
41 # include "ServiceUnreachable.hxx"
42 # include "Utils_SINGLETON.hxx"
43 # include "Utils_CommException.hxx"
45 # include "utilities.h"
46 # include "OpUtil.hxx"
48 # include "RegWidget.hxx"
49 # include "HelpWindow.hxx"
50 # include "IntervalWindow.hxx"
54 RegWidget* RegWidget::myRegWidgetPtr = 0;
55 QString addSlash( const QString& );
56 QString findFile( QString filename );
58 #define BOLD( text ) ( QString( "<b>" ) + QString( text ) + QString( "</b>" ) )
61 Creates components list
64 Registry::Components_var MakeRegistry( CORBA::ORB_var &orb )
67 const char *registryName="Registry" ;
69 SALOME_NamingService &naming = *SINGLETON_<SALOME_NamingService>::Instance() ;
70 naming.init_orb( orb ) ;
72 // Recuperation de la reference de l'objet
73 CORBA::Object_var object = 0 ;
76 SCRUTE(registryName) ;
77 object = naming.Resolve( registryName ) ;
78 if(CORBA::is_nil(object)) throw CommException( "unable to find the RegistryService" ) ;
80 catch( const ServiceUnreachable &ex )
83 exit( EXIT_FAILURE ) ;
85 catch( const CORBA::Exception &exx )
87 exit( EXIT_FAILURE ) ;
90 // Specialisation de l'objet generique
92 return Registry::Components::_narrow( object ) ;
96 Only one global registry window should exist at the moment
97 This method creates registry window if necessary and returns it
100 RegWidget* RegWidget::GetRegWidget( CORBA::ORB_var &orb , QWidget *parent, const char *name )
102 if ( !myRegWidgetPtr )
103 myRegWidgetPtr = new RegWidget( orb, parent, name );
104 return myRegWidgetPtr;
110 RegWidget::RegWidget(CORBA::ORB_var &orb, QWidget *parent, const char *name )
111 : QMainWindow( parent, name, WType_TopLevel | WDestructiveClose ),
112 _VarComponents( MakeRegistry(orb) ),
113 _clients(0), _history(0), _parent( parent ),
114 _tabWidget(0), _refresh(0), _interval(0),
115 myInfoWindow(0), myHelpWindow(0), myIntervalWindow(0)
117 QString aFile = findFile("default.png");
118 /* char* dir = getenv( "CSF_ResourcesDefaults" );
122 path = qDir.filePath( "default.png" );
124 QPixmap pm ( aFile );
128 // Buttons definition
129 QToolBar* topbar = new QToolBar( tr("Toolbar"), this );
130 setDockEnabled( topbar, DockTornOff, false );
131 setDockMenuEnabled( false );
133 _refresh = new QPushButton( tr( "Refresh" ), topbar );
134 connect( _refresh, SIGNAL( clicked() ), this, SLOT( slotListeSelect() ) );
135 QToolTip::add( _refresh, "", toolTipGroup(), tr("Immediately updates list of components") );
137 /* PAL5540 - this button is needless
138 QPushButton* help = new QPushButton( tr( "Help" ), topbar );
139 connect( help, SIGNAL( clicked() ), this, SLOT( slotHelp() ) );
140 QToolTip::add( help, "", toolTipGroup(), tr("Opens Help window") );
143 _interval = new QPushButton( tr( "Interval" ), topbar );
144 connect( _interval, SIGNAL( clicked() ), this, SLOT( slotSelectRefresh() ) );
145 QToolTip::add( _interval, "", toolTipGroup(), tr("Changes refresh interval") );
147 // Display area and associated slots definition
148 _tabWidget = new QTabWidget( this );
149 _clients = new QListView( _tabWidget );
151 _history = new QListView( _tabWidget );
154 _tabWidget->addTab( _clients, tr( "Running" ) );
155 _tabWidget->addTab( _history, tr( "History" ) );
156 connect( _tabWidget, SIGNAL( currentChanged( QWidget* )), this, SLOT( slotListeSelect() ) );
157 connect( _clients, SIGNAL( clicked( QListViewItem* ) ), this, SLOT( slotClientChanged( QListViewItem* ) ) );
158 connect( _history, SIGNAL( clicked( QListViewItem* ) ), this, SLOT( slotHistoryChanged( QListViewItem* ) ) );
159 setCentralWidget( _tabWidget );
161 // Timer definition (used to automaticaly refresh the display area)
162 _counter = new QTimer( this );
163 connect( _counter, SIGNAL( timeout() ), this, SLOT( slotListeSelect() ) );
164 myRefreshInterval = 10;
165 _counter->start( myRefreshInterval * 1000 );
169 PIXELS largeur = 800 ;
170 PIXELS hauteur = 350 ;
171 setGeometry( xpos, ypos, largeur, hauteur ) ;
173 statusBar()->message(" ");
179 RegWidget::~RegWidget()
181 MESSAGE("Debut du Destructeur");
189 bool RegWidget::eventFilter( QObject* object, QEvent* event )
192 if ( object == myHelpWindow && event->type() == QEvent::Close ) {
195 else if ( object == myInfoWindow && event->type() == QEvent::Close ) {
198 else if ( object == myIntervalWindow && event->type() == QEvent::Close ) {
199 myIntervalWindow = 0;
202 return QMainWindow::eventFilter( object, event );
206 Searches item in the list and returns it's index or -1 if not found
208 int RegWidget::numitem(const QString &name, const QString &pid, const QString &machine,const Registry::AllInfos *listclient)
211 for (CORBA::ULong i=0; i<listclient->length(); i++)
213 const Registry::Infos & c_info=(*listclient)[i];
214 ASSERT( c_info.name!=NULL);
216 b.setNum(int(c_info.pid));
217 if ( (name.compare(QString(c_info.name)) == 0) &&
218 (machine.compare(QString(c_info.machine)) == 0) &&
219 (pid.compare(b) == 0) )
230 Returns text, containing information about client [ static ]
232 QString RegWidget::setlongText( const Registry::Infos &c_info)
234 BEGIN_OF("setlongText");
235 ASSERT( c_info.name != NULL );
236 QString a = QString( "<hr><h2>" ) + tr( "Code" ) + QString( " : " );
237 a.append( QString( c_info.name ) );
238 a.append( "</h1><hr><br>" );
239 a.append( tr( "Process Id" ) + QString( " : " ) );
240 a.append( BOLD( QString::number( int( c_info.pid ) ) ) );
241 a.append( QString( " " ) + tr( "on machine" ) + QString( " " ) );
242 a.append( BOLD( c_info.machine ) );
243 a.append( QString( " " ) + tr( "ip address" ) + QString( " : " ) );
244 a.append( BOLD( c_info.adip ) );
247 a.append( tr( "launched by user" ) + QString( " " ) );
248 a.append( BOLD( c_info.pwname ) );
249 a.append( QString( " ( " ) + tr( "pid" ) + QString( " : " ) );
250 a.append( BOLD( QString::number( int( c_info.uid ) ) ) );
251 a.append( QString( " )<br> " ) + tr( "in directory" ) + QString( " " ));
252 a.append( BOLD( c_info.cdir ) );
254 a.append( QString( "<br>" ) + tr( "begins" ) + QString( " " ) );
255 char * t1 = (char * )duplicate(ctime(&c_info.tc_start));
256 t1 [strlen(t1) -1 ] = ' ';
257 a.append( BOLD( t1 ) );
261 if (c_info.tc_hello != 0 )
263 char * t2 = (char * )duplicate(ctime(&c_info.tc_hello));
264 t2 [strlen(t2) -1 ] = ' ';
265 a.append( tr( "last signal" ) + QString(" : ") );
266 a.append( BOLD( t2 ) );
270 if ((c_info.tc_end - c_info.difftime) != 0)
272 char * t3 = (char * )duplicate(ctime(&c_info.tc_end));
273 t3 [strlen(t3) -1 ] = ' ';
274 a.append( tr( "ends" ) + QString( " " ) );
275 a.append( BOLD( t3 ) );
281 a.append( tr( "still running" ) + QString( "<br>" ) );
284 SCRUTE(c_info.difftime);
285 if (c_info.difftime!= 0)
287 a.append( QString( "(" ) + tr( "Time on" ) + QString( " " ) );
288 a.append( BOLD( c_info.machine ) );
289 a.append( QString( " " ) + tr( "differs from server's time. The difference is" ) + QString( " " ));
290 a.append( BOLD( QString::number( int( c_info.difftime ) ) ) );
291 a.append( QString( " " ) + tr( "seconds" ) + QString( ")<br>" ) );
293 END_OF("setlongText");
301 void RegWidget::closeEvent( QCloseEvent *e)
303 BEGIN_OF("closeEvent");
305 myInfoWindow->close();
307 myHelpWindow->close();
308 if (myIntervalWindow)
309 myIntervalWindow->close();
311 END_OF("closeEvent");
317 void RegWidget::SetListe()
319 BEGIN_OF("SetListe");
320 _clients->addColumn( tr( "Component" ), -1);
321 _clients->addColumn( tr( "PID" ), -1 );
322 _clients->addColumn( tr( "User Name" ), -1 );
323 _clients->addColumn( tr( "Machine" ), -1 );
324 _clients->addColumn( tr( "begins" ), -1 );
325 _clients->addColumn( tr( "hello" ) , -1 );
326 _clients->setColumnAlignment( 1, Qt::AlignRight );
333 void RegWidget::SetListeHistory()
335 BEGIN_OF("SetListeHistory")
336 _history->addColumn( tr( "Component" ), -1);
337 _history->addColumn( tr( "PID" ), -1 );
338 _history->addColumn( tr( "User Name" ), -1 );
339 _history->addColumn( tr( "Machine" ), -1 );
340 _history->addColumn( tr( "begins" ), -1 );
341 _history->addColumn( tr( "ends" ), -1 );
342 _history->setColumnAlignment( 1, Qt::AlignRight );
343 END_OF("SetListeHistory")
349 void RegWidget::InfoHistory()
352 BEGIN_OF("InfoHistory")
356 _serverhistory = _VarComponents->history();
357 for (CORBA::ULong i=0; i<_serverhistory->length(); i++)
359 const Registry::Infos & c_info=(*_serverhistory)[i];
360 ASSERT( c_info.name!=NULL);
362 a.setNum(int(c_info.pid));
363 char * t1 = (char * )duplicate(ctime(&c_info.tc_start));
364 t1 [strlen(t1) -1 ] = ' ';
365 char * t2 = (char * )duplicate(ctime(&c_info.tc_end));
366 t2 [strlen(t2) -1 ] = ' ';
367 QListViewItem * item = new QListViewItem(_history, QString(c_info.name),\
368 a, QString(c_info.pwname), QString(c_info.machine), \
369 QString(t1), QString(t2));
378 _interval->setDisabled( TRUE ) ;
379 _refresh->setDisabled( TRUE ) ;
381 MESSAGE("Sorry, No more Registry Server") ;
382 statusBar()->message( tr( "Sorry, No more Registry Server" ) ) ;
384 END_OF("InfoHistory")
390 void RegWidget::InfoReg()
396 _serverclients = _VarComponents->getall();
397 for (CORBA::ULong i=0; i<_serverclients->length(); i++)
399 const Registry::Infos & c_info=(*_serverclients)[i];
400 ASSERT( c_info.name!=NULL);
402 a.setNum(int(c_info.pid));
403 char * t1 = (char * )duplicate(ctime(&c_info.tc_start));
404 t1 [strlen(t1) -1 ] = ' ';
405 char * t2 = (char * )duplicate(ctime(&c_info.tc_hello));
406 t2 [strlen(t2) -1 ] = ' ';
407 QListViewItem * item = new QListViewItem(_clients, QString(c_info.name),\
408 a, QString(c_info.pwname), QString(c_info.machine), \
409 QString(t1), QString(t2));
418 _interval->setDisabled( TRUE ) ;
419 _refresh->setDisabled( TRUE ) ;
421 MESSAGE("Sorry, No more Registry Server") ;
422 statusBar()->message( tr( "Sorry, No more Registry Server" ) ) ;
428 Called when <Refresh> button is clicked
430 void RegWidget::slotListeSelect()
434 ASSERT(_tabWidget->currentPage() != NULL);
435 if (_tabWidget->currentPage () == _clients) InfoReg();
436 else if (_tabWidget->currentPage () == _history) InfoHistory();
440 MESSAGE("Sorry, No more Registry Server") ;
441 statusBar()->message( tr( "Sorry, No more Registry Server" ) ) ;
446 Called when <Interval> button is clicked (changing refresh interval)
448 void RegWidget::slotSelectRefresh()
450 BEGIN_OF("slotSelectRefresh");
451 myIntervalWindow = new IntervalWindow(this);
452 myIntervalWindow->installEventFilter( this );
453 myIntervalWindow->setValue(myRefreshInterval);
454 myIntervalWindow->show();
455 connect( myIntervalWindow->Cancel(), SIGNAL( clicked() ), myIntervalWindow, SLOT( close() ) );
456 connect( myIntervalWindow->Ok(), SIGNAL( clicked() ), this, SLOT( slotIntervalOk() ) );
457 END_OF("slotSelectRefresh");
460 void RegWidget::slotIntervalOk()
462 BEGIN_OF("slotIntervalOk");
463 myRefreshInterval = myIntervalWindow->getValue();
464 _counter->changeInterval( myRefreshInterval * 1000 );
465 SCRUTE(myRefreshInterval);
466 myIntervalWindow->close();
467 END_OF("slotIntervalOk");
470 Called when <Help> button is clicked
472 void RegWidget::slotHelp()
474 BEGIN_OF("slotHelp()");
476 if ( !myHelpWindow ) {
477 myHelpWindow = new HelpWindow( this );
478 myHelpWindow->installEventFilter( this );
480 myHelpWindow->show();
481 myHelpWindow->raise();
482 myHelpWindow->setActiveWindow();
484 END_OF("slotHelp()") ;
488 Called when user clicks on item in <Running> list
490 void RegWidget::slotClientChanged( QListViewItem* item )
492 BEGIN_OF("slotClientChanged()") ;
497 blockSignals( true ); // for sure that item will not be deleted when refreshing
499 int numeroItem = numitem(item->text(0), item->text(1), item->text(3), _serverclients);
501 SCRUTE(item->text(1)) ;
503 ASSERT(numeroItem>=0) ;
504 ASSERT((size_t)numeroItem<_serverclients->length()) ;
505 const Registry::Infos & c_info=(*_serverclients)[numeroItem];
506 ASSERT( c_info.name!=NULL);
508 if ( !myInfoWindow ) {
509 myInfoWindow = new InfoWindow( this );
510 myInfoWindow->installEventFilter( this );
512 QString a = tr( "More about" ) + QString( " " ) + QString( c_info.name );
513 myInfoWindow->setCaption(a);
514 myInfoWindow->setText( RegWidget::setlongText( c_info) );
515 myInfoWindow->show();
516 myInfoWindow->raise();
517 myInfoWindow->setActiveWindow();
519 blockSignals( false ); // enabling signals again
521 END_OF("slotClientChanged()") ;
526 Called when user clicks on item in <History> list
528 void RegWidget::slotHistoryChanged( QListViewItem* item )
531 BEGIN_OF("slotHistoryChanged()") ;
536 blockSignals( true ); // for sure that item will not be deleted when refreshing
538 int numeroItem = numitem(item->text(0), item->text(1), item->text(3), _serverhistory);
541 SCRUTE(item->text(1)) ;
542 ASSERT(numeroItem>=0) ;
543 ASSERT((size_t)numeroItem<_serverhistory->length()) ;
544 const Registry::Infos & c_info=(*_serverhistory)[numeroItem];
545 ASSERT( c_info.name!=NULL);
547 if ( !myInfoWindow ) {
548 myInfoWindow = new InfoWindow( this );
549 myInfoWindow->installEventFilter( this );
551 QString a = tr( "More about" ) + QString( " " ) + QString( c_info.name );
552 myInfoWindow->setCaption(a);
553 myInfoWindow->setText( RegWidget::setlongText( c_info ) );
554 myInfoWindow->show();
555 myInfoWindow->raise();
556 myInfoWindow->setActiveWindow();
558 blockSignals( false ); // enabling signals again
560 END_OF("slotHistoryChanged()") ;
567 InfoWindow::InfoWindow( QWidget* parent, const char* name )
568 : QMainWindow( parent, name, WType_TopLevel | WDestructiveClose )
570 BEGIN_OF("InfoWindow");
571 myTextView = new QTextView( this, "myTextView" );
572 setCentralWidget( myTextView );
573 setMinimumSize( 450, 250 );
574 END_OF("InfoWindow");
580 void InfoWindow::setText( const QString& text )
582 myTextView->setText( text );
585 static const char* SEPARATOR = ":";
587 QString findFile( QString filename )
592 // Try ${HOME}/.salome/resources directory
593 cenv = getenv( "HOME" );
595 dir.sprintf( "%s", cenv );
596 if ( !dir.isEmpty() ) {
597 dir = addSlash(dir) ;
598 dir = dir + ".salome" ;
599 dir = addSlash(dir) ;
600 dir = dir + "resources" ;
601 dir = addSlash(dir) ;
602 QFileInfo fileInfo( dir + filename );
603 if ( fileInfo.isFile() && fileInfo.exists() )
604 return fileInfo.filePath();
607 // Try ${SALOME_SITE_DIR}/share/salome/resources directory
608 cenv = getenv( "SALOME_SITE_DIR" );
610 dir.sprintf( "%s", cenv );
611 if ( !dir.isEmpty() ) {
612 dir = addSlash(dir) ;
613 dir = dir + "share" ;
614 dir = addSlash(dir) ;
615 cenv = getenv("SALOME_SITE_NAME");
616 if (cenv) dir = dir + cenv;
617 else dir = dir + "salome" ;
618 dir = addSlash(dir) ;
619 dir = dir + "resources" ;
620 dir = addSlash(dir) ;
621 QFileInfo fileInfo( dir + filename );
622 if ( fileInfo.isFile() && fileInfo.exists() )
623 return fileInfo.filePath();
626 // Try ${KERNEL_ROOT_DIR}/share/salome/resources directory
627 cenv = getenv( "KERNEL_ROOT_DIR" );
629 dir.sprintf( "%s", cenv );
630 if ( !dir.isEmpty() ) {
631 dir = addSlash(dir) ;
632 dir = dir + "share" ;
633 dir = addSlash(dir) ;
634 dir = dir + "salome" ;
635 dir = addSlash(dir) ;
636 dir = dir + "resources" ;
637 dir = addSlash(dir) ;
638 QFileInfo fileInfo( dir + filename );
639 if ( fileInfo.isFile() && fileInfo.exists() )
640 return fileInfo.filePath();
643 // Try CSF_SaloameResources env.var directory ( or directory list )
644 cenv = getenv( "CSF_SalomeResources" );
646 dir.sprintf( "%s", cenv );
647 if ( !dir.isEmpty() ) {
648 QStringList dirList = QStringList::split( SEPARATOR, dir, false ); // skip empty entries
649 for ( int i = 0; i < dirList.count(); i++ ) {
650 QFileInfo fileInfo( addSlash( dirList[ i ] ) + filename );
651 if ( fileInfo.isFile() && fileInfo.exists() )
652 return fileInfo.filePath();
658 QString addSlash( const QString& path )
660 if (!path.isNull()) {
666 if ( path.at(path.length()-1) != slash )