]> SALOME platform Git repositories - modules/gui.git/blob - src/ObjBrowser/OB_Browser.cxx
Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/gui.git] / src / ObjBrowser / OB_Browser.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include "OB_Browser.h"
20
21 #include "OB_Filter.h"
22 #include "OB_ListItem.h"
23 #include "OB_ListView.h"
24 #include "OB_FindDlg.h"
25
26 #include <SUIT_DataObjectIterator.h>
27 #include <SUIT_TreeSync.h>
28
29 #include <qcursor.h>
30 #include <qlayout.h>
31 #include <qtooltip.h>
32 #include <qpainter.h>
33 #include <qwmatrix.h>
34 #include <qlistview.h>
35 #include <qpopupmenu.h>
36 #include <qdatetime.h>
37
38 #include <time.h>
39
40 /*!
41   \class  OB_Browser::ToolTip
42   Tool tip for OB_Browser.
43 */
44
45 class OB_Browser::ToolTip : public QToolTip
46 {
47 public:
48   ToolTip( OB_Browser* b, QWidget* p = 0 );
49   virtual ~ToolTip();
50
51   void        maybeTip( const QPoint& );
52
53 private:
54   OB_Browser* myBrowser;
55 };
56
57 /*!
58   Constructor
59 */
60 OB_Browser::ToolTip::ToolTip( OB_Browser* b, QWidget* p )
61 : QToolTip( p ),
62 myBrowser( b )
63 {
64 }
65
66 /*!
67   Destructor
68 */
69 OB_Browser::ToolTip::~ToolTip()
70 {
71 }
72
73 /*!
74   It is called when there is a possibility that a tool tip
75   should be shown and must decide whether there is a tool tip for the point
76   in the widget that this QToolTip object relates to.
77   \param pos - point co-ordinates
78 */
79 void OB_Browser::ToolTip::maybeTip( const QPoint& pos )
80 {
81   if ( !parentWidget() || !myBrowser || !myBrowser->isShowToolTips() )
82           return;
83
84   QListView* lv = myBrowser->listView();
85
86   QListViewItem* item = lv->itemAt( pos );
87   SUIT_DataObject* obj = myBrowser->dataObject( item );
88   if ( !obj )
89     return;
90
91   QString aText = obj->toolTip();
92
93   if ( aText.isEmpty() )
94     return;
95
96   QRect aRect = lv->itemRect( item );
97
98   tip( aRect, aText );
99 }
100
101
102 typedef SUIT_DataObject*   ObjPtr;
103 typedef OB_ListItem*       ItemPtr;
104
105 /*!
106    \class  OB_BrowserSync
107    Auxiliary class for synchronizing tree of SUIT_DataObjects and list view items
108 */
109 class OB_BrowserSync
110 {
111 public:
112   OB_BrowserSync( OB_Browser* );
113   bool     isEqual( const ObjPtr&, const ItemPtr& ) const;
114   ObjPtr   nullSrc() const;
115   ItemPtr  nullTrg() const;
116   ItemPtr  createItem( const ObjPtr&, const ItemPtr&, const ItemPtr&, const bool ) const;
117   void     updateItem( const ObjPtr& , const ItemPtr& ) const;
118   void     deleteItemWithChildren( const ItemPtr& ) const;
119   void     children( const ObjPtr&, QValueList<ObjPtr>& ) const;
120   void     children( const ItemPtr&, QValueList<ItemPtr>& ) const;
121   ItemPtr  parent( const ItemPtr& ) const;
122 private:
123   bool     needUpdate( const ItemPtr& ) const;
124   OB_Browser*   myBrowser;
125 };
126
127
128 /*!
129   Constructor
130 */
131 OB_BrowserSync::OB_BrowserSync( OB_Browser* ob )
132 : myBrowser( ob )
133 {
134 }
135
136 /*!
137   \return true if item must be updated
138   \param item - item to be checked
139 */
140 bool OB_BrowserSync::needUpdate( const ItemPtr& item ) const
141 {
142   bool update = false;
143   if ( item ) {
144     SUIT_DataObject* obj = item->dataObject();
145     if ( obj ) {
146       // 1. check text
147       update = ( item->text( 0 ) != obj->name() ) || myBrowser->needToUpdateTexts( item );
148
149       if ( !update ) { 
150         // 2. check pixmap (compare serialNumber()-s)
151         QPixmap objPix = obj->icon();
152         const QPixmap* itemPix = item->pixmap( 0 );
153         update = (  objPix.isNull() && (  itemPix && !itemPix->isNull() ) ) || 
154                  ( !objPix.isNull() && ( !itemPix ||  itemPix->isNull() ) ); 
155         if ( !update && !objPix.isNull() && itemPix && !itemPix->isNull() ) {
156           int aIconW = objPix.width();
157           if( aIconW > 20 ) {
158             QWMatrix aM;
159             double aScale = 20.0 / aIconW;
160             aM.scale( aScale, aScale );
161             objPix = objPix.xForm( aM );
162           }
163           update = ( objPix.serialNumber() != itemPix->serialNumber() );
164         }
165       }
166     }
167   }
168   return update;
169 }
170
171 /*!
172   Updates item
173   \param p - item
174 */
175 void OB_BrowserSync::updateItem( const ObjPtr& o, const ItemPtr& p ) const
176 {
177   if ( p && needUpdate( p ) ) { 
178     //    printf( "--- needUpdate for %s = true ---\n", p->text( 0 ).latin1() );
179     myBrowser->updateText( p );
180     p->update();
181   }
182   if( o && myBrowser->getUpdater() )
183     {
184       myBrowser->getUpdater()->update( o, p );
185     }
186 }
187
188 /*!
189   Creates item by SUIT object
190   \param src - corresponding SUIT object
191   \param parent - parent for item
192   \param after - previous sibling for item
193   \param prepend - item must be added to start of children list
194 */
195 ItemPtr OB_BrowserSync::createItem( const ObjPtr& src,
196                                     const ItemPtr& parent, const ItemPtr& after,
197                                     const bool prepend ) const
198 {
199   ItemPtr i = myBrowser ? dynamic_cast<ItemPtr>( myBrowser->createItem( src, parent, after, prepend ) ) : 0;
200   if( i )
201     i->setOpen( src->isOpen() );
202   return i;
203 }
204
205 /*!
206   Deletes object with all children
207   \param i - item
208 */
209 void OB_BrowserSync::deleteItemWithChildren( const ItemPtr& i ) const
210 {
211   if( myBrowser && myBrowser->myItems.contains( i->dataObject() ) )
212   {
213     myBrowser->removeReferences( i );
214     delete i;
215   }
216 }
217
218 /*!
219   \return true if objects correspond each other at all
220   \param p - suit object
221   \param q - object browser item
222 */
223 bool OB_BrowserSync::isEqual( const ObjPtr& p, const ItemPtr& q ) const
224 {
225   bool isRoot = p==myBrowser->getRootObject() && !q,
226        isEq = p && q && q->dataObject()==p;
227   return isRoot || ( !p && !q ) || isEq;
228 }
229
230 /*!
231   \return null suit object
232 */
233 ObjPtr OB_BrowserSync::nullSrc() const
234 {
235   return 0;
236 }
237
238 /*!
239   \return null item
240 */
241 ItemPtr OB_BrowserSync::nullTrg() const
242 {
243   return 0;
244 }
245
246 /*!
247   Fills list with children of SUIT object
248   \param p - SUIT object
249   \param ch - list to be filled
250 */
251 void OB_BrowserSync::children( const ObjPtr& p, QValueList<ObjPtr>& ch ) const
252 {
253   DataObjectList l;
254   if( p )
255   {
256     p->children( l );
257     ch.clear();
258     for( SUIT_DataObject* o = l.first(); o; o = l.next() )
259       ch.append( o );
260   }
261 }
262
263 /*!
264   Fills list with children of item
265   \param p - item
266   \param ch - list to be filled
267 */
268 void OB_BrowserSync::children( const ItemPtr& p, QValueList<ItemPtr>& ch ) const
269 {
270   for( QListViewItem* item = p ? p->firstChild() : myBrowser->listView()->firstChild(); item; item = item->nextSibling() )
271   {
272     ItemPtr p = dynamic_cast<ItemPtr>( item );
273     if( p )
274       ch.append( p );
275   }
276 }
277
278 /*!
279   \return parent of item
280   \param p - item
281 */
282 ItemPtr OB_BrowserSync::parent( const ItemPtr& p ) const
283 {
284   return p ? dynamic_cast<ItemPtr>( p->parent() ) : 0;
285 }
286
287
288 /*!
289   Constructor
290 */
291 OB_Browser::OB_Browser( QWidget* parent, SUIT_DataObject* root )
292 : QFrame( parent ),
293
294 myRoot( 0 ),
295 myTooltip( 0 ),
296 myUpdater( 0 ),
297 myAutoOpenLevel( 0 ),
298 myAutoUpdate( false ),
299 myAutoDelObjs( false ),
300 myRootDecorated( true )
301 {
302   myView = new OB_ListView( QtxListView::HeaderAuto, this );
303   myView->setAppropriate( myView->addColumn( "Data" ), false );
304   myView->setSorting( -1 );
305   myView->setRootIsDecorated( true );
306   myView->setSelectionMode( QListView::Extended );
307   myView->installEventFilter( this );
308   myView->viewport()->installEventFilter( this );
309
310   myFindDlg = new OB_FindDlg( this );
311   myFindDlg->hide();
312
313   QVBoxLayout* main = new QVBoxLayout( this );
314   main->addWidget( myView, 1 );
315   main->addWidget( myFindDlg, 0 );
316
317   myShowToolTips = true;
318   myTooltip = new ToolTip( this, myView->viewport() );
319
320   connect( myView, SIGNAL( dropped( QPtrList<QListViewItem>, QListViewItem*, int ) ),
321            this, SLOT( onDropped( QPtrList<QListViewItem>, QListViewItem*, int ) ) );
322   connect( myView, SIGNAL( selectionChanged() ), this, SIGNAL( selectionChanged() ) );
323   connect( myView, SIGNAL( doubleClicked( QListViewItem* ) ),
324            this, SLOT( onDoubleClicked( QListViewItem* ) ) );
325
326   setRootObject( root );
327
328   setModified();
329 }
330
331 /*!
332   Destructor
333 */
334 OB_Browser::~OB_Browser()
335 {
336   myItems.clear();
337   delete myTooltip;
338   setUpdater( 0 );
339 }
340
341 /*!
342   \return true if root is decorated by +
343 */
344 bool OB_Browser::rootIsDecorated() const
345 {
346   return myRootDecorated;
347 }
348
349 /*!
350   Sets state "root is recorated"
351   \param decor - new value of state
352 */
353 void OB_Browser::setRootIsDecorated( const bool decor )
354 {
355   if ( decor == rootIsDecorated() ) 
356     return;
357
358   myRootDecorated = decor;
359   updateTree( 0, false );
360 }
361
362 /*!
363   \return number of levels to be auto opened on update tree
364 */
365 int OB_Browser::autoOpenLevel() const
366 {
367   return myAutoOpenLevel;
368 }
369
370 /*!
371   Changes number of levels to be auto opened on update tree
372   \param level - new number of levels
373 */
374 void OB_Browser::setAutoOpenLevel( const int level )
375 {
376   if ( myAutoOpenLevel == level )
377     return;
378
379   myAutoOpenLevel = level;
380 }
381
382 /*!
383   Opens branches from 1 to \alevels. If parameter value negative then autoOpenLevel() value will be used.
384   \sa autoOpenLevel()
385 */
386 void OB_Browser::openLevels( const int levels )
387 {
388   int level = levels < 0 ? autoOpenLevel() : levels;
389   QListView* lv = listView();
390   if ( !lv || level < 1 )
391     return;
392
393   QListViewItem* item = lv->firstChild();
394   while ( item )
395   {
396     openBranch( item, level );
397     item = item->nextSibling();
398   }
399 }
400
401 /*!
402   \return state "are tooltips shown"
403 */
404 bool OB_Browser::isShowToolTips()
405 {
406   return myShowToolTips;
407 }
408
409 /*!
410   Sets new value of state "are tooltips shown"
411   \param theDisplay - new value
412 */
413 void OB_Browser::setShowToolTips( const bool theDisplay )
414 {
415   myShowToolTips = theDisplay;
416 }
417
418 /*!
419   \return true if object browser automatically updates tree after SUIT object removing
420 */
421 bool OB_Browser::isAutoUpdate() const
422 {
423   return myAutoUpdate;
424 }
425
426 /*!
427   Sets new value of "auto update": whether object browser automatically updates tree after SUIT object removing
428 */
429 void OB_Browser::setAutoUpdate( const bool on )
430 {
431   myAutoUpdate = on;
432 }
433
434 /*!
435   \return true if object browser must delete old tree on setRootObject(), replaceTree()
436   \sa setRootObject(), replaceTree()
437 */
438 bool OB_Browser::isAutoDeleteObjects() const
439 {
440   return myAutoDelObjs;
441 }
442
443 /*!
444   Sets whether object browser must delete old tree on setRootObject(), replaceTree()
445   \sa setRootObject(), replaceTree()
446 */
447 void OB_Browser::setAutoDeleteObjects( const bool on )
448 {
449   myAutoDelObjs = on;
450 }
451
452 /*!
453   \return updater of browser
454 */
455 OB_Updater* OB_Browser::getUpdater() const
456 {
457   return myUpdater;
458 }
459
460 /*!
461   \sets new updater of browser
462 */
463 void OB_Browser::setUpdater( OB_Updater* theUpdate )
464 {
465   if( myUpdater )
466     delete myUpdater;
467   myUpdater = theUpdate;
468 }
469
470 /*!
471   \return root SUIT object of browser
472 */
473 SUIT_DataObject* OB_Browser::getRootObject() const
474 {
475   return myRoot;
476 }
477
478 /*!
479   Sets new root SUIT object of browser
480   \param theRoot - new root object
481 */
482 void OB_Browser::setRootObject( SUIT_DataObject* theRoot )
483 {
484   DataObjectKey curKey;
485   DataObjectMap selObjs, openObjs;
486   DataObjectKeyMap selKeys, openKeys;
487
488   int selNum = numberOfSelected();
489
490   SUIT_DataObject* curObj = 0;
491   if ( theRoot )
492     curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey );
493
494   removeConnections( myRoot );
495   if ( myRoot != theRoot && isAutoDeleteObjects() )
496     delete myRoot;
497
498   myRoot = theRoot;
499
500   createConnections( myRoot );
501
502   if ( myRoot )
503     updateView( myRoot );
504   else if ( listView() )
505   {
506     myItems.clear();
507     listView()->clear();
508   }
509
510   restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
511
512   autoOpenBranches();
513
514   setModified();
515
516   if ( selNum != numberOfSelected() )
517     emit selectionChanged();
518 }
519
520 /*!
521   \return number of selected items
522 */
523 int OB_Browser::numberOfSelected() const
524 {
525   int count = 0;
526   if ( listView() )
527   {
528     for ( QListViewItemIterator it( listView() ); it.current(); ++it )
529       if ( it.current()->isSelected() ) 
530         count++;
531   }
532   return count;
533 }
534
535 /*!
536   \return list of selected objects
537 */
538 DataObjectList OB_Browser::getSelected() const
539 {
540   DataObjectList lst;
541   getSelected( lst );
542   return lst;
543 }
544
545 /*!
546   Fills list with selected objects
547 */
548 void OB_Browser::getSelected( DataObjectList& theObjList ) const
549 {
550   theObjList.clear();
551
552   if ( !listView() )
553     return;
554
555   for ( QListViewItemIterator it( listView() ); it.current(); ++it )
556   {
557     if ( it.current()->isSelected() ) 
558     {
559       SUIT_DataObject* obj = dataObject( it.current() );
560       if ( obj )
561         theObjList.append( obj );
562     }
563   }
564 }
565
566 /*!
567   Sets selected object
568   \param theObject - new selected object
569   \param append - if it is true, then other selected objects are left as selected,
570   otherwise only 'theObject' will be selected
571 */
572 void OB_Browser::setSelected( const SUIT_DataObject* theObject, const bool append )
573 {
574   DataObjectList lst;
575   lst.append( theObject );
576   setSelected( lst, append );
577 }
578
579 /*!
580   Sets selected objects
581   \param theObjLst - new selected objects
582   \param append - if it is true, then other selected objects are left as selected,
583   otherwise only 'theObjLst' will be selected
584 */
585 void OB_Browser::setSelected( const DataObjectList& theObjLst, const bool append )
586 {
587   QListView* lv = listView();
588
589   if ( !lv )
590     return;
591
592   bool changed = false;
593   bool block = lv->signalsBlocked();
594   lv->blockSignals( true );
595
596   QMap<QListViewItem*, int> map;
597   for ( DataObjectListIterator itr( theObjLst ); itr.current(); ++itr )
598     map.insert( listViewItem( itr.current() ), 0 );
599
600   for ( QListViewItemIterator it( lv ); it.current(); ++it )
601   {
602     QListViewItem* item = it.current();
603     if ( map.contains( item ) && !lv->isSelected( item ) )
604     {
605       changed = true;
606       lv->setSelected( item, true );
607     }
608     if ( !append && !map.contains( item ) && lv->isSelected( item ) )
609     {
610       changed = true;
611       lv->setSelected( item, false );
612     }
613   }
614
615   lv->blockSignals( block );
616
617   if ( changed )
618   {
619     int count = 0;
620     QListViewItem* sel = 0;
621     QListViewItem* cur = lv->currentItem();
622     for ( QListViewItemIterator iter( lv ); iter.current() && !sel; ++iter, count++ )
623     {
624       if ( iter.current()->isSelected() && cur == iter.current() )
625         sel = iter.current();
626     }
627
628     for ( QListViewItemIterator itr( lv ); itr.current() && !sel; ++itr )
629     {
630       if ( itr.current()->isSelected() )
631               sel = itr.current();
632     }
633
634     if ( sel )
635       lv->setCurrentItem( sel );
636
637     if ( sel && count == 1 )
638       lv->ensureItemVisible( sel );
639
640     emit selectionChanged();
641   }
642 }
643
644 /*!
645   \return true if item corresponding to object is opened
646   \param theObject - object to be checked
647 */
648 bool OB_Browser::isOpen( SUIT_DataObject* theObject ) const
649 {
650   bool res = false;
651   if ( listView() )
652     res = listView()->isOpen( listViewItem( theObject ) );
653   return res;
654 }
655
656 /*!
657   Sets opened state of item
658   \param theObject - object corresponding to item
659   \param theOpen - new opened state
660 */
661 void OB_Browser::setOpen( SUIT_DataObject* theObject, const bool theOpen )
662 {
663   if ( listView() )
664     listView()->setOpen( listViewItem( theObject ), theOpen );
665 }
666
667 /*!
668   \return SUIT object correspondint to item at position 'pos'
669   \param pos - position
670 */
671 SUIT_DataObject* OB_Browser::dataObjectAt( const QPoint& pos ) const
672 {
673   SUIT_DataObject* obj = 0;
674
675   QListView* lv = listView();
676   if ( lv )
677     obj = dataObject( lv->itemAt( pos ) );
678
679   return obj;
680 }
681
682 /*!
683   \return filter of list view
684 */
685 OB_Filter* OB_Browser::filter() const
686 {
687   return myView->filter();
688 }
689
690 /*!
691   Changes filter of list view
692   \param f - new filter
693 */
694 void OB_Browser::setFilter( OB_Filter* f )
695 {
696   myView->setFilter( f );
697 }
698
699 /*!
700   Adds new column to list view
701   \param label - title of column
702   \param id - id of column
703   \param width - width of column
704 */
705 int OB_Browser::addColumn( const QString& label, const int id, const int width )
706 {
707   return addColumn( QIconSet(), label, id, width );
708 }
709
710 /*!
711   Adds new column to list view
712   \param icon - icon of column
713   \param label - title of column
714   \param id - id of column
715   \param width - width of column
716 */
717 int OB_Browser::addColumn( const QIconSet& icon, const QString& label, const int id, const int width )
718 {
719   QListView* lv = listView();
720   if ( !lv )
721     return -1;
722
723   int theId = id;
724   if ( theId < 0 )
725   {
726     while ( myColumnIds.contains( theId ) )
727       theId++;
728   }
729
730   if ( myColumnIds.contains( theId ) )
731     return -1; // can not reuse id
732
733   int sec = -1;
734   if ( icon.isNull() )
735     sec = lv->addColumn( label, width );
736   else
737     sec = lv->addColumn( icon, label, width );
738
739   if ( sec == -1 )
740     return -1;
741
742   myColumnIds.insert( theId, sec );
743   updateText();
744
745   return theId;
746 }
747
748 /*!
749   Removes column
750   \param id - id of column
751 */
752 void OB_Browser::removeColumn( const int id )
753 {
754   QListView* lv = listView();
755   if ( !lv || !myColumnIds.contains( id ) )
756     return;
757
758   int sec = myColumnIds[id];
759   lv->removeColumn( sec );
760
761   // update map of column indeces
762   myColumnIds.remove( id );
763   for ( QMap<int, int>::iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
764   {
765     if ( it.key() > id )
766       it.data()--;
767   }
768   updateText();
769 }
770
771 /*!
772   Sets title of first column (name column)
773   \param label - new title
774 */
775 void OB_Browser::setNameTitle( const QString& label )
776 {
777   setNameTitle( QIconSet(), label );
778 }
779
780 /*!
781   Sets title and icon of first column (name column)
782   \param icon - new icon
783   \param label - new title
784 */
785 void OB_Browser::setNameTitle( const QIconSet& icon, const QString& label )
786 {
787   QListView* lv = listView();
788   if ( !lv )
789     return;
790
791   if ( icon.isNull() )
792     lv->setColumnText( 0, label );
793   else
794     lv->setColumnText( 0, icon, label );
795 }
796
797 /*!
798   Sets title of column
799   \param id - column id
800   \param label - new column title
801 */
802 void OB_Browser::setColumnTitle( const int id, const QString& label )
803 {
804   setColumnTitle( id, QIconSet(), label );
805 }
806
807 /*!
808   Sets title and icon of column
809   \param id - column id
810   \param icon - new column icon
811   \param label - new column title
812 */
813 void OB_Browser::setColumnTitle( const int id, const QIconSet& icon, const QString& label )
814 {
815   QListView* lv = listView();
816   if ( !lv || !myColumnIds.contains( id ) )
817     return;
818
819   if ( icon.isNull() )
820     lv->setColumnText( myColumnIds[id], label );
821   else
822     lv->setColumnText( myColumnIds[id], icon, label );
823 }
824
825 /*!
826   \return title of first column (name column)
827 */
828 QString OB_Browser::nameTitle() const
829 {
830   return myView->columnText( 0 );
831 }
832
833 /*!
834   \return title of first column (name column)
835   \param id - column id
836 */
837 QString OB_Browser::columnTitle( const int id ) const
838 {
839   QString txt;
840   if ( myColumnIds.contains( id ) )
841     txt = myView->columnText( myColumnIds[id] );
842   return txt;
843 }
844
845 /*!
846   \return true if column is visible
847   \param id - column id
848 */
849 bool OB_Browser::isColumnVisible( const int id ) const
850 {
851   return myColumnIds.contains( id ) && myView->isShown( myColumnIds[id] );
852 }
853
854 /*!
855   Sets visibility of column
856   \param id - column id
857   \param on - new visibility state
858 */
859 void OB_Browser::setColumnShown( const int id, const bool on )
860 {
861   if ( !myColumnIds.contains( id ) )
862     return;
863
864   myView->setShown( myColumnIds[id], on );
865   if( !on )
866     myView->setColumnWidthMode( myColumnIds[id], QListView::Manual );
867 }
868
869 /*!
870   Sets global width mode
871   \param mode - new width mode
872 */
873 void OB_Browser::setWidthMode( QListView::WidthMode mode )
874 {
875   for ( int i = 0, n = myView->columns(); i < n; i++ )
876     if( mode!=QListView::Maximum || myView->columnWidth( i )>0 )
877       myView->setColumnWidthMode( i, mode );
878 }
879
880 /*!
881   \return list of columns ids
882 */
883 QValueList<int> OB_Browser::columns() const
884 {
885   QValueList<int> lst;
886   for ( QMap<int, int>::ConstIterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
887     lst.append( it.key() );
888   return lst;
889 }
890
891 /*!
892   \return true if it is possible to show/hide column by popup
893   \param id - column id
894 */
895 bool OB_Browser::appropriateColumn( const int id ) const
896 {
897   bool res = false;
898   if ( myColumnIds.contains( id ) )
899     res = myView->appropriate( myColumnIds[id] );
900   return res;
901 }
902
903 /*!
904   Sets "appropriate state": is it possible to show/hide column by popup
905   \param id - column id
906   \param on - new state
907 */
908 void OB_Browser::setAppropriateColumn( const int id, const bool on )
909 {
910   if ( !myColumnIds.contains( id ) )
911     return;
912
913   myView->setAppropriate( myColumnIds[id], on );
914 }
915
916 /*!
917   Updates tree
918   \param obj - start object
919   \param autoOpen - to open automatically branches of autoOpenLevel()
920   \sa autoOpenLevel()
921 */
922 void OB_Browser::updateTree( SUIT_DataObject* obj, const bool autoOpen )
923 {
924 //  QTime t1 = QTime::currentTime();
925
926   if ( !obj && !(obj = getRootObject()) )
927     return;
928
929   DataObjectKey curKey;
930   DataObjectMap selObjs, openObjs;
931   DataObjectKeyMap selKeys, openKeys;
932
933   int selNum = numberOfSelected();
934
935   SUIT_DataObject* curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey );
936
937   updateView( obj );
938
939   restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
940
941   if ( autoOpen )
942     autoOpenBranches();
943
944   setModified();
945
946   if ( selNum != numberOfSelected() )
947     emit selectionChanged();
948
949 //  QTime t2 = QTime::currentTime();
950 //  qDebug( QString( "update tree time = %1 msecs" ).arg( t1.msecsTo( t2 ) ) );
951 }
952
953 /*!
954   Replaces part of tree starting at object 'src' by tree starting at object 'trg'
955 */
956 void OB_Browser::replaceTree( SUIT_DataObject* src, SUIT_DataObject* trg )
957 {
958   if ( !src || !trg || src == trg || src->root() != getRootObject() )
959     return;
960
961   DataObjectKey curKey;
962   DataObjectMap selObjs, openObjs;
963   DataObjectKeyMap selKeys, openKeys;
964
965   int selNum = numberOfSelected();
966
967   SUIT_DataObject* curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey );
968
969   SUIT_DataObject* parent = src->parent();
970   int pos = parent ? parent->childPos( src ) : -1;
971
972   src->setParent( 0 );
973
974   removeConnections( src );
975   if ( isAutoDeleteObjects() )
976     delete src;
977
978   if ( parent && pos != -1 )
979     parent->insertChild( trg, pos );
980
981   trg->setParent( parent );
982
983   updateView( trg );
984   createConnections( trg );
985
986   restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
987
988   setModified();
989
990   if ( selNum != numberOfSelected() )
991     emit selectionChanged();
992 }
993
994 /*!
995   Updates view
996   \param startObj - start object
997 */
998 void OB_Browser::updateView( SUIT_DataObject* startObj )
999 {
1000   QListView* lv = listView();
1001   if ( !lv )
1002     return;
1003
1004   if ( !startObj || startObj->root() != getRootObject() )
1005     return;
1006
1007   //qDebug( "updateView:" );
1008   //startObj->dump();
1009
1010   if ( startObj == myRoot )
1011   {
1012     OB_BrowserSync sync( this );
1013     synchronize<ObjPtr,ItemPtr,OB_BrowserSync>( myRoot, 0, sync );
1014   }
1015   else
1016   {
1017     OB_BrowserSync sync( this );
1018     OB_ListItem* startItem = dynamic_cast<OB_ListItem*>( listViewItem( startObj ) );
1019     synchronize<ObjPtr,ItemPtr,OB_BrowserSync>( startObj, startItem, sync );
1020   }
1021 }
1022
1023 /*!
1024   Creates new list item
1025   \return new item
1026   \param o - corresponding SUIT object
1027   \param parent - parent item
1028   \param after - item after that new item must be added
1029   \param prepend - new item must be added as first
1030 */
1031 QListViewItem* OB_Browser::createItem( const SUIT_DataObject* o, QListViewItem* parent,
1032                                        QListViewItem* after, const bool prepend )
1033 {
1034   QListView* lv = listView();
1035
1036   if ( !lv || !o )
1037     return 0;
1038
1039   QListViewItem* item = 0;
1040   SUIT_DataObject* obj = (SUIT_DataObject*)o;
1041
1042   int type = -1;
1043
1044   switch ( obj->checkType() )
1045   {
1046   case SUIT_DataObject::CheckBox:
1047     type = QCheckListItem::CheckBox;
1048     break;
1049   case SUIT_DataObject::RadioButton:
1050     type = QCheckListItem::RadioButton;
1051     break;
1052   }
1053
1054   if ( parent )
1055   {
1056     if ( after ) 
1057     {
1058       if ( type == -1 )
1059         item = new OB_ListItem( obj, parent, after );
1060       else
1061         item = new OB_CheckListItem( obj, parent, after, (QCheckListItem::Type)type );
1062     }
1063     else if ( prepend )
1064     {
1065       if ( type == -1 )
1066         item = new OB_ListItem( obj, parent );
1067       else
1068         item = new OB_CheckListItem( obj, parent,  (QCheckListItem::Type)type );
1069     }
1070     else // append
1071     {
1072       after = parent->firstChild();
1073       while ( after && after->nextSibling() )
1074         after = after->nextSibling();
1075       if ( type == -1 )
1076         item = new OB_ListItem( obj, parent, after );
1077       else
1078         item = new OB_CheckListItem( obj, parent, after, (QCheckListItem::Type)type );
1079     }
1080   }
1081   else
1082   {
1083     if ( after ) 
1084     {
1085       if ( type == -1 )
1086         item = new OB_ListItem( obj, lv, after );
1087       else
1088         item = new OB_CheckListItem( obj, lv, after, (QCheckListItem::Type)type );
1089     }
1090     else if ( prepend )
1091     {
1092       if ( type == -1 )
1093         item = new OB_ListItem( obj, lv );
1094       else
1095         item = new OB_CheckListItem( obj, lv,  (QCheckListItem::Type)type );
1096     }
1097     else // append
1098     {
1099       after = lv->firstChild();
1100       while ( after && after->nextSibling() )
1101         after = after->nextSibling();
1102       if ( type == -1 )
1103         item = new OB_ListItem( obj, lv, after );
1104       else
1105         item = new OB_CheckListItem( obj, lv, after, (QCheckListItem::Type)type );
1106     }
1107   }
1108
1109   myItems.insert( obj, item );
1110   obj->connect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1111   updateText( item );
1112
1113   return item;
1114 }
1115
1116 /*!
1117   Adjusts width by root item
1118 */
1119 void OB_Browser::adjustWidth()
1120 {
1121   if ( !listView() )
1122     return;
1123
1124   listView()->setColumnWidth( 0, 0 );
1125   if ( listView()->firstChild() )
1126     adjustWidth( listView()->firstChild() );
1127 }
1128
1129 /*!
1130   Adjusts width by item
1131   \param item
1132 */
1133 void OB_Browser::adjustWidth( QListViewItem* item )
1134 {
1135   while ( item )
1136   {
1137     item->widthChanged( 0 );
1138     if ( item->isOpen() )
1139       adjustWidth( item->firstChild() );
1140     item = item->nextSibling();
1141   }
1142 }
1143
1144 /*!
1145   \return SUIT object corresponding to item
1146   \param item
1147 */
1148 SUIT_DataObject* OB_Browser::dataObject( const QListViewItem* item ) const
1149 {
1150   SUIT_DataObject* obj = 0;
1151
1152   if ( item && item->rtti() == OB_ListItem::RTTI() )
1153     obj = ((OB_ListItem*)item)->dataObject();
1154   else if ( item && item->rtti() == OB_CheckListItem::RTTI() )
1155     obj = ((OB_CheckListItem*)item)->dataObject();
1156
1157   return obj;
1158 }
1159
1160 /*!
1161   \return item corresponding to SUIT object
1162   \param obj - SUIT object
1163 */
1164 QListViewItem* OB_Browser::listViewItem( const SUIT_DataObject* obj ) const
1165 {
1166   QListViewItem* item = 0;
1167
1168   if ( myItems.contains( (SUIT_DataObject*)obj ) )
1169     item = myItems[(SUIT_DataObject*)obj];
1170
1171   return item;
1172 }
1173
1174 /*!
1175   \return list view of object browser
1176 */
1177 QListView* OB_Browser::listView() const
1178 {
1179   return myView;
1180 }
1181
1182 /*!
1183   \remove all items referencing current (through data objects)
1184 */
1185 void OB_Browser::removeReferences( QListViewItem* item )
1186 {
1187   if ( !item )
1188     return;
1189
1190   SUIT_DataObject* obj = dataObject( item );
1191   obj->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1192   myItems.remove( obj );
1193
1194   QListViewItem* i = item->firstChild();
1195   while ( i )
1196   {
1197     removeReferences( i );
1198     i = i->nextSibling();
1199   }
1200 }
1201
1202 /*!
1203   Connects all children to SLOT onDestroyed
1204 */
1205 void OB_Browser::createConnections( SUIT_DataObject* obj )
1206 {
1207   if ( !obj )
1208     return;
1209
1210   DataObjectList childList;
1211   obj->children( childList, true );
1212
1213   childList.prepend( obj );
1214
1215   for ( DataObjectListIterator it( childList ); it.current(); ++it )
1216     it.current()->connect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1217 }
1218
1219 /*!
1220   Disconnects all children from SLOT onDestroyed
1221 */
1222 void OB_Browser::removeConnections( SUIT_DataObject* obj )
1223 {
1224   if ( !obj )
1225     return;
1226
1227   DataObjectList childList;
1228   obj->children( childList, true );
1229
1230   childList.prepend( obj );
1231
1232   for ( DataObjectListIterator it( childList ); it.current(); ++it )
1233     it.current()->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1234 }
1235
1236 /*!
1237   Stores states (opened, selected) of current tree items
1238   \return current item
1239   \param selObjs, selKeys - maps of selected objects
1240   \param openObjs, openKeys - maps of opened objects
1241   \param curKey - map of current objects
1242 */
1243 SUIT_DataObject* OB_Browser::storeState( DataObjectMap& selObjs, DataObjectMap& openObjs,
1244                                          DataObjectKeyMap& selKeys, DataObjectKeyMap& openKeys,
1245                                          DataObjectKey& curKey ) const
1246 {
1247   QListView* lv = listView();
1248   if ( !lv )
1249     return 0;
1250
1251   SUIT_DataObject* curObj = dataObject( lv->currentItem() );
1252
1253   curKey = objectKey( curObj );
1254
1255   for ( QListViewItemIterator it( lv ); it.current(); ++it )
1256   {
1257     SUIT_DataObject* obj = dataObject( it.current() );
1258     if ( !obj )
1259       continue;
1260
1261     selObjs.insert( obj, lv->isSelected( it.current() ) );
1262     openObjs.insert( obj, lv->isOpen( it.current() ) );
1263     if ( lv->isSelected( it.current() ) )
1264       selKeys.insert( objectKey( obj ), 0 );
1265     if ( lv->isOpen( it.current() ) )
1266       openKeys.insert( objectKey( obj ), 0 );
1267   }
1268
1269   return curObj;
1270 }
1271
1272 /*!
1273   Restores states (opened, selected) of current tree items
1274   \param selObjs, selKeys - maps of selected objects
1275   \param openObjs, openKeys - maps of opened objects
1276   \param curKey - map of current objects
1277 */
1278 void OB_Browser::restoreState( const DataObjectMap& selObjs, const DataObjectMap& openObjs,
1279                                const SUIT_DataObject* curObj, const DataObjectKeyMap& selKeys,
1280                                const DataObjectKeyMap& openKeys, const DataObjectKey& curKey )
1281 {
1282   QListView* lv = listView();
1283   if ( !lv )
1284     return;
1285
1286   bool block = lv->signalsBlocked();
1287   lv->blockSignals( true );
1288
1289   QListViewItem* curItem = 0;
1290   for ( QListViewItemIterator it( lv ); it.current(); ++it )
1291   {
1292     QListViewItem* item = it.current();
1293     SUIT_DataObject* obj = dataObject( item );
1294
1295     if ( !obj )
1296       continue;
1297
1298     DataObjectKey key = objectKey( obj );
1299
1300     if ( selObjs.contains( obj ) )
1301     {
1302       if ( selObjs[obj] && !lv->isSelected( item ) )
1303         lv->setSelected( item, true );
1304     }
1305     else if ( !key.isNull() && selKeys.contains( key ) && !lv->isSelected( item ) )
1306       lv->setSelected( item, true );
1307
1308     if ( openObjs.contains( obj ) )
1309     {
1310       bool parentOpen = true;
1311       if( item && item->parent() )
1312         parentOpen = item->parent()->isOpen();
1313         
1314       if ( openObjs[obj] && parentOpen )
1315         lv->setOpen( item, true );
1316     }
1317     else if ( !key.isNull() && openKeys.contains( key ) )
1318     {
1319       bool parentOpen = true;
1320       if( item && item->parent() )
1321         parentOpen = item->parent()->isOpen();
1322
1323       if( parentOpen )
1324         lv->setOpen( item, true );
1325     }
1326
1327     if ( !curItem && ( curObj == obj || ( !curKey.isNull() && curKey == key )) )
1328       curItem = item;
1329   }
1330
1331   if ( curItem )
1332     lv->setCurrentItem( curItem );
1333
1334   lv->blockSignals( block );
1335 }
1336
1337 /*!
1338   Creates object key by tree item
1339 */
1340 OB_Browser::DataObjectKey OB_Browser::objectKey( QListViewItem* i ) const
1341 {
1342   return objectKey( dataObject( i ) );
1343 }
1344
1345 /*!
1346   Creates object key by SUIT object
1347 */
1348 OB_Browser::DataObjectKey OB_Browser::objectKey( SUIT_DataObject* obj ) const
1349 {
1350   if ( !obj )
1351     return 0;
1352
1353   return DataObjectKey( obj->key() );
1354 }
1355
1356 /*!
1357   Custom key press event handler, updates tree by F5
1358 */
1359 void OB_Browser::keyPressEvent( QKeyEvent* e )
1360 {
1361   if ( e->key() == Qt::Key_F5 )
1362     updateTree( 0, false );
1363
1364   QFrame::keyPressEvent( e );
1365 }
1366
1367 /*!
1368   SLOT: called if action "Expand all" is activated
1369 */
1370 void OB_Browser::onExpand()
1371 {
1372   DataObjectList selected;
1373   getSelected( selected );
1374   for ( DataObjectListIterator itr( selected ); itr.current(); ++itr )
1375     expand( listViewItem( itr.current() ) );
1376 }
1377
1378 /*!
1379   SLOT: called if action "Show/hide column" is activated by popup
1380 */
1381 void OB_Browser::onColumnVisible( int id )
1382 {
1383   setColumnShown( id, !isColumnVisible( id ) );
1384 }
1385
1386 /*!
1387   SLOT: called if SUIT object is destroyed
1388 */
1389 void OB_Browser::onDestroyed( SUIT_DataObject* obj )
1390 {
1391   removeObject( obj );
1392 }
1393
1394 /*!
1395   SLOT: called on finish of drag-n-drop operation
1396   \param items - dragged items
1397   \param item - destination (item on that they were dropped)
1398   \param action - QDropEvent::Action
1399 */
1400 void OB_Browser::onDropped( QPtrList<QListViewItem> items, QListViewItem* item, int action )
1401 {
1402   SUIT_DataObject* obj = dataObject( item );
1403   if ( !obj )
1404     return;
1405
1406   DataObjectList lst;
1407   for ( QPtrListIterator<QListViewItem> it( items ); it.current(); ++it )
1408   {
1409     SUIT_DataObject* o = dataObject( it.current() );
1410     if ( o )
1411       lst.append( o );
1412   }
1413
1414   if ( !lst.isEmpty() )
1415     emit dropped( lst, obj, action );
1416 }
1417
1418 /*!
1419   Updates texts of items
1420 */
1421 void OB_Browser::updateText()
1422 {
1423   if ( myColumnIds.isEmpty() )
1424     return;
1425
1426   QListView* lv = listView();
1427   if ( !lv )
1428     return;
1429
1430   for ( QListViewItemIterator it( lv ); it.current(); ++it )
1431   {
1432     SUIT_DataObject* obj = dataObject( it.current() );
1433     if ( !obj )
1434       continue;
1435
1436     for( QMap<int, int>::iterator itr = myColumnIds.begin(); itr != myColumnIds.end(); ++itr )
1437       it.current()->setText( itr.data(), obj->text( itr.key() ) );
1438   }
1439 }
1440
1441 /*!
1442   \return true if item must be updated
1443   \param item - item to be checked
1444 */
1445 bool OB_Browser::needToUpdateTexts( QListViewItem* item ) const
1446 {
1447   SUIT_DataObject* obj = dataObject( item );
1448   if ( !obj )
1449     return false;
1450
1451   for( QMap<int, int>::const_iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
1452     if( item->text( it.data() ) != obj->text( it.key() ) )
1453       return true;
1454   return false;
1455 }
1456
1457 /*!
1458   Updates texts of item
1459   \param item - item to be updated
1460 */
1461 void OB_Browser::updateText( QListViewItem* item )
1462 {
1463   SUIT_DataObject* obj = dataObject( item );
1464   if ( !obj )
1465     return;
1466
1467   for( QMap<int, int>::iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
1468     item->setText( it.data(), obj->text( it.key() ) );
1469 }
1470
1471 /*!
1472   Custom event filter
1473 */
1474 bool OB_Browser::eventFilter( QObject* o, QEvent* e )
1475 {
1476   if ( o == myView && e->type() == QEvent::ContextMenu )
1477   {
1478     QContextMenuEvent* ce = (QContextMenuEvent*)e;
1479     if ( ce->reason() != QContextMenuEvent::Mouse )
1480       contextMenuRequest( ce );
1481     return true;
1482   }
1483   if ( o == myView->viewport() && e->type() == QEvent::MouseButtonRelease )
1484   {
1485     QMouseEvent* me = (QMouseEvent*)e;
1486     if ( me->button() == RightButton )
1487     {
1488       QContextMenuEvent ce( QContextMenuEvent::Mouse, me->pos(), me->globalPos(), me->state() );
1489       contextMenuRequest( &ce );
1490       return true;
1491     }
1492   }
1493
1494   return QFrame::eventFilter( o, e );
1495 }
1496
1497 /*!
1498   Adds custom actions to popup
1499   \param menu - popup menu
1500 */
1501 void OB_Browser::contextMenuPopup( QPopupMenu* menu )
1502 {
1503 /*  QValueList<int> cols;
1504   for ( QMap<int, int>::ConstIterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
1505   {
1506     if ( appropriateColumn( it.key() ) )
1507       cols.append( it.key() );
1508   }
1509
1510   uint num = menu->count();
1511   menu->setCheckable( true );
1512   for ( QValueList<int>::const_iterator iter = cols.begin(); iter != cols.end(); ++iter )
1513   {
1514     QString name = columnTitle( *iter );
1515     if ( name.isEmpty() )
1516       continue;
1517
1518     int id = menu->insertItem( name, this, SLOT( onColumnVisible( int ) ) );
1519     menu->setItemChecked( id, isColumnVisible( *iter ) );
1520     menu->setItemParameter( id, *iter );
1521   }
1522   if ( menu->count() != num )
1523     menu->insertSeparator();*/
1524
1525   DataObjectList selected;
1526   getSelected( selected );
1527
1528   bool closed = false;
1529   for ( DataObjectListIterator itr( selected ); itr.current() && !closed; ++itr )
1530     closed = hasClosed( listViewItem( itr.current() ) );
1531
1532   if ( closed )
1533   {
1534     menu->insertItem( tr( "MEN_EXPAND_ALL" ), this, SLOT( onExpand() ) );
1535     menu->insertSeparator();
1536   }
1537 }
1538
1539 /*!
1540   Expands item with all it's children
1541 */
1542 void OB_Browser::expand( QListViewItem* item )
1543 {
1544   if ( !item )
1545     return;
1546
1547   item->setOpen( true );
1548   for ( QListViewItem* child = item->firstChild(); child; child = child->nextSibling() )
1549     expand( child );
1550 }
1551
1552 /*!
1553   \return true if item or one of it's children isn't opened
1554 */
1555 bool OB_Browser::hasClosed( QListViewItem* item ) const
1556 {
1557   if ( !item )
1558     return false;
1559
1560   if ( item->childCount() && !item->isOpen() )
1561     return true;
1562
1563   bool has = false;
1564   for ( QListViewItem* child = item->firstChild(); child && !has; child = child->nextSibling() )
1565     has = hasClosed( child );
1566
1567   return has;
1568 }
1569
1570 /*!
1571   Removes SUIT object
1572   \param obj - SUIT object to be removed
1573   \param autoUpd - auto tree updating
1574 */
1575 void OB_Browser::removeObject( SUIT_DataObject* obj, const bool autoUpd )
1576 {
1577   if ( !obj )
1578     return;
1579
1580   // Removing list view items from <myItems> recursively for all children.
1581   // Otherwise, "delete item" line will destroy all item's children,
1582   // and <myItems> will contain invalid pointers (see ~QListViewItem() description in Qt docs)
1583   DataObjectList childList;
1584   obj->children( childList, true );
1585   for ( DataObjectListIterator it( childList ); it.current(); ++it )
1586   {
1587     it.current()->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1588     myItems.remove( it.current() );
1589   }
1590
1591   QListViewItem* item = listViewItem( obj );
1592
1593   obj->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1594   myItems.remove( obj );
1595
1596   if ( obj == myRoot )
1597   {
1598     // remove all child list view items
1599     setRootObject( 0 );
1600     return;
1601   }
1602
1603   if( !autoUpd )
1604     return;
1605
1606   if ( isAutoUpdate() )
1607   {
1608     SUIT_DataObject* pObj = item && item->parent() ? dataObject( item->parent() ) : 0;
1609     updateTree( pObj, false );
1610   }
1611
1612   delete item;
1613 }
1614
1615 /*!
1616   Opens branches from 1 to autoOpenLevel()
1617   \sa autoOpenLevel()
1618 */
1619 void OB_Browser::autoOpenBranches()
1620 {
1621   openLevels();
1622 }
1623
1624 /*!
1625   Opens branch
1626   \param item
1627   \param level
1628 */
1629 void OB_Browser::openBranch( QListViewItem* item, const int level )
1630 {
1631   if ( level < 1 )
1632     return;
1633
1634   while ( item )
1635   {
1636     item->setOpen( true );
1637     openBranch( item->firstChild(), level - 1 );
1638     item = item->nextSibling();
1639   }
1640 }
1641
1642 /*!
1643   SLOT: called on double click on item, emits signal
1644 */
1645 void OB_Browser::onDoubleClicked( QListViewItem* item )
1646 {
1647   if ( item )
1648     emit doubleClicked( dataObject( item ) );
1649 }
1650
1651 /*!
1652   Stores time of last modification
1653 */
1654 void OB_Browser::setModified()
1655 {
1656   myModifiedTime = clock();
1657 }
1658
1659 OB_ObjSearch* OB_Browser::getSearch() const
1660 {
1661   return myFindDlg->getSearch();
1662 }
1663
1664 void OB_Browser::setSearch( OB_ObjSearch* s )
1665 {
1666   myFindDlg->setSearch( s );
1667 }
1668
1669 void OB_Browser::enableSearch( const bool on )
1670 {
1671   myFindDlg->setShown( on );
1672 }