Back to index

salome-gui  6.5.0
QtxDockWidget.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // File:      QtxDockWidget.cxx
00024 // Author:    Sergey TELKOV
00025 //
00026 #include "QtxDockWidget.h"
00027 
00028 #include <QAction>
00029 #include <QLayout>
00030 #include <QMainWindow>
00031 #include <QResizeEvent>
00032 #include <QApplication>
00033 
00040 class QtxDockWidget::Watcher : public QObject
00041 {
00042 public:
00043   Watcher( QtxDockWidget* );
00044 
00045   void           shown( QtxDockWidget* );
00046   void           hidden( QtxDockWidget* );
00047 
00048   virtual bool   eventFilter( QObject*, QEvent* );
00049 
00050   bool           isEmpty() const;
00051   bool           isVisible() const;
00052 
00053 protected:
00054   enum { Update = QEvent::User, Remove };
00055 
00056   virtual void   customEvent( QEvent* );
00057 
00058 private:
00059   void           installFilters();
00060 
00061   void           showContainer();
00062   void           hideContainer();
00063 
00064   void           updateIcon();
00065   void           updateCaption();
00066   void           updateVisibility();
00067 
00068   void           setEmpty( const bool );
00069   void           setVisible( const bool );
00070 
00071 private:
00072   QtxDockWidget* myCont;
00073   bool           myState;
00074   bool           myEmpty;
00075   bool           myBlock;
00076   bool           myShown;
00077 };
00078 
00083 QtxDockWidget::Watcher::Watcher( QtxDockWidget* cont )
00084 : QObject( cont ), myCont( cont ),
00085   myState( true ),
00086   myEmpty( false ),
00087   myBlock( false )
00088 {
00089   myCont->installEventFilter( this );
00090 
00091   installFilters();
00092 
00093   myShown = myCont->isVisibleTo( myCont->parentWidget() );
00094 }
00095 
00102 bool QtxDockWidget::Watcher::eventFilter( QObject* o, QEvent* e )
00103 {
00104   if ( o == myCont && ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ||
00105                         e->type() == QEvent::Hide || e->type() == QEvent::HideToParent ) )
00106   {
00107     installFilters();
00108   }
00109 
00110   if ( o == myCont && e->type() == QEvent::ChildAdded )
00111   {
00112     QChildEvent* ce = (QChildEvent*)e;
00113     if ( ce->child()->isWidgetType() )
00114       ce->child()->installEventFilter( this );
00115 
00116     QApplication::postEvent( this, new QEvent( (QEvent::Type)Update ) );
00117   }
00118 
00119   if ( o != myCont && e->type() == QEvent::WindowIconChange )
00120     updateIcon();
00121 
00122   if ( o != myCont && e->type() == QEvent::WindowTitleChange )
00123     updateCaption();
00124 
00125   if ( o != myCont && ( e->type() == QEvent::HideToParent || e->type() == QEvent::ShowToParent ) )
00126     updateVisibility();
00127 
00128   if ( o == myCont && e->type() == QEvent::ChildRemoved )
00129   {
00130     QApplication::postEvent( this, new QEvent( (QEvent::Type)Remove ) );
00131   }
00132 
00133   return false;
00134 }
00135 
00140 void QtxDockWidget::Watcher::shown( QtxDockWidget* dw )
00141 {
00142   if ( dw != myCont )
00143     return;
00144 
00145   setVisible( true );
00146 }
00147 
00152 void QtxDockWidget::Watcher::hidden( QtxDockWidget* dw )
00153 {
00154   if ( dw != myCont )
00155     return;
00156 
00157   setVisible( false );
00158 }
00159 
00160 bool QtxDockWidget::Watcher::isEmpty() const
00161 {
00162   return myEmpty;
00163 }
00164 
00165 bool QtxDockWidget::Watcher::isVisible() const
00166 {
00167   return myShown;
00168 }
00169 
00170 void QtxDockWidget::Watcher::setEmpty( const bool on )
00171 {
00172   myEmpty = on;
00173 }
00174 
00175 void QtxDockWidget::Watcher::setVisible( const bool on )
00176 {
00177   myShown = on;
00178 }
00179 
00183 void QtxDockWidget::Watcher::showContainer()
00184 {
00185   if ( !myCont )
00186     return;
00187 
00188   bool vis = isVisible();
00189 
00190   QtxDockWidget* cont = myCont;
00191   myCont = 0;
00192   cont->show();
00193   myCont = cont;
00194 
00195   setVisible( vis );
00196 }
00197 
00201 void QtxDockWidget::Watcher::hideContainer()
00202 {
00203   if ( !myCont )
00204     return;
00205 
00206   bool vis = isVisible();
00207 
00208   QtxDockWidget* cont = myCont;
00209   myCont = 0;
00210   cont->hide();
00211   myCont = cont;
00212 
00213   setVisible( vis );
00214 }
00215 
00220 void QtxDockWidget::Watcher::customEvent( QEvent* e )
00221 {
00222   if ( e->type() == (QEvent::Type)Update )
00223   {
00224     updateIcon();
00225     updateCaption();
00226     updateVisibility();
00227   }
00228   else if ( myCont && e->type() == (QEvent::Type)Remove && !myCont->widget() )
00229   {
00230     myCont->deleteLater();
00231     myCont = 0;
00232   }
00233 }
00234 
00239 void QtxDockWidget::Watcher::installFilters()
00240 {
00241   if ( !myCont )
00242     return;
00243 
00244   QLayout* l = myCont->layout();
00245   if ( !l )
00246     return;
00247 
00248   for ( int i = 0; i < (int)l->count(); i++ )
00249   {
00250     if ( l->itemAt( i ) && l->itemAt( i )->widget() )
00251       l->itemAt( i )->widget()->installEventFilter( this );
00252   }
00253 }
00254 
00259 void QtxDockWidget::Watcher::updateVisibility()
00260 {
00261   if ( !myCont )
00262     return;
00263 
00264   bool vis = false;
00265   if ( myCont->widget() )
00266     vis = myCont->widget()->isVisibleTo( myCont );
00267   else
00268   {
00269     QLayout* l = myCont->layout();
00270     if ( l )
00271     {
00272       for ( int i = 0; i < (int)l->count() && !vis; i++ )
00273         vis = l->itemAt( i ) && l->itemAt( i )->widget() && l->itemAt( i )->widget()->isVisibleTo( myCont );
00274     }
00275   }
00276 
00277   bool empty = isEmpty();
00278   if ( empty == vis )
00279   {
00280     empty = !vis;
00281     setEmpty( empty );
00282     if ( !empty )
00283       myCont->toggleViewAction()->setVisible( myState );
00284     else
00285     {
00286       myState = myCont->toggleViewAction()->isVisible();
00287       myCont->toggleViewAction()->setVisible( false );
00288     }
00289   }
00290 
00291   vis = !empty && isVisible();
00292   if ( vis != myCont->isVisibleTo( myCont->parentWidget() ) )
00293     vis ? showContainer() : hideContainer();
00294 }
00295 
00299 void QtxDockWidget::Watcher::updateIcon()
00300 {
00301   if ( !myCont || !myCont->widget() || myBlock )
00302     return;
00303 
00304   myBlock = true;
00305   myCont->setWindowIcon( myCont->widget()->windowIcon() );
00306   myBlock = false;
00307 }
00308 
00312 void QtxDockWidget::Watcher::updateCaption()
00313 {
00314   if ( myCont && myCont->widget() && !myCont->widget()->windowTitle().isNull() )
00315     myCont->setWindowTitle( myCont->widget()->windowTitle() );
00316 }
00317 
00329 QtxDockWidget::QtxDockWidget( const QString& title, QWidget* parent, Qt::WindowFlags f )
00330 : QDockWidget( title, parent, f ),
00331   myWatcher( 0 ),
00332   myOrientation( (Qt::Orientation)-1 )
00333 {
00334   updateState();
00335 }
00336 
00344 QtxDockWidget::QtxDockWidget( const bool watch, QWidget* parent, Qt::WindowFlags f )
00345 : QDockWidget( parent, f ),
00346   myWatcher( 0 ),
00347   myOrientation( (Qt::Orientation)-1 )
00348 {
00349   if ( watch )
00350     myWatcher = new Watcher( this );
00351 
00352   updateState();
00353 }
00354 
00360 QtxDockWidget::QtxDockWidget( QWidget* parent, Qt::WindowFlags f )
00361 : QDockWidget( parent, f ),
00362 myWatcher( 0 )
00363 {
00364 }
00365 
00369 QtxDockWidget::~QtxDockWidget()
00370 {
00371 }
00372 
00377 QSize QtxDockWidget::sizeHint() const
00378 {
00379   QSize sz = QDockWidget::sizeHint();
00380 
00381   // printf( "----------------> QtxDockWidget::sizeHint()\n" );
00382 
00383   return QSize( 500, 100 );
00384 
00385   return sz;
00386 }
00387 
00392 QSize QtxDockWidget::minimumSizeHint() const
00393 {
00394   QSize sz = QDockWidget::minimumSizeHint();
00395 
00396   return sz;
00397 }
00398 
00403 void QtxDockWidget::setVisible( bool on )
00404 {
00405   updateGeometry();
00406   if ( widget() )
00407     widget()->updateGeometry();
00408 
00409   QDockWidget::setVisible( on && ( myWatcher ? !myWatcher->isEmpty() : true )  );
00410 
00411   if ( myWatcher )
00412   {
00413     if ( on )
00414       myWatcher->shown( this );
00415     else
00416       myWatcher->hidden( this );
00417   }
00418 }
00419 
00424 void QtxDockWidget::resizeEvent( QResizeEvent* e )
00425 {
00426   QDockWidget::resizeEvent( e );
00427   updateState();
00428 }
00429 
00434 Qt::Orientation QtxDockWidget::orientation() const
00435 {
00436   QMainWindow* mw = 0;
00437   QWidget* wid = parentWidget();
00438   while ( wid && !mw )
00439   {
00440     mw = ::qobject_cast<QMainWindow*>( wid );
00441     wid = wid->parentWidget();
00442   }
00443 
00444   Qt::Orientation res = (Qt::Orientation)-1;
00445 
00446   if ( !mw )
00447     return res;
00448 
00449   Qt::DockWidgetArea area = mw->dockWidgetArea( (QtxDockWidget*)this );
00450   switch ( area )
00451   {
00452   case Qt::LeftDockWidgetArea:
00453   case Qt::RightDockWidgetArea:
00454     res = Qt::Vertical;
00455     break;
00456   case Qt::TopDockWidgetArea:
00457   case Qt::BottomDockWidgetArea:
00458     res = Qt::Horizontal;
00459     break;
00460   default:
00461     break;
00462   }
00463 
00464   return res;
00465 }
00466 
00470 void QtxDockWidget::updateState()
00471 {
00472   Qt::Orientation o = orientation();
00473   if ( myOrientation == o )
00474     return;
00475 
00476   myOrientation = o;
00477 
00478   emit orientationChanged( myOrientation );
00479 }
00480