Salome HOME
Join modifications from branch OCC_debug_for_3_2_0b1
[modules/gui.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 # 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 "RegWidget.h"
49 # include "HelpWindow.hxx" 
50 # include "IntervalWindow.hxx"
51 using namespace std;
52
53 typedef int PIXELS;
54 RegWidget* RegWidget::myRegWidgetPtr = 0;
55 QString addSlash( const QString& );
56 QString findFile( QString filename );
57
58 #define BOLD( text ) ( QString( "<b>" ) + QString( text ) + QString( "</b>" ) )
59
60 static const char* const time_data[] = { 
61 "16 16 6 1",
62 ". c None",
63 "b c None",
64 "# c #000000",
65 "a c #4c4c4c",
66 "d c #878787",
67 "c c #ffffff",
68 ".....#####ab....",
69 "...##cc#dc##ab..",
70 "..#ccc###dcc#ab.",
71 ".#ccccc#dcccc#a.",
72 ".#ccccc#dcccc#ab",
73 "#cccccc#dccccc#a",
74 "#cccccc#dccc#c#a",
75 "#c##ccc########a",
76 "#ccddcccdddd#d#a",
77 "#cccccccccccdc#a",
78 ".#ccccccccccc#aa",
79 ".#ccccc#ccccc#a.",
80 "..#cccc#dccc#aa.",
81 "...##cccdc##aa..",
82 ".....#####aaa...",
83 "......aaaaa....."};
84
85 static const char* const close_data[] = { 
86 "16 16 6 1",
87 "d c None",
88 ". c None",
89 "# c #000000",
90 "a c #4c4c4c",
91 "c c #5b5b5b",
92 "b c #ffffff",
93 ".....#####a.....",
94 "...##bbbbb##a...",
95 "..#bbbbbbbbb#a..",
96 ".#b#cbbbbbb#d#a.",
97 ".#bc#cbbbb#cb#a.",
98 "#bbbc#cbb#cbbb#a",
99 "#bbbbc#c#cbbbb#a",
100 "#bbbbbc#cbbbbb#a",
101 "#bbbbc#c#cbbbb#a",
102 "#bbb#ccbb##bbb#a",
103 ".#b#c#bbbbc#b#aa",
104 ".#bc#bbbbbb#c#a.",
105 "..#bbbbbbbbb#aa.",
106 "...##bbbbb##aa..",
107 ".....#####aaa...",
108 "......aaaaa....."};
109
110 static const char* const refresh_data[] = { 
111 "16 16 5 1",
112 ". c None",
113 "# c #000000",
114 "a c #4c4c4c",
115 "c c #878787",
116 "b c #ffffff",
117 ".....#####a.....",
118 "...##bb#bb##a...",
119 "..#bbbbc#bbb#a..",
120 ".#bbbb####cbb#a.",
121 ".#bbb#cc#cbbb#a.",
122 "#bbb#cb#cbbbbb#a",
123 "#bb#cbbbbbb#bb#a",
124 "#bb#cbbbbbb#cb#a",
125 "#bb#cbbbbbb#cb#a",
126 "#bbbbbb#bb#cbb#a",
127 ".#bbbb#cb#cbb#aa",
128 ".#bbb####cbbb#a.",
129 "..#bbb#cbbbb#aa.",
130 "...##bb#cb##aa..",
131 ".....#####aaa...",
132 "......aaaaa....."};
133
134 /*!
135   Creates components list
136 */
137
138 Registry::Components_var MakeRegistry( CORBA::ORB_var &orb )
139 {
140
141   const char *registryName="Registry" ;
142   
143   SALOME_NamingService &naming = *SINGLETON_<SALOME_NamingService>::Instance() ;
144   naming.init_orb( orb ) ;
145   
146   // Recuperation de la reference de l'objet
147   CORBA::Object_var object = 0 ;
148   try
149     {
150       SCRUTE(registryName) ;
151       object = naming.Resolve( registryName ) ;
152       if(CORBA::is_nil(object)) throw CommException( "unable to find the RegistryService" ) ;
153     }
154   catch( const ServiceUnreachable &ex )
155     {
156       MESSAGE( ex.what() )
157       exit( EXIT_FAILURE ) ;
158     }
159   catch( const CORBA::Exception &exx )
160     {
161       exit( EXIT_FAILURE ) ;
162     }
163   
164   // Specialisation de l'objet generique
165   
166   return Registry::Components::_narrow( object ) ;
167 }
168
169 /*!
170   Only one global registry window should exist at the moment
171   This method creates registry window if necessary and returns it
172   [ static ] 
173 */
174 RegWidget* RegWidget::GetRegWidget( CORBA::ORB_var &orb , QWidget *parent, const char *name )
175 {
176   if ( !myRegWidgetPtr ) 
177     myRegWidgetPtr = new RegWidget( orb, parent, name );
178   return myRegWidgetPtr;
179 }
180
181 /*!
182   Constructor  
183 */
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)
190 {
191    QString aFile = findFile("default.png");
192  /* char* dir = getenv( "CSF_ResourcesDefaults" );
193   QString path( "" );
194   if ( dir ) {
195     QDir qDir( dir );
196     path = qDir.filePath( "default.png" );
197   }*/
198   QPixmap pm ( aFile );
199   if ( !pm.isNull() )
200     setIcon( pm );
201
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 );
206
207   // Buttons definition
208   QToolBar* topbar = new QToolBar( tr("Toolbar"), this );
209   setDockEnabled( topbar, DockTornOff, false );
210   setDockMenuEnabled( false );
211
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") );
217   
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") );
222   */
223   
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") );
229   
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") );
236   
237   // Display area and associated slots definition
238   _tabWidget = new QTabWidget( this );
239   _clients   = new QListView( _tabWidget );
240   SetListe();
241   _history   = new QListView( _tabWidget );
242   SetListeHistory();
243   
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 );
250   
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 );
256   
257   PIXELS xpos    = 160 ;
258   PIXELS ypos    = 100 ;
259   PIXELS largeur = 800 ;
260   PIXELS hauteur = 350 ;
261   setGeometry( xpos, ypos, largeur, hauteur ) ;
262   setCaption( name ) ;
263   statusBar()->message("    ");
264 }
265
266 /*!
267   Destructor
268 */
269 RegWidget::~RegWidget()
270 {
271   MESSAGE("Debut du Destructeur");
272   _counter->stop();
273   myRegWidgetPtr = 0;
274 };
275
276 /*!
277   Event filter
278 */
279 bool RegWidget::eventFilter( QObject* object, QEvent* event )
280 {
281   if ( object ) {
282     if ( object == myHelpWindow && event->type() == QEvent::Close ) {
283       myHelpWindow = 0;
284     }
285     else if ( object == myInfoWindow && event->type() == QEvent::Close ) {
286       myInfoWindow = 0;
287     }
288     else if ( object == myIntervalWindow && event->type() == QEvent::Close ) {
289       myIntervalWindow = 0;
290     }
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() );
295       }
296     }
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() );
301       }
302     }
303   }
304   return QMainWindow::eventFilter( object, event );
305 }
306
307 /*!
308   Searches item in the list and returns it's index or -1 if not found
309 */
310 int RegWidget::numitem(const QString &name, const QString &pid, const QString &machine,const Registry::AllInfos *listclient)
311 {
312   BEGIN_OF("numitem");
313   for (CORBA::ULong i=0; i<listclient->length(); i++)
314     {       
315       const Registry::Infos & c_info=(*listclient)[i];
316       ASSERT( c_info.name!=NULL);
317       QString b;
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) )
322         {
323           END_OF("numitem");
324           return i;
325         }
326     }
327   END_OF("numitem");
328   return -1;
329 }
330
331 /*!
332   Returns text, containing information about client [ static ]
333 */
334 QString RegWidget::setlongText( const Registry::Infos &c_info)
335 {
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 ) );
347   a.append( "<br>" );
348   
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 ) );
355   
356   time_t aTime;
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 ) ); 
362   delete [] t1;
363   a.append( "<br>" );
364   
365   if (c_info.tc_hello != 0 )
366     {
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 ) ); 
372       a.append( "<br>" );
373       delete [] t2;
374     }
375   if ((c_info.tc_end - c_info.difftime) != 0)
376     {
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 ) ); 
382       a.append( "<br>" );
383       delete [] t3;
384     }
385   else
386     {
387       a.append( tr( "still running" ) + QString( "<br>" ) );
388     }
389   
390   SCRUTE(c_info.difftime);
391   if (c_info.difftime!= 0)
392     {
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>" ) );
398     }
399   END_OF("setlongText");  
400   return a;
401   
402 }
403
404 /*!
405   Close event
406 */
407 void RegWidget::closeEvent( QCloseEvent *e)
408 {
409   BEGIN_OF("closeEvent");
410   if ( myInfoWindow )
411     myInfoWindow->close();
412   if ( myHelpWindow )
413     myHelpWindow->close();
414   if (myIntervalWindow)
415     myIntervalWindow->close();
416   e->accept();
417   END_OF("closeEvent");
418 };
419
420 /*!
421   Setups Clients list
422 */
423 void RegWidget::SetListe()
424 {
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 );
435   END_OF("SetListe");
436 }
437
438 /*!
439   Setups History list
440 */
441 void RegWidget::SetListeHistory()
442 {
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")
454 }
455
456 /*!
457   Updates History list
458 */
459 void RegWidget::InfoHistory()
460 {
461
462   BEGIN_OF("InfoHistory")
463     _history->clear();
464   try
465     {
466       time_t aTime;
467       _serverhistory = _VarComponents->history();
468       for (CORBA::ULong i=0; i<_serverhistory->length(); i++)
469         {       
470           const Registry::Infos & c_info=(*_serverhistory)[i];
471           ASSERT( c_info.name!=NULL);
472           QString a;
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));
483           item=0 ;
484           delete [] t1;
485           delete [] t2;
486           
487         }
488     }
489   catch( ... )
490     {
491       _interval->setDisabled( TRUE ) ;
492       _refresh->setDisabled( TRUE ) ;
493       _counter->stop();
494       MESSAGE("Sorry, No more Registry Server") ;
495       statusBar()->message( tr( "Sorry, No more Registry Server" ) ) ;
496     }
497   END_OF("InfoHistory")
498 }
499
500 /*!
501   Updates clients list
502 */
503 void RegWidget::InfoReg()
504 {
505   BEGIN_OF("InfoReg")
506   _clients->clear();
507   try
508     {
509       time_t aTime;
510       _serverclients = _VarComponents->getall();
511       for (CORBA::ULong i=0; i<_serverclients->length(); i++)
512         {       
513           const Registry::Infos & c_info=(*_serverclients)[i];
514           ASSERT( c_info.name!=NULL);
515           QString a;
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));
526           item=0 ;
527           delete [] t1;
528           delete [] t2;
529           
530         }
531     }
532   catch( ... )
533     {
534       _interval->setDisabled( TRUE ) ;
535       _refresh->setDisabled( TRUE ) ;
536       _counter->stop();
537       MESSAGE("Sorry, No more Registry Server") ;
538       statusBar()->message( tr( "Sorry, No more Registry Server" ) ) ;
539     }
540   END_OF("InfoReg")
541 }
542
543 /*!
544   Called when <Refresh> button is clicked
545 */
546 void RegWidget::slotListeSelect()
547 {
548   try
549     {
550       ASSERT(_tabWidget->currentPage() != NULL);
551       if (_tabWidget->currentPage () == _clients) InfoReg();
552       else if (_tabWidget->currentPage () == _history) InfoHistory();
553     }
554   catch( ... )
555     {
556       MESSAGE("Sorry, No more Registry Server") ;
557       statusBar()->message( tr( "Sorry, No more Registry Server" ) ) ;
558     }
559 }
560
561 /*!
562   Called when <Interval> button is clicked (changing refresh interval)
563 */
564 void RegWidget::slotSelectRefresh()
565 {
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");
574 }
575
576 /*!
577   SLOT: called when button OK is clicked in interval window
578 */
579 void RegWidget::slotIntervalOk()
580 {
581   BEGIN_OF("slotIntervalOk");
582   myRefreshInterval = myIntervalWindow->getValue();
583   _counter->changeInterval( myRefreshInterval * 1000 );
584   SCRUTE(myRefreshInterval);
585   myIntervalWindow->close();
586   END_OF("slotIntervalOk");
587 }
588 /*!
589   Called when <Help> button is clicked
590 */
591 void RegWidget::slotHelp()
592 {
593   BEGIN_OF("slotHelp()");
594
595   if ( !myHelpWindow ) {
596     myHelpWindow  = new HelpWindow( this );
597     myHelpWindow->installEventFilter( this );
598   }
599   myHelpWindow->show();
600   myHelpWindow->raise();
601   myHelpWindow->setActiveWindow();
602   
603   END_OF("slotHelp()") ;
604 }
605
606 /*!
607   Called when user clicks on item in <Running> list
608 */
609 void RegWidget::slotClientChanged( QListViewItem* item )
610 {
611   BEGIN_OF("slotClientChanged()") ;
612
613   if ( item <= 0)
614     return;
615
616   blockSignals( true ); // for sure that item will not be deleted when refreshing
617
618   int numeroItem = numitem(item->text(0), item->text(1), item->text(3), _serverclients);
619   SCRUTE(numeroItem) ;
620   SCRUTE(item->text(1)) ;
621   
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);
626   
627   if ( !myInfoWindow ) {
628     myInfoWindow  = new InfoWindow( this );
629     myInfoWindow->installEventFilter( this );
630   }
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();
637
638   blockSignals( false ); // enabling signals again
639
640   END_OF("slotClientChanged()") ;
641   return ;
642 }
643
644 /*!
645   Called when user clicks on item in <History> list
646 */
647 void RegWidget::slotHistoryChanged( QListViewItem* item )
648 {
649
650   BEGIN_OF("slotHistoryChanged()") ;
651   
652   if ( item <= 0)
653     return;
654
655   blockSignals( true ); // for sure that item will not be deleted when refreshing
656
657   int numeroItem = numitem(item->text(0), item->text(1), item->text(3), _serverhistory);
658   
659   SCRUTE(numeroItem) ;
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);
665   
666   if ( !myInfoWindow ) {
667     myInfoWindow  = new InfoWindow( this );
668     myInfoWindow->installEventFilter( this );
669   }
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();
676
677   blockSignals( false ); // enabling signals again
678
679   END_OF("slotHistoryChanged()") ;
680   return ;
681 }
682
683 /*!
684   Constructor
685 */
686 InfoWindow::InfoWindow( QWidget* parent, const char* name )
687      : QMainWindow( parent, name, WType_TopLevel | WDestructiveClose )
688 {
689   BEGIN_OF("InfoWindow");
690   myTextView = new QTextView( this, "myTextView" );
691   setCentralWidget( myTextView );
692   setMinimumSize( 450, 250 );
693   END_OF("InfoWindow");
694 }
695
696 /*!
697   Sets text
698 */
699 void InfoWindow::setText( const QString& text )
700 {
701   myTextView->setText( text );
702 }
703
704 /*!
705   Key press event
706 */
707 void InfoWindow::keyPressEvent( QKeyEvent * e )
708 {
709   QMainWindow::keyPressEvent( e );
710   if ( e->key() == Key_Escape )
711     close();
712 }
713
714 static const char* SEPARATOR    = ":";
715
716 QString findFile( QString filename )
717 {
718   QString dir;
719   char* cenv;
720   
721   // Try ${HOME}/.salome/resources directory
722   cenv = getenv( "HOME" );
723   if ( cenv ) {
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();
734     }
735   }
736   // Try ${SALOME_SITE_DIR}/share/salome/resources directory
737   cenv = getenv( "SALOME_SITE_DIR" );
738   if ( cenv ) {
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();
753     }
754   }
755   // Try ${KERNEL_ROOT_DIR}/share/salome/resources directory
756   cenv = getenv( "KERNEL_ROOT_DIR" );
757   if ( cenv ) {
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();
770     }
771   }
772
773   //SRN Added support for SALOMEGUI
774   cenv = getenv( "SALOMEGUI_ROOT_DIR" );
775   if ( cenv ) {
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();
788     }
789   }
790
791   // Try CSF_SaloameResources env.var directory ( or directory list )
792   cenv = getenv( "CSF_SalomeResources" );
793   if ( cenv ) {
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();
801       }
802     }
803   }
804   return filename;
805 }
806 QString addSlash( const QString& path )
807 {
808   if (!path.isNull()) {
809 #ifdef WNT
810     QChar slash ('\\');
811 #else
812     QChar slash ('/');
813 #endif
814     if ( path.at(path.length()-1) != slash )
815       return path + slash;
816   }
817   return path;
818 }