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