Salome HOME
Join modifications from branch OCC_debug_for_3_2_0b1
[modules/gui.git] / src / Qtx / QtxToolBar.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/
18 //
19 // File:      QtxToolBar.cxx
20 // Author:    Sergey TELKOV
21
22 #include "QtxToolBar.h"
23
24 #include <qlayout.h>
25 #include <qpixmap.h>
26 #include <qdockarea.h>
27 #include <qobjectlist.h>
28 #include <qmainwindow.h>
29 #include <qapplication.h>
30
31 /*!
32     Class: QtxToolBar::Watcher [Internal]
33     Descr: Internal object with event filter.
34 */
35
36 class QtxToolBar::Watcher : public QObject
37 {
38 public:
39   Watcher( QtxToolBar* );
40
41   void         shown( QtxToolBar* );
42   void         hided( QtxToolBar* );
43
44   virtual bool eventFilter( QObject*, QEvent* );
45
46 protected:
47   virtual void customEvent( QCustomEvent* );
48
49 private:
50   enum { Install = QEvent::User, Update };
51
52 private:
53   void         installFilters();
54
55   void         showContainer();
56   void         hideContainer();
57
58   void         updateIcon();
59   void         updateCaption();
60   void         updateVisibility();
61
62 private:
63   QtxToolBar*  myCont;
64   bool         myState;
65   bool         myEmpty;
66   bool         myVisible;
67 };
68
69 /*!
70   Constructor
71 */
72 QtxToolBar::Watcher::Watcher( QtxToolBar* cont )
73 : QObject( cont ),
74 myCont( cont ),
75 myState( true ),
76 myEmpty( true )
77 {
78   if ( myCont->mainWindow() )
79     myState = myCont->mainWindow()->appropriate( myCont );
80
81   myCont->installEventFilter( this );
82   myVisible = myCont->isVisibleTo( myCont->parentWidget() );
83
84   installFilters();
85 }
86
87 /*!
88   Custom event filter
89 */
90 bool QtxToolBar::Watcher::eventFilter( QObject* o, QEvent* e )
91 {
92   if ( o == myCont && e->type() == QEvent::ChildInserted )
93     QApplication::postEvent( this, new QCustomEvent( Install ) );
94
95   if ( o != myCont && e->type() == QEvent::IconChange )
96     updateIcon();
97
98   if ( o != myCont && e->type() == QEvent::CaptionChange )
99     updateCaption();
100
101   bool updVis = ( o != myCont && ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ||
102                                    e->type() == QEvent::Hide || e->type() == QEvent::HideToParent ) ) ||
103                 ( o == myCont && ( e->type() == QEvent::ChildRemoved || e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ) );
104
105   if ( updVis )
106   {
107     QtxToolBar* cont = myCont;
108     myCont = 0;
109     QApplication::sendPostedEvents( this, Update );
110     myCont = cont;
111     QApplication::postEvent( this, new QCustomEvent( Update ) );
112   }
113
114   return false;
115 }
116
117 /*!
118   Sets internal visibility state to true
119 */
120 void QtxToolBar::Watcher::shown( QtxToolBar* tb )
121 {
122   if ( tb != myCont )
123     return;
124
125   myVisible = true;
126 }
127
128 /*!
129   Sets internal visibility state to false
130 */
131 void QtxToolBar::Watcher::hided( QtxToolBar* tb )
132 {
133   if ( tb != myCont )
134     return;
135
136   myVisible = false;
137 }
138
139 /*!
140   Shows corresponding QtxToolBar
141 */
142 void QtxToolBar::Watcher::showContainer()
143 {
144   if ( !myCont )
145     return;
146
147   QtxToolBar* cont = myCont;
148   myCont = 0;
149   cont->show();
150   myCont = cont;
151 }
152
153 /*!
154   Hides corresponding QtxToolBar
155 */
156 void QtxToolBar::Watcher::hideContainer()
157 {
158   if ( !myCont )
159     return;
160
161   QtxToolBar* cont = myCont;
162   myCont = 0;
163   cont->hide();
164   myCont = cont;
165 }
166
167 /*!
168   Event handler of custom events
169 */
170 void QtxToolBar::Watcher::customEvent( QCustomEvent* e )
171 {
172   switch ( e->type() )
173   {
174   case Install:
175     installFilters();
176     updateIcon();
177     updateCaption();
178   case Update:
179     updateVisibility();
180   }
181 }
182
183 /*!
184   Installs event filters
185 */
186 void QtxToolBar::Watcher::installFilters()
187 {
188   if ( !myCont )
189     return;
190
191   const QObjectList* objList = myCont->children();
192   if ( !objList )
193     return;
194
195   for ( QObjectListIt it( *objList ); it.current(); ++it )
196   {
197     if ( it.current()->isWidgetType() &&
198          qstrcmp( "qt_dockwidget_internal", it.current()->name() ) )
199       it.current()->installEventFilter( this );
200   }
201 }
202
203 /*!
204   Update visibility state
205 */
206 void QtxToolBar::Watcher::updateVisibility()
207 {
208   if ( !myCont )
209     return;
210
211   bool vis = false;
212
213   const QObjectList* objList = myCont->children();
214   if ( objList )
215   {
216     for ( QObjectListIt it( *objList ); it.current() && !vis; ++it )
217     {
218       if ( !it.current()->isWidgetType() ||
219            !qstrcmp( "qt_dockwidget_internal", it.current()->name() ) )
220         continue;
221
222       QWidget* wid = (QWidget*)it.current();
223       vis = wid->isVisibleTo( wid->parentWidget() );
224     }
225   }
226
227   QMainWindow* mw = myCont->mainWindow();
228   if ( mw && myEmpty == vis )
229   {
230     myEmpty = !vis;
231     if ( !myEmpty )
232       mw->setAppropriate( myCont, myState );
233     else
234     {
235       myState = mw->appropriate( myCont );
236       mw->setAppropriate( myCont, false );
237     }
238   }
239
240   vis = !myEmpty && myVisible;
241   if ( vis != myCont->isVisibleTo( myCont->parentWidget() ) )
242     vis ? showContainer() : hideContainer();
243 }
244
245 /*!
246   Updates icon
247 */
248 void QtxToolBar::Watcher::updateIcon()
249 {
250   if ( !myCont || !myCont->widget() )
251     return;
252   
253   const QPixmap* ico = myCont->widget()->icon();
254   myCont->setIcon( ico ? *ico : QPixmap() );
255 }
256
257 /*!
258   Updates caption
259 */
260 void QtxToolBar::Watcher::updateCaption()
261 {
262   if ( myCont && myCont->widget() && !myCont->widget()->caption().isNull() )
263     myCont->setCaption( myCont->widget()->caption() );
264 }
265
266 /*!
267   Constructor
268 */
269 QtxToolBar::QtxToolBar( const bool watch, const QString& label, QMainWindow* main,
270                         QWidget* parent, bool newLine, const char* name, WFlags f )
271 : QToolBar( label, main, parent, newLine, name, f ),
272 myWatcher( 0 ),
273 myStretch( false )
274 {
275   if ( watch )
276     myWatcher = new Watcher( this );
277 }
278
279 /*!
280   Constructor
281 */
282 QtxToolBar::QtxToolBar( const QString& label, QMainWindow* main,
283                         QWidget* parent, bool newLine, const char* name, WFlags f )
284 : QToolBar( label, main, parent, newLine, name, f ),
285 myWatcher( 0 ),
286 myStretch( false )
287 {
288 }
289
290 /*!
291   Constructor
292 */
293 QtxToolBar::QtxToolBar( const bool watch, QMainWindow* main, const char* name )
294 : QToolBar( main, name ),
295 myWatcher( 0 ),
296 myStretch( false )
297 {
298   if ( watch )
299     myWatcher = new Watcher( this );
300 }
301
302 /*!
303   Constructor
304 */
305 QtxToolBar::QtxToolBar( QMainWindow* main, const char* name )
306 : QToolBar( main, name ),
307 myWatcher( 0 ),
308 myStretch( false )
309 {
310 }
311
312 /*!
313   Destructor
314 */
315 QtxToolBar::~QtxToolBar()
316 {
317 }
318
319 /*!
320   Change the toolbar's main widget
321   \param wid - new main widget
322 */
323 void QtxToolBar::setWidget( QWidget* wid )
324 {
325   if ( wid )
326     wid->reparent( this, QPoint( 0, 0 ), wid->isVisibleTo( wid->parentWidget() ) );
327
328   QToolBar::setWidget( wid );
329
330   if ( !boxLayout() )
331     return;
332
333   for ( QLayoutIterator it = boxLayout()->iterator(); it.current(); ++it )
334   {
335     if ( it.current()->widget() == wid )
336     {
337       it.deleteCurrent();
338       break;
339     }
340   }
341 }
342
343 /*!
344   \return true if toolbar is stretchable
345 */
346 bool QtxToolBar::isStretchable() const
347 {
348   return myStretch;
349 }
350
351 /*!
352   Sets stretchable state of toolbar
353   \param on - new state
354 */
355 void QtxToolBar::setStretchable( const bool on )
356 {
357   if ( myStretch == on )
358     return;
359
360   myStretch = on;
361
362   boxLayout()->setStretchFactor( widget(), myStretch ? 1 : 0 );
363
364   if ( myStretch != isHorizontalStretchable() ||
365        myStretch != isVerticalStretchable() )
366   {
367           if ( orientation() == Horizontal )
368             setHorizontalStretchable( myStretch );
369           else
370             setVerticalStretchable( myStretch );
371   }
372 }
373
374 /*!
375   \return the recommended size for the widget
376 */
377 QSize QtxToolBar::sizeHint() const
378 {
379   QSize sz = QToolBar::sizeHint();
380
381   if ( place() == InDock && isStretchable() && area() )
382   {
383     if ( orientation() == Horizontal )
384       sz.setWidth( area()->width() );
385     else
386       sz.setHeight( area()->height() );
387   }
388
389   return sz;
390 }
391
392 /*!
393   \return the recommended minimum size for the widget
394 */
395 QSize QtxToolBar::minimumSizeHint() const
396 {
397   QSize sz = QToolBar::minimumSizeHint();
398
399   if ( place() == InDock && isStretchable() && area() )
400   {
401     if ( orientation() == Horizontal )
402       sz.setWidth( area()->width() );
403     else
404       sz.setHeight( area()->height() );
405   }
406
407   return sz;
408 }
409
410 /*!
411   Shows toolbar
412 */
413 void QtxToolBar::show()
414 {
415   if ( myWatcher )
416     myWatcher->shown( this );
417
418   QToolBar::show();
419 }
420
421 /*!
422   Hides toolbar
423 */
424 void QtxToolBar::hide()
425 {
426   if ( myWatcher )
427     myWatcher->hided( this );
428
429   QToolBar::hide();
430 }