Salome HOME
d9c62a9bf4b6b041d8ad828df238cb02cf76e24f
[modules/gui.git] / src / TOOLSGUI / ToolsGUI_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.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 //
24 //  File   : ToolsGUI_RegWidget.cxx
25 //  Author : Pascale NOYRET, EDF
26 //  Module : SALOME
27 //  $Header$
28
29 # include <qpushbutton.h>
30 # include <qlistview.h>
31 # include <qtabwidget.h> 
32 # include <qstatusbar.h>
33 # include <qtextview.h>
34 # include <qtimer.h>
35 # include <qinputdialog.h>
36 # include <qtoolbar.h>
37 # include <qdir.h>
38 # include <qtooltip.h>
39
40 # include "SALOME_NamingService.hxx"
41 # include "ServiceUnreachable.hxx"
42 # include "Utils_SINGLETON.hxx"
43 # include "Utils_CommException.hxx"
44
45 # include "utilities.h"
46 # include "OpUtil.hxx"
47
48 # include "ToolsGUI_RegWidget.h"
49 # include "ToolsGUI_HelpWindow.h"
50 # include "ToolsGUI_IntervalWindow.h"
51
52 # include "Qtx.h"
53
54 using namespace std;
55
56 typedef int PIXELS;
57 ToolsGUI_RegWidget* ToolsGUI_RegWidget::myRegWidgetPtr = 0;
58
59 QString addSlash( const QString& );
60 QString findFile( QString filename );
61
62 #define BOLD( text ) ( QString( "<b>" ) + QString( text ) + QString( "</b>" ) )
63
64 static const char* const time_data[] = { 
65 "16 16 6 1",
66 ". c None",
67 "b c None",
68 "# c #000000",
69 "a c #4c4c4c",
70 "d c #878787",
71 "c c #ffffff",
72 ".....#####ab....",
73 "...##cc#dc##ab..",
74 "..#ccc###dcc#ab.",
75 ".#ccccc#dcccc#a.",
76 ".#ccccc#dcccc#ab",
77 "#cccccc#dccccc#a",
78 "#cccccc#dccc#c#a",
79 "#c##ccc########a",
80 "#ccddcccdddd#d#a",
81 "#cccccccccccdc#a",
82 ".#ccccccccccc#aa",
83 ".#ccccc#ccccc#a.",
84 "..#cccc#dccc#aa.",
85 "...##cccdc##aa..",
86 ".....#####aaa...",
87 "......aaaaa....."};
88
89 static const char* const close_data[] = { 
90 "16 16 6 1",
91 "d c None",
92 ". c None",
93 "# c #000000",
94 "a c #4c4c4c",
95 "c c #5b5b5b",
96 "b c #ffffff",
97 ".....#####a.....",
98 "...##bbbbb##a...",
99 "..#bbbbbbbbb#a..",
100 ".#b#cbbbbbb#d#a.",
101 ".#bc#cbbbb#cb#a.",
102 "#bbbc#cbb#cbbb#a",
103 "#bbbbc#c#cbbbb#a",
104 "#bbbbbc#cbbbbb#a",
105 "#bbbbc#c#cbbbb#a",
106 "#bbb#ccbb##bbb#a",
107 ".#b#c#bbbbc#b#aa",
108 ".#bc#bbbbbb#c#a.",
109 "..#bbbbbbbbb#aa.",
110 "...##bbbbb##aa..",
111 ".....#####aaa...",
112 "......aaaaa....."};
113
114 static const char* const refresh_data[] = { 
115 "16 16 5 1",
116 ". c None",
117 "# c #000000",
118 "a c #4c4c4c",
119 "c c #878787",
120 "b c #ffffff",
121 ".....#####a.....",
122 "...##bb#bb##a...",
123 "..#bbbbc#bbb#a..",
124 ".#bbbb####cbb#a.",
125 ".#bbb#cc#cbbb#a.",
126 "#bbb#cb#cbbbbb#a",
127 "#bb#cbbbbbb#bb#a",
128 "#bb#cbbbbbb#cb#a",
129 "#bb#cbbbbbb#cb#a",
130 "#bbbbbb#bb#cbb#a",
131 ".#bbbb#cb#cbb#aa",
132 ".#bbb####cbbb#a.",
133 "..#bbb#cbbbb#aa.",
134 "...##bb#cb##aa..",
135 ".....#####aaa...",
136 "......aaaaa....."};
137
138 /*!
139   Creates components list
140 */
141
142 Registry::Components_var MakeRegistry( CORBA::ORB_var &orb )
143 {
144
145   const char *registryName="Registry" ;
146   
147   SALOME_NamingService &naming = *SINGLETON_<SALOME_NamingService>::Instance() ;
148   naming.init_orb( orb ) ;
149   
150   // Recuperation de la reference de l'objet
151   CORBA::Object_var object = 0 ;
152   try
153   {
154     SCRUTE(registryName) ;
155     object = naming.Resolve( registryName ) ;
156     if(CORBA::is_nil(object)) throw CommException( "unable to find the RegistryService" ) ;
157   }
158   catch( const ServiceUnreachable& ex )
159   {
160     MESSAGE( ex.what() )
161     exit( EXIT_FAILURE ) ;
162   }
163   catch( const CORBA::Exception& )
164   {
165     exit( EXIT_FAILURE ) ;
166   }
167
168   // Specialisation de l'objet generique
169
170   return Registry::Components::_narrow( object ) ;
171 }
172
173 /*!
174   Only one global registry window should exist at the moment
175   This method creates registry window if necessary and returns it
176   [ static ] 
177 */
178 ToolsGUI_RegWidget* ToolsGUI_RegWidget::GetRegWidget( CORBA::ORB_var &orb , QWidget *parent, const char *name )
179 {
180   if ( !myRegWidgetPtr ) 
181     myRegWidgetPtr = new ToolsGUI_RegWidget( orb, parent, name );
182   return myRegWidgetPtr;
183 }
184
185 /*!
186   Constructor  
187 */
188 ToolsGUI_RegWidget::ToolsGUI_RegWidget(CORBA::ORB_var &orb, QWidget *parent, const char *name ) 
189      : QMainWindow( parent, name, WType_TopLevel | WDestructiveClose ),
190        _VarComponents( MakeRegistry(orb) ),
191        _clients(0), _history(0), _parent( parent ),
192        _tabWidget(0), _refresh(0), _interval(0),
193        myInfoWindow(0), myHelpWindow(0), myIntervalWindow(0)
194 {
195    QString aFile = findFile("default.png");
196  /* char* dir = getenv( "CSF_ResourcesDefaults" );
197   QString path( "" );
198   if ( dir ) {
199     QDir qDir( dir );
200     path = qDir.filePath( "default.png" );
201   }*/
202   QPixmap pm ( aFile );
203   if ( !pm.isNull() )
204     setIcon( pm );
205
206   // pixmap for buttons
207   QPixmap image_refresh ( ( const char** ) refresh_data );
208   QPixmap image_interval( ( const char** ) time_data );
209   QPixmap image_close   ( ( const char** ) close_data );
210
211   // Buttons definition
212   QToolBar* topbar = new QToolBar( tr("Toolbar"), this );
213   setDockEnabled( topbar, DockTornOff, false );
214   setDockMenuEnabled( false );
215
216   _refresh = new QPushButton( tr( "Refresh" ), topbar );
217   _refresh->setIconSet( image_refresh );
218   _refresh->setFocusPolicy( NoFocus );
219   connect( _refresh, SIGNAL( clicked() ), this, SLOT( slotListeSelect() ) );
220   QToolTip::add( _refresh, "", toolTipGroup(), tr("Immediately updates list of components") );
221   
222   /* PAL5540 - this button is needless
223   QPushButton* help = new QPushButton( tr( "Help" ), topbar );
224   connect( help, SIGNAL( clicked() ), this, SLOT( slotHelp() ) );
225   QToolTip::add( help, "", toolTipGroup(), tr("Opens Help window") );
226   */
227   
228   _interval = new QPushButton( tr( "Interval" ), topbar );
229   _interval->setIconSet( image_interval );
230   _interval->setFocusPolicy( NoFocus );
231   connect( _interval, SIGNAL( clicked() ), this, SLOT( slotSelectRefresh() ) );
232   QToolTip::add( _interval, "", toolTipGroup(), tr("Changes refresh interval") );
233   
234   topbar->addSeparator();
235   _close = new QPushButton( tr("Close"), topbar );
236   _close->setIconSet( image_close );
237   _close->setFocusPolicy( NoFocus );
238   connect( _close, SIGNAL( clicked() ), this, SLOT( close() ) );
239   QToolTip::add( _close, "", toolTipGroup(), tr("Closes Registry window") );
240   
241   // Display area and associated slots definition
242   _tabWidget = new QTabWidget( this );
243   _clients   = new QListView( _tabWidget );
244   SetListe();
245   _history   = new QListView( _tabWidget );
246   SetListeHistory();
247   
248   _tabWidget->addTab( _clients, tr( "Running" ) );
249   _tabWidget->addTab( _history, tr( "History" ) );
250   connect( _tabWidget, SIGNAL( currentChanged( QWidget* )), this, SLOT( slotListeSelect() ) );
251   connect( _clients,   SIGNAL( clicked( QListViewItem* ) ),        this, SLOT( slotClientChanged( QListViewItem* ) ) );
252   connect( _history,   SIGNAL( clicked( QListViewItem* ) ),        this, SLOT( slotHistoryChanged( QListViewItem* ) ) );
253   setCentralWidget( _tabWidget );
254   
255   // Timer definition (used to automaticaly refresh the display area)
256   _counter = new QTimer( this );
257   connect( _counter, SIGNAL( timeout() ), this, SLOT( slotListeSelect() ) );
258   myRefreshInterval = 10;
259   _counter->start( myRefreshInterval * 1000 );
260   
261   PIXELS xpos    = 160 ;
262   PIXELS ypos    = 100 ;
263   PIXELS largeur = 800 ;
264   PIXELS hauteur = 350 ;
265   setGeometry( xpos, ypos, largeur, hauteur ) ;
266   setCaption( name ) ;
267   statusBar()->message("    ");
268 }
269
270 /*!
271   Destructor
272 */
273 ToolsGUI_RegWidget::~ToolsGUI_RegWidget()
274 {
275   MESSAGE("Debut du Destructeur");
276   _counter->stop();
277   myRegWidgetPtr = 0;
278 };
279
280 /*!
281   Event filter
282 */
283 bool ToolsGUI_RegWidget::eventFilter( QObject* object, QEvent* event )
284 {
285   if ( object ) {
286     if ( object == myHelpWindow && event->type() == QEvent::Close ) {
287       myHelpWindow = 0;
288     }
289     else if ( object == myInfoWindow && event->type() == QEvent::Close ) {
290       myInfoWindow = 0;
291     }
292     else if ( object == myIntervalWindow && event->type() == QEvent::Close ) {
293       myIntervalWindow = 0;
294     }
295     else if ( object == _clients && event->type() == QEvent::KeyPress ) {
296       QKeyEvent* ke = (QKeyEvent*)event;
297       if ( ke->key() == Key_Enter || ke->key() == Key_Return ) {
298         slotClientChanged( _clients->currentItem() );
299       }
300     }
301     else if ( object == _history && event->type() == QEvent::KeyPress ) {
302       QKeyEvent* ke = (QKeyEvent*)event;
303       if ( ke->key() == Key_Enter || ke->key() == Key_Return ) {
304         slotHistoryChanged( _history->currentItem() );
305       }
306     }
307   }
308   return QMainWindow::eventFilter( object, event );
309 }
310
311 /*!
312   Searches item in the list and returns it's index or -1 if not found
313 */
314 int ToolsGUI_RegWidget::numitem(const QString &name, const QString &pid, const QString &machine,const Registry::AllInfos *listclient)
315 {
316   BEGIN_OF("numitem");
317   for (CORBA::ULong i=0; i<listclient->length(); i++)
318     {       
319       const Registry::Infos & c_info=(*listclient)[i];
320       ASSERT( c_info.name!=NULL);
321       QString b;
322       b.setNum(int(c_info.pid));
323       if ( (name.compare(QString(c_info.name)) == 0) && 
324           (machine.compare(QString(c_info.machine)) == 0) && 
325           (pid.compare(b) == 0) )
326         {
327           END_OF("numitem");
328           return i;
329         }
330     }
331   END_OF("numitem");
332   return -1;
333 }
334
335 /*!
336   Returns text, containing information about client [ static ]
337 */
338 QString ToolsGUI_RegWidget::setlongText( const Registry::Infos &c_info)
339 {
340   BEGIN_OF("setlongText");
341   ASSERT( c_info.name != NULL );
342   QString a = QString( "<hr><h2>" ) + tr( "Code" ) + QString( " : " );
343   a.append( QString( c_info.name ) );
344   a.append( "</h1><hr><br>" );
345   a.append( "<code>" ); // ASV: 28.07.06 : added <code> tags to make the text font be 
346                         // fixed width (looks much better on Windows)
347   a.append( tr( "Process Id" ) + QString( " : " ) );
348   a.append( BOLD( QString::number( int( c_info.pid ) ) ) );
349   a.append( QString( " " ) + tr( "on machine" ) + QString( " " ) );
350   a.append( BOLD( c_info.machine ) ); 
351   a.append( QString( " " ) + tr( "ip address" ) + QString( " : " ) );
352   a.append( BOLD( c_info.adip ) );
353   a.append( "<br>" );
354   
355   a.append( tr( "launched by user" ) + QString( " " ) );
356   a.append( BOLD( c_info.pwname ) );
357   a.append( QString( " ( " ) + tr( "pid" ) + QString( " : " ) );
358   a.append( BOLD( QString::number( int( c_info.uid ) ) ) );
359   a.append( QString( " )<br> " ) + tr( "in directory" ) + QString( " " ));
360   a.append( BOLD( c_info.cdir ) );
361
362   time_t aTime;
363   a.append( QString( "<br>" ) + tr( "begins" ) + QString( " " ) );
364   aTime = time_t(c_info.tc_start);
365   char * t1 = (char * )duplicate(ctime(&aTime));
366   t1 [strlen(t1) -1 ] = ' ';
367   a.append( BOLD( t1 ) ); 
368   delete [] t1;
369   a.append( "<br>" );
370   
371   if (c_info.tc_hello != 0 )
372     {
373       aTime = time_t(c_info.tc_hello);
374       char * t2 = (char * )duplicate(ctime(&aTime));
375       t2 [strlen(t2) -1 ] = ' ';
376       a.append( tr( "last signal" ) + QString(" : ") ); 
377       a.append( BOLD( t2 ) ); 
378       a.append( "<br>" );
379       delete [] t2;
380     }
381   if ((c_info.tc_end - c_info.difftime) != 0)
382     {
383       aTime = time_t(c_info.tc_end);
384       char * t3 = (char * )duplicate(ctime(&aTime));
385       t3 [strlen(t3) -1 ] = ' ';
386       a.append( tr( "ends" ) + QString( " " ) ); 
387       a.append( BOLD( t3 ) ); 
388       a.append( "<br>" );
389       delete [] t3;
390     }
391   else
392     {
393       a.append( tr( "still running" ) + QString( "<br>" ) );
394     }
395   
396   SCRUTE(c_info.difftime);
397   if (c_info.difftime!= 0)
398     {
399       a.append( QString( "(" ) + tr( "Time on" ) + QString( " " ) ); 
400       a.append( BOLD( c_info.machine ) ); 
401       a.append( QString( " " ) + tr( "differs from server's time. The difference is" ) + QString( " " )); 
402       a.append( BOLD( QString::number( int( c_info.difftime ) ) ) );
403       a.append( QString( " " ) + tr( "seconds" ) + QString( ")<br>" ) );
404     }
405   a.append( "</code>" ); // ASV: 28.07.06 : added <code> tags to make the text font be 
406                          // fixed width (looks much better on Windows)
407   END_OF("setlongText");  
408   return a;
409   
410 }
411
412 /*!
413   Close event
414 */
415 void ToolsGUI_RegWidget::closeEvent( QCloseEvent *e)
416 {
417   BEGIN_OF("closeEvent");
418   if ( myInfoWindow )
419     myInfoWindow->close();
420   if ( myHelpWindow )
421     myHelpWindow->close();
422   if (myIntervalWindow)
423     myIntervalWindow->close();
424   e->accept();
425   END_OF("closeEvent");
426 };
427
428 /*!
429   Setups Clients list
430 */
431 void ToolsGUI_RegWidget::SetListe()
432 {
433   BEGIN_OF("SetListe");
434   _clients->installEventFilter( this );
435   _clients->setAllColumnsShowFocus( true );
436   _clients->addColumn( tr( "Component" ), -1);
437   _clients->addColumn( tr( "PID" ), -1 );
438   _clients->addColumn( tr( "User Name" ), -1 );
439   _clients->addColumn( tr( "Machine" ), -1 );
440   _clients->addColumn( tr( "begins" ), -1 );
441   _clients->addColumn( tr( "hello" ) , -1 );
442   _clients->setColumnAlignment( 1, Qt::AlignRight );
443   END_OF("SetListe");
444 }
445
446 /*!
447   Setups History list
448 */
449 void ToolsGUI_RegWidget::SetListeHistory()
450 {
451    BEGIN_OF("SetListeHistory")
452   _history->installEventFilter( this );
453   _history->setAllColumnsShowFocus( true );
454   _history->addColumn( tr( "Component" ), -1);
455   _history->addColumn( tr( "PID" ), -1 );
456   _history->addColumn( tr( "User Name" ), -1 );
457   _history->addColumn( tr( "Machine" ), -1 );
458   _history->addColumn( tr( "begins" ), -1 );
459   _history->addColumn( tr( "ends" ), -1 );
460   _history->setColumnAlignment( 1, Qt::AlignRight );
461    END_OF("SetListeHistory")
462 }
463
464 /*!
465   Updates History list
466 */
467 void ToolsGUI_RegWidget::InfoHistory()
468 {
469
470   BEGIN_OF("InfoHistory")
471     _history->clear();
472   try
473     {
474       time_t aTime;
475       _serverhistory = _VarComponents->history();
476       for (CORBA::ULong i=0; i<_serverhistory->length(); i++)
477         {       
478           const Registry::Infos & c_info=(*_serverhistory)[i];
479           ASSERT( c_info.name!=NULL);
480           QString a;
481           a.setNum(int(c_info.pid));
482           aTime = time_t(c_info.tc_start);
483           char * t1 = (char * )duplicate(ctime(&aTime));
484           t1 [strlen(t1) -1 ] = ' ';
485           aTime = time_t(c_info.tc_end);
486           char * t2 = (char * )duplicate(ctime(&aTime));
487           t2 [strlen(t2) -1 ] = ' ';
488           QListViewItem * item = new QListViewItem(_history, QString(c_info.name),\
489                                                    a, QString(c_info.pwname), QString(c_info.machine), \
490                                                    QString(t1), QString(t2));
491           item=0 ;
492           delete [] t1;
493           delete [] t2;
494           
495         }
496     }
497   catch( ... )
498     {
499       _interval->setDisabled( TRUE ) ;
500       _refresh->setDisabled( TRUE ) ;
501       _counter->stop();
502       MESSAGE("Sorry, No more Registry Server") ;
503       statusBar()->message( tr( "Sorry, No more Registry Server" ) ) ;
504     }
505   END_OF("InfoHistory")
506 }
507
508 /*!
509   Updates clients list
510 */
511 void ToolsGUI_RegWidget::InfoReg()
512 {
513   BEGIN_OF("InfoReg")
514   _clients->clear();
515   try
516     {
517       time_t aTime;
518       _serverclients = _VarComponents->getall();
519       for (CORBA::ULong i=0; i<_serverclients->length(); i++)
520         {       
521           const Registry::Infos & c_info=(*_serverclients)[i];
522           ASSERT( c_info.name!=NULL);
523           QString a;
524           a.setNum(int(c_info.pid));
525           aTime = time_t(c_info.tc_start);
526           char * t1 = (char * )duplicate(ctime(&aTime));
527           t1 [strlen(t1) -1 ] = ' ';
528           aTime = time_t(c_info.tc_hello);
529           char * t2 = (char * )duplicate(ctime(&aTime));
530           t2 [strlen(t2) -1 ] = ' ';
531           QListViewItem * item = new QListViewItem(_clients, QString(c_info.name),\
532                                                    a, QString(c_info.pwname), QString(c_info.machine), \
533                                                    QString(t1), QString(t2));
534           item=0 ;
535           delete [] t1;
536           delete [] t2;
537           
538         }
539     }
540   catch( ... )
541     {
542       _interval->setDisabled( TRUE ) ;
543       _refresh->setDisabled( TRUE ) ;
544       _counter->stop();
545       MESSAGE("Sorry, No more Registry Server") ;
546       statusBar()->message( tr( "Sorry, No more Registry Server" ) ) ;
547     }
548   END_OF("InfoReg")
549 }
550
551 /*!
552   Called when <Refresh> button is clicked
553 */
554 void ToolsGUI_RegWidget::slotListeSelect()
555 {
556   try
557     {
558       ASSERT(_tabWidget->currentPage() != NULL);
559       if (_tabWidget->currentPage () == _clients) InfoReg();
560       else if (_tabWidget->currentPage () == _history) InfoHistory();
561     }
562   catch( ... )
563     {
564       MESSAGE("Sorry, No more Registry Server") ;
565       statusBar()->message( tr( "Sorry, No more Registry Server" ) ) ;
566     }
567 }
568
569 /*!
570   Called when <Interval> button is clicked (changing refresh interval)
571 */
572 void ToolsGUI_RegWidget::slotSelectRefresh()
573 {
574   BEGIN_OF("slotSelectRefresh");
575   myIntervalWindow = new ToolsGUI_IntervalWindow(this);
576   myIntervalWindow->installEventFilter( this );
577   myIntervalWindow->setValue(myRefreshInterval);
578   myIntervalWindow->show();
579   connect( myIntervalWindow->Cancel(), SIGNAL( clicked() ), myIntervalWindow, SLOT( close() ) );
580   connect( myIntervalWindow->Ok(), SIGNAL( clicked() ), this, SLOT( slotIntervalOk() ) );
581   END_OF("slotSelectRefresh");
582 }
583
584 /*!
585   SLOT: called when IntervalWindow's OK button is clicked
586 */
587 void ToolsGUI_RegWidget::slotIntervalOk()
588 {
589   BEGIN_OF("slotIntervalOk");
590   myRefreshInterval = myIntervalWindow->getValue();
591   _counter->changeInterval( myRefreshInterval * 1000 );
592   SCRUTE(myRefreshInterval);
593   myIntervalWindow->close();
594   END_OF("slotIntervalOk");
595 }
596 /*!
597   Called when <Help> button is clicked
598 */
599 void ToolsGUI_RegWidget::slotHelp()
600 {
601   BEGIN_OF("slotHelp()");
602
603   if ( !myHelpWindow ) {
604     myHelpWindow  = new ToolsGUI_HelpWindow( this );
605     myHelpWindow->installEventFilter( this );
606   }
607   myHelpWindow->show();
608   myHelpWindow->raise();
609   myHelpWindow->setActiveWindow();
610   
611   END_OF("slotHelp()") ;
612 }
613
614 /*!
615   Called when user clicks on item in <Running> list
616 */
617 void ToolsGUI_RegWidget::slotClientChanged( QListViewItem* item )
618 {
619   BEGIN_OF("slotClientChanged()") ;
620
621   if ( item <= 0)
622     return;
623
624   blockSignals( true ); // for sure that item will not be deleted when refreshing
625
626   int numeroItem = numitem(item->text(0), item->text(1), item->text(3), _serverclients);
627   SCRUTE(numeroItem) ;
628   SCRUTE(item->text(1)) ;
629   
630   ASSERT(numeroItem>=0) ;
631   ASSERT((size_t)numeroItem<_serverclients->length()) ;
632   const Registry::Infos & c_info=(*_serverclients)[numeroItem];
633   ASSERT( c_info.name!=NULL);
634   
635   if ( !myInfoWindow ) {
636     myInfoWindow  = new ToolsGUI_InfoWindow( this );
637     myInfoWindow->installEventFilter( this );
638   }
639   QString a = tr( "More about" ) + QString( " " ) + QString( c_info.name );
640   myInfoWindow->setCaption(a);
641   myInfoWindow->setText( ToolsGUI_RegWidget::setlongText( c_info) );
642   myInfoWindow->show();
643   myInfoWindow->raise();
644   myInfoWindow->setActiveWindow();
645
646   blockSignals( false ); // enabling signals again
647
648   END_OF("slotClientChanged()") ;
649   return ;
650 }
651
652 /*!
653   Called when user clicks on item in <History> list
654 */
655 void ToolsGUI_RegWidget::slotHistoryChanged( QListViewItem* item )
656 {
657
658   BEGIN_OF("slotHistoryChanged()") ;
659   
660   if ( item <= 0)
661     return;
662
663   blockSignals( true ); // for sure that item will not be deleted when refreshing
664
665   int numeroItem = numitem(item->text(0), item->text(1), item->text(3), _serverhistory);
666   
667   SCRUTE(numeroItem) ;
668   SCRUTE(item->text(1)) ;
669   ASSERT(numeroItem>=0) ;
670   ASSERT((size_t)numeroItem<_serverhistory->length()) ;
671   const Registry::Infos & c_info=(*_serverhistory)[numeroItem];
672   ASSERT( c_info.name!=NULL);
673   
674   if ( !myInfoWindow ) {
675     myInfoWindow  = new ToolsGUI_InfoWindow( this );
676     myInfoWindow->installEventFilter( this );
677   }
678   QString a = tr( "More about" ) + QString( " " ) + QString( c_info.name );
679   myInfoWindow->setCaption(a);
680   myInfoWindow->setText( ToolsGUI_RegWidget::setlongText( c_info ) );
681   myInfoWindow->show();
682   myInfoWindow->raise();
683   myInfoWindow->setActiveWindow();
684
685   blockSignals( false ); // enabling signals again
686
687   END_OF("slotHistoryChanged()") ;
688   return ;
689 }
690
691 /*!
692   Constructor
693 */
694 ToolsGUI_InfoWindow::ToolsGUI_InfoWindow( QWidget* parent, const char* name )
695      : QMainWindow( parent, name, WType_TopLevel | WDestructiveClose )
696 {
697   BEGIN_OF("InfoWindow");
698   myTextView = new QTextView( this, "myTextView" );
699   setCentralWidget( myTextView );
700   setMinimumSize( 450, 250 );
701   END_OF("InfoWindow");
702 }
703
704 /*!
705   Sets text
706 */
707 void ToolsGUI_InfoWindow::setText( const QString& text )
708 {
709   myTextView->setText( text );
710 }
711
712 /*!
713   Key press event
714 */
715 void ToolsGUI_InfoWindow::keyPressEvent( QKeyEvent * e )
716 {
717   QMainWindow::keyPressEvent( e );
718   if ( e->key() == Key_Escape )
719     close();
720 }
721
722 static const char* SEPARATOR    = ":";
723
724 QString findFile( QString filename )
725 {
726   QString dir;
727   char* cenv;
728   
729   // Try ${HOME}/.salome/resources directory
730   cenv = getenv( "HOME" );
731   if ( cenv ) {
732     dir.sprintf( "%s", cenv );
733     if ( !dir.isEmpty() ) {
734       dir = addSlash(dir) ;
735       dir = dir + ".salome" ;
736       dir = addSlash(dir) ;
737       dir = dir + "resources" ;
738       dir = addSlash(dir) ;
739       QFileInfo fileInfo( dir + filename );
740       if ( fileInfo.isFile() && fileInfo.exists() )
741         return fileInfo.filePath();
742     }
743   }
744   // Try ${SALOME_SITE_DIR}/share/salome/resources directory
745   cenv = getenv( "SALOME_SITE_DIR" );
746   if ( cenv ) {
747     dir.sprintf( "%s", cenv );
748     if ( !dir.isEmpty() ) {
749       dir = addSlash(dir) ;
750       dir = dir + "share" ;
751       dir = addSlash(dir) ;
752       cenv = getenv("SALOME_SITE_NAME");
753       if (cenv)  dir = dir + cenv;
754       else       dir = dir + "salome" ;
755       dir = addSlash(dir) ;
756       dir = dir + "resources" ;
757       dir = addSlash(dir) ;
758       QFileInfo fileInfo( dir + filename );
759       if ( fileInfo.isFile() && fileInfo.exists() )
760         return fileInfo.filePath();
761     }
762   }
763   // Try ${KERNEL_ROOT_DIR}/share/salome/resources directory
764   cenv = getenv( "KERNEL_ROOT_DIR" );
765   if ( cenv ) {
766     dir.sprintf( "%s", cenv );
767     if ( !dir.isEmpty() ) {
768       dir = addSlash(dir) ;
769       dir = dir + "share" ;
770       dir = addSlash(dir) ;
771       dir = dir + "salome" ;
772       dir = addSlash(dir) ;
773       dir = dir + "resources" ;
774       dir = addSlash(dir) ;
775       dir = dir + "kernel" ;
776       dir = addSlash(dir) ;
777       QFileInfo fileInfo( dir + filename );
778       if ( fileInfo.isFile() && fileInfo.exists() )
779         return fileInfo.filePath();
780     }
781   }
782
783   //SRN Added support for SALOMEGUI
784   cenv = getenv( "SALOMEGUI_ROOT_DIR" );
785   if ( cenv ) {
786     dir.sprintf( "%s", cenv );
787     if ( !dir.isEmpty() ) {
788       dir = addSlash(dir) ;
789       dir = dir + "share" ;
790       dir = addSlash(dir) ;
791       dir = dir + "salome" ;
792       dir = addSlash(dir) ;
793       dir = dir + "resources" ;
794       dir = addSlash(dir) ;
795       QFileInfo fileInfo( dir + filename );
796       if ( fileInfo.isFile() && fileInfo.exists() )
797         return fileInfo.filePath();
798     }
799   }
800
801   // Try CSF_SaloameResources env.var directory ( or directory list )
802   cenv = getenv( "CSF_SalomeResources" );
803   if ( cenv ) {
804   dir.sprintf( "%s", cenv );
805   if ( !dir.isEmpty() )
806   {
807     QStringList dirList = QStringList::split( SEPARATOR, dir, false ); // skip empty entries
808     for ( int i = 0; i < (int)dirList.count(); i++ )
809     {
810             QFileInfo fileInfo( addSlash( dirList[ i ] ) + filename );
811             if ( fileInfo.isFile() && fileInfo.exists() )
812               return fileInfo.filePath();
813       }
814     }
815   }
816   return filename;
817 }
818
819 QString addSlash( const QString& path )
820 {
821   return Qtx::addSlash( path );
822 }