Salome HOME
Copyrights update
[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 QtxToolBar::Watcher::Watcher( QtxToolBar* cont )
70 : QObject( cont ),
71 myCont( cont ),
72 myState( true ),
73 myEmpty( true )
74 {
75   if ( myCont->mainWindow() )
76     myState = myCont->mainWindow()->appropriate( myCont );
77
78   myCont->installEventFilter( this );
79   myVisible = myCont->isVisibleTo( myCont->parentWidget() );
80
81   installFilters();
82 }
83
84 bool QtxToolBar::Watcher::eventFilter( QObject* o, QEvent* e )
85 {
86   if ( o == myCont && e->type() == QEvent::ChildInserted )
87     QApplication::postEvent( this, new QCustomEvent( Install ) );
88
89   if ( o != myCont && e->type() == QEvent::IconChange )
90     updateIcon();
91
92   if ( o != myCont && e->type() == QEvent::CaptionChange )
93     updateCaption();
94
95   bool updVis = ( o != myCont && ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ||
96                                    e->type() == QEvent::Hide || e->type() == QEvent::HideToParent ) ) ||
97                 ( o == myCont && ( e->type() == QEvent::ChildRemoved || e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ) );
98
99   if ( updVis )
100   {
101     QtxToolBar* cont = myCont;
102     myCont = 0;
103     QApplication::sendPostedEvents( this, Update );
104     myCont = cont;
105     QApplication::postEvent( this, new QCustomEvent( Update ) );
106   }
107
108   return false;
109 }
110
111 void QtxToolBar::Watcher::shown( QtxToolBar* tb )
112 {
113   if ( tb != myCont )
114     return;
115
116   myVisible = true;
117 }
118
119 void QtxToolBar::Watcher::hided( QtxToolBar* tb )
120 {
121   if ( tb != myCont )
122     return;
123
124   myVisible = false;
125 }
126
127 void QtxToolBar::Watcher::showContainer()
128 {
129   if ( !myCont )
130     return;
131
132   QtxToolBar* cont = myCont;
133   myCont = 0;
134   cont->show();
135   myCont = cont;
136 }
137
138 void QtxToolBar::Watcher::hideContainer()
139 {
140   if ( !myCont )
141     return;
142
143   QtxToolBar* cont = myCont;
144   myCont = 0;
145   cont->hide();
146   myCont = cont;
147 }
148
149 void QtxToolBar::Watcher::customEvent( QCustomEvent* e )
150 {
151   switch ( e->type() )
152   {
153   case Install:
154     installFilters();
155     updateIcon();
156     updateCaption();
157   case Update:
158     updateVisibility();
159   }
160 }
161
162 void QtxToolBar::Watcher::installFilters()
163 {
164   if ( !myCont )
165     return;
166
167   const QObjectList* objList = myCont->children();
168   if ( !objList )
169     return;
170
171   for ( QObjectListIt it( *objList ); it.current(); ++it )
172   {
173     if ( it.current()->isWidgetType() &&
174          qstrcmp( "qt_dockwidget_internal", it.current()->name() ) )
175       it.current()->installEventFilter( this );
176   }
177 }
178
179 void QtxToolBar::Watcher::updateVisibility()
180 {
181   if ( !myCont )
182     return;
183
184   bool vis = false;
185
186   const QObjectList* objList = myCont->children();
187   if ( objList )
188   {
189     for ( QObjectListIt it( *objList ); it.current() && !vis; ++it )
190     {
191       if ( !it.current()->isWidgetType() ||
192            !qstrcmp( "qt_dockwidget_internal", it.current()->name() ) )
193         continue;
194
195       QWidget* wid = (QWidget*)it.current();
196       vis = wid->isVisibleTo( wid->parentWidget() );
197     }
198   }
199
200   QMainWindow* mw = myCont->mainWindow();
201   if ( mw && myEmpty == vis )
202   {
203     myEmpty = !vis;
204     if ( !myEmpty )
205       mw->setAppropriate( myCont, myState );
206     else
207     {
208       myState = mw->appropriate( myCont );
209       mw->setAppropriate( myCont, false );
210     }
211   }
212
213   vis = !myEmpty && myVisible;
214   if ( vis != myCont->isVisibleTo( myCont->parentWidget() ) )
215     vis ? showContainer() : hideContainer();
216 }
217
218 void QtxToolBar::Watcher::updateIcon()
219 {
220   if ( !myCont || !myCont->widget() )
221     return;
222   
223   const QPixmap* ico = myCont->widget()->icon();
224   myCont->setIcon( ico ? *ico : QPixmap() );
225 }
226
227 void QtxToolBar::Watcher::updateCaption()
228 {
229   if ( myCont && myCont->widget() && !myCont->widget()->caption().isNull() )
230     myCont->setCaption( myCont->widget()->caption() );
231 }
232
233 /*!
234     Class: QtxToolBar [Public]
235     Descr: 
236 */
237
238 QtxToolBar::QtxToolBar( const bool watch, const QString& label, QMainWindow* main,
239                         QWidget* parent, bool newLine, const char* name, WFlags f )
240 : QToolBar( label, main, parent, newLine, name, f ),
241 myWatcher( 0 ),
242 myStretch( false )
243 {
244   if ( watch )
245     myWatcher = new Watcher( this );
246 }
247
248 QtxToolBar::QtxToolBar( const QString& label, QMainWindow* main,
249                         QWidget* parent, bool newLine, const char* name, WFlags f )
250 : QToolBar( label, main, parent, newLine, name, f ),
251 myWatcher( 0 ),
252 myStretch( false )
253 {
254 }
255
256 QtxToolBar::QtxToolBar( const bool watch, QMainWindow* main, const char* name )
257 : QToolBar( main, name ),
258 myWatcher( 0 ),
259 myStretch( false )
260 {
261   if ( watch )
262     myWatcher = new Watcher( this );
263 }
264
265 QtxToolBar::QtxToolBar( QMainWindow* main, const char* name )
266 : QToolBar( main, name ),
267 myWatcher( 0 ),
268 myStretch( false )
269 {
270 }
271
272 QtxToolBar::~QtxToolBar()
273 {
274 }
275
276 void QtxToolBar::setWidget( QWidget* wid )
277 {
278   if ( wid )
279     wid->reparent( this, QPoint( 0, 0 ), wid->isVisibleTo( wid->parentWidget() ) );
280
281   QToolBar::setWidget( wid );
282
283   if ( !boxLayout() )
284     return;
285
286   for ( QLayoutIterator it = boxLayout()->iterator(); it.current(); ++it )
287   {
288     if ( it.current()->widget() == wid )
289     {
290       it.deleteCurrent();
291       break;
292     }
293   }
294 }
295
296 bool QtxToolBar::isStretchable() const
297 {
298   return myStretch;
299 }
300
301 void QtxToolBar::setStretchable( const bool on )
302 {
303   if ( myStretch == on )
304     return;
305
306   myStretch = on;
307
308   boxLayout()->setStretchFactor( widget(), myStretch ? 1 : 0 );
309
310   if ( myStretch != isHorizontalStretchable() ||
311        myStretch != isVerticalStretchable() )
312   {
313           if ( orientation() == Horizontal )
314             setHorizontalStretchable( myStretch );
315           else
316             setVerticalStretchable( myStretch );
317   }
318 }
319
320 QSize QtxToolBar::sizeHint() const
321 {
322   QSize sz = QToolBar::sizeHint();
323
324   if ( place() == InDock && isStretchable() && area() )
325   {
326     if ( orientation() == Horizontal )
327       sz.setWidth( area()->width() );
328     else
329       sz.setHeight( area()->height() );
330   }
331
332   return sz;
333 }
334
335 QSize QtxToolBar::minimumSizeHint() const
336 {
337   QSize sz = QToolBar::minimumSizeHint();
338
339   if ( place() == InDock && isStretchable() && area() )
340   {
341     if ( orientation() == Horizontal )
342       sz.setWidth( area()->width() );
343     else
344       sz.setHeight( area()->height() );
345   }
346
347   return sz;
348 }
349
350 void QtxToolBar::show()
351 {
352   if ( myWatcher )
353     myWatcher->shown( this );
354
355   QToolBar::show();
356 }
357
358 void QtxToolBar::hide()
359 {
360   if ( myWatcher )
361     myWatcher->hided( this );
362
363   QToolBar::hide();
364 }