Salome HOME
Popup item "Refresh"
[modules/gui.git] / src / Qtx / QtxDockAction.cxx
1 // File:      QtxDockAction.cxx
2 // Author:    Sergey TELKOV
3
4 #include "QtxDockAction.h"
5
6 #include "QtxResourceMgr.h"
7
8 #include <qevent.h>
9 #include <qtoolbar.h>
10 #include <qdockarea.h>
11 #include <qdockwindow.h>
12 #include <qmainwindow.h>
13 #include <qapplication.h>
14
15 /*!
16         Name: QtxDockAction [public]
17         Desc: Constructs an Dock action with given main window and name.
18 */
19
20 QtxDockAction::QtxDockAction( QMainWindow* mw, const char* name )
21 : QtxAction( "Windows and Toolbars", "Windows and Toolbars", 0, mw, name ),
22 myMain( mw ),
23 myAutoAdd( true ),
24 mySeparate( true ),
25 myAutoPlace( true )
26 {
27   initialize( mw );
28 }
29
30 /*!
31         Name: QtxDockAction [public]
32         Desc: This constructor creates an action with the following properties: the
33                     description text, the menu text and. It is a child of given main window
34         and named specified name.
35 */
36
37 QtxDockAction::QtxDockAction( const QString& text, const QString& menuText, QMainWindow* mw, const char* name )
38 : QtxAction( text, menuText, 0, mw, name ),
39 myMain( mw ),
40 myAutoAdd( true ),
41 mySeparate( true ),
42 myAutoPlace( true )
43 {
44   initialize( mw );
45 }
46
47 /*!
48         Name: QtxDockAction [public]
49         Desc: This constructor creates an action with the following properties: the
50                     description text, the menu text, the icon or iconset icon and keyboard
51         accelerator. It is a child of given main window and named specified name.
52 */
53
54 QtxDockAction::QtxDockAction( const QString& text, const QIconSet& icon, const QString& menuText, QMainWindow* mw, const char* name )
55 : QtxAction( text, icon, menuText, 0, mw, name ),
56 myMain( mw ),
57 myAutoAdd( true ),
58 mySeparate( true ),
59 myAutoPlace( true )
60 {
61   initialize( mw );
62 }
63
64 /*!
65         Name: ~QtxDockAction [public]
66         Desc: Removes all added popup items.
67 */
68
69 QtxDockAction::~QtxDockAction()
70 {
71   for ( MenuMap::ConstIterator mIt = myMenu.begin(); mIt != myMenu.end(); ++mIt )
72     removeFrom( mIt.key() );
73
74   for ( InfoMap::ConstIterator iIt = myInfo.begin(); iIt != myInfo.end(); ++iIt )
75     delete iIt.data().a;
76 }
77
78 /*!
79         Name: mainWindow [public]
80         Desc: Returns the main window which contains managed dock windows.
81 */
82
83 QMainWindow* QtxDockAction::mainWindow() const
84 {
85   return myMain;
86 }
87
88 /*!
89         Name: isAutoAdd [public]
90         Desc: Returns the auto add property. If this property is setted then all newly
91         appeared dock windows will be automatically added.
92 */
93
94 bool QtxDockAction::isAutoAdd() const
95 {
96   return myAutoAdd;
97 }
98
99 /*!
100         Name: setAutoAdd [public]
101         Desc: Sets the auto add property. If this property is setted then all newly
102         appeared dock windows will be automatically added.
103 */
104
105 void QtxDockAction::setAutoAdd( const bool on )
106 {
107   myAutoAdd = on;
108 }
109
110 /*!
111         Name: isAutoPlace [public]
112         Desc: Returns the auto place property. If this property is setted then all newly
113         added dock windows will be automatically placed according stored place information.
114 */
115
116 bool QtxDockAction::isAutoPlace() const
117 {
118   return myAutoPlace;
119 }
120
121 /*!
122         Name: setAutoPlace [public]
123         Desc: Sets the auto place property. If this property is setted then all newly
124         added dock windows will be automatically placed according stored place
125         information.
126 */
127
128 void QtxDockAction::setAutoPlace( const bool on )
129 {
130   myAutoPlace = on;
131 }
132
133 /*!
134         Name: isSeparate [public]
135         Desc: Returns the 'separate' property.
136 */
137
138 bool QtxDockAction::isSeparate() const
139 {
140   return mySeparate;
141 }
142
143 /*!
144         Name: setSeparate [public]
145         Desc: Sets the 'separate' property. If this property is 'true' then toolbars and
146         dock windows menu items will be placed in different popup menus  otherwise
147         their will  be placed  in  one  common  popup  menu. This property will be
148         affected in next method 'addTo'.
149 */
150
151 void QtxDockAction::setSeparate( const bool on )
152 {
153   mySeparate = on;
154 }
155
156 /*!
157         Name: addTo [public]
158         Desc: Add the dock windows sub menu item to the end of specified popup.
159 */
160
161 bool QtxDockAction::addTo( QWidget* wid )
162 {
163   return addTo( wid, -1 );
164 }
165
166 /*!
167         Name: addTo [public]
168         Desc: Add the dock windows sub menu item to specified popup at the given index.
169 */
170
171 bool QtxDockAction::addTo( QWidget* wid, const int idx )
172 {
173   if ( !wid || !wid->inherits( "QPopupMenu" ) )
174     return false;
175
176   QPopupMenu* pm = (QPopupMenu*)wid;
177   checkPopup( pm );
178
179   if ( myMenu.contains( pm ) )
180     return false;
181
182   MenuInfo mInfo;
183   mInfo.dock = new QPopupMenu( pm );
184   mInfo.tool = isSeparate() ? new QPopupMenu( pm ) : 0;
185
186   QString dock, tool;
187   splitMenuText( dock, tool );
188
189   myMenu.insert( pm, mInfo );
190
191   int index = idx;
192
193   if ( mInfo.dock )
194     iconSet().isNull() ? pm->insertItem ( dock, mInfo.dock, -1, index ) :
195                          pm->insertItem ( iconSet(), dock, mInfo.dock, -1, index );
196
197   if ( index >= 0 )
198     index++;
199
200   if ( mInfo.tool )
201     iconSet().isNull() ? pm->insertItem ( tool, mInfo.tool, -1, index ) :
202                          pm->insertItem ( iconSet(), tool, mInfo.tool, -1, index );
203
204   connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
205   connect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) );
206
207   return true;
208 }
209
210 /*!
211         Name: removeFrom [public]
212         Desc: Removes dock window sub menu from specified popup.
213 */
214
215 bool QtxDockAction::removeFrom( QWidget* wid )
216 {
217   QPopupMenu* pm = (QPopupMenu*)wid;
218
219   if ( myMenu.contains( pm ) )
220   {
221     pm->removeItem( findId( pm, myMenu[pm].dock ) );
222     pm->removeItem( findId( pm, myMenu[pm].tool ) );
223
224     delete myMenu[pm].dock;
225     delete myMenu[pm].tool;
226     myMenu.remove( pm );
227
228     disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
229     disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) );
230   }
231
232   return QtxAction::removeFrom( wid );
233 }
234
235 /*!
236         Name: addDockWindow [public]
237         Desc: Add dock window to internal data structures. Action will be include all added
238         dock windows in to menu and manage their place configuration.
239 */
240
241 bool QtxDockAction::addDockWindow( QDockWindow* dw )
242 {
243   if ( !dw || !mainWindow() )
244     return false;
245
246   if ( myInfo.contains( dw ) )
247     return false;
248
249   myInfo.insert( dw, DockInfo() );
250
251   DockInfo& inf = myInfo[dw];
252   inf.name = windowName( dw );
253   QAction* a = inf.a = new QAction( mainWindow(), 0, true );
254
255   autoLoadPlaceInfo( dw );
256
257   bool block = a->signalsBlocked();
258   a->blockSignals( true );
259   a->setOn( dw->isVisibleTo( mainWindow() ) );
260   a->blockSignals( block );
261
262   updateInfo( dw );
263   savePlaceInfo( dw );
264
265   dw->installEventFilter( this );
266
267   connect( a, SIGNAL( toggled( bool ) ), this, SLOT( onToggled( bool ) ) );
268   connect( dw, SIGNAL( destroyed( QObject* ) ), this, SLOT( onWindowDestroyed( QObject* ) ) );
269   connect( dw, SIGNAL( visibilityChanged( bool ) ), this, SLOT( onVisibilityChanged( bool ) ) );
270
271   return true;
272 }
273
274 /*!
275         Name: removeDockWindow [public]
276         Desc: Remove dock window from internal data structures. Action will not manage this window.
277 */
278
279 bool QtxDockAction::removeDockWindow( QDockWindow* dw )
280 {
281   if ( !myInfo.contains( dw ) )
282     return false;
283
284   myGeom.remove( myInfo[dw].name );
285
286   delete myInfo[dw].a;
287   myInfo.remove( dw );
288
289   dw->removeEventFilter( this );
290
291   disconnect( dw, SIGNAL( destroyed( QObject* ) ), this, SLOT( onWindowDestroyed( QObject* ) ) );
292   disconnect( dw, SIGNAL( visibilityChanged( bool ) ), this, SLOT( onVisibilityChanged( bool ) ) );
293
294   return true;
295 }
296
297 /*!
298         Name: eventFilter [public]
299         Desc: Event filter process caption and icon changing of managed dock windows
300         and try to add newly appeared dock windows.
301 */
302
303 bool QtxDockAction::eventFilter( QObject* o, QEvent* e )
304 {
305   if ( o->inherits( "QDockWindow" ) && ( e->type() == QEvent::CaptionChange ||
306                                          e->type() == QEvent::IconChange ) )
307     updateInfo( (QDockWindow*)o );
308
309   if ( o->inherits( "QDockArea" ) && e->type() == QEvent::ChildRemoved )
310   {
311     QChildEvent* ce = (QChildEvent*)e;
312     if ( ce->child() && ce->child()->inherits( "QDockWindow" ) )
313       savePlaceInfo( (QDockWindow*)ce->child() );
314   }
315
316   if ( o->inherits( "QDockArea" ) && e->type() == QEvent::ChildInserted )
317   {
318     QChildEvent* ce = (QChildEvent*)e;
319     if ( ce->child() && ce->child()->inherits( "QDockWindow" ) )
320       QApplication::postEvent( this, new QCustomEvent( (QEvent::Type)AutoAdd, ce->child() ) );
321   }
322
323   return false;
324 }
325
326 /*!
327         Name: restoreGeometry [public]
328         Desc: Retrieve the dock window geometry. If dock window specified as 0
329         then all windows geometry will be restored.
330 */
331
332 void QtxDockAction::restoreGeometry( QDockWindow* dw ) const
333 {
334   QPtrList<QDockWindow> dwList;
335
336   if ( dw )
337     dwList.append( dw );
338   else
339     dockWindows( dwList );
340
341   for ( QPtrListIterator<QDockWindow> it( dwList ); it.current(); ++it )
342     loadPlaceInfo( it.current() );
343 }
344
345 /*!
346         Name: storeGeometry [public]
347         Desc: Store the dock window geometry. If dock window specified as 0
348         then all windows geometry will be stored.
349 */
350
351 void QtxDockAction::storeGeometry( QDockWindow* dw )
352 {
353   QPtrList<QDockWindow> dwList;
354
355   if ( dw )
356     dwList.append( dw );
357   else
358     dockWindows( dwList );
359
360   for ( QPtrListIterator<QDockWindow> it( dwList ); it.current(); ++it )
361     savePlaceInfo( it.current() );
362 }
363
364 /*!
365         Name: loadGeometry [public]
366         Desc: Retrieve the dock windows geometry information from the specified resource manager section.
367 */
368
369 void QtxDockAction::loadGeometry( QtxResourceMgr* resMgr, const QString& section, const bool clear )
370 {
371   QString sec = section.stripWhiteSpace();
372   if ( !resMgr || sec.isEmpty() )
373     return;
374
375   QMap<QString, int> map;
376   QStringList params = resMgr->parameters( sec );
377   for ( QStringList::const_iterator it = params.begin(); it != params.end(); ++it )
378   {
379     QString p = QStringList::split( ".", *it, true ).first().stripWhiteSpace();
380     if ( !p.isEmpty() )
381       map.insert( p, 0 );
382   }
383
384   for ( QMap<QString, int>::ConstIterator itr = map.begin(); itr != map.end(); ++itr )
385   {
386     GeomInfo inf;
387     if ( !clear && myGeom.contains( itr.key() ) )
388       inf = myGeom[itr.key()];
389     else
390     {
391       inf.vis = true; inf.newLine = false; inf.place = DockTop;
392       inf.index = 0; inf.offset = 0;
393       inf.x = 0; inf.y = 0; inf.w = 0; inf.h = 0;
394       inf.fixW = -1; inf.fixH = -1;
395     }
396     if ( loadGeometry( resMgr, sec, itr.key(), inf ) )
397       myGeom.insert( itr.key(), inf );
398   }
399 }
400
401 /*!
402         Name: saveGeometry [public]
403         Desc: Store the dock windows geometry information into the specified resource manager section.
404 */
405
406 void QtxDockAction::saveGeometry( QtxResourceMgr* resMgr, const QString& section, const bool clear ) const
407 {
408   QString sec = section.stripWhiteSpace();
409   if ( !resMgr || sec.isEmpty() )
410     return;
411
412   if ( clear )
413     resMgr->removeSection( sec );
414
415   for ( GeomMap::ConstIterator it = myGeom.begin(); it != myGeom.end(); ++it )
416     saveGeometry( resMgr, sec, it.key(), it.data() );
417 }
418
419 /*!
420         Name: onAboutToShow [private slots]
421         Desc: Prepare sub popup with dock windows list when parent popup is shown.
422 */
423
424 void QtxDockAction::onAboutToShow()
425 {
426   const QObject* obj = sender();
427   if ( obj && obj->inherits( "QPopupMenu" ) )
428   {
429     QPopupMenu* pm = (QPopupMenu*)obj;
430     fillPopup( pm );
431     pm->setItemEnabled( findId( pm, myMenu[pm].dock ), isEnabled() && myMenu[pm].dock && myMenu[pm].dock->count() );
432     pm->setItemEnabled( findId( pm, myMenu[pm].tool ), isEnabled() && myMenu[pm].tool && myMenu[pm].tool->count() );
433   }
434 }
435
436 /*!
437         Name: onToggled [private slots]
438         Desc: Show or hide dock window when user toggled window item in popup.
439 */
440
441 void QtxDockAction::onToggled( bool on )
442 {
443   QDockWindow* dw = dockWindow( (QAction*)sender() );
444   if ( dw )
445     on ? dw->show() : dw->hide();
446 }
447
448 /*!
449         Name: onPopupDestroyed [private slots]
450         Desc: Remove destroyed popup from data structures.
451 */
452
453 void QtxDockAction::onPopupDestroyed( QObject* obj )
454 {
455   myMenu.remove( (QPopupMenu*)obj );
456 }
457
458 /*!
459         Name: onWindowDestroyed [private slots]
460         Desc: Remove information about destroyed dock window.
461 */
462
463 void QtxDockAction::onWindowDestroyed( QObject* obj )
464 {
465   QDockWindow* dw = (QDockWindow*)obj;
466   if ( !myInfo.contains( dw ) )
467     return;
468
469   delete myInfo[dw].a;
470   myInfo.remove( dw );
471 }
472
473 /*!
474         Name: onVisibilityChanged [private slots]
475         Desc: Toggle corresponded action when visibility state of dock window changed.
476 */
477
478 void QtxDockAction::onVisibilityChanged( bool on )
479 {
480   const QObject* obj = sender();
481   if ( !obj || !obj->inherits( "QDockWindow" ) )
482     return;
483
484   QDockWindow* dw = (QDockWindow*)obj;
485
486   QAction* a = action( dw );
487   if ( a && a->isOn() != on )
488   {
489     bool block = a->signalsBlocked();
490     a->blockSignals( true );
491     a->setOn( on );
492     a->blockSignals( block );
493   }
494
495   savePlaceInfo( dw );
496 }
497
498 /*!
499         Name: onDockWindowPositionChanged [private slots]
500         Desc: Update dock window place information
501 */
502
503 void QtxDockAction::onDockWindowPositionChanged( QDockWindow* dw )
504 {
505   savePlaceInfo( dw );
506 }
507
508 /*!
509         Name: event [protected]
510         Desc: Check consistency the popup content and internal datas.
511         Synchronize internal data structures with popup content.
512 */
513
514 bool QtxDockAction::event( QEvent* e )
515 {
516   if ( e->type() == AutoAdd )
517   {
518     QCustomEvent* ce = (QCustomEvent*)e;
519     QDockWindow* dw = (QDockWindow*)ce->data();
520     if ( !myInfo.contains( dw ) )
521     {
522       autoAddDockWindow( dw );
523       autoLoadPlaceInfo( dw );
524     }
525   }
526
527   return QtxAction::event( e );
528 }
529
530 /*!
531         Name: checkPopup [private]
532         Desc: Check consistency the popup content and internal datas.
533         Synchronize internal data structures with popup content.
534 */
535
536 void QtxDockAction::checkPopup( QPopupMenu* pm )
537 {
538   if ( !myMenu.contains( pm ) )
539     return;
540
541   int id = findId( pm, myMenu[pm].dock );
542   if ( id == -1 )
543   {
544     delete myMenu[pm].dock;
545     myMenu[pm].dock = 0;
546   }
547   id = findId( pm, myMenu[pm].tool );
548   if ( id == -1 )
549   {
550     delete myMenu[pm].tool;
551     myMenu[pm].tool = 0;
552   }
553
554   if ( !myMenu[pm].dock )
555   {
556     delete myMenu[pm].tool;
557     myMenu.remove( pm );
558     disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
559   }
560 }
561
562 /*!
563         Name: fillPopup [private]
564         Desc: Clear the popup and the add to it required actions.
565 */
566
567 void QtxDockAction::fillPopup( QPopupMenu* pm ) const
568 {
569   if ( !pm || !mainWindow() )
570     return;
571
572   if ( !myMenu.contains( pm ) )
573     return;
574
575   QPopupMenu* dockMenu = myMenu[pm].dock;
576   QPopupMenu* toolMenu = myMenu[pm].tool;
577
578   for ( InfoMap::ConstIterator mit = myInfo.begin(); mit != myInfo.end(); ++mit )
579   {
580     mit.data().a->removeFrom( dockMenu );
581     mit.data().a->removeFrom( toolMenu );
582   }
583
584   if ( dockMenu )
585     dockMenu->clear();
586
587   if ( toolMenu )
588     toolMenu->clear();
589
590   QPtrList<QDockWindow> dockList;
591   dockWindows( dockList, mainWindow() );
592
593   if ( dockList.isEmpty() )
594     return;
595
596   QPtrList<QAction> toolBars, windows;
597   for ( QPtrListIterator<QDockWindow> it( dockList ); it.current(); ++it )
598   {
599     if ( !myInfo.contains( it.current() ) )
600     {
601       QtxDockAction* that = (QtxDockAction*)this;
602       that->autoAddDockWindow( it.current() );
603     }
604
605     if ( !mainWindow()->appropriate( it.current() ) ||
606          it.current()->caption().isEmpty() || !action( it.current() ) )
607       continue;
608
609     if ( isToolBar( it.current() ) )
610       toolBars.append( action( it.current() ) );
611     else
612       windows.append( action( it.current() ) );
613   }
614
615   for ( QPtrListIterator<QAction> wit( windows ); wit.current(); ++wit )
616     wit.current()->addTo( dockMenu );
617
618   dockMenu->insertSeparator();
619
620   for ( QPtrListIterator<QAction> tit( toolBars ); tit.current(); ++tit )
621     tit.current()->addTo( toolMenu ? toolMenu : dockMenu );
622
623   Qtx::simplifySeparators( dockMenu );
624   Qtx::simplifySeparators( toolMenu );
625 }
626
627 /*!
628         Name: isToolBar [private]
629         Desc: Returns 'true' if dock window is a toolbar.
630 */
631
632 bool QtxDockAction::isToolBar( QDockWindow* dw ) const
633 {
634   return dw && dw->inherits( "QToolBar" );
635 }
636
637 /*!
638         Name: findId [private]
639         Desc: Returns identificator of popup item which contains sub popup 'pm' in the popup 'cont'.
640 */
641
642 int QtxDockAction::findId( QPopupMenu* cont, QPopupMenu* pm ) const
643 {
644   if ( !cont || !pm )
645     return -1;
646
647   int id = -1;
648
649   for ( int i = 0; i < (int)cont->count() && id == -1; i++ )
650   {
651     QMenuData* md = 0;
652     QMenuItem* item = cont->findItem( cont->idAt( i ), &md );
653     if ( item && md == cont && item->popup() == pm )
654       id = item->id();
655   }
656   return id;
657 }
658
659 /*!
660         Name: dockWindows [private]
661         Desc: Returns all dock windows of the main window.
662 */
663
664 void QtxDockAction::dockWindows( QPtrList<QDockWindow>& lst, QMainWindow* main ) const
665 {
666   lst.clear();
667
668   QMainWindow* mw = main ? main : mainWindow();
669   if ( !mw )
670     return;
671
672   lst = mw->dockWindows();
673 }
674
675 /*!
676         Name: updateInfo [private]
677         Desc: Updates icon and caption info of dock window in the corresponded action.
678 */
679
680 void QtxDockAction::updateInfo( QDockWindow* dw )
681 {
682   QAction* a = action( dw );
683   if ( !a )
684     return;
685
686   a->setText( dw->caption() );
687   a->setMenuText( dw->caption() );
688
689   if ( isToolBar( dw ) )
690     a->setStatusTip( tr( "Toggles toolbar \"%1\" on/off" ).arg( dw->caption() ) );
691   else
692     a->setStatusTip( tr( "Toggles window \"%1\" on/off" ).arg( dw->caption() ) );
693
694   const QPixmap* icon = dw->icon();
695   if ( icon )
696     a->setIconSet( *icon );
697 }
698
699 /*!
700         Name: savePlaceInfo [private]
701         Desc: Store the place and geometry information from specified dock window.
702 */
703
704 void QtxDockAction::savePlaceInfo( QDockWindow* dw )
705 {
706   if ( !myInfo.contains( dw ) )
707     return;
708
709   if ( !myGeom.contains( myInfo[dw].name ) )
710     myGeom.insert( myInfo[dw].name, GeomInfo() );
711
712   GeomInfo& inf = myGeom[myInfo[dw].name];
713
714   Dock dock;
715   inf.vis = dw->isVisibleTo( mainWindow() );
716   mainWindow()->getLocation( dw, dock, inf.index, inf.newLine, inf.offset );
717
718   inf.place = dock;
719   inf.x = dw->x();
720   inf.y = dw->y();
721   inf.w = dw->width();
722   inf.h = dw->height();
723   inf.fixW = dw->fixedExtent().width();
724   inf.fixH = dw->fixedExtent().height();
725 }
726
727 /*!
728         Name: loadPlaceInfo [private]
729         Desc: Retrieve the stored place and geometry information to specified dock window.
730 */
731
732 void QtxDockAction::loadPlaceInfo( QDockWindow* dw ) const
733 {
734   if ( !myInfo.contains( dw ) )
735     return;
736
737   QString winName = myInfo[dw].name;
738   if ( winName.isEmpty() || !myGeom.contains( winName ) )
739     return;
740
741   GeomInfo inf = myGeom[myInfo[dw].name];
742
743   mainWindow()->moveDockWindow( dw, (Qt::Dock)inf.place, inf.newLine, inf.index, inf.offset );
744   dw->setGeometry( inf.x, inf.y, inf.w, inf.h );
745
746   dw->setFixedExtentWidth( inf.fixW );
747   dw->setFixedExtentHeight( inf.fixH );
748
749   QtxDockAction* that = (QtxDockAction*)this;
750   that->myGeom.insert( myInfo[dw].name, inf );
751 }
752
753 /*!
754         Name: action [private]
755         Desc: Returns action for the given dock window.
756 */
757
758 QAction* QtxDockAction::action( QDockWindow* dw ) const
759 {
760   QAction* a = 0;
761   if ( myInfo.contains( dw ) )
762     a = myInfo[dw].a;
763   return a;
764 }
765
766 /*!
767         Name: dockWindow [private]
768         Desc: Returns dock window for the given action.
769 */
770
771 QDockWindow* QtxDockAction::dockWindow( const QAction* a ) const
772 {
773   QDockWindow* dw = 0;
774   for ( InfoMap::ConstIterator it = myInfo.begin(); it != myInfo.end() && !dw; ++it )
775   {
776     if ( it.data().a == a )
777       dw = it.key();
778   }
779   return dw;
780 }
781
782 /*!
783         Name: initialize [private]
784         Desc: Initialisation of the object. Sets the event filters and add existing dock windows.
785 */
786
787 void QtxDockAction::initialize( QMainWindow* mw )
788 {
789   if ( !mw )
790     return;
791
792   QPtrList<QDockWindow> lst;
793   dockWindows( lst, mw );
794
795   for ( QPtrListIterator<QDockWindow> it( lst ); it.current(); ++it )
796     autoAddDockWindow( it.current() );
797
798   if ( mw->topDock() )
799     mw->topDock()->installEventFilter( this );
800   if ( mw->leftDock() )
801     mw->leftDock()->installEventFilter( this );
802   if ( mw->rightDock() )
803     mw->rightDock()->installEventFilter( this );
804   if ( mw->bottomDock() )
805     mw->bottomDock()->installEventFilter( this );
806
807   connect( mw, SIGNAL( dockWindowPositionChanged( QDockWindow* ) ),
808            this, SLOT( onDockWindowPositionChanged( QDockWindow* ) ) );
809 }
810
811 /*!
812         Name: windowName [private]
813         Desc: Generate the dock window name.
814 */
815
816 QString QtxDockAction::windowName( QDockWindow* dw ) const
817 {
818   QString name;
819
820   if ( dw )
821   {
822     name = dw->name( "" );
823     if ( name.isEmpty() )
824       name = dw->caption();
825   }
826
827   return name;
828 }
829
830 /*!
831         Name: autoAddDockWindow [private]
832         Desc: Add the dock window if auto add property is setted.
833 */
834
835 bool QtxDockAction::autoAddDockWindow( QDockWindow* dw )
836 {
837   if ( !isAutoAdd() )
838     return false;
839
840   return addDockWindow( dw );
841 }
842
843 /*!
844         Name: autoLoadPlaceInfo [private]
845         Desc: Retieve the dock window place geometry if auto place property is setted.
846 */
847
848 void QtxDockAction::autoLoadPlaceInfo( QDockWindow* dw )
849 {
850   if ( isAutoPlace() )
851     loadPlaceInfo( dw );
852 }
853
854 /*!
855         Name: splitMenuText [private]
856         Desc: 
857 */
858
859 void QtxDockAction::splitMenuText( QString& dock, QString& tool ) const
860 {
861   dock = tool = menuText();
862   if ( !isSeparate() )
863     return;
864
865   QStringList lst = splitText( menuText(), "|" );
866   if ( lst.count() < 2 )
867     lst = splitText( menuText(), "and" );
868
869   dock = lst.first();
870   tool = lst.last();
871 }
872
873 /*!
874         Name: splitText [private]
875         Desc: 
876 */
877
878 QStringList QtxDockAction::splitText( const QString& str, const QString& sep ) const
879 {
880   QStringList res;
881
882   int idx = str.lower().find( sep.lower() );
883   if ( idx != -1 )
884   {
885     res.append( str.mid( 0, idx ).stripWhiteSpace() );
886     res.append( str.mid( idx + sep.length() ).stripWhiteSpace() );
887   }
888
889   return res;
890 }
891
892 /*!
893         Name: dockPlace [private]
894         Desc: 
895 */
896
897 int QtxDockAction::dockPlace( const QString& dockName ) const
898 {
899   static QMap<QString, int> dockNameMap;
900   if ( dockNameMap.isEmpty() )
901   {
902     dockNameMap["top"]       = DockTop;
903     dockNameMap["bottom"]    = DockBottom;
904     dockNameMap["left"]      = DockLeft;
905     dockNameMap["right"]     = DockRight;
906     dockNameMap["tornoff"]   = DockTornOff;
907     dockNameMap["torn_off"]  = DockTornOff;
908     dockNameMap["outside"]   = DockTornOff;
909     dockNameMap["undock"]    = DockTornOff;
910     dockNameMap["minimized"] = DockMinimized;
911     dockNameMap["unmanaged"] = DockUnmanaged;
912   }
913
914   int res = -1;
915   if ( dockNameMap.contains( dockName.lower() ) )
916     res = dockNameMap[dockName.lower()];
917   return res;
918 }
919
920 bool QtxDockAction::loadGeometry( QtxResourceMgr* resMgr, const QString& sec,
921                                   const QString& name, GeomInfo& inf ) const
922 {
923   if ( !resMgr || sec.isEmpty() || name.isEmpty() )
924     return false;
925
926   QString tmpl = QString( "%1.%2" ).arg( name );
927
928   inf.vis     = resMgr->booleanValue( sec, tmpl.arg( "visible" ), inf.vis );
929   inf.newLine = resMgr->booleanValue( sec, tmpl.arg( "new_line" ), inf.newLine );
930
931   inf.index   = resMgr->integerValue( sec, tmpl.arg( "index" ), inf.index );
932   inf.offset  = resMgr->integerValue( sec, tmpl.arg( "offset" ), inf.offset );
933
934   inf.x       = resMgr->integerValue( sec, tmpl.arg( "x" ), inf.x );
935   inf.y       = resMgr->integerValue( sec, tmpl.arg( "y" ), inf.y );
936   inf.w       = resMgr->integerValue( sec, tmpl.arg( "width" ), inf.w );
937   inf.h       = resMgr->integerValue( sec, tmpl.arg( "height" ), inf.h );
938
939   inf.fixW    = resMgr->integerValue( sec, tmpl.arg( "fixed_width" ), inf.fixW );
940   inf.fixH    = resMgr->integerValue( sec, tmpl.arg( "fixed_height" ), inf.fixH );
941
942   int place = -1;
943   if ( !resMgr->value( sec, tmpl.arg( "place" ), place ) )
944   {
945     QString placeStr;
946     if ( resMgr->value( sec, tmpl.arg( "place" ), placeStr ) )
947       place = dockPlace( placeStr );
948   }
949
950   if ( place >= DockUnmanaged && place <= DockMinimized )
951     inf.place = place;
952
953   return true;
954 }
955
956 bool QtxDockAction::saveGeometry( QtxResourceMgr* resMgr, const QString& sec,
957                                   const QString& name, const GeomInfo& inf ) const
958 {
959   if ( !resMgr || sec.isEmpty() || name.isEmpty() )
960     return false;
961
962   QString tmpl = QString( "%1.%2" ).arg( name );
963
964   resMgr->setValue( sec, tmpl.arg( "visible" ), inf.vis );
965   resMgr->setValue( sec, tmpl.arg( "new_line" ), inf.newLine );
966   resMgr->setValue( sec, tmpl.arg( "index" ), inf.index );
967   resMgr->setValue( sec, tmpl.arg( "offset" ), inf.offset );
968   resMgr->setValue( sec, tmpl.arg( "x" ), inf.x );
969   resMgr->setValue( sec, tmpl.arg( "y" ), inf.y );
970   resMgr->setValue( sec, tmpl.arg( "width" ), inf.w );
971   resMgr->setValue( sec, tmpl.arg( "height" ), inf.h );
972   resMgr->setValue( sec, tmpl.arg( "fixed_width" ), inf.fixW );
973   resMgr->setValue( sec, tmpl.arg( "fixed_height" ), inf.fixH );
974   resMgr->setValue( sec, tmpl.arg( "place" ), inf.place );
975
976   return true;
977 }