Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qquickaction.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qquickaction_p.h"
5#include "qquickaction_p_p.h"
8
9#include <QtGui/qevent.h>
10#if QT_CONFIG(shortcut)
11# include <QtGui/private/qshortcutmap_p.h>
12#endif
13#include <QtGui/private/qguiapplication_p.h>
14#include <QtQuick/private/qquickitem_p.h>
15
17
22
85#if QT_CONFIG(shortcut)
86static QKeySequence variantToKeySequence(const QVariant &var)
87{
88 if (var.metaType().id() == QMetaType::Int)
89 return QKeySequence(static_cast<QKeySequence::StandardKey>(var.toInt()));
91}
92
93QQuickActionPrivate::ShortcutEntry::ShortcutEntry(QObject *target)
94 : m_target(target)
95{
96}
97
98QQuickActionPrivate::ShortcutEntry::~ShortcutEntry()
99{
100 ungrab();
101}
102
103QObject *QQuickActionPrivate::ShortcutEntry::target() const
104{
105 return m_target;
106}
107
108int QQuickActionPrivate::ShortcutEntry::shortcutId() const
109{
110 return m_shortcutId;
111}
112
113void QQuickActionPrivate::ShortcutEntry::grab(const QKeySequence &shortcut, bool enabled)
114{
115 if (shortcut.isEmpty() || m_shortcutId)
116 return;
117
119 m_shortcutId = QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(m_target, shortcut, context, QQuickShortcutContext::matcher);
120
121 if (!enabled)
122 QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(false, m_shortcutId, m_target);
123}
124
125void QQuickActionPrivate::ShortcutEntry::ungrab()
126{
127 if (!m_shortcutId)
128 return;
129
130 QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(m_shortcutId, m_target);
131 m_shortcutId = 0;
132}
133
134void QQuickActionPrivate::ShortcutEntry::setEnabled(bool enabled)
135{
136 if (!m_shortcutId)
137 return;
138
139 QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(enabled, m_shortcutId, m_target);
140}
141
142QVariant QQuickActionPrivate::shortcut() const
143{
144 return vshortcut;
145}
146
147void QQuickActionPrivate::setShortcut(const QVariant &var)
148{
149 Q_Q(QQuickAction);
150 if (vshortcut == var)
151 return;
152
153 defaultShortcutEntry->ungrab();
154 for (QQuickActionPrivate::ShortcutEntry *entry : std::as_const(shortcutEntries))
155 entry->ungrab();
156
157 vshortcut = var;
158 keySequence = variantToKeySequence(var);
159
160 defaultShortcutEntry->grab(keySequence, enabled);
161 for (QQuickActionPrivate::ShortcutEntry *entry : std::as_const(shortcutEntries))
162 entry->grab(keySequence, enabled);
163
164 emit q->shortcutChanged(keySequence);
165}
166#endif // QT_CONFIG(shortcut)
167
169{
170 Q_Q(QQuickAction);
171 if (enabled == enable)
172 return;
173
174 enabled = enable;
175
176#if QT_CONFIG(shortcut)
177 defaultShortcutEntry->setEnabled(enable);
178 for (QQuickActionPrivate::ShortcutEntry *entry : std::as_const(shortcutEntries))
179 entry->setEnabled(enable);
180#endif
181
182 emit q->enabledChanged(enable);
183}
184
186{
187 Q_Q(QQuickAction);
188 if (!item)
189 return false;
190
191 item->installEventFilter(q);
193 return true;
194}
195
197{
198 Q_Q(QQuickAction);
199 if (!item)
200 return false;
201
202 item->removeEventFilter(q);
204 return true;
205}
206
208{
209 if (!watchItem(item))
210 return;
211
212#if QT_CONFIG(shortcut)
213 QQuickActionPrivate::ShortcutEntry *entry = new QQuickActionPrivate::ShortcutEntry(item);
214 if (item->isVisible())
215 entry->grab(keySequence, enabled);
216 shortcutEntries += entry;
217
218 updateDefaultShortcutEntry();
219#endif
220}
221
223{
224#if QT_CONFIG(shortcut)
225 QQuickActionPrivate::ShortcutEntry *entry = findShortcutEntry(item);
226 if (!entry || !unwatchItem(item))
227 return;
228
229 shortcutEntries.removeOne(entry);
230 delete entry;
231
232 updateDefaultShortcutEntry();
233#else
234 Q_UNUSED(item);
235#endif
236}
237
239{
240#if QT_CONFIG(shortcut)
241 QQuickActionPrivate::ShortcutEntry *entry = findShortcutEntry(item);
242 if (!entry)
243 return;
244
245 if (item->isVisible())
246 entry->grab(keySequence, enabled);
247 else
248 entry->ungrab();
249
250 updateDefaultShortcutEntry();
251#else
252 Q_UNUSED(item);
253#endif
254}
255
257{
259}
260
261#if QT_CONFIG(shortcut)
263{
264 Q_Q(QQuickAction);
265 if (event->key() != keySequence)
266 return false;
267
268 QQuickActionPrivate::ShortcutEntry *entry = findShortcutEntry(object);
269 if (!entry || event->shortcutId() != entry->shortcutId())
270 return false;
271
272 q->trigger(entry->target());
273 return true;
274}
275
276QQuickActionPrivate::ShortcutEntry *QQuickActionPrivate::findShortcutEntry(QObject *target) const
277{
278 Q_Q(const QQuickAction);
279 if (target == q)
280 return defaultShortcutEntry;
281 for (QQuickActionPrivate::ShortcutEntry *entry : shortcutEntries) {
282 if (entry->target() == target)
283 return entry;
284 }
285 return nullptr;
286}
287
288void QQuickActionPrivate::updateDefaultShortcutEntry()
289{
290 bool hasActiveShortcutEntries = false;
291 for (QQuickActionPrivate::ShortcutEntry *entry : std::as_const(shortcutEntries)) {
292 if (entry->shortcutId()) {
293 hasActiveShortcutEntries = true;
294 break;
295 }
296 }
297
298 if (hasActiveShortcutEntries)
299 defaultShortcutEntry->ungrab();
300 else if (!defaultShortcutEntry->shortcutId())
301 defaultShortcutEntry->grab(keySequence, enabled);
302}
303#endif // QT_CONFIG(shortcut)
304
307{
308#if QT_CONFIG(shortcut)
309 Q_D(QQuickAction);
310 d->defaultShortcutEntry = new QQuickActionPrivate::ShortcutEntry(this);
311#endif
312}
313
315{
316 Q_D(QQuickAction);
317 if (d->group)
318 d->group->removeAction(this);
319
320#if QT_CONFIG(shortcut)
321 for (QQuickActionPrivate::ShortcutEntry *entry : std::as_const(d->shortcutEntries))
322 d->unwatchItem(qobject_cast<QQuickItem *>(entry->target()));
323
324 qDeleteAll(d->shortcutEntries);
325 delete d->defaultShortcutEntry;
326#endif
327}
328
335{
336 Q_D(const QQuickAction);
337 return d->text;
338}
339
341{
342 Q_D(QQuickAction);
343 if (d->text == text)
344 return;
345
346 d->text = text;
348}
349
361{
362 Q_D(const QQuickAction);
363 return d->icon;
364}
365
367{
368 Q_D(QQuickAction);
369 if (d->icon == icon)
370 return;
371
372 d->icon = icon;
373 d->icon.ensureRelativeSourceResolved(this);
375}
376
383{
384 Q_D(const QQuickAction);
385 return d->enabled && (!d->group || d->group->isEnabled());
386}
387
389{
390 Q_D(QQuickAction);
391 d->explicitEnabled = true;
392 d->setEnabled(enabled);
393}
394
396{
397 Q_D(QQuickAction);
398 if (!d->explicitEnabled)
399 return;
400
401 d->explicitEnabled = false;
402 d->setEnabled(true);
403}
404
413{
414 Q_D(const QQuickAction);
415 return d->checked;
416}
417
418void QQuickAction::setChecked(bool checked)
419{
420 Q_D(QQuickAction);
421 if (d->checked == checked)
422 return;
423
424 d->checked = checked;
426}
427
438{
439 Q_D(const QQuickAction);
440 return d->checkable;
441}
442
443void QQuickAction::setCheckable(bool checkable)
444{
445 Q_D(QQuickAction);
446 if (d->checkable == checkable)
447 return;
448
449 d->checkable = checkable;
451}
452
453#if QT_CONFIG(shortcut)
469QKeySequence QQuickAction::shortcut() const
470{
471 Q_D(const QQuickAction);
472 return d->keySequence;
473}
474
475void QQuickAction::setShortcut(const QKeySequence &shortcut)
476{
477 Q_D(QQuickAction);
478 d->setShortcut(shortcut.toString());
479}
480#endif // QT_CONFIG(shortcut)
481
488{
489 Q_D(QQuickAction);
490 if (!d->enabled)
491 return;
492
493 if (d->checkable)
494 setChecked(!d->checked);
495
497}
498
505{
506 Q_D(QQuickAction);
507 d->trigger(source, true);
508}
509
511{
512 Q_Q(QQuickAction);
513 if (!enabled)
514 return;
515
516 QPointer<QObject> guard = q;
517 // the checked action of an exclusive group cannot be unchecked
518 if (checkable && (!checked || !group || !group->isExclusive() || group->checkedAction() != q)) {
519 if (doToggle)
520 q->toggle(source);
521 else
522 emit q->toggled(source);
523 }
524
525 if (!guard.isNull())
526 emit q->triggered(source);
527}
528
530{
531#if QT_CONFIG(shortcut)
532 Q_D(QQuickAction);
533 if (event->type() == QEvent::Shortcut)
534 return d->handleShortcutEvent(this, static_cast<QShortcutEvent *>(event));
535#endif
536 return QObject::event(event);
537}
538
540{
541#if QT_CONFIG(shortcut)
542 Q_D(QQuickAction);
543 if (event->type() == QEvent::Shortcut)
544 return d->handleShortcutEvent(object, static_cast<QShortcutEvent *>(event));
545#else
546 Q_UNUSED(object);
548#endif
549 return false;
550}
551
553
554#include "moc_qquickaction_p.cpp"
\inmodule QtCore
Definition qcoreevent.h:45
bool isVisible() const
Returns true if the item is visible; otherwise, false is returned.
static QGuiApplicationPrivate * instance()
The QKeySequence class encapsulates a key sequence as used by shortcuts.
static QKeySequence fromString(const QString &str, SequenceFormat format=PortableText)
int id(int=0) const
Definition qmetatype.h:454
\inmodule QtCore
Definition qobject.h:90
virtual bool event(QEvent *event)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition qobject.cpp:1363
\inmodule QtCore
Definition qpointer.h:18
bool isNull() const
Returns true if the referenced object has been destroyed or if there is no referenced object; otherwi...
Definition qpointer.h:67
void trigger(QObject *, bool doToggle)
bool handleShortcutEvent(QObject *object, QShortcutEvent *event)
void itemDestroyed(QQuickItem *item) override
void registerItem(QQuickItem *item)
bool watchItem(QQuickItem *item)
void setEnabled(bool enable)
Abstract user interface action.
void itemVisibilityChanged(QQuickItem *item) override
bool unwatchItem(QQuickItem *item)
void unregisterItem(QQuickItem *item)
void toggled(QObject *source=nullptr)
bool eventFilter(QObject *object, QEvent *event) override
Filters events if this object has been installed as an event filter for the watched object.
void setEnabled(bool enabled)
bool isCheckable() const
\qmlproperty bool QtQuick.Controls::Action::checkable
void setIcon(const QQuickIcon &icon)
QQuickAction(QObject *parent=nullptr)
void toggle(QObject *source=nullptr)
\qmlmethod void QtQuick.Controls::Action::toggle(QtObject source)
void checkedChanged(bool checked)
void checkableChanged(bool checkable)
void trigger(QObject *source=nullptr)
\qmlmethod void QtQuick.Controls::Action::trigger(QtObject source)
void setCheckable(bool checkable)
QQuickIcon icon
void setChecked(bool checked)
bool event(QEvent *event) override
This virtual function receives events to an object and should return true if the event e was recogniz...
void setText(const QString &text)
void textChanged(const QString &text)
void iconChanged(const QQuickIcon &icon)
bool isEnabled() const
\qmlproperty bool QtQuick.Controls::Action::enabled
bool isChecked() const
\qmlproperty bool QtQuick.Controls::Action::checked
void removeItemChangeListener(QQuickItemChangeListener *, ChangeTypes types)
void addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:64
The QShortcutEvent class provides an event which is generated when the user presses a key combination...
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
\inmodule QtCore
Definition qvariant.h:64
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
QMetaType metaType() const
QString text
qDeleteAll(list.begin(), list.end())
Combined button and popup list for selecting options.
ShortcutContext
@ WindowShortcut
static void * context
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLboolean GLuint group
GLenum target
GLboolean enable
GLsizei GLsizei GLchar * source
struct _cl_event * event
GLuint entry
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
QQuickItem * qobject_cast< QQuickItem * >(QObject *o)
Definition qquickitem.h:483
#define emit
#define Q_UNUSED(x)
QGraphicsItem * item
static bool matcher(QObject *object, Qt::ShortcutContext context)
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent