source: trunk/src/qt3support/widgets/q3action.cpp@ 168

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

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

File size: 64.9 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 Qt3Support 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 "q3action.h"
43
44#ifndef QT_NO_ACTION
45
46#include "qevent.h"
47#include "q3toolbar.h"
48#include "qlist.h"
49#include "q3popupmenu.h"
50#include "q3accel.h"
51#include "qtoolbutton.h"
52#include "qcombobox.h"
53#include "qtooltip.h"
54#include "qwhatsthis.h"
55#include "qstatusbar.h"
56#include "qaction.h"
57
58QT_BEGIN_NAMESPACE
59
60/*!
61 \class Q3Action
62 \brief The Q3Action class provides an abstract user interface
63 action that can appear both in menus and tool bars.
64
65 \compat
66
67 In GUI applications many commands can be invoked via a menu
68 option, a toolbar button and a keyboard accelerator. Since the
69 same action must be performed regardless of how the action was
70 invoked, and since the menu and toolbar should be kept in sync, it
71 is useful to represent a command as an \e action. An action can be
72 added to a menu and a toolbar and will automatically keep them in
73 sync. For example, if the user presses a Bold toolbar button the
74 Bold menu item will automatically be checked.
75
76 A Q3Action may contain an icon, a menu text, an accelerator, a
77 status text, a "What's This?" text and a tool tip. Most of these can
78 be set in the constructor. They can also be set independently with
79 setIconSet(), setText(), setMenuText(), setToolTip(),
80 setStatusTip(), setWhatsThis() and setAccel().
81
82 An action may be a toggle action e.g. a Bold toolbar button, or a
83 command action, e.g. 'Open File' to invoke an open file dialog.
84 Toggle actions emit the toggled() signal when their state changes.
85 Both command and toggle actions emit the activated() signal when
86 they are invoked. Use setToggleAction() to set an action's toggled
87 status. To see if an action is a toggle action use
88 isToggleAction(). A toggle action may be "on", isOn() returns
89 true, or "off", isOn() returns false.
90
91 Actions are added to widgets (menus or toolbars) using addTo(),
92 and removed using removeFrom(). Note that when using Q3ToolBar and
93 Q3PopupMenu, their actions must be Q3Actions.
94
95 Once a Q3Action has been created it should be added to the relevant
96 menu and toolbar and then connected to the slot which will perform
97 the action.
98
99 We recommend that actions are created as children of the window
100 that they are used in. In most cases actions will be children of
101 the application's main window.
102
103 To prevent recursion, don't create an action as a child of a
104 widget that the action is later added to.
105*/
106
107class Q3ActionPrivate
108{
109public:
110 Q3ActionPrivate(Q3Action *act);
111 ~Q3ActionPrivate();
112 QIcon *icon;
113 QString text;
114 QString menutext;
115 QString tooltip;
116 QString statustip;
117 QString whatsthis;
118#ifndef QT_NO_ACCEL
119 QKeySequence key;
120 Q3Accel* accel;
121 int accelid;
122#endif
123 uint enabled : 1;
124 uint visible : 1;
125 uint toggleaction : 1;
126 uint on : 1;
127 uint forceDisabled : 1;
128 uint forceInvisible : 1;
129 Q3ActionGroupPrivate* d_group;
130 Q3Action *action;
131
132 struct MenuItem {
133 MenuItem():popup(0),id(0){}
134 Q3PopupMenu* popup;
135 int id;
136 };
137 // ComboItem is only necessary for actions that are
138 // in dropdown/exclusive actiongroups. The actiongroup
139 // will clean this up
140 struct ComboItem {
141 ComboItem():combo(0), id(0) {}
142 QComboBox *combo;
143 int id;
144 };
145 //just bindings to the Qt4.0 widgets
146 struct Action4Item {
147 Action4Item():widget(0){}
148 QWidget* widget;
149 static QAction *action;
150 };
151 QList<Action4Item *> action4items;
152 QList<MenuItem *> menuitems;
153 QList<QToolButton *> toolbuttons;
154 QList<ComboItem *> comboitems;
155
156 enum Update { Icons = 1, Visibility = 2, State = 4, EverythingElse = 8 };
157 void update(uint upd = EverythingElse);
158
159 QString menuText() const;
160 QString toolTip() const;
161 QString statusTip() const;
162};
163QAction *Q3ActionPrivate::Action4Item::action = 0;
164
165Q3ActionPrivate::Q3ActionPrivate(Q3Action *act)
166 : icon(0),
167#ifndef QT_NO_ACCEL
168 key(0), accel(0), accelid(0),
169#endif
170 enabled(true), visible(true), toggleaction(false), on(false),
171 forceDisabled(false), forceInvisible(false)
172 , d_group(0), action(act)
173{
174}
175
176Q3ActionPrivate::~Q3ActionPrivate()
177{
178 QList<QToolButton*>::Iterator ittb(toolbuttons.begin());
179 QToolButton *tb;
180
181 while (ittb != toolbuttons.end()) {
182 tb = *ittb;
183 ++ittb;
184 delete tb;
185 }
186
187 QList<Q3ActionPrivate::MenuItem*>::Iterator itmi(menuitems.begin());
188 Q3ActionPrivate::MenuItem* mi;
189 while (itmi != menuitems.end()) {
190 mi = *itmi;
191 ++itmi;
192 Q3PopupMenu* menu = mi->popup;
193 if (menu->findItem(mi->id))
194 menu->removeItem(mi->id);
195 }
196 qDeleteAll(menuitems);
197
198 QList<Q3ActionPrivate::Action4Item*>::Iterator itmi4(action4items.begin());
199 Q3ActionPrivate::Action4Item* mi4;
200 while (itmi4 != action4items.end()) {
201 mi4 = *itmi4;
202 ++itmi4;
203 mi4->widget->removeAction(mi4->action);
204 }
205 delete Q3ActionPrivate::Action4Item::action;
206 Q3ActionPrivate::Action4Item::action = 0;
207 qDeleteAll(action4items);
208
209 QList<Q3ActionPrivate::ComboItem*>::Iterator itci(comboitems.begin());
210 Q3ActionPrivate::ComboItem* ci;
211 while (itci != comboitems.end()) {
212 ci = *itci;
213 ++itci;
214 QComboBox* combo = ci->combo;
215 combo->clear();
216 Q3ActionGroup *group = qobject_cast<Q3ActionGroup*>(action->parent());
217 if (group) {
218 QObjectList siblings = group->queryList("Q3Action");
219
220 for (int i = 0; i < siblings.size(); ++i) {
221 Q3Action *sib = qobject_cast<Q3Action*>(siblings.at(i));
222 sib->removeFrom(combo);
223 }
224 for (int i = 0; i < siblings.size(); ++i) {
225 Q3Action *sib = qobject_cast<Q3Action*>(siblings.at(i));
226 if (sib == action)
227 continue;
228 sib->addTo(combo);
229 }
230 }
231 }
232 qDeleteAll(comboitems);
233
234#ifndef QT_NO_ACCEL
235 delete accel;
236#endif
237 delete icon;
238}
239
240class Q3ActionGroupPrivate
241{
242public:
243 uint exclusive: 1;
244 uint dropdown: 1;
245 QList<Q3Action*> actions;
246 Q3Action* selected;
247 Q3Action* separatorAction;
248
249 struct MenuItem {
250 MenuItem():popup(0),id(0){}
251 Q3PopupMenu* popup;
252 int id;
253 };
254 struct Action4Item {
255 Action4Item():widget(0){}
256 QWidget* widget;
257 static QAction *action;
258 };
259 QList<Action4Item *> action4items;
260 QList<QComboBox*> comboboxes;
261 QList<QToolButton*> menubuttons;
262 QList<MenuItem*> menuitems;
263 QList<Q3PopupMenu*> popupmenus;
264
265 void update(const Q3ActionGroup *);
266};
267QAction *Q3ActionGroupPrivate::Action4Item::action = 0;
268
269void Q3ActionPrivate::update(uint upd)
270{
271 for (QList<MenuItem*>::Iterator it(menuitems.begin()); it != menuitems.end(); ++it) {
272 MenuItem* mi = *it;
273 QString t = menuText();
274#ifndef QT_NO_ACCEL
275 if (key)
276 t += QLatin1Char('\t') + (QString)QKeySequence(key);
277#endif
278 if (upd & State) {
279 mi->popup->setItemEnabled(mi->id, enabled);
280 if (toggleaction)
281 mi->popup->setItemChecked(mi->id, on);
282 }
283 if (upd & Visibility)
284 mi->popup->setItemVisible(mi->id, visible);
285
286 if (upd & Icons) {
287 if (icon)
288 mi->popup->changeItem(mi->id, *icon, t);
289 else
290 mi->popup->changeItem(mi->id, QIcon(), t);
291 }
292 if (upd & EverythingElse) {
293 mi->popup->changeItem(mi->id, t);
294 if (!whatsthis.isEmpty())
295 mi->popup->setWhatsThis(mi->id, whatsthis);
296 if (toggleaction) {
297 mi->popup->setCheckable(true);
298 mi->popup->setItemChecked(mi->id, on);
299 }