source: trunk/src/gui/kernel/qwidgetaction.cpp@ 561

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

trunk: Merged in qt 4.6.1 sources.

File size: 9.3 KB
RevLine 
[2]1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
[561]4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
[2]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**
[561]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.
[2]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**
[561]36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
[2]38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qwidgetaction.h"
43#include "qdebug.h"
44
45#ifndef QT_NO_ACTION
46#include "qwidgetaction_p.h"
47
48QT_BEGIN_NAMESPACE
49
50/*!
51 \class QWidgetAction
52 \since 4.2
53 \brief The QWidgetAction class extends QAction by an interface
54 for inserting custom widgets into action based containers, such
55 as toolbars.
56
[561]57 \ingroup mainwindow-classes
58
[2]59 Most actions in an application are represented as items in menus or
60 buttons in toolbars. However sometimes more complex widgets are
61 necessary. For example a zoom action in a word processor may be
62 realized using a QComboBox in a QToolBar, presenting a range
63 of different zoom levels. QToolBar provides QToolBar::insertWidget()
64 as convenience function for inserting a single widget.
65 However if you want to implement an action that uses custom
66 widgets for visualization in multiple containers then you have to
67 subclass QWidgetAction.
68
69 If a QWidgetAction is added for example to a QToolBar then
70 QWidgetAction::createWidget() is called. Reimplementations of that
71 function should create a new custom widget with the specified parent.
72
73 If the action is removed from a container widget then
74 QWidgetAction::deleteWidget() is called with the previously created custom
75 widget as argument. The default implementation hides the widget and deletes
76 it using QObject::deleteLater().
77
78 If you have only one single custom widget then you can set it as default
79 widget using setDefaultWidget(). That widget will then be used if the
80 action is added to a QToolBar, or in general to an action container that
81 supports QWidgetAction. If a QWidgetAction with only a default widget is
82 added to two toolbars at the same time then the default widget is shown
83 only in the first toolbar the action was added to. QWidgetAction takes
84 over ownership of the default widget.
85
86 Note that it is up to the widget to activate the action, for example by
87 reimplementing mouse event handlers and calling QAction::trigger().
88
89 \bold {Mac OS X}: If you add a widget to a menu in the application's menu
90 bar on Mac OS X, the widget will be added and it will function but with some
91 limitations:
92 \list 1
93 \o The widget is reparented away from the QMenu to the native menu
94 view. If you show the menu in some other place (e.g. as a popup menu),
95 the widget will not be there.
96 \o Focus/Keyboard handling of the widget is not possible.
97 \o Due to Apple's design, mouse tracking on the widget currently does
98 not work.
99 \o Connecting the triggered() signal to a slot that opens a modal
100 dialog will cause a crash in Mac OS X 10.4 (known bug acknowledged
101 by Apple), a workaround is to use a QueuedConnection instead of a
102 DirectConnection.
103 \endlist
104
105 \sa QAction, QActionGroup, QWidget
106*/
107
108/*!
109 Constructs an action with \a parent.
110*/
111QWidgetAction::QWidgetAction(QObject *parent)
112 : QAction(*(new QWidgetActionPrivate), parent)
113{
114}
115
116/*!
117 Destroys the object and frees allocated resources.
118*/
119QWidgetAction::~QWidgetAction()
120{
121 Q_D(QWidgetAction);
122 for (int i = 0; i < d->createdWidgets.count(); ++i)
123 disconnect(d->createdWidgets.at(i), SIGNAL(destroyed(QObject*)),
124 this, SLOT(_q_widgetDestroyed(QObject*)));
125 QList<QWidget *> widgetsToDelete = d->createdWidgets;
126 d->createdWidgets.clear();
127 qDeleteAll(widgetsToDelete);
128 delete d->defaultWidget;
129}
130
131/*!
132 Sets \a widget to be the default widget. The ownership is
133 transferred to QWidgetAction. Unless createWidget() is
134 reimplemented by a subclass to return a new widget the default
135 widget is used when a container widget requests a widget through
136 requestWidget().
137*/
138void QWidgetAction::setDefaultWidget(QWidget *widget)
139{
140 Q_D(QWidgetAction);
141 if (widget == d->defaultWidget || d->defaultWidgetInUse)
142 return;
143 delete d->defaultWidget;
144 d->defaultWidget = widget;
145 if (!widget)
146 return;
147
148 setVisible(!(widget->isHidden() && widget->testAttribute(Qt::WA_WState_ExplicitShowHide)));
149 d->defaultWidget->hide();
150 d->defaultWidget->setParent(0);
151 d->defaultWidgetInUse = false;
152 if (!isEnabled())
153 d->defaultWidget->setEnabled(false);
154}
155
156/*!
157 Returns the default widget.
158*/
159QWidget *QWidgetAction::defaultWidget() const
160{
161 Q_D(const QWidgetAction);
162 return d->defaultWidget;
163}
164
165/*!
166 Returns a widget that represents the action, with the given \a
167 parent.
168
169 Container widgets that support actions can call this function to
170 request a widget as visual representation of the action.
171
172 \sa releaseWidget(), createWidget(), defaultWidget()
173*/
174QWidget *QWidgetAction::requestWidget(QWidget *parent)
175{
176 Q_D(QWidgetAction);
177
178 QWidget *w = createWidget(parent);
179 if (!w) {
180 if (d->defaultWidgetInUse || !d->defaultWidget)
181 return 0;
182 d->defaultWidget->setParent(parent);
183 d->defaultWidgetInUse = true;
184 return d->defaultWidget;
185 }
186
187 connect(w, SIGNAL(destroyed(QObject*)),
188 this, SLOT(_q_widgetDestroyed(QObject*)));
189 d->createdWidgets.append(w);
190 return w;
191}
192
193/*!
194 Releases the specified \a widget.
195
196 Container widgets that support actions call this function when a widget
197 action is removed.
198
199 \sa requestWidget(), deleteWidget(), defaultWidget()
200*/
201void QWidgetAction::releaseWidget(QWidget *widget)
202{
203 Q_D(QWidgetAction);
204
205 if (widget == d->defaultWidget) {
206 d->defaultWidget->hide();
207 d->defaultWidget->setParent(0);
208 d->defaultWidgetInUse = false;
209 return;
210 }
211
212 if (!d->createdWidgets.contains(widget))
213 return;
214
[561]215 disconnect(widget, SIGNAL(destroyed(QObject*)),
216 this, SLOT(_q_widgetDestroyed(QObject*)));
[2]217 d->createdWidgets.removeAll(widget);
218 deleteWidget(widget);
219}
220
221/*!
222 \reimp
223*/
224bool QWidgetAction::event(QEvent *event)
225{
226 Q_D(QWidgetAction);
227 if (event->type() == QEvent::ActionChanged) {
228 if (d->defaultWidget)
229 d->defaultWidget->setEnabled(isEnabled());
[561]230 for (int i = 0; i < d->createdWidgets.count(); ++i)
231 d->createdWidgets.at(i)->setEnabled(isEnabled());
[2]232 }
233 return QAction::event(event);
234}
235
236/*!
237 \reimp
238 */
239bool QWidgetAction::eventFilter(QObject *obj, QEvent *event)
240{
241 return QAction::eventFilter(obj,event);
242}
243
244/*!
245 This function is called whenever the action is added to a container widget
246 that supports custom widgets. If you don't want a custom widget to be
247 used as representation of the action in the specified \a parent widget then
248 0 should be returned.
249
250 \sa deleteWidget()
251*/
252QWidget *QWidgetAction::createWidget(QWidget *parent)
253{
254 Q_UNUSED(parent)
255 return 0;
256}
257
258/*!
259 This function is called whenever the action is removed from a
260 container widget that displays the action using a custom \a
261 widget previously created using createWidget(). The default
262 implementation hides the \a widget and schedules it for deletion
263 using QObject::deleteLater().
264
265 \sa createWidget()
266*/
267void QWidgetAction::deleteWidget(QWidget *widget)
268{
269 widget->hide();
270 widget->deleteLater();
271}
272
273/*!
274 Returns the list of widgets that have been using createWidget() and
275 are currently in use by widgets the action has been added to.
276*/
277QList<QWidget *> QWidgetAction::createdWidgets() const
278{
279 Q_D(const QWidgetAction);
280 return d->createdWidgets;
281}
282
283QT_END_NAMESPACE
284
285#include "moc_qwidgetaction.cpp"
286
287#endif // QT_NO_ACTION
Note: See TracBrowser for help on using the repository browser.