Salome HOME
6154653feafdadf3a983c29347c00961c22cc698
[modules/gui.git] / src / Qtx / QtxToolBar.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File:      QtxToolBar.cxx
23 // Author:    Sergey TELKOV
24 //
25 #include "QtxToolBar.h"
26
27 #include <QAction>
28 #include <QMainWindow>
29 #include <QApplication>
30
31 /*!
32   \class QtxToolBar::Watcher
33   \internal
34   \brief Internal class which goal is to watch parent toolbar state changing.
35 */
36
37 class QtxToolBar::Watcher : public QObject
38 {
39 public:
40   Watcher( QtxToolBar* );
41
42   void         shown( QtxToolBar* );
43   void         hidden( QtxToolBar* );
44
45   virtual bool eventFilter( QObject*, QEvent* );
46
47   bool           isEmpty() const;
48   bool           isVisible() const;
49
50 protected:
51   virtual void customEvent( QEvent* );
52
53 private:
54   enum { Install = QEvent::User, Update };
55
56 private:
57   void         installFilters();
58
59   void         showContainer();
60   void         hideContainer();
61
62   void         updateVisibility();
63
64   void         setEmpty( const bool );
65   void         setVisible( const bool );
66
67 private:
68   QtxToolBar*  myCont;
69   bool         myState;
70   bool         myEmpty;
71 };
72
73 /*!
74   \brief Constructor.
75   \param cont toolbar to be watched
76 */
77 QtxToolBar::Watcher::Watcher( QtxToolBar* cont )
78 : QObject( cont ),
79   myCont( cont ),
80   myState( true ),
81   myEmpty( false )
82 {
83   setVisible( myCont->isVisibleTo( myCont->parentWidget() ) );
84
85   myCont->installEventFilter( this );
86
87   installFilters();
88 }
89
90 /*!
91   \brief Custom event filter.
92   \param o event receiver object
93   \param e event sent to object
94   \return \c true if further event processing should be stopped
95 */
96 bool QtxToolBar::Watcher::eventFilter( QObject* o, QEvent* e )
97 {
98   if ( o == myCont && e->type() == QEvent::ChildAdded )
99     QApplication::postEvent( this, new QEvent( (QEvent::Type)Install ) );
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 ||
104                                    e->type() == QEvent::ShowToParent || e->type() == QEvent::ActionAdded ||
105                                    e->type() == QEvent::ActionRemoved ) );
106
107   if ( updVis )
108   {
109     QtxToolBar* cont = myCont;
110     myCont = 0;
111     QApplication::sendPostedEvents( this, Update );
112     myCont = cont;
113     QApplication::postEvent( this, new QEvent( (QEvent::Type)Update ) );
114   }
115
116   return false;
117 }
118
119 /*!
120   \brief Set internal status to "shown"
121   \param tb toolbar
122 */
123 void QtxToolBar::Watcher::shown( QtxToolBar* tb )
124 {
125   if ( tb != myCont )
126     return;
127
128   setVisible( true );
129 }
130
131 /*!
132   \brief Set internal status to "hidden"
133   \param tb toolbar
134 */
135 void QtxToolBar::Watcher::hidden( QtxToolBar* tb )
136 {
137   if ( tb != myCont )
138     return;
139
140   setVisible( false );
141 }
142
143 bool QtxToolBar::Watcher::isEmpty() const
144 {
145   return myEmpty;
146 }
147
148 bool QtxToolBar::Watcher::isVisible() const
149 {
150   bool vis = false;
151   if ( myCont && myCont->toggleViewAction() )
152     vis = myCont->toggleViewAction()->isChecked();
153   return vis;
154 }
155
156 void QtxToolBar::Watcher::setEmpty( const bool on )
157 {
158   myEmpty = on;
159 }
160
161 void QtxToolBar::Watcher::setVisible( const bool on )
162 {
163   if ( !myCont || !myCont->toggleViewAction() )
164     return;
165
166   bool block = myCont->toggleViewAction()->signalsBlocked();
167   myCont->toggleViewAction()->blockSignals( true );
168   myCont->toggleViewAction()->setChecked( on );
169   myCont->toggleViewAction()->blockSignals( block );
170 }
171
172 /*!
173   \brief Show the toolbar being watched
174 */
175 void QtxToolBar::Watcher::showContainer()
176 {
177   if ( !myCont )
178     return;
179
180   bool vis = isVisible();
181
182   QtxToolBar* cont = myCont;
183   myCont = 0;
184   cont->show();
185   myCont = cont;
186
187   setVisible( vis );
188 }
189
190 /*!
191   \brief Hide the toolbar being watched
192 */
193 void QtxToolBar::Watcher::hideContainer()
194 {
195   if ( !myCont )
196     return;
197
198   bool vis = isVisible();
199
200   QtxToolBar* cont = myCont;
201   myCont = 0;
202   cont->hide();
203   myCont = cont;
204
205   setVisible( vis );
206 }
207
208 /*!
209   \brief Proces custom events.
210   \param e custom event
211 */
212 void QtxToolBar::Watcher::customEvent( QEvent* e )
213 {
214   switch ( e->type() )
215   {
216   case Install:
217     installFilters();
218     break;
219   case Update:
220     updateVisibility();
221     break;
222   default:
223     break;
224   }
225 }
226
227 /*!
228   \brief Install this object as event dilter to all children widgets
229          of the toolbar being watched.
230 */
231 void QtxToolBar::Watcher::installFilters()
232 {
233   if ( !myCont )
234     return;
235
236   const QObjectList& objList = myCont->children();
237   for ( QObjectList::const_iterator it = objList.begin(); it != objList.end(); ++it )
238   {
239     if ( (*it)->isWidgetType() && qstrcmp( "qt_dockwidget_internal", (*it)->objectName().toLatin1() ) )
240       (*it)->installEventFilter( this );
241   }
242 }
243
244 /*!
245   \brief Update visibility state of all children widgets of the toolbar
246          being watched.
247 */
248 void QtxToolBar::Watcher::updateVisibility()
249 {
250   if ( !myCont )
251     return;
252
253   bool vis = false;
254   QList<QAction*> actList = myCont->actions();
255   for ( QList<QAction*>::const_iterator it = actList.begin(); it != actList.end() && !vis; ++it )
256   {
257     if ( (*it)->isSeparator() )
258       continue;
259
260     vis = (*it)->isVisible();
261   }
262
263   QMainWindow* mw = myCont->mainWindow();
264   bool empty = isEmpty();
265   if ( mw && empty == vis )
266   {
267     empty = !vis;
268     setEmpty( empty );
269     if ( !empty )
270       myCont->toggleViewAction()->setVisible( myState );
271     else
272     {
273       myState = myCont->toggleViewAction()->isVisible();
274       myCont->toggleViewAction()->setVisible( false );
275     }
276   }
277
278   vis = !empty && isVisible();
279   if ( vis != myCont->isVisibleTo( myCont->parentWidget() ) )
280     vis ? showContainer() : hideContainer();
281 }
282
283 /*!
284   \class QtxToolBar
285   \brief Enhanced toolbar class.
286 */
287
288 /*!
289   \brief Constructor.
290   \param watch if \c true the event filter is installed to watch toolbar state changes 
291          to update it properly
292   \param label toolbar title
293   \param parent parent widget
294 */
295 QtxToolBar::QtxToolBar( const bool watch, const QString& label, QWidget* parent )
296 : QToolBar( label, parent ),
297   myWatcher( 0 ),
298   myStretch( false )
299 {
300   if ( watch )
301     myWatcher = new Watcher( this );
302
303   if ( QMainWindow* mw = ::qobject_cast<QMainWindow*>( parent ) )
304     mw->addToolBar( this );
305 }
306
307 /*!
308   \brief Constructor.
309   \param label toolbar title
310   \param parent parent widget
311 */
312 QtxToolBar::QtxToolBar( const QString& label, QWidget* parent )
313 : QToolBar( label, parent ),
314   myWatcher( 0 ),
315   myStretch( false )
316 {
317   if ( QMainWindow* mw = ::qobject_cast<QMainWindow*>( parent ) )
318     mw->addToolBar( this );
319 }
320
321 /*!
322   \brief Constructor.
323   \param watch if \c true the event filter is installed to watch toolbar state changes 
324          to update it properly
325   \param parent parent widget
326 */
327 QtxToolBar::QtxToolBar( const bool watch, QWidget* parent )
328 : QToolBar( parent ),
329   myWatcher( 0 ),
330   myStretch( false )
331 {
332   if ( watch )
333     myWatcher = new Watcher( this );
334
335   if ( QMainWindow* mw = ::qobject_cast<QMainWindow*>( parent ) )
336     mw->addToolBar( this );
337 }
338
339 /*!
340   \brief Constructor.
341   \param parent parent widget
342 */
343 QtxToolBar::QtxToolBar( QWidget* parent )
344 : QToolBar( parent ),
345   myWatcher( 0 ),
346   myStretch( false )
347 {
348   if ( QMainWindow* mw = ::qobject_cast<QMainWindow*>( parent ) )
349     mw->addToolBar( this );
350 }
351
352 /*!
353   \brief Destructor.
354 */
355 QtxToolBar::~QtxToolBar()
356 {
357 }
358
359 /*!
360   \brief Show/hide the toolbar.
361   \param on new visibility state
362 */
363 void QtxToolBar::setVisible( bool visible )
364 {
365   if ( myWatcher )
366   {
367     if ( visible )
368       myWatcher->shown( this );
369     else
370       myWatcher->hidden( this );
371   }
372
373   QToolBar::setVisible( visible );
374 }
375
376 /*!
377   \brief Get parent main window.
378   \return main window pointer
379 */
380 QMainWindow* QtxToolBar::mainWindow() const
381 {
382   QMainWindow* mw = 0;
383   QWidget* wid = parentWidget();
384   while ( !mw && wid )
385   {
386     mw = ::qobject_cast<QMainWindow*>( wid );
387     wid = wid->parentWidget();
388   }
389   return mw;
390 }
391
392 bool QtxToolBar::event( QEvent* e )
393 {
394   if ( e->type() == QEvent::WindowTitleChange && objectName().isEmpty() )
395     setObjectName( windowTitle() );
396
397   return QToolBar::event( e );
398 }