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

Last change on this file since 324 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 9.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
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
57 Most actions in an application are represented as items in menus or
58 buttons in toolbars. However sometimes more complex widgets are
59 necessary. For example a zoom action in a word processor may be
60 realized using a QComboBox in a QToolBar, presenting a range
61 of different zoom levels. QToolBar provides QToolBar::insertWidget()
62 as convenience function for inserting a single widget.
63 However if you want to implement an action that uses custom
64 widgets for visualization in multiple containers then you have to
65 subclass QWidgetAction.
66
67 If a QWidgetAction is added for example to a QToolBar then
68 QWidgetAction::createWidget() is called. Reimplementations of that
69 function should create a new custom widget with the specified parent.
70
71 If the action is removed from a container widget then
72 QWidgetAction::deleteWidget() is called with the previously created custom
73 widget as argument. The default implementation hides the widget and deletes
74 it using QObject::deleteLater().
75
76 If you have only one single custom widget then you can set it as default
77 widget using setDefaultWidget(). That widget will then be used if the
78 action is added to a QToolBar, or in general to an action container that
79 supports QWidgetAction. If a QWidgetAction with only a default widget is
80 added to two toolbars at the same time then the default widget is shown
81 only in the first toolbar the action was added to. QWidgetAction takes
82 over ownership of the default widget.
83
84 Note that it is up to the widget to activate the action, for example by
85 reimplementing mouse event handlers and calling QAction::trigger().
86
87 \bold {Mac OS X}: If you add a widget to a menu in the application's menu
88 bar on Mac OS X, the widget will be added and it will function but with some
89 limitations:
90 \list 1
91 \o The widget is reparented away from the QMenu to the native menu
92 view. If you show the menu in some other place (e.g. as a popup menu),
93 the widget will not be there.
94 \o Focus/Keyboard handling of the widget is not possible.
95 \o Due to Apple's design, mouse tracking on the widget currently does
96 not work.
97 \o Connecting the triggered() signal to a slot that opens a modal
98 dialog will cause a crash in Mac OS X 10.4 (known bug acknowledged
99 by Apple), a workaround is to use a QueuedConnection instead of a
100 DirectConnection.
101 \endlist
102
103 \ingroup application
104 \mainclass
105
106 \sa QAction, QActionGroup, QWidget
107*/
108
109/*!
110 Constructs an action with \a parent.
111*/
112QWidgetAction::QWidgetAction(QObject *parent)
113 : QAction(*(new QWidgetActionPrivate), parent)
114{
115}
116
117/*!
118 Destroys the object and frees allocated resources.
119*/
120QWidgetAction::~QWidgetAction()
121{
122 Q_D(QWidgetAction);
123 for (int i = 0; i < d->createdWidgets.count(); ++i)
124 disconnect(d->createdWidgets.at(i), SIGNAL(destroyed(QObject*)),
125 this, SLOT(_q_widgetDestroyed(QObject*)));
126 QList<QWidget *> widgetsToDelete = d->createdWidgets;
127 d->createdWidgets.clear();
128 qDeleteAll(widgetsToDelete);
129 delete d->defaultWidget;
130}
131
132/*!
133 Sets \a widget to be the default widget. The ownership is
134 transferred to QWidgetAction. Unless createWidget() is
135 reimplemented by a subclass to return a new widget the default
136 widget is used when a container widget requests a widget through
137 requestWidget().
138*/
139void QWidgetAction::setDefaultWidget(QWidget *widget)
140{
141 Q_D(QWidgetAction);
142 if (widget == d->defaultWidget || d->defaultWidgetInUse)
143 return;
144 delete d->defaultWidget;
145 d->defaultWidget = widget;
146 if (!widget)
147 return;
148
149 setVisible(!(widget->isHidden() && widget->testAttribute(Qt::WA_WState_ExplicitShowHide)));
150 d->defaultWidget->hide();
151 d->defaultWidget->setParent(0);
152 d->defaultWidgetInUse = false;
153 if (!isEnabled())
154 d->defaultWidget->setEnabled(false);
155}
156
157/*!
158 Returns the default widget.
159*/
160QWidget *QWidgetAction::defaultWidget() const
161{
162 Q_D(const QWidgetAction);
163 return d->defaultWidget;
164}
165
166/*!
167 Returns a widget that represents the action, with the given \a
168 parent.
169
170 Container widgets that support actions can call this function to
171 request a widget as visual representation of the action.
172
173 \sa releaseWidget(), createWidget(), defaultWidget()
174*/
175QWidget *QWidgetAction::requestWidget(QWidget *parent)
176{
177 Q_D(QWidgetAction);
178
179 QWidget *w = createWidget(parent);
180 if (!w) {
181 if (d->defaultWidgetInUse || !d->defaultWidget)
182 return 0;
183 d->defaultWidget->setParent(parent);
184 d->defaultWidgetInUse = true;
185 return d->defaultWidget;
186 }
187
188 connect(w, SIGNAL(destroyed(QObject*)),
189 this, SLOT(_q_widgetDestroyed(QObject*)));
190 d->createdWidgets.append(w);
191 return w;
192}
193
194/*!
195 Releases the specified \a widget.
196
197 Container widgets that support actions call this function when a widget
198 action is removed.
199
200 \sa requestWidget(), deleteWidget(), defaultWidget()
201*/
202void QWidgetAction::releaseWidget(QWidget *widget)
203{
204 Q_D(QWidgetAction);
205
206 if (widget == d->defaultWidget) {
207 d->defaultWidget->hide();
208 d->defaultWidget->setParent(0);
209 d->defaultWidgetInUse = false;
210 return;
211 }
212
213 if (!d->createdWidgets.contains(widget))
214 return;
215
216 disconnect(widget, SIGNAL(destroyed(QObject *)),
217 this, SLOT(_q_widgetDestroyed(QObject *)));
218 d->createdWidgets.removeAll(widget);
219 deleteWidget(widget);
220}
221
222/*!
223 \reimp
224*/
225bool QWidgetAction::event(QEvent *event)
226{
227 Q_D(QWidgetAction);
228 if (event->type() == QEvent::ActionChanged) {
229 if (d->defaultWidget)
230 d->defaultWidget->setEnabled(isEnabled());
231 foreach (QWidget *w, d->createdWidgets)
232 w->setEnabled(isEnabled());
233 }
234 return QAction::event(event);
235}
236
237/*!
238 \reimp
239 */
240bool QWidgetAction::eventFilter(QObject *obj, QEvent *event)
241{
242 return QAction::eventFilter(obj,event);
243}
244
245/*!
246 This function is called whenever the action is added to a container widget
247 that supports custom widgets. If you don't want a custom widget to be
248 used as representation of the action in the specified \a parent widget then
249 0 should be returned.
250
251 \sa deleteWidget()
252*/
253QWidget *QWidgetAction::createWidget(QWidget *parent)
254{
255 Q_UNUSED(parent)
256 return 0;
257}
258
259/*!
260 This function is called whenever the action is removed from a
261 container widget that displays the action using a custom \a
262 widget previously created using createWidget(). The default
263 implementation hides the \a widget and schedules it for deletion
264 using QObject::deleteLater().
265
266 \sa createWidget()
267*/
268void QWidgetAction::deleteWidget(QWidget *widget)
269{
270 widget->hide();
271 widget->deleteLater();
272}
273
274/*!
275 Returns the list of widgets that have been using createWidget() and
276 are currently in use by widgets the action has been added to.
277*/
278QList<QWidget *> QWidgetAction::createdWidgets() const
279{
280 Q_D(const QWidgetAction);
281 return d->createdWidgets;
282}
283
284QT_END_NAMESPACE
285
286#include "moc_qwidgetaction.cpp"
287
288#endif // QT_NO_ACTION
Note: See TracBrowser for help on using the repository browser.