Salome HOME
b132fe9b0510648b2b973dfefc81ed9816eefb7c
[modules/gui.git] / src / Qtx / QtxToolBar.cxx
1 // File:      QtxToolBar.cxx
2 // Author:    Sergey TELKOV
3
4 #include "QtxToolBar.h"
5
6 #include <qlayout.h>
7 #include <qpixmap.h>
8 #include <qdockarea.h>
9 #include <qobjectlist.h>
10 #include <qmainwindow.h>
11 #include <qapplication.h>
12
13 /*!
14     Class: QtxToolBar::Watcher [Internal]
15     Descr: Internal object with event filter.
16 */
17
18 class QtxToolBar::Watcher : public QObject
19 {
20 public:
21   Watcher( QtxToolBar* );
22
23   virtual bool eventFilter( QObject*, QEvent* );
24
25 protected:
26   virtual void customEvent( QCustomEvent* );
27
28 private:
29   enum { Install = QEvent::User, Update };
30
31 private:
32   void         installFilters();
33
34   void         updateIcon();
35   void         updateCaption();
36   void         updateVisibility();
37
38 private:
39   bool         myVis;
40   QtxToolBar*  myCont;
41 };
42
43 QtxToolBar::Watcher::Watcher( QtxToolBar* cont )
44 : QObject( cont ),
45 myCont( cont ),
46 myVis( true )
47 {
48   if ( myCont->mainWindow() )
49     myVis = myCont->mainWindow()->appropriate( myCont );
50
51   myCont->installEventFilter( this );
52
53   installFilters();
54 }
55
56 bool QtxToolBar::Watcher::eventFilter( QObject* o, QEvent* e )
57 {
58   if ( o == myCont && e->type() == QEvent::ChildInserted )
59     QApplication::postEvent( this, new QCustomEvent( Install ) );
60
61   if ( o != myCont && e->type() == QEvent::IconChange )
62     updateIcon();
63
64   if ( o != myCont && e->type() == QEvent::CaptionChange )
65     updateCaption();
66
67   bool updVis = ( o != myCont && ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ||
68                                    e->type() == QEvent::Hide || e->type() == QEvent::HideToParent ) ) ||
69                 ( o == myCont && e->type() == QEvent::ChildRemoved );
70
71   if ( updVis )
72   {
73     QtxToolBar* cont = myCont;
74     myCont = 0;
75     QApplication::sendPostedEvents( this, Update );
76     myCont = cont;
77     QApplication::postEvent( this, new QCustomEvent( Update ) );
78   }
79
80   return false;
81 }
82
83 void QtxToolBar::Watcher::customEvent( QCustomEvent* e )
84 {
85   switch ( e->type() )
86   {
87   case Install:
88     installFilters();
89     updateIcon();
90     updateCaption();
91   case Update:
92     updateVisibility();
93   }
94 }
95
96 void QtxToolBar::Watcher::installFilters()
97 {
98   if ( !myCont )
99     return;
100
101   const QObjectList* objList = myCont->children();
102   if ( !objList )
103     return;
104
105   for ( QObjectListIt it( *objList ); it.current(); ++it )
106   {
107     if ( it.current()->isWidgetType() &&
108          qstrcmp( "qt_dockwidget_internal", it.current()->name() ) )
109       it.current()->installEventFilter( this );
110   }
111 }
112
113 void QtxToolBar::Watcher::updateVisibility()
114 {
115   if ( !myCont )
116     return;
117
118   bool vis = false;
119
120   const QObjectList* objList = myCont->children();
121   if ( objList )
122   {
123     for ( QObjectListIt it( *objList ); it.current() && !vis; ++it )
124     {
125       if ( !it.current()->isWidgetType() ||
126            !qstrcmp( "qt_dockwidget_internal", it.current()->name() ) )
127         continue;
128
129       QWidget* wid = (QWidget*)it.current();
130       vis = wid->isVisibleTo( wid->parentWidget() );
131     }
132   }
133
134   QMainWindow* mw = myCont->mainWindow();
135   if ( mw )
136   {
137     if ( vis )
138       mw->setAppropriate( myCont, myVis );
139     else
140     {
141       myVis = mw->appropriate( myCont );
142       mw->setAppropriate( myCont, false );
143     }
144   }
145
146   if ( vis )
147     myCont->show();
148   else
149     myCont->hide();
150 }
151
152 void QtxToolBar::Watcher::updateIcon()
153 {
154   if ( !myCont || !myCont->widget() )
155     return;
156   
157   const QPixmap* ico = myCont->widget()->icon();
158   myCont->setIcon( ico ? *ico : QPixmap() );
159 }
160
161 void QtxToolBar::Watcher::updateCaption()
162 {
163   if ( myCont && myCont->widget() && !myCont->widget()->caption().isNull() )
164     myCont->setCaption( myCont->widget()->caption() );
165 }
166
167 /*!
168     Class: QtxToolBar [Public]
169     Descr: 
170 */
171
172 QtxToolBar::QtxToolBar( const bool watch, const QString& label, QMainWindow* main,
173                         QWidget* parent, bool newLine, const char* name, WFlags f )
174 : QToolBar( label, main, parent, newLine, name, f ),
175 myWatcher( 0 ),
176 myStretch( false )
177 {
178   if ( watch )
179     myWatcher = new Watcher( this );
180 }
181
182 QtxToolBar::QtxToolBar( const QString& label, QMainWindow* main,
183                         QWidget* parent, bool newLine, const char* name, WFlags f )
184 : QToolBar( label, main, parent, newLine, name, f ),
185 myWatcher( 0 ),
186 myStretch( false )
187 {
188 }
189
190 QtxToolBar::QtxToolBar( const bool watch, QMainWindow* main, const char* name )
191 : QToolBar( main, name ),
192 myWatcher( 0 ),
193 myStretch( false )
194 {
195   if ( watch )
196     myWatcher = new Watcher( this );
197 }
198
199 QtxToolBar::QtxToolBar( QMainWindow* main, const char* name )
200 : QToolBar( main, name ),
201 myWatcher( 0 ),
202 myStretch( false )
203 {
204 }
205
206 QtxToolBar::~QtxToolBar()
207 {
208 }
209
210 void QtxToolBar::setWidget( QWidget* wid )
211 {
212   if ( wid )
213     wid->reparent( this, QPoint( 0, 0 ), wid->isVisibleTo( wid->parentWidget() ) );
214
215   QToolBar::setWidget( wid );
216
217   if ( !boxLayout() )
218     return;
219
220   for ( QLayoutIterator it = boxLayout()->iterator(); it.current(); ++it )
221   {
222     if ( it.current()->widget() == wid )
223     {
224       it.deleteCurrent();
225       break;
226     }
227   }
228 }
229
230 bool QtxToolBar::isStretchable() const
231 {
232   return myStretch;
233 }
234
235 void QtxToolBar::setStretchable( const bool on )
236 {
237   if ( myStretch == on )
238     return;
239
240   myStretch = on;
241
242   boxLayout()->setStretchFactor( widget(), myStretch ? 1 : 0 );
243
244   if ( myStretch != isHorizontalStretchable() ||
245        myStretch != isVerticalStretchable() )
246   {
247           if ( orientation() == Horizontal )
248             setHorizontalStretchable( myStretch );
249           else
250             setVerticalStretchable( myStretch );
251   }
252 }
253
254 QSize QtxToolBar::sizeHint() const
255 {
256   QSize sz = QToolBar::sizeHint();
257
258   if ( place() == InDock && isStretchable() && area() )
259   {
260     if ( orientation() == Horizontal )
261       sz.setWidth( area()->width() );
262     else
263       sz.setHeight( area()->height() );
264   }
265
266   return sz;
267 }
268
269 QSize QtxToolBar::minimumSizeHint() const
270 {
271   QSize sz = QToolBar::minimumSizeHint();
272
273   if ( place() == InDock && isStretchable() && area() )
274   {
275     if ( orientation() == Horizontal )
276       sz.setWidth( area()->width() );
277     else
278       sz.setHeight( area()->height() );
279   }
280
281   return sz;
282 }