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.h"
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>" ) )
60 static const char* const time_data[] = {
85 static const char* const close_data[] = {
110 static const char* const refresh_data[] = {
135 Creates components list
138 Registry::Components_var MakeRegistry( CORBA::ORB_var &orb )
141 const char *registryName="Registry" ;
143 SALOME_NamingService &naming = *SINGLETON_<SALOME_NamingService>::Instance() ;
144 naming.init_orb( orb ) ;
146 // Recuperation de la reference de l'objet
147 CORBA::Object_var object = 0 ;
150 SCRUTE(registryName) ;
151 object = naming.Resolve( registryName ) ;
152 if(CORBA::is_nil(object)) throw CommException( "unable to find the RegistryService" ) ;
154 catch( const ServiceUnreachable &ex )
157 exit( EXIT_FAILURE ) ;
159 catch( const CORBA::Exception &exx )
161 exit( EXIT_FAILURE ) ;
164 // Specialisation de l'objet generique
166 return Registry::Components::_narrow( object ) ;
170 Only one global registry window should exist at the moment
171 This method creates registry window if necessary and returns it
174 RegWidget* RegWidget::GetRegWidget( CORBA::ORB_var &orb , QWidget *parent, const char *name )
176 if ( !myRegWidgetPtr )
177 myRegWidgetPtr = new RegWidget( orb, parent, name );
178 return myRegWidgetPtr;
184 RegWidget::RegWidget(CORBA::ORB_var &orb, QWidget *parent, const char *name )
185 : QMainWindow( parent, name, WType_TopLevel | WDestructiveClose ),
186 _VarComponents( MakeRegistry(orb) ),
187 _clients(0), _history(0), _parent( parent ),
188 _tabWidget(0), _refresh(0), _interval(0),
189 myInfoWindow(0), myHelpWindow(0), myIntervalWindow(0)
191 QString aFile = findFile("default.png");
192 /* char* dir = getenv( "CSF_ResourcesDefaults" );
196 path = qDir.filePath( "default.png" );
198 QPixmap pm ( aFile );
202 // pixmap for buttons
203 QPixmap image_refresh ( ( const char** ) refresh_data );
204 QPixmap image_interval( ( const char** ) time_data );
205 QPixmap image_close ( ( const char** ) close_data );
207 // Buttons definition
208 QToolBar* topbar = new QToolBar( tr("Toolbar"), this );
209 setDockEnabled( topbar, DockTornOff, false );
210 setDockMenuEnabled( false );
212 _refresh = new QPushButton( tr( "Refresh" ), topbar );
213 _refresh->setIconSet( image_refresh );
214 _refresh->setFocusPolicy( NoFocus );
215 connect( _refresh, SIGNAL( clicked() ), this, SLOT( slotListeSelect() ) );
216 QToolTip::add( _refresh, "", toolTipGroup(), tr("Immediately updates list of components") );
218 /* PAL5540 - this button is needless
219 QPushButton* help = new QPushButton( tr( "Help" ), topbar );
220 connect( help, SIGNAL( clicked() ), this, SLOT( slotHelp() ) );
221 QToolTip::add( help, "", toolTipGroup(), tr("Opens Help window") );
224 _interval = new QPushButton( tr( "Interval" ), topbar );
225 _interval->setIconSet( image_interval );
226 _interval->setFocusPolicy( NoFocus );
227 connect( _interval, SIGNAL( clicked() ), this, SLOT( slotSelectRefresh() ) );
228 QToolTip::add( _interval, "", toolTipGroup(), tr("Changes refresh interval") );
230 topbar->addSeparator();
231 _close = new QPushButton( tr("Close"), topbar );
232 _close->setIconSet( image_close );
233 _close->setFocusPolicy( NoFocus );
234 connect( _close, SIGNAL( clicked() ), this, SLOT( close() ) );
235 QToolTip::add( _close, "", toolTipGroup(), tr("Closes Registry window") );
237 // Display area and associated slots definition
238 _tabWidget = new QTabWidget( this );
239 _clients = new QListView( _tabWidget );
241 _history = new QListView( _tabWidget );
244 _tabWidget->addTab( _clients, tr( "Running" ) );
245 _tabWidget->addTab( _history, tr( "History" ) );
246 connect( _tabWidget, SIGNAL( currentChanged( QWidget* )), this, SLOT( slotListeSelect() ) );
247 connect( _clients, SIGNAL( clicked( QListViewItem* ) ), this, SLOT( slotClientChanged( QListViewItem* ) ) );
248 connect( _history, SIGNAL( clicked( QListViewItem* ) ), this, SLOT( slotHistoryChanged( QListViewItem* ) ) );
249 setCentralWidget( _tabWidget );
251 // Timer definition (used to automaticaly refresh the display area)
252 _counter = new QTimer( this );
253 connect( _counter, SIGNAL( timeout() ), this, SLOT( slotListeSelect() ) );
254 myRefreshInterval = 10;
255 _counter->start( myRefreshInterval * 1000 );
259 PIXELS largeur = 800 ;
260 PIXELS hauteur = 350 ;
261 setGeometry( xpos, ypos, largeur, hauteur ) ;
263 statusBar()->message(" ");
269 RegWidget::~RegWidget()
271 MESSAGE("Debut du Destructeur");
279 bool RegWidget::eventFilter( QObject* object, QEvent* event )
282 if ( object == myHelpWindow && event->type() == QEvent::Close ) {
285 else if ( object == myInfoWindow && event->type() == QEvent::Close ) {
288 else if ( object == myIntervalWindow && event->type() == QEvent::Close ) {
289 myIntervalWindow = 0;
291 else if ( object == _clients && event->type() == QEvent::KeyPress ) {
292 QKeyEvent* ke = (QKeyEvent*)event;
293 if ( ke->key() == Key_Enter || ke->key() == Key_Return ) {
294 slotClientChanged( _clients->currentItem() );
297 else if ( object == _history && event->type() == QEvent::KeyPress ) {
298 QKeyEvent* ke = (QKeyEvent*)event;
299 if ( ke->key() == Key_Enter || ke->key() == Key_Return ) {
300 slotHistoryChanged( _history->currentItem() );
304 return QMainWindow::eventFilter( object, event );
308 Searches item in the list and returns it's index or -1 if not found
310 int RegWidget::numitem(const QString &name, const QString &pid, const QString &machine,const Registry::AllInfos *listclient)
313 for (CORBA::ULong i=0; i<listclient->length(); i++)
315 const Registry::Infos & c_info=(*listclient)[i];
316 ASSERT( c_info.name!=NULL);
318 b.setNum(int(c_info.pid));
319 if ( (name.compare(QString(c_info.name)) == 0) &&
320 (machine.compare(QString(c_info.machine)) == 0) &&
321 (pid.compare(b) == 0) )
332 Returns text, containing information about client [ static ]
334 QString RegWidget::setlongText( const Registry::Infos &c_info)
336 BEGIN_OF("setlongText");
337 ASSERT( c_info.name != NULL );
338 QString a = QString( "<hr><h2>" ) + tr( "Code" ) + QString( " : " );
339 a.append( QString( c_info.name ) );
340 a.append( "</h1><hr><br>" );
341 a.append( tr( "Process Id" ) + QString( " : " ) );
342 a.append( BOLD( QString::number( int( c_info.pid ) ) ) );
343 a.append( QString( " " ) + tr( "on machine" ) + QString( " " ) );
344 a.append( BOLD( c_info.machine ) );
345 a.append( QString( " " ) + tr( "ip address" ) + QString( " : " ) );
346 a.append( BOLD( c_info.adip ) );
349 a.append( tr( "launched by user" ) + QString( " " ) );
350 a.append( BOLD( c_info.pwname ) );
351 a.append( QString( " ( " ) + tr( "pid" ) + QString( " : " ) );
352 a.append( BOLD( QString::number( int( c_info.uid ) ) ) );
353 a.append( QString( " )<br> " ) + tr( "in directory" ) + QString( " " ));
354 a.append( BOLD( c_info.cdir ) );
357 a.append( QString( "<br>" ) + tr( "begins" ) + QString( " " ) );
358 aTime = time_t(c_info.tc_start);
359 char * t1 = (char * )duplicate(ctime(&aTime));
360 t1 [strlen(t1) -1 ] = ' ';
361 a.append( BOLD( t1 ) );
365 if (c_info.tc_hello != 0 )
367 aTime = time_t(c_info.tc_hello);
368 char * t2 = (char * )duplicate(ctime(&aTime));
369 t2 [strlen(t2) -1 ] = ' ';
370 a.append( tr( "last signal" ) + QString(" : ") );
371 a.append( BOLD( t2 ) );
375 if ((c_info.tc_end - c_info.difftime) != 0)
377 aTime = time_t(c_info.tc_end);
378 char * t3 = (char * )duplicate(ctime(&aTime));
379 t3 [strlen(t3) -1 ] = ' ';
380 a.append( tr( "ends" ) + QString( " " ) );
381 a.append( BOLD( t3 ) );
387 a.append( tr( "still running" ) + QString( "<br>" ) );
390 SCRUTE(c_info.difftime);
391 if (c_info.difftime!= 0)
393 a.append( QString( "(" ) + tr( "Time on" ) + QString( " " ) );
394 a.append( BOLD( c_info.machine ) );
395 a.append( QString( " " ) + tr( "differs from server's time. The difference is" ) + QString( " " ));
396 a.append( BOLD( QString::number( int( c_info.difftime ) ) ) );
397 a.append( QString( " " ) + tr( "seconds" ) + QString( ")<br>" ) );
399 END_OF("setlongText");
407 void RegWidget::closeEvent( QCloseEvent *e)
409 BEGIN_OF("closeEvent");
411 myInfoWindow->close();
413 myHelpWindow->close();
414 if (myIntervalWindow)
415 myIntervalWindow->close();
417 END_OF("closeEvent");
423 void RegWidget::SetListe()
425 BEGIN_OF("SetListe");
426 _clients->installEventFilter( this );
427 _clients->setAllColumnsShowFocus( true );
428 _clients->addColumn( tr( "Component" ), -1);
429 _clients->addColumn( tr( "PID" ), -1 );
430 _clients->addColumn( tr( "User Name" ), -1 );
431 _clients->addColumn( tr( "Machine" ), -1 );
432 _clients->addColumn( tr( "begins" ), -1 );
433 _clients->addColumn( tr( "hello" ) , -1 );
434 _clients->setColumnAlignment( 1, Qt::AlignRight );
441 void RegWidget::SetListeHistory()
443 BEGIN_OF("SetListeHistory")
444 _history->installEventFilter( this );
445 _history->setAllColumnsShowFocus( true );
446 _history->addColumn( tr( "Component" ), -1);
447 _history->addColumn( tr( "PID" ), -1 );
448 _history->addColumn( tr( "User Name" ), -1 );
449 _history->addColumn( tr( "Machine" ), -1 );
450 _history->addColumn( tr( "begins" ), -1 );
451 _history->addColumn( tr( "ends" ), -1 );
452 _history->setColumnAlignment( 1, Qt::AlignRight );
453 END_OF("SetListeHistory")
459 void RegWidget::InfoHistory()
462 BEGIN_OF("InfoHistory")
467 _serverhistory = _VarComponents->history();
468 for (CORBA::ULong i=0; i<_serverhistory->length(); i++)
470 const Registry::Infos & c_info=(*_serverhistory)[i];
471 ASSERT( c_info.name!=NULL);
473 a.setNum(int(c_info.pid));
474 aTime = time_t(c_info.tc_start);
475 char * t1 = (char * )duplicate(ctime(&aTime));
476 t1 [strlen(t1) -1 ] = ' ';
477 aTime = time_t(c_info.tc_end);
478 char * t2 = (char * )duplicate(ctime(&aTime));
479 t2 [strlen(t2) -1 ] = ' ';
480 QListViewItem * item = new QListViewItem(_history, QString(c_info.name),\
481 a, QString(c_info.pwname), QString(c_info.machine), \
482 QString(t1), QString(t2));
491 _interval->setDisabled( TRUE ) ;
492 _refresh->setDisabled( TRUE ) ;
494 MESSAGE("Sorry, No more Registry Server") ;
495 statusBar()->message( tr( "Sorry, No more Registry Server" ) ) ;
497 END_OF("InfoHistory")
503 void RegWidget::InfoReg()
510 _serverclients = _VarComponents->getall();
511 for (CORBA::ULong i=0; i<_serverclients->length(); i++)
513 const Registry::Infos & c_info=(*_serverclients)[i];
514 ASSERT( c_info.name!=NULL);
516 a.setNum(int(c_info.pid));
517 aTime = time_t(c_info.tc_start);
518 char * t1 = (char * )duplicate(ctime(&aTime));
519 t1 [strlen(t1) -1 ] = ' ';
520 aTime = time_t(c_info.tc_hello);
521 char * t2 = (char * )duplicate(ctime(&aTime));
522 t2 [strlen(t2) -1 ] = ' ';
523 QListViewItem * item = new QListViewItem(_clients, QString(c_info.name),\
524 a, QString(c_info.pwname), QString(c_info.machine), \
525 QString(t1), QString(t2));
534 _interval->setDisabled( TRUE ) ;
535 _refresh->setDisabled( TRUE ) ;
537 MESSAGE("Sorry, No more Registry Server") ;
538 statusBar()->message( tr( "Sorry, No more Registry Server" ) ) ;
544 Called when <Refresh> button is clicked
546 void RegWidget::slotListeSelect()
550 ASSERT(_tabWidget->currentPage() != NULL);
551 if (_tabWidget->currentPage () == _clients) InfoReg();
552 else if (_tabWidget->currentPage () == _history) InfoHistory();
556 MESSAGE("Sorry, No more Registry Server") ;
557 statusBar()->message( tr( "Sorry, No more Registry Server" ) ) ;
562 Called when <Interval> button is clicked (changing refresh interval)
564 void RegWidget::slotSelectRefresh()
566 BEGIN_OF("slotSelectRefresh");
567 myIntervalWindow = new IntervalWindow(this);
568 myIntervalWindow->installEventFilter( this );
569 myIntervalWindow->setValue(myRefreshInterval);
570 myIntervalWindow->show();
571 connect( myIntervalWindow->Cancel(), SIGNAL( clicked() ), myIntervalWindow, SLOT( close() ) );
572 connect( myIntervalWindow->Ok(), SIGNAL( clicked() ), this, SLOT( slotIntervalOk() ) );
573 END_OF("slotSelectRefresh");
577 SLOT: called when button OK is clicked in interval window
579 void RegWidget::slotIntervalOk()
581 BEGIN_OF("slotIntervalOk");
582 myRefreshInterval = myIntervalWindow->getValue();
583 _counter->changeInterval( myRefreshInterval * 1000 );
584 SCRUTE(myRefreshInterval);
585 myIntervalWindow->close();
586 END_OF("slotIntervalOk");
589 Called when <Help> button is clicked
591 void RegWidget::slotHelp()
593 BEGIN_OF("slotHelp()");
595 if ( !myHelpWindow ) {
596 myHelpWindow = new HelpWindow( this );
597 myHelpWindow->installEventFilter( this );
599 myHelpWindow->show();
600 myHelpWindow->raise();
601 myHelpWindow->setActiveWindow();
603 END_OF("slotHelp()") ;
607 Called when user clicks on item in <Running> list
609 void RegWidget::slotClientChanged( QListViewItem* item )
611 BEGIN_OF("slotClientChanged()") ;
616 blockSignals( true ); // for sure that item will not be deleted when refreshing
618 int numeroItem = numitem(item->text(0), item->text(1), item->text(3), _serverclients);
620 SCRUTE(item->text(1)) ;
622 ASSERT(numeroItem>=0) ;
623 ASSERT((size_t)numeroItem<_serverclients->length()) ;
624 const Registry::Infos & c_info=(*_serverclients)[numeroItem];
625 ASSERT( c_info.name!=NULL);
627 if ( !myInfoWindow ) {
628 myInfoWindow = new InfoWindow( this );
629 myInfoWindow->installEventFilter( this );
631 QString a = tr( "More about" ) + QString( " " ) + QString( c_info.name );
632 myInfoWindow->setCaption(a);
633 myInfoWindow->setText( RegWidget::setlongText( c_info) );
634 myInfoWindow->show();
635 myInfoWindow->raise();
636 myInfoWindow->setActiveWindow();
638 blockSignals( false ); // enabling signals again
640 END_OF("slotClientChanged()") ;
645 Called when user clicks on item in <History> list
647 void RegWidget::slotHistoryChanged( QListViewItem* item )
650 BEGIN_OF("slotHistoryChanged()") ;
655 blockSignals( true ); // for sure that item will not be deleted when refreshing
657 int numeroItem = numitem(item->text(0), item->text(1), item->text(3), _serverhistory);
660 SCRUTE(item->text(1)) ;
661 ASSERT(numeroItem>=0) ;
662 ASSERT((size_t)numeroItem<_serverhistory->length()) ;
663 const Registry::Infos & c_info=(*_serverhistory)[numeroItem];
664 ASSERT( c_info.name!=NULL);
666 if ( !myInfoWindow ) {
667 myInfoWindow = new InfoWindow( this );
668 myInfoWindow->installEventFilter( this );
670 QString a = tr( "More about" ) + QString( " " ) + QString( c_info.name );
671 myInfoWindow->setCaption(a);
672 myInfoWindow->setText( RegWidget::setlongText( c_info ) );
673 myInfoWindow->show();
674 myInfoWindow->raise();
675 myInfoWindow->setActiveWindow();
677 blockSignals( false ); // enabling signals again
679 END_OF("slotHistoryChanged()") ;
686 InfoWindow::InfoWindow( QWidget* parent, const char* name )
687 : QMainWindow( parent, name, WType_TopLevel | WDestructiveClose )
689 BEGIN_OF("InfoWindow");
690 myTextView = new QTextView( this, "myTextView" );
691 setCentralWidget( myTextView );
692 setMinimumSize( 450, 250 );
693 END_OF("InfoWindow");
699 void InfoWindow::setText( const QString& text )
701 myTextView->setText( text );
707 void InfoWindow::keyPressEvent( QKeyEvent * e )
709 QMainWindow::keyPressEvent( e );
710 if ( e->key() == Key_Escape )
714 static const char* SEPARATOR = ":";
716 QString findFile( QString filename )
721 // Try ${HOME}/.salome/resources directory
722 cenv = getenv( "HOME" );
724 dir.sprintf( "%s", cenv );
725 if ( !dir.isEmpty() ) {
726 dir = addSlash(dir) ;
727 dir = dir + ".salome" ;
728 dir = addSlash(dir) ;
729 dir = dir + "resources" ;
730 dir = addSlash(dir) ;
731 QFileInfo fileInfo( dir + filename );
732 if ( fileInfo.isFile() && fileInfo.exists() )
733 return fileInfo.filePath();
736 // Try ${SALOME_SITE_DIR}/share/salome/resources directory
737 cenv = getenv( "SALOME_SITE_DIR" );
739 dir.sprintf( "%s", cenv );
740 if ( !dir.isEmpty() ) {
741 dir = addSlash(dir) ;
742 dir = dir + "share" ;
743 dir = addSlash(dir) ;
744 cenv = getenv("SALOME_SITE_NAME");
745 if (cenv) dir = dir + cenv;
746 else dir = dir + "salome" ;
747 dir = addSlash(dir) ;
748 dir = dir + "resources" ;
749 dir = addSlash(dir) ;
750 QFileInfo fileInfo( dir + filename );
751 if ( fileInfo.isFile() && fileInfo.exists() )
752 return fileInfo.filePath();
755 // Try ${KERNEL_ROOT_DIR}/share/salome/resources directory
756 cenv = getenv( "KERNEL_ROOT_DIR" );
758 dir.sprintf( "%s", cenv );
759 if ( !dir.isEmpty() ) {
760 dir = addSlash(dir) ;
761 dir = dir + "share" ;
762 dir = addSlash(dir) ;
763 dir = dir + "salome" ;
764 dir = addSlash(dir) ;
765 dir = dir + "resources" ;
766 dir = addSlash(dir) ;
767 QFileInfo fileInfo( dir + filename );
768 if ( fileInfo.isFile() && fileInfo.exists() )
769 return fileInfo.filePath();
773 //SRN Added support for SALOMEGUI
774 cenv = getenv( "SALOMEGUI_ROOT_DIR" );
776 dir.sprintf( "%s", cenv );
777 if ( !dir.isEmpty() ) {
778 dir = addSlash(dir) ;
779 dir = dir + "share" ;
780 dir = addSlash(dir) ;
781 dir = dir + "salome" ;
782 dir = addSlash(dir) ;
783 dir = dir + "resources" ;
784 dir = addSlash(dir) ;
785 QFileInfo fileInfo( dir + filename );
786 if ( fileInfo.isFile() && fileInfo.exists() )
787 return fileInfo.filePath();
791 // Try CSF_SaloameResources env.var directory ( or directory list )
792 cenv = getenv( "CSF_SalomeResources" );
794 dir.sprintf( "%s", cenv );
795 if ( !dir.isEmpty() ) {
796 QStringList dirList = QStringList::split( SEPARATOR, dir, false ); // skip empty entries
797 for ( int i = 0; i < dirList.count(); i++ ) {
798 QFileInfo fileInfo( addSlash( dirList[ i ] ) + filename );
799 if ( fileInfo.isFile() && fileInfo.exists() )
800 return fileInfo.filePath();
806 QString addSlash( const QString& path )
808 if (!path.isNull()) {
814 if ( path.at(path.length()-1) != slash )