source: trunk/src/gui/kernel/qactiongroup.cpp@ 808

Last change on this file since 808 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 12.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qactiongroup.h"
43
44#ifndef QT_NO_ACTION
45
46#include "qaction_p.h"
47#include "qapplication.h"
48#include "qevent.h"
49#include "qlist.h"
50
51QT_BEGIN_NAMESPACE
52
53class QActionGroupPrivate : public QObjectPrivate
54{
55 Q_DECLARE_PUBLIC(QActionGroup)
56public:
57 QActionGroupPrivate() : exclusive(1), enabled(1), visible(1) { }
58 QList<QAction *> actions;
59 QPointer<QAction> current;
60 uint exclusive : 1;
61 uint enabled : 1;
62 uint visible : 1;
63
64private:
65 void _q_actionTriggered(); //private slot
66 void _q_actionChanged(); //private slot
67 void _q_actionHovered(); //private slot
68};
69
70void QActionGroupPrivate::_q_actionChanged()
71{
72 Q_Q(QActionGroup);
73 QAction *action = qobject_cast<QAction*>(q->sender());
74 Q_ASSERT_X(action != 0, "QWidgetGroup::_q_actionChanged", "internal error");
75 if(exclusive) {
76 if (action->isChecked()) {
77 if (action != current) {
78 if(current)
79 current->setChecked(false);
80 current = action;
81 }
82 } else if (action == current) {
83 current = 0;
84 }
85 }
86}
87
88void QActionGroupPrivate::_q_actionTriggered()
89{
90 Q_Q(QActionGroup);
91 QAction *action = qobject_cast<QAction*>(q->sender());
92 Q_ASSERT_X(action != 0, "QWidgetGroup::_q_actionTriggered", "internal error");
93 emit q->triggered(action);
94 emit q->selected(action);
95}
96
97void QActionGroupPrivate::_q_actionHovered()
98{
99 Q_Q(QActionGroup);
100 QAction *action = qobject_cast<QAction*>(q->sender());
101 Q_ASSERT_X(action != 0, "QWidgetGroup::_q_actionHovered", "internal error");
102 emit q->hovered(action);
103}
104
105/*!
106 \class QActionGroup
107 \brief The QActionGroup class groups actions together.
108
109 \ingroup mainwindow-classes
110
111 In some situations it is useful to group actions together. For
112 example, if you have a \gui{Left Align} action, a \gui{Right
113 Align} action, a \gui{Justify} action, and a \gui{Center} action,
114 only one of these actions should be active at any one time. One
115 simple way of achieving this is to group the actions together in
116 an action group.
117
118 Here's a example (from the \l{mainwindows/menus}{Menus} example):
119
120 \snippet examples/mainwindows/menus/mainwindow.cpp 6
121
122 Here we create a new action group. Since the action group is
123 exclusive by default, only one of the actions in the group is
124 checked at any one time.
125
126 \img qactiongroup-align.png Alignment options in a QMenu
127
128 A QActionGroup emits an triggered() signal when one of its
129 actions is chosen. Each action in an action group emits its
130 triggered() signal as usual.
131
132 As stated above, an action group is \l exclusive by default; it
133 ensures that only one checkable action is active at any one time.
134 If you want to group checkable actions without making them
135 exclusive, you can turn of exclusiveness by calling
136 setExclusive(false).
137
138 Actions can be added to an action group using addAction(), but it
139 is usually more convenient to specify a group when creating
140 actions; this ensures that actions are automatically created with
141 a parent. Actions can be visually separated from each other by
142 adding a separator action to the group; create an action and use
143 QAction's \l {QAction::}{setSeparator()} function to make it
144 considered a separator. Action groups are added to widgets with
145 the QWidget::addActions() function.
146
147 \sa QAction
148*/
149
150/*!
151 Constructs an action group for the \a parent object.
152
153 The action group is exclusive by default. Call setExclusive(false)
154 to make the action group non-exclusive.
155*/
156QActionGroup::QActionGroup(QObject* parent) : QObject(*new QActionGroupPrivate, parent)
157{
158}
159
160/*!
161 Destroys the action group.
162*/
163QActionGroup::~QActionGroup()
164{
165}
166
167/*!
168 \fn QAction *QActionGroup::addAction(QAction *action)
169
170 Adds the \a action to this group, and returns it.
171
172 Normally an action is added to a group by creating it with the
173 group as its parent, so this function is not usually used.
174
175 \sa QAction::setActionGroup()
176*/
177QAction *QActionGroup::addAction(QAction* a)
178{
179 Q_D(QActionGroup);
180 if(!d->actions.contains(a)) {
181 d->actions.append(a);
182 QObject::connect(a, SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
183 QObject::connect(a, SIGNAL(changed()), this, SLOT(_q_actionChanged()));
184 QObject::connect(a, SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
185 }
186 if(!a->d_func()->forceDisabled) {
187 a->setEnabled(d->enabled);
188 a->d_func()->forceDisabled = false;
189 }
190 if(!a->d_func()->forceInvisible) {
191 a->setVisible(d->visible);
192 a->d_func()->forceInvisible = false;
193 }
194 if(a->isChecked())
195 d->current = a;
196 QActionGroup *oldGroup = a->d_func()->group;
197 if(oldGroup != this) {
198 if (oldGroup)
199 oldGroup->removeAction(a);
200 a->d_func()->group = this;
201 }
202 return a;
203}
204
205/*!
206 Creates and returns an action with \a text. The newly created
207 action is a child of this action group.
208
209 Normally an action is added to a group by creating it with the
210 group as parent, so this function is not usually used.
211
212 \sa QAction::setActionGroup()
213*/
214QAction *QActionGroup::addAction(const QString &text)
215{
216 return new QAction(text, this);
217}
218
219/*!
220 Creates and returns an action with \a text and an \a icon. The
221 newly created action is a child of this action group.
222
223 Normally an action is added to a group by creating it with the
224 group as its parent, so this function is not usually used.
225
226 \sa QAction::setActionGroup()
227*/
228QAction *QActionGroup::addAction(const QIcon &icon, const QString &text)
229{
230 return new QAction(icon, text, this);
231}
232
233/*!
234 Removes the \a action from this group. The action will have no
235 parent as a result.
236
237 \sa QAction::setActionGroup()
238*/
239void QActionGroup::removeAction(QAction *action)
240{
241 Q_D(QActionGroup);
242 if (d->actions.removeAll(action)) {
243 if (action == d->current)
244 d->current = 0;
245 QObject::disconnect(action, SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
246 QObject::disconnect(action, SIGNAL(changed()), this, SLOT(_q_actionChanged()));
247 QObject::disconnect(action, SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
248 action->d_func()->group = 0;
249 }
250}
251
252/*!
253 Returns the list of this groups's actions. This may be empty.
254*/
255QList<QAction*> QActionGroup::actions() const
256{
257 Q_D(const QActionGroup);
258 return d->actions;
259}
260
261/*!
262 \property QActionGroup::exclusive
263 \brief whether the action group does exclusive checking
264
265 If exclusive is true, only one checkable action in the action group
266 can ever be active at any time. If the user chooses another
267 checkable action in the group, the one they chose becomes active and
268 the one that was active becomes inactive.
269
270 \sa QAction::checkable
271*/
272void QActionGroup::setExclusive(bool b)
273{
274 Q_D(QActionGroup);
275 d->exclusive = b;
276}
277
278bool QActionGroup::isExclusive() const
279{
280 Q_D(const QActionGroup);
281 return d->exclusive;
282}
283
284/*!
285 \fn void QActionGroup::setDisabled(bool b)
286
287 This is a convenience function for the \l enabled property, that
288 is useful for signals--slots connections. If \a b is true the
289 action group is disabled; otherwise it is enabled.
290*/
291
292/*!
293 \property QActionGroup::enabled
294 \brief whether the action group is enabled
295
296 Each action in the group will be enabled or disabled unless it
297 has been explicitly disabled.
298
299 \sa QAction::setEnabled()
300*/
301void QActionGroup::setEnabled(bool b)
302{
303 Q_D(QActionGroup);
304 d->enabled = b;
305 for(QList<QAction*>::const_iterator it = d->actions.constBegin(); it != d->actions.constEnd(); ++it) {
306 if(!(*it)->d_func()->forceDisabled) {
307 (*it)->setEnabled(b);
308 (*it)->d_func()->forceDisabled = false;
309 }
310 }
311}
312
313bool QActionGroup::isEnabled() const
314{
315 Q_D(const QActionGroup);
316 return d->enabled;
317}
318
319/*!
320 Returns the currently checked action in the group, or 0 if none
321 are checked.
322*/
323QAction *QActionGroup::checkedAction() const
324{
325 Q_D(const QActionGroup);
326 return d->current;
327}
328
329/*!
330 \property QActionGroup::visible
331 \brief whether the action group is visible
332
333 Each action in the action group will match the visible state of
334 this group unless it has been explicitly hidden.
335
336 \sa QAction::setEnabled()
337*/
338void QActionGroup::setVisible(bool b)
339{
340 Q_D(QActionGroup);
341 d->visible = b;
342 for(QList<QAction*>::Iterator it = d->actions.begin(); it != d->actions.end(); ++it) {
343 if(!(*it)->d_func()->forceInvisible) {
344 (*it)->setVisible(b);
345 (*it)->d_func()->forceInvisible = false;
346 }
347 }
348}
349
350bool QActionGroup::isVisible() const
351{
352 Q_D(const QActionGroup);
353 return d->visible;
354}
355
356/*!
357 \fn void QActionGroup::triggered(QAction *action)
358
359 This signal is emitted when the given \a action in the action
360 group is activated by the user; for example, when the user clicks
361 a menu option, toolbar button, or presses an action's shortcut key
362 combination.
363
364 Connect to this signal for command actions.
365
366 \sa QAction::activate()
367*/
368
369/*!
370 \fn void QActionGroup::hovered(QAction *action)
371
372 This signal is emitted when the given \a action in the action
373 group is highlighted by the user; for example, when the user
374 pauses with the cursor over a menu option, toolbar button, or
375 presses an action's shortcut key combination.
376
377 \sa QAction::activate()
378*/
379
380/*!
381 \fn void QActionGroup::add(QAction* a)
382
383 Use addAction() instead.
384*/
385
386/*!
387 \fn void QActionGroup::addSeparator()
388
389 Normally you add a separator to the menus or widgets to which
390 actions are added, so this function is very rarely needed.
391
392 \oldcode
393 actionGroup->addSeparator();
394 \newcode
395 QAction *separator = new QAction(this);
396 separator->setSeparator(true);
397 actionGroup->addAction(separator);
398 \endcode
399*/
400
401/*!
402 \fn bool QActionGroup::addTo(QWidget *widget)
403
404 \oldcode
405 actionGroup->addTo(widget);
406 \newcode
407 widget->addActions(actionGroup->actions());
408 \endcode
409*/
410
411/*!
412 \fn void QActionGroup::selected(QAction *action);
413
414 Use triggered() instead.
415
416*/
417
418QT_END_NAMESPACE
419
420#include "moc_qactiongroup.cpp"
421
422#endif // QT_NO_ACTION
Note: See TracBrowser for help on using the repository browser.