]> SALOME platform Git repositories - modules/gui.git/blob - src/Qtx/QtxActionGroup.cxx
Salome HOME
eeea9d7775c24d4358727ba93d5508a978b3e4c0
[modules/gui.git] / src / Qtx / QtxActionGroup.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:      QtxActionGroup.cxx
23 // Author:    Sergey TELKOV
24 //
25 #include "QtxActionGroup.h"
26
27 #include "QtxComboBox.h"
28
29 #include <QMenu>
30 #include <QMenuBar>
31 #include <QActionGroup>
32
33 /*!
34   \class QtxActionGroup
35   \brief The QtxActionGroup class groups actions together.
36
37   QtxActionGroup class operates with a list of actions in the similar way as it does QActionGroup class.
38   But in contrast to the Qt 4's class, QtxActrionGroup behaves rather like it was in Qt series 3x.
39   For example, it automatically shows exclusive combo box widget when action group is added to the toolbar
40   and if \a usesDropDown and \a exclusive flags are both set to \c true.
41   
42   The setExclusive() function is used to ensure that only one action is active at any moment:
43   it should be used with actions which have their \a checkable state set to \c true.
44
45   Action group actions appear as individual menu options and toolbar buttons. For exclusive action
46   groups use setUsesDropDown() to display the actions in a subwidget of the toolbar or menu the action group
47   is added on.
48
49   Actions can be added to the action group using add() function. Add the action group to the menu or
50   toolbar in the same way as for single action - using addAction() method of QMenu or QToolbar class.
51 */
52
53 /*!
54   \brief Constructor
55
56   The created action group is exclusive by default.
57
58   \param parent owner object
59   \sa setExclusive()
60 */
61 QtxActionGroup::QtxActionGroup( QObject* parent )
62 : QtxActionSet( parent ),
63   myDropDown( false )
64 {
65   setMenu( new QMenu( 0 ) );
66   myActionGroup = new QActionGroup( this );
67
68   connect( myActionGroup, SIGNAL( triggered( QAction* ) ), this, SLOT( onTriggered( QAction* ) ) );
69 }
70
71 /*!
72   \brief Constructor
73   \param parent owner object
74   \param exclusive if \c true only one action in the group will ever be active
75   \sa setExclusive()
76 */
77 QtxActionGroup::QtxActionGroup( QObject* parent, const bool exclusive )
78 : QtxActionSet( parent ),
79   myDropDown( false )
80 {
81   setMenu( new QMenu( 0 ) );
82   myActionGroup = new QActionGroup( this );
83   myActionGroup->setExclusive( exclusive );
84
85   connect( myActionGroup, SIGNAL( triggered( QAction* ) ), this, SIGNAL( selected( QAction* ) ) );
86 }
87
88 /*!
89   \brief Destructor.
90 */
91 QtxActionGroup::~QtxActionGroup()
92 {
93 }
94
95 /*!
96   \brief Check if the action group is exclusive
97   \return \c true if the action group is exclusive and \c false otherwise
98   \sa setExclusive(), setUsesDropDown()
99 */
100 bool QtxActionGroup::isExclusive() const
101 {
102   return myActionGroup->isExclusive();
103 }
104
105 /*!
106   \brief Set/clear the action group exclusiveness
107   \param on if \c true the action group will be exclusive
108   \sa isExclusive(), setUsesDropDown()
109 */
110 void QtxActionGroup::setExclusive( const bool on )
111 {
112   if ( myActionGroup->isExclusive() == on )
113     return;
114
115   bool e = isEmptyAction();
116
117   myActionGroup->setExclusive( on );
118
119   if ( e != isEmptyAction() )
120     updateType();
121 }
122
123 /*!
124   \brief Check if action group should appear in a subwidget of parent widget
125
126   Note: for this option to take into effect, the \a exclusive flag should
127   be also set to \c true
128
129   \return \c true if the action group is shown in subwidget
130   \sa setUsesDropDown(), setExclusive()
131 */
132 bool QtxActionGroup::usesDropDown() const
133 {
134   return myDropDown;
135 }
136
137 /*!
138   \brief Defines a way how the group's actions should be displayed in parent widget 
139   action group is added to - as a group of actions or in a subwidget (e.g. in the
140   combo box).
141   \param on if \c true, action group will be shown in the subwidget
142   \sa usesDropDown(), setExclusive()
143 */
144 void QtxActionGroup::setUsesDropDown( const bool on )
145 {
146   if ( myDropDown == on )
147     return;
148
149   bool e = isEmptyAction();
150
151   myDropDown = on;
152
153   if ( e != isEmptyAction() )
154     updateType();
155 }
156
157 /*!
158   \brief Append the specified action into group.
159   \a action action to be added to the action group
160 */
161 void QtxActionGroup::add( QAction* a )
162 {
163   insertAction( a );
164 }
165
166 /*!
167   \brief Called when some subwidget item is activated by the user.
168   \param id item identifier
169 */
170 void QtxActionGroup::onActivated( int id )
171 {
172   const QObject* s = sender();
173
174   QAction* a = action( id );
175   if ( !a )
176     return;
177
178   if ( a->isChecked() )
179     return;
180
181   a->setChecked( true );
182   a->trigger();
183
184   QList<QWidget*> lst = createdWidgets();
185   for ( QList<QWidget*>::iterator it = lst.begin(); it != lst.end(); ++it )
186   {
187     QtxComboBox* cb = ::qobject_cast<QtxComboBox*>( *it );
188     if ( cb && cb != s )
189       cb->setCurrentId( id );
190   }
191 }
192
193 /*!
194   \brief Called when some action owned by this action group is activated by the user
195   \param a action being activated
196 */
197 void QtxActionGroup::onTriggered( QAction* a )
198 {
199   int id = actionId( a );
200   if ( id != -1 ) {
201     QList<QWidget*> lst = createdWidgets();
202     for ( QList<QWidget*>::iterator it = lst.begin(); it != lst.end(); ++it )
203     {
204       QtxComboBox* cb = ::qobject_cast<QtxComboBox*>( *it );
205       if ( cb )
206         cb->setCurrentId( id );
207     }
208   }
209   
210   emit selected( a );
211 }
212
213 /*!
214   \brief Update action group for the specified widget.
215   \param w a widget this action group is added to
216 */
217 void QtxActionGroup::updateAction( QWidget* w )
218 {
219   if ( !::qobject_cast<QMenu*>( w ) && !::qobject_cast<QMenuBar*>( w ) ) {
220     QtxComboBox* cb = createdWidget( w );
221     if ( !cb )
222       QtxActionSet::updateAction( w );
223     else
224     {
225       updateAction( cb );
226       
227       QList<QAction*> lst = actions();
228       for ( QList<QAction*>::iterator it = lst.begin(); it != lst.end(); ++it )
229         w->removeAction( *it );
230     }
231   }
232   else
233   {
234     if ( !usesDropDown() ) {
235       QtxActionSet::updateAction( w );
236     }
237     else {
238       QList<QAction*> lst = actions();
239       for ( QList<QAction*>::iterator it = lst.begin(); it != lst.end(); ++it )
240         w->removeAction( *it );
241     }
242   }
243 }
244
245 /*!
246   \brief Update action group for the specified combo box.
247   \param cb a combo box this action group is added to
248 */
249 void QtxActionGroup::updateAction( QtxComboBox* cb )
250 {
251   if ( !cb )
252     return;
253
254   cb->clear();
255   cb->setCleared( false );
256
257   QAction* cur = 0;
258   QList<QAction*> lst = actions();
259   for ( QList<QAction*>::iterator it = lst.begin(); it != lst.end(); ++it )
260   {
261     QAction* a = *it;
262     cb->addItem( a->icon(), a->text() );
263     cb->setId( cb->count() - 1, actionId( a ) );
264     if ( a->isChecked() )
265       cur = a;
266   }
267
268   if ( cur )
269     cb->setCurrentId( actionId( cur ) );
270   else
271     cb->setCleared( true );
272 }
273
274 /*!
275   \brief Create widget representing action group in the widget
276   this action group is added to.
277   \param p widget this action group is being added to
278   \return new widget representing this action group
279 */
280 QWidget* QtxActionGroup::createWidget( QWidget* p )
281 {
282   if ( ::qobject_cast<QMenu*>( p ) || ::qobject_cast<QMenuBar*>( p ) )
283     return 0;
284
285   QtxComboBox* cb = !isEmptyAction() ? new QtxComboBox( p ) : 0;
286   if ( cb )
287     connect( cb, SIGNAL( activatedId( int ) ), this, SLOT( onActivated( int ) ) );
288   return cb;
289 }
290
291 /*!
292   \brief Check if the action itself should be invisible
293   (only child action are shown)
294   \return \c true if the action itself should be visible
295 */
296 bool QtxActionGroup::isEmptyAction() const
297 {
298   return !isExclusive() || !usesDropDown();
299 }
300
301 /*!
302   \brief Called when action is added to the action group
303   \param a action being added to the action group
304 */
305 void QtxActionGroup::actionAdded( QAction* a )
306 {
307   myActionGroup->addAction( a );
308   if ( menu() )
309     menu()->addAction( a );
310 }
311
312 /*!
313   \brief Called when action is removed from the action group
314   \param a action being removed from the action group
315 */
316 void QtxActionGroup::actionRemoved( QAction* a )
317 {
318   myActionGroup->removeAction( a );
319   if ( menu() )
320     menu()->removeAction( a );
321 }
322
323 /*!
324   \brief Internal update
325 */
326 void QtxActionGroup::updateType()
327 {
328   QList<QWidget*> lst = associatedWidgets();
329   for ( QList<QWidget*>::iterator it = lst.begin(); it != lst.end(); ++it )
330   {
331     QWidget* w = *it;
332     QList<QAction*> lst = w->actions();
333
334     int i = lst.indexOf( this );
335     w->removeAction( this );
336
337     lst = w->actions();
338     w->insertAction( i < lst.count() ? lst.at( i ) : 0, this );
339   }
340   setVisible( !isEmptyAction() );
341 }
342
343 /*!
344   \brief Get combo box created by this action group for the specified widget.
345   \param p widget this action group is added to
346   \return combo box if it was created for the specified widget or 0 otherwise
347 */
348 QtxComboBox* QtxActionGroup::createdWidget( QWidget* p )
349 {
350   QtxComboBox* cb = 0;
351   QList<QWidget*> lst = createdWidgets();
352   for ( QList<QWidget*>::iterator it = lst.begin(); it != lst.end() && !cb; ++it )
353   {
354     if ( (*it)->parent() == p )
355       cb = ::qobject_cast<QtxComboBox*>( *it );
356   }
357   return cb;
358 }
359
360 /*!
361   \fn void QtxActionGroup::selected( QAction* a );
362   \brief Emitted when some child action is toggled by the user.
363   \param a action being toggled
364 */