diff options
Diffstat (limited to 'src/gui/kernel')
37 files changed, 3383 insertions, 1413 deletions
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 9c80f1e2cc..548bc18698 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -48,11 +48,8 @@ HEADERS += \ kernel/qinputmethod.h \ kernel/qinputmethod_p.h \ kernel/qinternalmimedata_p.h \ - kernel/qkeysequence.h \ - kernel/qkeysequence_p.h \ kernel/qkeymapper_p.h \ kernel/qpalette.h \ - kernel/qshortcutmap_p.h \ kernel/qsessionmanager.h \ kernel/qsessionmanager_p.h \ kernel/qwindowdefs.h \ @@ -108,12 +105,10 @@ SOURCES += \ kernel/qevent.cpp \ kernel/qinputmethod.cpp \ kernel/qinternalmimedata.cpp \ - kernel/qkeysequence.cpp \ kernel/qkeymapper.cpp \ kernel/qpalette.cpp \ kernel/qguivariant.cpp \ kernel/qscreen.cpp \ - kernel/qshortcutmap.cpp \ kernel/qstylehints.cpp \ kernel/qtouchdevice.cpp \ kernel/qplatformsharedgraphicscache.cpp \ @@ -131,6 +126,18 @@ SOURCES += \ kernel/qhighdpiscaling.cpp \ kernel/qtestsupport_gui.cpp +qtConfig(action) { + HEADERS += \ + kernel/qaction.h \ + kernel/qaction_p.h \ + kernel/qactiongroup.h \ + kernel/qactiongroup_p.h + + SOURCES += \ + kernel/qactiongroup.cpp \ + kernel/qaction.cpp +} + qtConfig(draganddrop) { HEADERS += \ kernel/qdnd_p.h \ @@ -151,13 +158,24 @@ qtConfig(opengl) { HEADERS += \ kernel/qplatformopenglcontext.h \ kernel/qopenglcontext.h \ - kernel/qopenglcontext_p.h \ - kernel/qopenglwindow.h + kernel/qopenglcontext_p.h SOURCES += \ kernel/qplatformopenglcontext.cpp \ - kernel/qopenglcontext.cpp \ - kernel/qopenglwindow.cpp + kernel/qopenglcontext.cpp +} + +qtConfig(shortcut) { + HEADERS += \ + kernel/qshortcut.h \ + kernel/qshortcut_p.h \ + kernel/qshortcutmap_p.h \ + kernel/qkeysequence.h \ + kernel/qkeysequence_p.h + SOURCES += \ + kernel/qshortcut.cpp \ + kernel/qshortcutmap.cpp \ + kernel/qkeysequence.cpp } win32:HEADERS+=kernel/qwindowdefs_win.h diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp new file mode 100644 index 0000000000..99a614ddd9 --- /dev/null +++ b/src/gui/kernel/qaction.cpp @@ -0,0 +1,1378 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qaction.h" +#include "qactiongroup.h" + +#include "qaction_p.h" +#include "qguiapplication.h" +#include "qevent.h" +#include "qlist.h" +#include "qstylehints.h" +#if QT_CONFIG(shortcut) +# include <private/qshortcutmap_p.h> +#endif +#include <private/qguiapplication_p.h> +#include <private/qdebug_p.h> + +#define QAPP_CHECK(functionName) \ + if (Q_UNLIKELY(!QCoreApplication::instance())) { \ + qWarning("QAction: Initialize Q(Gui)Application before calling '" functionName "'."); \ + return; \ + } + +QT_BEGIN_NAMESPACE + +/* + internal: guesses a descriptive text from a text suited for a menu entry + */ +static QString qt_strippedText(QString s) +{ + s.remove(QLatin1String("...")); + for (int i = 0; i < s.size(); ++i) { + if (s.at(i) == QLatin1Char('&')) + s.remove(i, 1); + } + return s.trimmed(); +} + +QActionPrivate *QGuiApplicationPrivate::createActionPrivate() const +{ + return new QActionPrivate; +} + +QActionPrivate::QActionPrivate() : +#if QT_CONFIG(shortcut) + autorepeat(1), +#endif + enabled(1), explicitEnabled(0), explicitEnabledValue(1), visible(1), forceInvisible(0), checkable(0), + checked(0), separator(0), fontSet(false), + iconVisibleInMenu(-1), shortcutVisibleInContextMenu(-1) +{ +} + +#if QT_CONFIG(shortcut) +static bool dummy(QObject *, Qt::ShortcutContext) { return false; } // only for GUI testing. + +QShortcutMap::ContextMatcher QActionPrivate::contextMatcher() const +{ + return dummy; +}; +#endif // QT_CONFIG(shortcut) + +QActionPrivate::~QActionPrivate() = default; + +void QActionPrivate::destroy() +{ +} + +void QActionPrivate::sendDataChanged() +{ + Q_Q(QAction); + QActionEvent e(QEvent::ActionChanged, q); + QCoreApplication::sendEvent(q, &e); + + emit q->changed(); +} + +#if QT_CONFIG(shortcut) +void QActionPrivate::redoGrab(QShortcutMap &map) +{ + Q_Q(QAction); + if (shortcutId) + map.removeShortcut(shortcutId, q); + if (shortcut.isEmpty()) + return; + shortcutId = map.addShortcut(q, shortcut, shortcutContext, contextMatcher()); + if (!enabled) + map.setShortcutEnabled(false, shortcutId, q); + if (!autorepeat) + map.setShortcutAutoRepeat(false, shortcutId, q); +} + +void QActionPrivate::redoGrabAlternate(QShortcutMap &map) +{ + Q_Q(QAction); + for(int i = 0; i < alternateShortcutIds.count(); ++i) { + if (const int id = alternateShortcutIds.at(i)) + map.removeShortcut(id, q); + } + alternateShortcutIds.clear(); + if (alternateShortcuts.isEmpty()) + return; + for(int i = 0; i < alternateShortcuts.count(); ++i) { + const QKeySequence& alternate = alternateShortcuts.at(i); + if (!alternate.isEmpty()) + alternateShortcutIds.append(map.addShortcut(q, alternate, shortcutContext, contextMatcher())); + else + alternateShortcutIds.append(0); + } + if (!enabled) { + for(int i = 0; i < alternateShortcutIds.count(); ++i) { + const int id = alternateShortcutIds.at(i); + map.setShortcutEnabled(false, id, q); + } + } + if (!autorepeat) { + for(int i = 0; i < alternateShortcutIds.count(); ++i) { + const int id = alternateShortcutIds.at(i); + map.setShortcutAutoRepeat(false, id, q); + } + } +} + +void QActionPrivate::setShortcutEnabled(bool enable, QShortcutMap &map) +{ + Q_Q(QAction); + if (shortcutId) + map.setShortcutEnabled(enable, shortcutId, q); + for(int i = 0; i < alternateShortcutIds.count(); ++i) { + if (const int id = alternateShortcutIds.at(i)) + map.setShortcutEnabled(enable, id, q); + } +} +#endif // QT_NO_SHORTCUT + +bool QActionPrivate::showStatusText(QObject *object, const QString &str) +{ + if (QObject *receiver = object ? object : parent) { + QStatusTipEvent tip(str); + QCoreApplication::sendEvent(receiver, &tip); + return true; + } + return false; +} + +void QActionPrivate::setMenu(QObject *) +{ +} + +QObject *QActionPrivate::menu() const +{ + return nullptr; +} + +/*! + \class QAction + \brief The QAction class provides an abstraction for user commands + that can be added to different user interface components. + \since 6.0 + + \inmodule QtGui + + In applications many common commands can be invoked via menus, + toolbar buttons, and keyboard shortcuts. Since the user expects + each command to be performed in the same way, regardless of the + user interface used, it is useful to represent each command as + an \e action. + + Actions can be added to menus and toolbars, and will + automatically keep them in sync. For example, in a word processor, + if the user presses a Bold toolbar button, the Bold menu item + will automatically be checked. + + A QAction may contain an icon, menu text, a shortcut, status text, + "What's This?" text, and a tooltip. Most of these can be set in + the constructor. They can also be set independently with + setIcon(), setText(), setIconText(), setShortcut(), + setStatusTip(), setWhatsThis(), and setToolTip(). For menu items, + it is possible to set an individual font with setFont(). + + We recommend that actions are created as children of the window + they are used in. In most cases actions will be children of + the application's main window. + + \section1 QAction in widget applications + + Once a QAction has been created, it should be added to the relevant + menu and toolbar, then connected to the slot which will perform + the action. For example: + + \snippet mainwindows/application/mainwindow.cpp 19 + + Actions are added to widgets using QWidget::addAction() or + QGraphicsWidget::addAction(). Note that an action must be added to a + widget before it can be used. This is also true when the shortcut should + be global (i.e., Qt::ApplicationShortcut as Qt::ShortcutContext). + + Actions can be created as independent objects. But they may + also be created during the construction of menus. The QMenu class + contains convenience functions for creating actions suitable for + use as menu items. + + + \sa QMenu, QToolBar, {Application Example} +*/ + +/*! + \fn void QAction::trigger() + + This is a convenience slot that calls activate(Trigger). +*/ + +/*! + \fn void QAction::hover() + + This is a convenience slot that calls activate(Hover). +*/ + +/*! + \enum QAction::MenuRole + + This enum describes how an action should be moved into the application menu on \macos. + + \value NoRole This action should not be put into the application menu + \value TextHeuristicRole This action should be put in the application menu based on the action's text + as described in the QMenuBar documentation. + \value ApplicationSpecificRole This action should be put in the application menu with an application specific role + \value AboutQtRole This action handles the "About Qt" menu item. + \value AboutRole This action should be placed where the "About" menu item is in the application menu. The text of + the menu item will be set to "About <application name>". The application name is fetched from the + \c{Info.plist} file in the application's bundle (See \l{Qt for macOS - Deployment}). + \value PreferencesRole This action should be placed where the "Preferences..." menu item is in the application menu. + \value QuitRole This action should be placed where the Quit menu item is in the application menu. + + Setting this value only has effect on items that are in the immediate menus + of the menubar, not the submenus of those menus. For example, if you have + File menu in your menubar and the File menu has a submenu, setting the + MenuRole for the actions in that submenu have no effect. They will never be moved. +*/ + +/*! + Constructs an action with \a parent. If \a parent is an action + group the action will be automatically inserted into the group. + + \note The \a parent argument is optional since Qt 5.7. +*/ +QAction::QAction(QObject *parent) + : QAction(*QGuiApplicationPrivate::instance()->createActionPrivate(), parent) +{ +} + +/*! + Constructs an action with some \a text and \a parent. If \a + parent is an action group the action will be automatically + inserted into the group. + + The action uses a stripped version of \a text (e.g. "\&Menu + Option..." becomes "Menu Option") as descriptive text for + tool buttons. You can override this by setting a specific + description with setText(). The same text will be used for + tooltips unless you specify a different text using + setToolTip(). + +*/ +QAction::QAction(const QString &text, QObject *parent) + : QAction(parent) +{ + Q_D(QAction); + d->text = text; +} + +/*! + Constructs an action with an \a icon and some \a text and \a + parent. If \a parent is an action group the action will be + automatically inserted into the group. + + The action uses a stripped version of \a text (e.g. "\&Menu + Option..." becomes "Menu Option") as descriptive text for + tool buttons. You can override this by setting a specific + description with setText(). The same text will be used for + tooltips unless you specify a different text using + setToolTip(). +*/ +QAction::QAction(const QIcon &icon, const QString &text, QObject *parent) + : QAction(text, parent) +{ + Q_D(QAction); + d->icon = icon; +} + +/*! + \internal +*/ +QAction::QAction(QActionPrivate &dd, QObject *parent) + : QObject(dd, parent) +{ + Q_D(QAction); + d->group = qobject_cast<QActionGroup *>(parent); + if (d->group) + d->group->addAction(this); +} + +#if QT_CONFIG(shortcut) +/*! + \property QAction::shortcut + \brief the action's primary shortcut key + + Valid keycodes for this property can be found in \l Qt::Key and + \l Qt::Modifier. There is no default shortcut key. +*/ +void QAction::setShortcut(const QKeySequence &shortcut) +{ + QAPP_CHECK("setShortcut"); + + Q_D(QAction); + if (d->shortcut == shortcut) + return; + + d->shortcut = shortcut; + d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap); + d->sendDataChanged(); +} + +/*! + Sets \a shortcuts as the list of shortcuts that trigger the + action. The first element of the list is the primary shortcut. + + \sa shortcut +*/ +void QAction::setShortcuts(const QList<QKeySequence> &shortcuts) +{ + Q_D(QAction); + + QList <QKeySequence> listCopy = shortcuts; + + QKeySequence primary; + if (!listCopy.isEmpty()) + primary = listCopy.takeFirst(); + + if (d->shortcut == primary && d->alternateShortcuts == listCopy) + return; + + QAPP_CHECK("setShortcuts"); + + d->shortcut = primary; + d->alternateShortcuts = listCopy; + d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap); + d->redoGrabAlternate(QGuiApplicationPrivate::instance()->shortcutMap); + d->sendDataChanged(); +} + +/*! + Sets a platform dependent list of shortcuts based on the \a key. + The result of calling this function will depend on the currently running platform. + Note that more than one shortcut can assigned by this action. + If only the primary shortcut is required, use setShortcut instead. + + \sa QKeySequence::keyBindings() +*/ +void QAction::setShortcuts(QKeySequence::StandardKey key) +{ + QList <QKeySequence> list = QKeySequence::keyBindings(key); + setShortcuts(list); +} + +/*! + Returns the primary shortcut. + + \sa setShortcuts() +*/ +QKeySequence QAction::shortcut() const +{ + Q_D(const QAction); + return d->shortcut; +} + +/*! + Returns the list of shortcuts, with the primary shortcut as + the first element of the list. + + \sa setShortcuts() +*/ +QList<QKeySequence> QAction::shortcuts() const +{ + Q_D(const QAction); + QList <QKeySequence> shortcuts; + if (!d->shortcut.isEmpty()) + shortcuts << d->shortcut; + if (!d->alternateShortcuts.isEmpty()) + shortcuts << d->alternateShortcuts; + return shortcuts; +} + +/*! + \property QAction::shortcutContext + \brief the context for the action's shortcut + + Valid values for this property can be found in \l Qt::ShortcutContext. + The default value is Qt::WindowShortcut. +*/ +void QAction::setShortcutContext(Qt::ShortcutContext context) +{ + Q_D(QAction); + if (d->shortcutContext == context) + return; + QAPP_CHECK("setShortcutContext"); + d->shortcutContext = context; + d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap); + d->redoGrabAlternate(QGuiApplicationPrivate::instance()->shortcutMap); + d->sendDataChanged(); +} + +Qt::ShortcutContext QAction::shortcutContext() const +{ + Q_D(const QAction); + return d->shortcutContext; +} + +/*! + \property QAction::autoRepeat + \brief whether the action can auto repeat + + If true, the action will auto repeat when the keyboard shortcut + combination is held down, provided that keyboard auto repeat is + enabled on the system. + The default value is true. +*/ +void QAction::setAutoRepeat(bool on) +{ + Q_D(QAction); + if (d->autorepeat == on) + return; + QAPP_CHECK("setAutoRepeat"); + d->autorepeat = on; + d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap); + d->redoGrabAlternate(QGuiApplicationPrivate::instance()->shortcutMap); + d->sendDataChanged(); +} + +bool QAction::autoRepeat() const +{ + Q_D(const QAction); + return d->autorepeat; +} +#endif // QT_CONFIG(shortcut) + +/*! + \property QAction::font + \brief the action's font + + The font property is used to render the text set on the + QAction. The font can be considered a hint as it will not be + consulted in all cases based upon application and style. + + By default, this property contains the application's default font. + + \sa setText() +*/ +void QAction::setFont(const QFont &font) +{ + Q_D(QAction); + if (d->font == font) + return; + + d->fontSet = true; + d->font = font; + d->sendDataChanged(); +} + +QFont QAction::font() const +{ + Q_D(const QAction); + return d->font; +} + + +/*! + Destroys the object and frees allocated resources. +*/ +QAction::~QAction() +{ + Q_D(QAction); + + d->destroy(); + + if (d->group) + d->group->removeAction(this); +#if QT_CONFIG(shortcut) + if (d->shortcutId && qApp) { + QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(d->shortcutId, this); + for (int id : qAsConst(d->alternateShortcutIds)) + QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(id, this); + } +#endif +} + +/*! + Sets this action group to \a group. The action will be automatically + added to the group's list of actions. + + Actions within the group will be mutually exclusive. + + \sa QActionGroup, actionGroup() +*/ +void QAction::setActionGroup(QActionGroup *group) +{ + Q_D(QAction); + if(group == d->group) + return; + + if(d->group) + d->group->removeAction(this); + d->group = group; + if(group) + group->addAction(this); + d->sendDataChanged(); +} + +/*! + Returns the action group for this action. If no action group manages + this action, then \nullptr will be returned. + + \sa QActionGroup, setActionGroup() +*/ +QActionGroup *QAction::actionGroup() const +{ + Q_D(const QAction); + return d->group; +} + +/*! + \since 6.0 + Returns a list of objects this action has been added to. + + \sa QWidget::addAction(), QGraphicsWidget::addAction() +*/ +QVector<QObject*> QAction::associatedObjects() const +{ + Q_D(const QAction); + return d->associatedObjects; +} + +/*! + \fn QWidget *QAction::parentWidget() const + \obsolete Use parent() with qobject_cast() instead. + + Returns the parent widget. +*/ + +/*! + \fn QList<QWidget*> QAction::associatedWidgets() const + \obsolete Use associatedObjects() with qobject_cast() instead. + + Returns a list of widgets this action has been added to. + + \sa QWidget::addAction(), associatedObjects(), associatedGraphicsWidgets() +*/ + +/*! + \fn QList<QWidget*> QAction::associatedGraphicsWidgets() const + \obsolete Use associatedObjects() with qobject_cast() instead. + + Returns a list of graphics widgets this action has been added to. + + \sa QGraphicsWidget::addAction(), associatedObjects(), associatedWidgets() +*/ + +/*! + \property QAction::icon + \brief the action's icon + + In toolbars, the icon is used as the tool button icon; in menus, + it is displayed to the left of the menu text. There is no default + icon. + + If a null icon (QIcon::isNull()) is passed into this function, + the icon of the action is cleared. +*/ +void QAction::setIcon(const QIcon &icon) +{ + Q_D(QAction); + d->icon = icon; + d->sendDataChanged(); +} + +QIcon QAction::icon() const +{ + Q_D(const QAction); + return d->icon; +} + +/*! + If \a b is true then this action will be considered a separator. + + How a separator is represented depends on the widget it is inserted + into. Under most circumstances the text, submenu, and icon will be + ignored for separator actions. + + \sa isSeparator() +*/ +void QAction::setSeparator(bool b) +{ + Q_D(QAction); + if (d->separator == b) + return; + + d->separator = b; + d->sendDataChanged(); +} + +/*! + Returns \c true if this action is a separator action; otherwise it + returns \c false. + + \sa setSeparator() +*/ +bool QAction::isSeparator() const +{ + Q_D(const QAction); + return d->separator; +} + +/*! + \property QAction::text + \brief the action's descriptive text + + If the action is added to a menu, the menu option will consist of + the icon (if there is one), the text, and the shortcut (if there + is one). If the text is not explicitly set in the constructor, or + by using setText(), the action's description icon text will be + used as text. There is no default text. + + \sa iconText +*/ +void QAction::setText(const QString &text) +{ + Q_D(QAction); + if (d->text == text) + return; + + d->text = text; + d->sendDataChanged(); +} + +QString QAction::text() const +{ + Q_D(const QAction); + QString s = d->text; + if(s.isEmpty()) { + s = d->iconText; + s.replace(QLatin1Char('&'), QLatin1String("&&")); + } + return s; +} + +/*! + \property QAction::iconText + \brief the action's descriptive icon text + + If QToolBar::toolButtonStyle is set to a value that permits text to + be displayed, the text defined held in this property appears as a + label in the relevant tool button. + + It also serves as the default text in menus and tooltips if the action + has not been defined with setText() or setToolTip(), and will + also be used in toolbar buttons if no icon has been defined using setIcon(). + + If the icon text is not explicitly set, the action's normal text will be + used for the icon text. + + By default, this property contains an empty string. + + \sa setToolTip(), setStatusTip() +*/ +void QAction::setIconText(const QString &text) +{ + Q_D(QAction); + if (d->iconText == text) + return; + + d->iconText = text; + d->sendDataChanged(); +} + +QString QAction::iconText() const +{ + Q_D(const QAction); + if (d->iconText.isEmpty()) + return qt_strippedText(d->text); + return d->iconText; +} + +/*! + \property QAction::toolTip + \brief the action's tooltip + + This text is used for the tooltip. If no tooltip is specified, + the action's text is used. + + By default, this property contains the action's text. + + \sa setStatusTip(), setShortcut() +*/ +void QAction::setToolTip(const QString &tooltip) +{ + Q_D(QAction); + if (d->tooltip == tooltip) + return; + + d->tooltip = tooltip; + d->sendDataChanged(); +} + +QString QAction::toolTip() const +{ + Q_D(const QAction); + if (d->tooltip.isEmpty()) { + if (!d->text.isEmpty()) + return qt_strippedText(d->text); + return qt_strippedText(d->iconText); + } + return d->tooltip; +} + +/*! + \property QAction::statusTip + \brief the action's status tip + + The status tip is displayed on all status bars provided by the + action's top-level parent widget. + + By default, this property contains an empty string. + + \sa setToolTip(), showStatusText() +*/ +void QAction::setStatusTip(const QString &statustip) +{ + Q_D(QAction); + if (d->statustip == statustip) + return; + + d->statustip = statustip; + d->sendDataChanged(); +} + +QString QAction::statusTip() const +{ + Q_D(const QAction); + return d->statustip; +} + +/*! + Updates the relevant status bar for the UI represented by \a object by sending a + QStatusTipEvent. Returns \c true if an event was sent, otherwise returns \c false. + + If a null widget is specified, the event is sent to the action's parent. + + \sa statusTip +*/ +bool QAction::showStatusText(QObject *object) +{ + Q_D(QAction); + return d->showStatusText(object, statusTip()); +} + +/*! + \property QAction::whatsThis + \brief the action's "What's This?" help text + + The "What's This?" text is used to provide a brief description of + the action. The text may contain rich text. There is no default + "What's This?" text. + + \sa QWhatsThis +*/ +void QAction::setWhatsThis(const QString &whatsthis) +{ + Q_D(QAction); + if (d->whatsthis == whatsthis) + return; + + d->whatsthis = whatsthis; + d->sendDataChanged(); +} + +QString QAction::whatsThis() const +{ + Q_D(const QAction); + return d->whatsthis; +} + +/*! + \enum QAction::Priority + + This enum defines priorities for actions in user interface. + + \value LowPriority The action should not be prioritized in + the user interface. + + \value NormalPriority + + \value HighPriority The action should be prioritized in + the user interface. + + \sa priority +*/ + + +/*! + \property QAction::priority + + \brief the actions's priority in the user interface. + + This property can be set to indicate how the action should be prioritized + in the user interface. + + For instance, when toolbars have the Qt::ToolButtonTextBesideIcon + mode set, then actions with LowPriority will not show the text + labels. +*/ +void QAction::setPriority(Priority priority) +{ + Q_D(QAction); + if (d->priority == priority) + return; + + d->priority = priority; + d->sendDataChanged(); +} + +QAction::Priority QAction::priority() const +{ + Q_D(const QAction); + return d->priority; +} + +/*! + \property QAction::checkable + \brief whether the action is a checkable action + + A checkable action is one which has an on/off state. For example, + in a word processor, a Bold toolbar button may be either on or + off. An action which is not a toggle action is a command action; + a command action is simply executed, e.g. file save. + By default, this property is \c false. + + In some situations, the state of one toggle action should depend + on the state of others. For example, "Left Align", "Center" and + "Right Align" toggle actions are mutually exclusive. To achieve + exclusive toggling, add the relevant toggle actions to a + QActionGroup with the QActionGroup::exclusive property set to + true. + + \sa setChecked() +*/ +void QAction::setCheckable(bool b) +{ + Q_D(QAction); + if (d->checkable == b) + return; + + d->checkable = b; + QPointer<QAction> guard(this); + d->sendDataChanged(); + if (guard) + emit checkableChanged(b); + if (guard && d->checked) + emit toggled(b); +} + +bool QAction::isCheckable() const +{ + Q_D(const QAction); + return d->checkable; +} + +/*! + \fn void QAction::toggle() + + This is a convenience function for the \l checked property. + Connect to it to change the checked state to its opposite state. +*/ +void QAction::toggle() +{ + Q_D(QAction); + setChecked(!d->checked); +} + +/*! + \property QAction::checked + \brief whether the action is checked. + + Only checkable actions can be checked. By default, this is false + (the action is unchecked). + + \note The notifier signal for this property is toggled(). As toggling + a QAction changes its state, it will also emit a changed() signal. + + \sa checkable, toggled() +*/ +void QAction::setChecked(bool b) +{ + Q_D(QAction); + if (d->checked == b) + return; + + d->checked = b; + if (!d->checkable) + return; + QPointer<QAction> guard(this); + d->sendDataChanged(); + if (guard) + emit toggled(b); +} + +bool QAction::isChecked() const +{ + Q_D(const QAction); + return d->checked && d->checkable; +} + +/*! + \fn void QAction::setDisabled(bool b) + + This is a convenience function for the \l enabled property, that + is useful for signals--slots connections. If \a b is true the + action is disabled; otherwise it is enabled. +*/ + +/*! + \property QAction::enabled + \brief whether the action is enabled + + Disabled actions cannot be chosen by the user. They do not + disappear from menus or toolbars, but they are displayed in a way + which indicates that they are unavailable. For example, they might + be displayed using only shades of gray. + + \uicontrol{What's This?} help on disabled actions is still available, provided + that the QAction::whatsThis property is set. + + An action will be disabled when all widgets to which it is added + (with QWidget::addAction()) are disabled or not visible. When an + action is disabled, it is not possible to trigger it through its + shortcut. + + By default, this property is \c true (actions are enabled). + + \sa text +*/ +void QAction::setEnabled(bool b) +{ + Q_D(QAction); + if (d->explicitEnabledValue == b && d->explicitEnabled) + return; + d->explicitEnabledValue = b; + d->explicitEnabled = true; + QAPP_CHECK("setEnabled"); + d->setEnabled(b, false); +} + +bool QActionPrivate::setEnabled(bool b, bool byGroup) +{ + Q_Q(QAction); + if (b && !visible) + b = false; + if (b && !byGroup && (group && !group->isEnabled())) + b = false; + if (b && byGroup && explicitEnabled) + b = explicitEnabledValue; + + if (b == enabled) + return false; + + enabled = b; +#if QT_CONFIG(shortcut) + setShortcutEnabled(b, QGuiApplicationPrivate::instance()->shortcutMap); +#endif + QPointer guard(q); + sendDataChanged(); + if (guard) + emit q->enabledChanged(b); + return true; +} + +void QAction::resetEnabled() +{ + Q_D(QAction); + if (!d->explicitEnabled) + return; + d->explicitEnabled = false; + d->setEnabled(true, false); +} + +bool QAction::isEnabled() const +{ + Q_D(const QAction); + return d->enabled; +} + +/*! + \property QAction::visible + \brief whether the action can be seen (e.g. in menus and toolbars) + + If \e visible is true the action can be seen (e.g. in menus and + toolbars) and chosen by the user; if \e visible is false the + action cannot be seen or chosen by the user. + + Actions which are not visible are \e not grayed out; they do not + appear at all. + + By default, this property is \c true (actions are visible). +*/ +void QAction::setVisible(bool b) +{ + Q_D(QAction); + if (b == d->visible && b != d->forceInvisible) + return; + QAPP_CHECK("setVisible"); + d->forceInvisible = !b; + d->visible = b; + bool enabled = d->visible; + if (enabled && d->explicitEnabled) + enabled = d->explicitEnabledValue; + if (!d->setEnabled(enabled, false)) + d->sendDataChanged(); +} + + +bool QAction::isVisible() const +{ + Q_D(const QAction); + return d->visible; +} + +/*! + \reimp +*/ +bool QAction::event(QEvent *e) +{ + Q_D(QAction); + if (e->type() == QEvent::ActionChanged) { + for (auto object : qAsConst(d->associatedObjects)) + QCoreApplication::sendEvent(object, e); + } + +#if QT_CONFIG(shortcut) + if (e->type() == QEvent::Shortcut) { + QShortcutEvent *se = static_cast<QShortcutEvent *>(e); + Q_ASSERT_X(se->key() == d_func()->shortcut || d_func()->alternateShortcuts.contains(se->key()), + "QAction::event", + "Received shortcut event from incorrect shortcut"); + if (se->isAmbiguous()) + qWarning("QAction::event: Ambiguous shortcut overload: %s", se->key().toString(QKeySequence::NativeText).toLatin1().constData()); + else + activate(Trigger); + return true; + } +#endif // QT_CONFIG(shortcut) + return QObject::event(e); +} + +/*! + Returns the user data as set in QAction::setData. + + \sa setData() +*/ +QVariant QAction::data() const +{ + Q_D(const QAction); + return d->userData; +} + +/*! + Sets the action's internal data to the given \a userData. + + \sa data() +*/ +void QAction::setData(const QVariant &data) +{ + Q_D(QAction); + if (d->userData == data) + return; + d->userData = data; + d->sendDataChanged(); +} + +/*! + Sends the relevant signals for ActionEvent \a event. + + Action-based widgets use this API to cause the QAction + to emit signals as well as emitting their own. +*/ +void QAction::activate(ActionEvent event) +{ + Q_D(QAction); + if(event == Trigger) { + QPointer<QObject> guard = this; + if(d->checkable) { + // the checked action of an exclusive group may not be unchecked + if (d->checked && (d->group + && d->group->exclusionPolicy() == QActionGroup::ExclusionPolicy::Exclusive + && d->group->checkedAction() == this)) { + if (!guard.isNull()) + emit triggered(true); + return; + } + setChecked(!d->checked); + } + if (!guard.isNull()) + emit triggered(d->checked); + } else if(event == Hover) { + emit hovered(); + } +} + +/*! + \fn void QAction::triggered(bool checked) + + This signal is emitted when an action is activated by the user; + for example, when the user clicks a menu option, toolbar button, + or presses an action's shortcut key combination, or when trigger() + was called. Notably, it is \e not emitted when setChecked() or + toggle() is called. + + If the action is checkable, \a checked is true if the action is + checked, or false if the action is unchecked. + + \sa activate(), toggled(), checked +*/ + +/*! + \fn void QAction::toggled(bool checked) + + This signal is emitted whenever a checkable action changes its + isChecked() status. This can be the result of a user interaction, + or because setChecked() was called. As setChecked() changes the + QAction, it emits changed() in addition to toggled(). + + \a checked is true if the action is checked, or false if the + action is unchecked. + + \sa activate(), triggered(), checked +*/ + +/*! + \fn void QAction::hovered() + + This signal is emitted when an action is highlighted by the user; + for example, when the user pauses with the cursor over a menu option, + toolbar button, or presses an action's shortcut key combination. + + \sa activate() +*/ + +/*! + \fn void QAction::changed() + + This signal is emitted when an action has changed. If you + are only interested in actions in a given widget, you can + watch for QWidget::actionEvent() sent with an + QEvent::ActionChanged. + + \sa QWidget::actionEvent() +*/ + +/*! + \enum QAction::ActionEvent + + This enum type is used when calling QAction::activate() + + \value Trigger this will cause the QAction::triggered() signal to be emitted. + + \value Hover this will cause the QAction::hovered() signal to be emitted. +*/ + +/*! + \property QAction::menuRole + \brief the action's menu role + + This indicates what role the action serves in the application menu on + \macos. By default all actions have the TextHeuristicRole, which means that + the action is added based on its text (see QMenuBar for more information). + + The menu role can only be changed before the actions are put into the menu + bar in \macos (usually just before the first application window is + shown). +*/ +void QAction::setMenuRole(MenuRole menuRole) +{ + Q_D(QAction); + if (d->menuRole == menuRole) + return; + + d->menuRole = menuRole; + d->sendDataChanged(); +} + +QAction::MenuRole QAction::menuRole() const +{ + Q_D(const QAction); + return d->menuRole; +} + +/*! + \fn QMenu *QAction::menu() const + \obsolete + + Returns the menu contained by this action. + + In widget applications, actions that contain menus can be used to create menu + items with submenus, or inserted into toolbars to create buttons with popup menus. + + \sa QMenu::addAction() +*/ +QObject* QAction::menuObject() const +{ + Q_D(const QAction); + return d->menu(); +} + +/*! + \fn void QAction::setMenu(QMenu *menu) + \obsolete + + Sets the menu contained by this action to the specified \a menu. +*/ +void QAction::setMenuObject(QObject *object) +{ + Q_D(QAction); + d->setMenu(object); +} + +/*! + \property QAction::iconVisibleInMenu + \brief Whether or not an action should show an icon in a menu + + In some applications, it may make sense to have actions with icons in the + toolbar, but not in menus. If true, the icon (if valid) is shown in the menu, when it + is false, it is not shown. + + The default is to follow whether the Qt::AA_DontShowIconsInMenus attribute + is set for the application. Explicitly settings this property overrides + the presence (or abscence) of the attribute. + + For example: + \snippet code/src_gui_kernel_qaction.cpp 0 + + \sa icon, QCoreApplication::setAttribute() +*/ +void QAction::setIconVisibleInMenu(bool visible) +{ + Q_D(QAction); + if (d->iconVisibleInMenu == -1 || visible != bool(d->iconVisibleInMenu)) { + int oldValue = d->iconVisibleInMenu; + d->iconVisibleInMenu = visible; + // Only send data changed if we really need to. + if (oldValue != -1 + || visible == !QCoreApplication::testAttribute(Qt::AA_DontShowIconsInMenus)) { + d->sendDataChanged(); + } + } +} + +bool QAction::isIconVisibleInMenu() const +{ + Q_D(const QAction); + if (d->iconVisibleInMenu == -1) { + return !QCoreApplication::testAttribute(Qt::AA_DontShowIconsInMenus); + } + return d->iconVisibleInMenu; +} + +/*! + \property QAction::shortcutVisibleInContextMenu + \brief Whether or not an action should show a shortcut in a context menu + + In some applications, it may make sense to have actions with shortcuts in + context menus. If true, the shortcut (if valid) is shown when the action is + shown via a context menu, when it is false, it is not shown. + + The default is to follow whether the Qt::AA_DontShowShortcutsInContextMenus attribute + is set for the application, falling back to the widget style hint. + Explicitly setting this property overrides the presence (or abscence) of the attribute. + + \sa shortcut, QCoreApplication::setAttribute() +*/ +void QAction::setShortcutVisibleInContextMenu(bool visible) +{ + Q_D(QAction); + if (d->shortcutVisibleInContextMenu == -1 || visible != bool(d->shortcutVisibleInContextMenu)) { + int oldValue = d->shortcutVisibleInContextMenu; + d->shortcutVisibleInContextMenu = visible; + // Only send data changed if we really need to. + if (oldValue != -1 + || visible == !QCoreApplication::testAttribute(Qt::AA_DontShowShortcutsInContextMenus)) { + d->sendDataChanged(); + } + } +} + +bool QAction::isShortcutVisibleInContextMenu() const +{ + Q_D(const QAction); + if (d->shortcutVisibleInContextMenu == -1) { + return !QCoreApplication::testAttribute(Qt::AA_DontShowShortcutsInContextMenus) + && QGuiApplication::styleHints()->showShortcutsInContextMenus(); + } + return d->shortcutVisibleInContextMenu; +} + +#ifndef QT_NO_DEBUG_STREAM +Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAction *action) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "QAction(" << static_cast<const void *>(action); + if (action) { + d << " text=" << action->text(); + if (!action->toolTip().isEmpty()) + d << " toolTip=" << action->toolTip(); + if (action->isCheckable()) + d << " checked=" << action->isChecked(); +#if QT_CONFIG(shortcut) + if (!action->shortcut().isEmpty()) + d << " shortcut=" << action->shortcut(); +#endif + d << " menuRole="; + QtDebugUtils::formatQEnum(d, action->menuRole()); + d << " enabled=" << action->isEnabled(); + d << " visible=" << action->isVisible(); + } else { + d << '0'; + } + d << ')'; + return d; +} +#endif // QT_NO_DEBUG_STREAM + +QT_END_NAMESPACE + +#include "moc_qaction.cpp" diff --git a/src/gui/kernel/qaction.h b/src/gui/kernel/qaction.h new file mode 100644 index 0000000000..37c6b3a647 --- /dev/null +++ b/src/gui/kernel/qaction.h @@ -0,0 +1,276 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QACTION_H +#define QACTION_H + +#include <QtGui/qtguiglobal.h> +#if QT_CONFIG(shortcut) +# include <QtGui/qkeysequence.h> +#endif +#include <QtGui/qicon.h> +#include <QtCore/qstring.h> +#include <QtCore/qvariant.h> + +QT_REQUIRE_CONFIG(action); + +QT_BEGIN_NAMESPACE + +class QActionEvent; +class QActionGroup; +class QActionPrivate; +#if QT_DEPRECATED_SINCE(6,0) +class QWidget; +class QGraphicsWidget; +class QMenu; +#endif + +class Q_GUI_EXPORT QAction : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QAction) + + Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable NOTIFY checkableChanged FINAL) + Q_PROPERTY(bool checked READ isChecked WRITE setChecked NOTIFY toggled) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged RESET resetEnabled FINAL) + Q_PROPERTY(QIcon icon READ icon WRITE setIcon NOTIFY changed) + Q_PROPERTY(QString text READ text WRITE setText NOTIFY changed) + Q_PROPERTY(QString iconText READ iconText WRITE setIconText NOTIFY changed) + Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip NOTIFY changed) + Q_PROPERTY(QString statusTip READ statusTip WRITE setStatusTip NOTIFY changed) + Q_PROPERTY(QString whatsThis READ whatsThis WRITE setWhatsThis NOTIFY changed) + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY changed) +#if QT_CONFIG(shortcut) + Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut NOTIFY changed) + Q_PROPERTY(Qt::ShortcutContext shortcutContext READ shortcutContext WRITE setShortcutContext NOTIFY changed) + Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat NOTIFY changed) +#endif // QT_CONFIG(shortcut) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY changed) + Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole NOTIFY changed) + Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu NOTIFY changed) + Q_PROPERTY(bool shortcutVisibleInContextMenu READ isShortcutVisibleInContextMenu WRITE setShortcutVisibleInContextMenu NOTIFY changed) + Q_PROPERTY(Priority priority READ priority WRITE setPriority) + +public: + // note this is copied into qplatformmenu.h, which must stay in sync + enum MenuRole { NoRole = 0, TextHeuristicRole, ApplicationSpecificRole, AboutQtRole, + AboutRole, PreferencesRole, QuitRole }; + Q_ENUM(MenuRole) + enum Priority { LowPriority = 0, + NormalPriority = 128, + HighPriority = 256}; + Q_ENUM(Priority) + explicit QAction(QObject *parent = nullptr); + explicit QAction(const QString &text, QObject *parent = nullptr); + explicit QAction(const QIcon &icon, const QString &text, QObject *parent = nullptr); + + ~QAction(); + + QVector<QObject *> associatedObjects() const; + +#if QT_DEPRECATED_SINCE(6,0) +#ifdef Q_CLANG_QDOC + QWidget *parentWidget() const; + QList<QWidget*> associatedWidgets() const; + QList<QGraphicsWidget*> associatedGraphicsWidgets() const; +#else + /* + These are templates so that instantiation happens only in calling code, when + QWidget, QMenu, and QGraphicsWidget can be expected to be fully defined. + */ + template<typename T = QWidget*> + T parentWidget() const + { + auto result = parent(); + while (result && !qobject_cast<T>(result)) + result = result->parent(); + return static_cast<T>(result); + } + + template<typename T = QWidget*> + QList<T> associatedWidgets() const + { + QList<T> result; + for (auto object : associatedObjects()) + if (auto widget = qobject_cast<T>(object)) + result.append(widget); + return result; + } + template<typename T = QGraphicsWidget*> + QList<T> associatedGraphicsWidgets() const + { + QList<T> result; + for (auto object : associatedObjects()) + if (auto graphicsWidget = qobject_cast<T>(object)) + result.append(graphicsWidget); + return result; + } +#endif +#endif + + void setActionGroup(QActionGroup *group); + QActionGroup *actionGroup() const; + void setIcon(const QIcon &icon); + QIcon icon() const; + + void setText(const QString &text); + QString text() const; + + void setIconText(const QString &text); + QString iconText() const; + + void setToolTip(const QString &tip); + QString toolTip() const; + + void setStatusTip(const QString &statusTip); + QString statusTip() const; + + void setWhatsThis(const QString &what); + QString whatsThis() const; + + void setPriority(Priority priority); + Priority priority() const; + + void setSeparator(bool b); + bool isSeparator() const; + +#if QT_CONFIG(shortcut) + void setShortcut(const QKeySequence &shortcut); + QKeySequence shortcut() const; + + void setShortcuts(const QList<QKeySequence> &shortcuts); + void setShortcuts(QKeySequence::StandardKey); + QList<QKeySequence> shortcuts() const; + + void setShortcutContext(Qt::ShortcutContext context); + Qt::ShortcutContext shortcutContext() const; + + void setAutoRepeat(bool); + bool autoRepeat() const; +#endif // QT_CONFIG(shortcut) + + void setFont(const QFont &font); + QFont font() const; + + void setCheckable(bool); + bool isCheckable() const; + + QVariant data() const; + void setData(const QVariant &var); + + bool isChecked() const; + + bool isEnabled() const; + + bool isVisible() const; + + enum ActionEvent { Trigger, Hover }; + void activate(ActionEvent event); + + void setMenuRole(MenuRole menuRole); + MenuRole menuRole() const; + +#if QT_DEPRECATED_SINCE(6,0) +#ifdef Q_CLANG_QDOC + QMenu *menu() const; + void setMenu(QMenu *menu); +#else + template<typename T = QMenu*> + T menu() const + { + return qobject_cast<T>(menuObject()); + } + template<typename T = QMenu*> + void setMenu(T m) + { + setMenuObject(m); + } +#endif +#endif + + void setIconVisibleInMenu(bool visible); + bool isIconVisibleInMenu() const; + + void setShortcutVisibleInContextMenu(bool show); + bool isShortcutVisibleInContextMenu() const; + + bool showStatusText(QObject *object = nullptr); + +protected: + bool event(QEvent *) override; + QAction(QActionPrivate &dd, QObject *parent); + +public Q_SLOTS: + void trigger() { activate(Trigger); } + void hover() { activate(Hover); } + void setChecked(bool); + void toggle(); + void setEnabled(bool); + void resetEnabled(); + inline void setDisabled(bool b) { setEnabled(!b); } + void setVisible(bool); + +Q_SIGNALS: + void changed(); + void enabledChanged(bool enabled); + void checkableChanged(bool checkable); + void triggered(bool checked = false); + void hovered(); + void toggled(bool); + +private: + Q_DISABLE_COPY(QAction) + friend class QActionGroup; + friend class QWidget; + friend class QMenu; + friend class QMenuPrivate; + friend class QToolButton; + friend class QGraphicsWidget; + + QObject *menuObject() const; + void setMenuObject(QObject *object); +}; + +#ifndef QT_NO_DEBUG_STREAM +Q_GUI_EXPORT QDebug operator<<(QDebug, const QAction *); +#endif + +QT_END_NAMESPACE + +#endif // QACTION_H diff --git a/src/gui/kernel/qaction_p.h b/src/gui/kernel/qaction_p.h new file mode 100644 index 0000000000..111cb2958b --- /dev/null +++ b/src/gui/kernel/qaction_p.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QACTION_P_H +#define QACTION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/private/qtguiglobal_p.h> +#include <QtGui/qaction.h> +#include <QtGui/qfont.h> +#if QT_CONFIG(shortcut) +# include <QtGui/private/qshortcutmap_p.h> +#endif +#include "private/qobject_p.h" + +QT_REQUIRE_CONFIG(action); + +QT_BEGIN_NAMESPACE + +class QShortcutMap; + +class Q_GUI_EXPORT QActionPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QAction) +public: + QActionPrivate(); + ~QActionPrivate(); + + virtual void destroy(); + +#if QT_CONFIG(shortcut) + virtual QShortcutMap::ContextMatcher contextMatcher() const; +#endif + + static QActionPrivate *get(QAction *q) + { + return q->d_func(); + } + + bool setEnabled(bool enable, bool byGroup); + + QPointer<QActionGroup> group; + QString text; + QString iconText; + QIcon icon; + QString tooltip; + QString statustip; + QString whatsthis; +#if QT_CONFIG(shortcut) + QKeySequence shortcut; + QList<QKeySequence> alternateShortcuts; +#endif + QVariant userData; + + QObjectList associatedObjects; + virtual QObject *menu() const; + virtual void setMenu(QObject *menu); + +#if QT_CONFIG(shortcut) + int shortcutId = 0; + QVector<int> alternateShortcutIds; + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut; + uint autorepeat : 1; +#endif + QFont font; + uint enabled : 1, explicitEnabled : 1, explicitEnabledValue : 1; + uint visible : 1, forceInvisible : 1; + uint checkable : 1; + uint checked : 1; + uint separator : 1; + uint fontSet : 1; + + int iconVisibleInMenu : 2; // Only has values -1, 0, and 1 + int shortcutVisibleInContextMenu : 2; // Only has values -1, 0, and 1 + + QAction::MenuRole menuRole = QAction::TextHeuristicRole; + QAction::Priority priority = QAction::NormalPriority; + +#if QT_CONFIG(shortcut) + void redoGrab(QShortcutMap &map); + void redoGrabAlternate(QShortcutMap &map); + void setShortcutEnabled(bool enable, QShortcutMap &map); +#endif // QT_NO_SHORTCUT + + bool showStatusText(QObject *widget, const QString &str); + void sendDataChanged(); +}; + +QT_END_NAMESPACE + +#endif // QACTION_P_H diff --git a/src/gui/kernel/qactiongroup.cpp b/src/gui/kernel/qactiongroup.cpp new file mode 100644 index 0000000000..6e2efdb74b --- /dev/null +++ b/src/gui/kernel/qactiongroup.cpp @@ -0,0 +1,366 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qactiongroup.h" + +#include "qaction.h" +#include "qaction_p.h" +#include "qactiongroup_p.h" +#include "qevent.h" +#include "qlist.h" + +QT_BEGIN_NAMESPACE + +QActionGroupPrivate::QActionGroupPrivate() : + enabled(1), visible(1) +{ +} + +QActionGroupPrivate::~QActionGroupPrivate() = default; + +void QActionGroup::_q_actionChanged() +{ + Q_D(QActionGroup); + auto action = qobject_cast<QAction*>(sender()); + Q_ASSERT_X(action != nullptr, "QActionGroup::_q_actionChanged", "internal error"); + if (d->exclusionPolicy != QActionGroup::ExclusionPolicy::None) { + if (action->isChecked()) { + if (action != d->current) { + if (!d->current.isNull()) + d->current->setChecked(false); + d->current = action; + } + } else if (action == d->current) { + d->current = nullptr; + } + } +} + +void QActionGroup::_q_actionTriggered() +{ + auto action = qobject_cast<QAction*>(sender()); + Q_ASSERT_X(action != nullptr, "QActionGroup::_q_actionTriggered", "internal error"); + emit triggered(action); +} + +void QActionGroup::_q_actionHovered() +{ + auto action = qobject_cast<QAction*>(sender()); + Q_ASSERT_X(action != nullptr, "QActionGroup::_q_actionHovered", "internal error"); + emit hovered(action); +} + +/*! + \class QActionGroup + \brief The QActionGroup class groups actions together. + \since 6.0 + + \inmodule QtGui + + QActionGroup is a base class for classes grouping + classes inhheriting QAction objects together. + + In some situations it is useful to group QAction objects together. + For example, if you have a \uicontrol{Left Align} action, a \uicontrol{Right + Align} action, a \uicontrol{Justify} action, and a \uicontrol{Center} action, + only one of these actions should be active at any one time. One + simple way of achieving this is to group the actions together in + an action group, inheriting QActionGroup. + + \sa QAction +*/ + +/*! + \enum QActionGroup::ExclusionPolicy + + This enum specifies the different policies that can be used to + control how the group performs exclusive checking on checkable actions. + + \value None + The actions in the group can be checked independently of each other. + + \value Exclusive + Exactly one action can be checked at any one time. + This is the default policy. + + \value ExclusiveOptional + At most one action can be checked at any one time. The actions + can also be all unchecked. + + \sa exclusionPolicy +*/ + +/*! + Constructs an action group for the \a parent object. + + The action group is exclusive by default. Call setExclusive(false) + to make the action group non-exclusive. To make the group exclusive + but allow unchecking the active action call instead + setExclusionPolicy(QActionGroup::ExclusionPolicy::ExclusiveOptional) +*/ +QActionGroup::QActionGroup(QObject* parent) : + QActionGroup(*new QActionGroupPrivate, parent) +{ +} + +QActionGroup::QActionGroup(QActionGroupPrivate &dd, QObject *parent) : + QObject(dd, parent) +{ +} + +/*! + Destroys the action group. +*/ +QActionGroup::~QActionGroup() = default; + +/*! + \fn QAction *QActionGroup::addAction(QAction *action) + + Adds the \a action to this group, and returns it. + + Normally an action is added to a group by creating it with the + group as its parent, so this function is not usually used. + + \sa QAction::setActionGroup() +*/ +QAction *QActionGroup::addAction(QAction* a) +{ + Q_D(QActionGroup); + if (!d->actions.contains(a)) { + d->actions.append(a); + QObject::connect(a, &QAction::triggered, this, &QActionGroup::_q_actionTriggered); + QObject::connect(a, &QAction::changed, this, &QActionGroup::_q_actionChanged); + QObject::connect(a, &QAction::hovered, this, &QActionGroup::_q_actionHovered); + } + a->d_func()->setEnabled(d->enabled, true); + if (!a->d_func()->forceInvisible) { + a->setVisible(d->visible); + a->d_func()->forceInvisible = false; + } + if (a->isChecked()) + d->current = a; + QActionGroup *oldGroup = a->d_func()->group; + if (oldGroup != this) { + if (oldGroup) + oldGroup->removeAction(a); + a->d_func()->group = this; + a->d_func()->sendDataChanged(); + } + return a; +} + +/*! + Creates and returns an action with \a text. The newly created + action is a child of this action group. + + Normally an action is added to a group by creating it with the + group as parent, so this function is not usually used. + + \sa QAction::setActionGroup() +*/ +QAction *QActionGroup::addAction(const QString &text) +{ + return new QAction(text, this); +} + +/*! + Creates and returns an action with \a text and an \a icon. The + newly created action is a child of this action group. + + Normally an action is added to a group by creating it with the + group as its parent, so this function is not usually used. + + \sa QAction::setActionGroup() +*/ +QAction *QActionGroup::addAction(const QIcon &icon, const QString &text) +{ + return new QAction(icon, text, this); +} + +/*! + Removes the \a action from this group. The action will have no + parent as a result. + + \sa QAction::setActionGroup() +*/ +void QActionGroup::removeAction(QAction *action) +{ + Q_D(QActionGroup); + if (d->actions.removeAll(action)) { + if (action == d->current) + d->current = nullptr; + QObject::disconnect(action, &QAction::triggered, this, &QActionGroup::_q_actionTriggered); + QObject::disconnect(action, &QAction::changed, this, &QActionGroup::_q_actionChanged); + QObject::disconnect(action, &QAction::hovered, this, &QActionGroup::_q_actionHovered); + action->d_func()->group = nullptr; + } +} + +/*! + Returns the list of this groups's actions. This may be empty. +*/ +QList<QAction*> QActionGroup::actions() const +{ + Q_D(const QActionGroup); + return d->actions; +} + +/*! + \brief Enable or disable the group exclusion checking + + This is a convenience method that calls + setExclusionPolicy(ExclusionPolicy::Exclusive) when \a b is true, + else setExclusionPolicy(QActionGroup::ExclusionPolicy::None). + + \sa QActionGroup::exclusionPolicy +*/ +void QActionGroup::setExclusive(bool b) +{ + setExclusionPolicy(b ? QActionGroup::ExclusionPolicy::Exclusive + : QActionGroup::ExclusionPolicy::None); +} + +/*! + \brief Returns true if the group is exclusive + + The group is exclusive if the ExclusionPolicy is either Exclusive + or ExclusionOptional. + +*/ +bool QActionGroup::isExclusive() const +{ + return exclusionPolicy() != QActionGroup::ExclusionPolicy::None; +} + +/*! + \property QActionGroup::exclusionPolicy + \brief This property holds the group exclusive checking policy + + If exclusionPolicy is set to Exclusive, only one checkable + action in the action group can ever be active at any time. If the user + chooses another checkable action in the group, the one they chose becomes + active and the one that was active becomes inactive. If exclusionPolicy is + set to ExclusionOptional the group is exclusive but the active checkable + action in the group can be unchecked leaving the group with no actions + checked. + + \sa QAction::checkable +*/ +void QActionGroup::setExclusionPolicy(QActionGroup::ExclusionPolicy policy) +{ + Q_D(QActionGroup); + d->exclusionPolicy = policy; +} + +QActionGroup::ExclusionPolicy QActionGroup::exclusionPolicy() const +{ + Q_D(const QActionGroup); + return d->exclusionPolicy; +} + +/*! + \fn void QActionGroup::setDisabled(bool b) + + This is a convenience function for the \l enabled property, that + is useful for signals--slots connections. If \a b is true the + action group is disabled; otherwise it is enabled. +*/ + +/*! + \property QActionGroup::enabled + \brief whether the action group is enabled + + Each action in the group will be enabled or disabled unless it + has been explicitly disabled. + + \sa QAction::setEnabled() +*/ +void QActionGroup::setEnabled(bool b) +{ + Q_D(QActionGroup); + d->enabled = b; + for (auto action : qAsConst(d->actions)) { + action->d_func()->setEnabled(b, true); + } +} + +bool QActionGroup::isEnabled() const +{ + Q_D(const QActionGroup); + return d->enabled; +} + +/*! + Returns the currently checked action in the group, or \nullptr if + none are checked. +*/ +QAction *QActionGroup::checkedAction() const +{ + Q_D(const QActionGroup); + return d->current.data(); +} + +/*! + \property QActionGroup::visible + \brief whether the action group is visible + + Each action in the action group will match the visible state of + this group unless it has been explicitly hidden. + + \sa QAction::setEnabled() +*/ +void QActionGroup::setVisible(bool b) +{ + Q_D(QActionGroup); + d->visible = b; + for (auto action : qAsConst(d->actions)) { + if (!action->d_func()->forceInvisible) { + action->setVisible(b); + action->d_func()->forceInvisible = false; + } + } +} + +bool QActionGroup::isVisible() const +{ + Q_D(const QActionGroup); + return d->visible; +} + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qopenglwindow.h b/src/gui/kernel/qactiongroup.h index 7b3bf004a3..c485654d08 100644 --- a/src/gui/kernel/qopenglwindow.h +++ b/src/gui/kernel/qactiongroup.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -37,71 +37,74 @@ ** ****************************************************************************/ -#ifndef QOPENGLWINDOW_H -#define QOPENGLWINDOW_H +#ifndef QGUIACTIONGROUP_H +#define QGUIACTIONGROUP_H #include <QtGui/qtguiglobal.h> +#include <QtGui/qaction.h> -#ifndef QT_NO_OPENGL - -#include <QtGui/QPaintDeviceWindow> -#include <QtGui/QOpenGLContext> -#include <QtGui/QImage> +QT_REQUIRE_CONFIG(action); QT_BEGIN_NAMESPACE -class QOpenGLWindowPrivate; +class QActionGroupPrivate; -class Q_GUI_EXPORT QOpenGLWindow : public QPaintDeviceWindow +class Q_GUI_EXPORT QActionGroup : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(QOpenGLWindow) + Q_DECLARE_PRIVATE(QActionGroup) + + Q_PROPERTY(QActionGroup::ExclusionPolicy exclusionPolicy READ exclusionPolicy WRITE setExclusionPolicy) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible) public: - enum UpdateBehavior { - NoPartialUpdate, - PartialUpdateBlit, - PartialUpdateBlend + enum class ExclusionPolicy { + None, + Exclusive, + ExclusiveOptional }; + Q_ENUM(ExclusionPolicy) - explicit QOpenGLWindow(UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = nullptr); - explicit QOpenGLWindow(QOpenGLContext *shareContext, UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = nullptr); - ~QOpenGLWindow(); - - UpdateBehavior updateBehavior() const; - bool isValid() const; + explicit QActionGroup(QObject *parent); + ~QActionGroup(); - void makeCurrent(); - void doneCurrent(); + QAction *addAction(QAction *a); + QAction *addAction(const QString &text); + QAction *addAction(const QIcon &icon, const QString &text); + void removeAction(QAction *a); + QList<QAction*> actions() const; + QAction *checkedAction() const; - QOpenGLContext *context() const; - QOpenGLContext *shareContext() const; + bool isExclusive() const; + bool isEnabled() const; + bool isVisible() const; + ExclusionPolicy exclusionPolicy() const; - GLuint defaultFramebufferObject() const; - QImage grabFramebuffer(); +public Q_SLOTS: + void setEnabled(bool); + inline void setDisabled(bool b) { setEnabled(!b); } + void setVisible(bool); + void setExclusive(bool); + void setExclusionPolicy(ExclusionPolicy policy); Q_SIGNALS: - void frameSwapped(); + void triggered(QAction *); + void hovered(QAction *); -protected: - virtual void initializeGL(); - virtual void resizeGL(int w, int h); - virtual void paintGL(); - virtual void paintUnderGL(); - virtual void paintOverGL(); +private Q_SLOTS: + void _q_actionTriggered(); + void _q_actionHovered(); + void _q_actionChanged(); - void paintEvent(QPaintEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - int metric(PaintDeviceMetric metric) const override; - QPaintDevice *redirected(QPoint *) const override; +protected: + QActionGroup(QActionGroupPrivate &dd, QObject *parent); private: - Q_DISABLE_COPY(QOpenGLWindow) + Q_DISABLE_COPY(QActionGroup) }; QT_END_NAMESPACE -#endif // QT_NO_OPENGL - -#endif +#endif // QGUIACTIONGROUP_H diff --git a/src/gui/kernel/qactiongroup_p.h b/src/gui/kernel/qactiongroup_p.h new file mode 100644 index 0000000000..4b503783ed --- /dev/null +++ b/src/gui/kernel/qactiongroup_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGUIACTIONGROUP_P_H +#define QGUIACTIONGROUP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/private/qtguiglobal_p.h> +#include <QtGui/qactiongroup.h> +#include <QtGui/qfont.h> +#if QT_CONFIG(shortcut) +# include <QtGui/private/qshortcutmap_p.h> +#endif +#include "private/qobject_p.h" + +QT_REQUIRE_CONFIG(action); + +QT_BEGIN_NAMESPACE + +class Q_GUI_EXPORT QActionGroupPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QActionGroup) +public: + enum Signal { Triggered, Hovered }; + + QActionGroupPrivate(); + ~QActionGroupPrivate(); + + virtual void emitSignal(Signal, QAction *) {} + + QList<QAction *> actions; + QPointer<QAction> current; + uint enabled : 1; + uint visible : 1; + QActionGroup::ExclusionPolicy exclusionPolicy = QActionGroup::ExclusionPolicy::Exclusive; + +private: + void _q_actionTriggered(); //private slot + void _q_actionChanged(); //private slot + void _q_actionHovered(); //private slot +}; + +QT_END_NAMESPACE + +#endif // QACTIONGROUP_P_H diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 466e70db30..dc49d8b324 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -1235,7 +1235,7 @@ Qt::KeyboardModifiers QKeyEvent::modifiers() const return QInputEvent::modifiers(); } -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) /*! \fn bool QKeyEvent::matches(QKeySequence::StandardKey key) const \since 4.2 @@ -1251,7 +1251,7 @@ bool QKeyEvent::matches(QKeySequence::StandardKey matchKey) const const QList<QKeySequence> bindings = QKeySequence::keyBindings(matchKey); return bindings.contains(QKeySequence(searchkey)); } -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) /*! @@ -2063,7 +2063,6 @@ QInputMethodEvent::QInputMethodEvent(const QInputMethodEvent &other) QInputMethodEvent::~QInputMethodEvent() { - // must be empty until ### Qt 6 } /*! @@ -2292,7 +2291,6 @@ QVariant QInputMethodQueryEvent::value(Qt::InputMethodQuery query) const \value FourDMouse A 4D Mouse. \value RotationStylus A special stylus that also knows about rotation (a 6D stylus). \since 4.1 - \omitvalue XFreeEraser */ /*! @@ -2369,52 +2367,6 @@ QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalP { } -#if QT_DEPRECATED_SINCE(5, 15) -/*! - Construct a tablet event of the given \a type. - - The \a pos parameter indicates where the event occurred in the - widget; \a globalPos is the corresponding position in absolute - coordinates. - - \a pressure contains the pressure exerted on the \a device. - - \a pointerType describes the type of pen that is being used. - - \a xTilt and \a yTilt contain the device's degree of tilt from the - x and y axes respectively. - - \a keyState specifies which keyboard modifiers are pressed (e.g., - \uicontrol{Ctrl}). - - The \a uniqueID parameter contains the unique ID for the current device. - - The \a z parameter contains the coordinate of the device on the tablet, this - is usually given by a wheel on 4D mouse. If the device does not support a - Z-axis, pass zero here. - - The \a tangentialPressure parameter contins the tangential pressure of an air - brush. If the device does not support tangential pressure, pass 0 here. - - \a rotation contains the device's rotation in degrees. 4D mice support - rotation. If the device does not support rotation, pass 0 here. - - \sa pos(), globalPos(), device(), pressure(), xTilt(), yTilt(), uniqueId(), rotation(), - tangentialPressure(), z() - - \deprecated in 5.4: use the constructor with MouseButton status -*/ - -QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalPos, - int device, int pointerType, - qreal pressure, int xTilt, int yTilt, qreal tangentialPressure, - qreal rotation, int z, Qt::KeyboardModifiers keyState, qint64 uniqueID) - : QTabletEvent(type, pos, globalPos, device, pointerType, pressure, xTilt, yTilt, - tangentialPressure, rotation, z, keyState, uniqueID, Qt::NoButton, Qt::NoButton) -{ -} -#endif - /*! \internal */ @@ -2452,12 +2404,6 @@ Qt::MouseButtons QTabletEvent::buttons() const } /*! - \fn TabletDevices QTabletEvent::device() const - - \deprecated Use deviceType(). -*/ - -/*! \fn TabletDevices QTabletEvent::deviceType() const Returns the type of device that generated the event. @@ -2585,7 +2531,7 @@ Qt::MouseButtons QTabletEvent::buttons() const Returns the global x position of the mouse pointer at the time of the event. - \sa globalY(), globalPos(), hiResGlobalX() + \sa globalY(), globalPos() */ /*! @@ -2594,7 +2540,7 @@ Qt::MouseButtons QTabletEvent::buttons() const Returns the global y position of the tablet device at the time of the event. - \sa globalX(), globalPos(), hiResGlobalY() + \sa globalX(), globalPos() */ /*! @@ -2621,22 +2567,6 @@ Qt::MouseButtons QTabletEvent::buttons() const */ /*! - \fn qreal &QTabletEvent::hiResGlobalX() const - - The high precision x position of the tablet device. - - \obsolete use globalPosF() -*/ - -/*! - \fn qreal &QTabletEvent::hiResGlobalY() const - - The high precision y position of the tablet device. - - \obsolete use globalPosF() -*/ - -/*! \fn const QPointF &QTabletEvent::posF() const Returns the position of the device, relative to the widget that @@ -2718,10 +2648,6 @@ QNativeGestureEvent::QNativeGestureEvent(Qt::NativeGestureType type, const QPoin { } #endif -typedef QHash<const QNativeGestureEvent*, const QTouchDevice*> NativeGestureEventDataHash; -// ### Qt6: move this to a member in QNativeGestureEvent -Q_GLOBAL_STATIC(NativeGestureEventDataHash, g_nativeGestureEventDataHash) - /*! Constructs a native gesture event of type \a type originating from \a device. @@ -2736,27 +2662,20 @@ QNativeGestureEvent::QNativeGestureEvent(Qt::NativeGestureType type, const QTouc const QPointF &screenPos, qreal realValue, ulong sequenceId, quint64 intValue) : QInputEvent(QEvent::NativeGesture), mGestureType(type), mLocalPos(localPos), mWindowPos(windowPos), mScreenPos(screenPos), mRealValue(realValue), - mSequenceId(sequenceId), mIntValue(intValue) + mSequenceId(sequenceId), mIntValue(intValue), mDevice(device) { - g_nativeGestureEventDataHash->insert(this, device); } QNativeGestureEvent::~QNativeGestureEvent() -{ - g_nativeGestureEventDataHash->remove(this); -} + = default; /*! + \fn const QTouchDevice *QNativeGestureEvent::device() const \since 5.10 Returns the device. */ -const QTouchDevice *QNativeGestureEvent::device() const -{ - return g_nativeGestureEventDataHash->value(this); -} - /*! \fn QNativeGestureEvent::gestureType() const \since 5.2 @@ -3363,8 +3282,8 @@ QWhatsThisClickedEvent::~QWhatsThisClickedEvent() \ingroup events \inmodule QtGui - Actions can be added to widgets using QWidget::addAction(). This - generates an \l ActionAdded event, which you can handle to provide + Actions can be added to controls, for example by using QWidget::addAction(). + This generates an \l ActionAdded event, which you can handle to provide custom behavior. For example, QToolBar reimplements QWidget::actionEvent() to create \l{QToolButton}s for the actions. @@ -3615,7 +3534,7 @@ QToolBarChangeEvent::~QToolBarChangeEvent() #endif // QT_NO_TOOLBAR -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) /*! Constructs a shortcut event for the given \a key press, @@ -3636,7 +3555,7 @@ QShortcutEvent::~QShortcutEvent() { } -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) #ifndef QT_NO_DEBUG_STREAM @@ -3990,7 +3909,7 @@ QT_WARNING_POP dbg << ')'; } break; -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) case QEvent::Shortcut: { const QShortcutEvent *se = static_cast<const QShortcutEvent *>(e); dbg << "QShortcutEvent(" << se->key().toString() << ", id=" << se->shortcutId(); @@ -5014,9 +4933,8 @@ void QTouchEvent::TouchPoint::setFlags(InfoFlags flags) The \a startPos is the position of a touch or mouse event that started the scrolling. */ QScrollPrepareEvent::QScrollPrepareEvent(const QPointF &startPos) - : QEvent(QEvent::ScrollPrepare), m_target(nullptr), m_startPos(startPos) + : QEvent(QEvent::ScrollPrepare), m_startPos(startPos) { - Q_UNUSED(m_target); } /*! diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 4aba9ff729..05d79ad803 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -41,29 +41,31 @@ #define QEVENT_H #include <QtGui/qtguiglobal.h> -#include <QtGui/qwindowdefs.h> -#include <QtGui/qregion.h> + +#include <QtCore/qcoreevent.h> +#include <QtCore/qiodevice.h> #include <QtCore/qnamespace.h> #include <QtCore/qstring.h> -#include <QtGui/qkeysequence.h> -#include <QtCore/qcoreevent.h> #include <QtCore/qvariant.h> -#include <QtCore/qmap.h> // ### Qt 6: Remove #include <QtCore/qvector.h> -#include <QtCore/qset.h> // ### Qt 6: Remove #include <QtCore/qurl.h> -#include <QtCore/qfile.h> // ### Qt 6: Replace by <QtCore/qiodevice.h> and forward declare QFile +#include <QtGui/qregion.h> #include <QtGui/qvector2d.h> -#include <QtGui/qtouchdevice.h> // ### Qt 6: Replace by forward declaration +#include <QtGui/qwindowdefs.h> -QT_BEGIN_NAMESPACE +#if QT_CONFIG(shortcut) +# include <QtGui/qkeysequence.h> +#endif +QT_BEGIN_NAMESPACE +class QFile; class QAction; -#ifndef QT_NO_GESTURES +class QScreen; +class QTouchDevice; +#if QT_CONFIG(gestures) class QGesture; #endif -class QScreen; class Q_GUI_EXPORT QInputEvent : public QEvent { @@ -134,10 +136,6 @@ public: inline void setLocalPos(const QPointF &localPosition) { l = localPosition; } -#if QT_DEPRECATED_SINCE(5, 0) - QT_DEPRECATED inline QPointF posF() const { return l; } -#endif - Qt::MouseEventSource source() const; Qt::MouseEventFlags flags() const; @@ -273,20 +271,11 @@ class Q_GUI_EXPORT QTabletEvent : public QInputEvent { Q_GADGET public: - enum TabletDevice { NoDevice, Puck, Stylus, Airbrush, FourDMouse, - XFreeEraser /*internal*/, RotationStylus }; + enum TabletDevice { NoDevice, Puck, Stylus, Airbrush, FourDMouse, RotationStylus }; Q_ENUM(TabletDevice) enum PointerType { UnknownPointer, Pen, Cursor, Eraser }; Q_ENUM(PointerType) -#if QT_DEPRECATED_SINCE(5, 15) - // Actually deprecated since 5.4, in docs - QT_DEPRECATED_VERSION_X_5_15("Use the other QTabletEvent constructor") - QTabletEvent(Type t, const QPointF &pos, const QPointF &globalPos, - int device, int pointerType, qreal pressure, int xTilt, int yTilt, - qreal tangentialPressure, qreal rotation, int z, - Qt::KeyboardModifiers keyState, qint64 uniqueID); // ### remove in Qt 6 -#endif QTabletEvent(Type t, const QPointF &pos, const QPointF &globalPos, int device, int pointerType, qreal pressure, int xTilt, int yTilt, qreal tangentialPressure, qreal rotation, int z, @@ -296,9 +285,6 @@ public: inline QPoint pos() const { return mPos.toPoint(); } inline QPoint globalPos() const { return mGPos.toPoint(); } -#if QT_DEPRECATED_SINCE(5,0) - QT_DEPRECATED inline const QPointF &hiResGlobalPos() const { return mPos; } -#endif inline const QPointF &posF() const { return mPos; } inline const QPointF &globalPosF() const { return mGPos; } @@ -307,14 +293,6 @@ public: inline int y() const { return qRound(mPos.y()); } inline int globalX() const { return qRound(mGPos.x()); } inline int globalY() const { return qRound(mGPos.y()); } -#if QT_DEPRECATED_SINCE(5, 15) - QT_DEPRECATED_VERSION_X_5_15("use globalPosF().x()") - inline qreal hiResGlobalX() const { return mGPos.x(); } - QT_DEPRECATED_VERSION_X_5_15("use globalPosF().y()") - inline qreal hiResGlobalY() const { return mGPos.y(); } - QT_DEPRECATED_VERSION_X_5_15("Use deviceType()") - inline TabletDevice device() const { return TabletDevice(mDev); } -#endif inline TabletDevice deviceType() const { return TabletDevice(mDev); } inline PointerType pointerType() const { return PointerType(mPointerType); } inline qint64 uniqueId() const { return mUnique; } @@ -339,7 +317,7 @@ protected: }; #endif // QT_CONFIG(tabletevent) -#ifndef QT_NO_GESTURES +#if QT_CONFIG(gestures) class Q_GUI_EXPORT QNativeGestureEvent : public QInputEvent { public: @@ -361,7 +339,7 @@ public: const QPointF &windowPos() const { return mWindowPos; } const QPointF &screenPos() const { return mScreenPos; } - const QTouchDevice *device() const; + const QTouchDevice *device() const { return mDevice; } protected: Qt::NativeGestureType mGestureType; @@ -371,8 +349,9 @@ protected: qreal mRealValue; ulong mSequenceId; quint64 mIntValue; + const QTouchDevice *mDevice; }; -#endif // QT_NO_GESTURES +#endif // QT_CONFIG(gestures) class Q_GUI_EXPORT QKeyEvent : public QInputEvent { @@ -385,7 +364,7 @@ public: ~QKeyEvent(); int key() const { return k; } -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) bool matches(QKeySequence::StandardKey key) const; #endif Qt::KeyboardModifiers modifiers() const; @@ -397,22 +376,6 @@ public: inline quint32 nativeVirtualKey() const { return nVirtualKey; } inline quint32 nativeModifiers() const { return nModifiers; } - // Functions for the extended key event information -#if QT_DEPRECATED_SINCE(5, 0) - static inline QKeyEvent *createExtendedKeyEvent(Type type, int key, Qt::KeyboardModifiers modifiers, - quint32 nativeScanCode, quint32 nativeVirtualKey, - quint32 nativeModifiers, - const QString& text = QString(), bool autorep = false, - ushort count = 1) - { - return new QKeyEvent(type, key, modifiers, - nativeScanCode, nativeVirtualKey, nativeModifiers, - text, autorep, count); - } - - inline bool hasExtendedInfo() const { return true; } -#endif - protected: QString txt; int k; @@ -761,7 +724,7 @@ private: }; #endif -#ifndef QT_NO_ACTION +#if QT_CONFIG(action) class Q_GUI_EXPORT QActionEvent : public QEvent { QAction *act, *bef; @@ -772,7 +735,7 @@ public: inline QAction *action() const { return act; } inline QAction *before() const { return bef; } }; -#endif +#endif // QT_CONFIG(action) class Q_GUI_EXPORT QFileOpenEvent : public QEvent { @@ -802,7 +765,7 @@ private: }; #endif -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) class Q_GUI_EXPORT QShortcutEvent : public QEvent { public: @@ -837,10 +800,10 @@ private: Q_GUI_EXPORT QDebug operator<<(QDebug, const QEvent *); #endif -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) inline bool operator==(QKeyEvent *e, QKeySequence::StandardKey key){return (e ? e->matches(key) : false);} inline bool operator==(QKeySequence::StandardKey key, QKeyEvent *e){return (e ? e->matches(key) : false);} -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) class Q_GUI_EXPORT QPointingDeviceUniqueId { @@ -865,14 +828,6 @@ private: }; Q_DECLARE_TYPEINFO(QPointingDeviceUniqueId, Q_MOVABLE_TYPE); -#if 0 -#pragma qt_sync_suspend_processing -#endif -template <> class QList<QPointingDeviceUniqueId> {}; // to prevent instantiation: use QVector instead -#if 0 -#pragma qt_sync_resume_processing -#endif - Q_GUI_EXPORT bool operator==(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) noexcept; inline bool operator!=(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) noexcept { return !operator==(lhs, rhs); } @@ -991,13 +946,6 @@ public: friend class QQuickMultiPointTouchArea; }; -#if QT_DEPRECATED_SINCE(5, 0) - enum DeviceType { - TouchScreen, - TouchPad - }; -#endif - explicit QTouchEvent(QEvent::Type eventType, QTouchDevice *device = nullptr, Qt::KeyboardModifiers modifiers = Qt::NoModifier, @@ -1007,9 +955,6 @@ public: inline QWindow *window() const { return _window; } inline QObject *target() const { return _target; } -#if QT_DEPRECATED_SINCE(5, 0) - QT_DEPRECATED inline QTouchEvent::DeviceType deviceType() const { return static_cast<DeviceType>(int(_device->type())); } -#endif inline Qt::TouchPointStates touchPointStates() const { return _touchPointStates; } inline const QList<QTouchEvent::TouchPoint> &touchPoints() const { return _touchPoints; } inline QTouchDevice *device() const { return _device; } @@ -1060,7 +1005,6 @@ public: void setContentPos(const QPointF &pos); private: - QObject* m_target; // Qt 6 remove. QPointF m_startPos; QSizeF m_viewportSize; QRectF m_contentPosRange; diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 13369dc8f6..92256078dc 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -614,6 +614,13 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME \li \c {dpiawareness=[0|1|2]} Sets the DPI awareness of the process (see \l{High DPI Displays}, since Qt 5.4). \li \c {fontengine=freetype}, uses the FreeType font engine. + \li \c {fontengine=directwrite}, uses the experimental DirectWrite + font database and defaults to using the DirectWrite font + engine (which is otherwise only used for some font types + or font properties.) This affects font selection and aims + to provide font naming more consistent with other platforms, + but does not support all font formats, such as Postscript + Type-1 or Microsoft FNT fonts. \li \c {menus=[native|none]}, controls the use of native menus. Native menus are implemented using Win32 API and are simpler than @@ -1208,14 +1215,18 @@ Q_LOGGING_CATEGORY(lcQpaPluginLoading, "qt.qpa.plugin"); static void init_platform(const QString &pluginNamesWithArguments, const QString &platformPluginPath, const QString &platformThemeName, int &argc, char **argv) { - QStringList plugins = pluginNamesWithArguments.split(QLatin1Char(';')); + QStringList plugins = pluginNamesWithArguments.split(QLatin1Char(';'), Qt::SkipEmptyParts); QStringList platformArguments; QStringList availablePlugins = QPlatformIntegrationFactory::keys(platformPluginPath); for (const auto &pluginArgument : plugins) { // Split into platform name and arguments - QStringList arguments = pluginArgument.split(QLatin1Char(':')); + QStringList arguments = pluginArgument.split(QLatin1Char(':'), Qt::SkipEmptyParts); + if (arguments.isEmpty()) + continue; const QString name = arguments.takeFirst().toLower(); QString argumentsKey = name; + if (name.isEmpty()) + continue; argumentsKey[0] = argumentsKey.at(0).toUpper(); arguments.append(QLibraryInfo::platformPluginArguments(argumentsKey)); diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 5239b58c97..ab1e6a46cd 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -62,7 +62,10 @@ #include <qpa/qwindowsysteminterface.h> #include <qpa/qwindowsysteminterface_p.h> -#include "private/qshortcutmap_p.h" +#if QT_CONFIG(shortcut) +# include "private/qshortcutmap_p.h" +#endif + #include <qicon.h> QT_BEGIN_NAMESPACE @@ -75,6 +78,12 @@ class QPlatformDragQtResponse; class QDrag; #endif // QT_CONFIG(draganddrop) class QInputDeviceManager; +#ifndef QT_NO_ACTION +class QActionPrivate; +#endif +#if QT_CONFIG(shortcut) +class QShortcutPrivate; +#endif class Q_GUI_EXPORT QGuiApplicationPrivate : public QCoreApplicationPrivate { @@ -263,7 +272,7 @@ public: QIcon forcedWindowIcon; static QList<QObject *> generic_plugin_list; -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) QShortcutMap shortcutMap; #endif @@ -323,6 +332,13 @@ public: static void resetCachedDevicePixelRatio(); +#ifndef QT_NO_ACTION + virtual QActionPrivate *createActionPrivate() const; +#endif +#ifndef QT_NO_SHORTCUT + virtual QShortcutPrivate *createShortcutPrivate() const; +#endif + protected: virtual void notifyThemeChanged(); diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp index c9c45ba815..e0e0d11ae3 100644 --- a/src/gui/kernel/qguivariant.cpp +++ b/src/gui/kernel/qguivariant.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -45,7 +45,9 @@ #include "qcursor.h" #include "qfont.h" #include "qimage.h" -#include "qkeysequence.h" +#if QT_CONFIG(shortcut) +# include "qkeysequence.h" +#endif #include "qtransform.h" #include "qpalette.h" #include "qpen.h" @@ -99,19 +101,6 @@ struct GuiTypesFilter { }; }; -static void construct(QVariant::Private *x, const void *copy) -{ - const int type = x->type; - QVariantConstructor<GuiTypesFilter> constructor(x, copy); - QMetaTypeSwitcher::switcher<void>(constructor, type, nullptr); -} - -static void clear(QVariant::Private *d) -{ - QVariantDestructor<GuiTypesFilter> destructor(d); - QMetaTypeSwitcher::switcher<void>(destructor, d->type, nullptr); -} - // This class is a hack that customizes access to QPolygon and QPolygonF template<class Filter> class QGuiVariantIsNull : public QVariantIsNull<Filter> { @@ -129,7 +118,7 @@ public: static bool isNull(const QVariant::Private *d) { QGuiVariantIsNull<GuiTypesFilter> isNull(d); - return QMetaTypeSwitcher::switcher<bool>(isNull, d->type, nullptr); + return QMetaTypeSwitcher::switcher<bool>(isNull, d->type().id(), nullptr); } // This class is a hack that customizes access to QPixmap, QBitmap, QCursor and QIcon @@ -171,7 +160,7 @@ public: static bool compare(const QVariant::Private *a, const QVariant::Private *b) { QGuiVariantComparator<GuiTypesFilter> comparator(a, b); - return QMetaTypeSwitcher::switcher<bool>(comparator, a->type, nullptr); + return QMetaTypeSwitcher::switcher<bool>(comparator, a->type().id(), nullptr); } static bool convert(const QVariant::Private *d, int t, @@ -179,7 +168,7 @@ static bool convert(const QVariant::Private *d, int t, { switch (t) { case QMetaType::QByteArray: - if (d->type == QMetaType::QColor) { + if (d->type().id() == QMetaType::QColor) { const QColor *c = v_cast<QColor>(d); *static_cast<QByteArray *>(result) = c->name(c->alpha() != 255 ? QColor::HexArgb : QColor::HexRgb).toLatin1(); return true; @@ -187,8 +176,8 @@ static bool convert(const QVariant::Private *d, int t, break; case QMetaType::QString: { QString *str = static_cast<QString *>(result); - switch (d->type) { -#ifndef QT_NO_SHORTCUT + switch (d->type().id()) { +#if QT_CONFIG(shortcut) case QMetaType::QKeySequence: *str = (*v_cast<QKeySequence>(d)).toString(QKeySequence::NativeText); return true; @@ -207,13 +196,13 @@ static bool convert(const QVariant::Private *d, int t, break; } case QMetaType::QPixmap: - if (d->type == QMetaType::QImage) { + if (d->type().id() == QMetaType::QImage) { *static_cast<QPixmap *>(result) = QPixmap::fromImage(*v_cast<QImage>(d)); return true; - } else if (d->type == QMetaType::QBitmap) { + } else if (d->type().id() == QMetaType::QBitmap) { *static_cast<QPixmap *>(result) = *v_cast<QBitmap>(d); return true; - } else if (d->type == QMetaType::QBrush) { + } else if (d->type().id() == QMetaType::QBrush) { if (v_cast<QBrush>(d)->style() == Qt::TexturePattern) { *static_cast<QPixmap *>(result) = v_cast<QBrush>(d)->texture(); return true; @@ -221,26 +210,26 @@ static bool convert(const QVariant::Private *d, int t, } break; case QMetaType::QImage: - if (d->type == QMetaType::QPixmap) { + if (d->type().id() == QMetaType::QPixmap) { *static_cast<QImage *>(result) = v_cast<QPixmap>(d)->toImage(); return true; - } else if (d->type == QMetaType::QBitmap) { + } else if (d->type().id() == QMetaType::QBitmap) { *static_cast<QImage *>(result) = v_cast<QBitmap>(d)->toImage(); return true; } break; case QMetaType::QBitmap: - if (d->type == QMetaType::QPixmap) { + if (d->type().id() == QMetaType::QPixmap) { *static_cast<QBitmap *>(result) = *v_cast<QPixmap>(d); return true; - } else if (d->type == QMetaType::QImage) { + } else if (d->type().id() == QMetaType::QImage) { *static_cast<QBitmap *>(result) = QBitmap::fromImage(*v_cast<QImage>(d)); return true; } break; -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) case QMetaType::Int: - if (d->type == QMetaType::QKeySequence) { + if (d->type().id() == QMetaType::QKeySequence) { const QKeySequence &seq = *v_cast<QKeySequence>(d); *static_cast<int *>(result) = seq.isEmpty() ? 0 : seq[0]; return true; @@ -248,20 +237,20 @@ static bool convert(const QVariant::Private *d, int t, break; #endif case QMetaType::QFont: - if (d->type == QMetaType::QString) { + if (d->type().id() == QMetaType::QString) { QFont *f = static_cast<QFont *>(result); f->fromString(*v_cast<QString>(d)); return true; } break; case QMetaType::QColor: - if (d->type == QMetaType::QString) { + if (d->type().id() == QMetaType::QString) { static_cast<QColor *>(result)->setNamedColor(*v_cast<QString>(d)); return static_cast<QColor *>(result)->isValid(); - } else if (d->type == QMetaType::QByteArray) { + } else if (d->type().id() == QMetaType::QByteArray) { static_cast<QColor *>(result)->setNamedColor(QLatin1String(*v_cast<QByteArray>(d))); return true; - } else if (d->type == QMetaType::QBrush) { + } else if (d->type().id() == QMetaType::QBrush) { if (v_cast<QBrush>(d)->style() == Qt::SolidPattern) { *static_cast<QColor *>(result) = v_cast<QBrush>(d)->color(); return true; @@ -269,18 +258,18 @@ static bool convert(const QVariant::Private *d, int t, } break; case QMetaType::QBrush: - if (d->type == QMetaType::QColor) { + if (d->type().id() == QMetaType::QColor) { *static_cast<QBrush *>(result) = QBrush(*v_cast<QColor>(d)); return true; - } else if (d->type == QMetaType::QPixmap) { + } else if (d->type().id() == QMetaType::QPixmap) { *static_cast<QBrush *>(result) = QBrush(*v_cast<QPixmap>(d)); return true; } break; -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) case QMetaType::QKeySequence: { QKeySequence *seq = static_cast<QKeySequence *>(result); - switch (d->type) { + switch (d->type().id()) { case QMetaType::QString: *seq = QKeySequence(*v_cast<QString>(d)); return true; @@ -311,13 +300,11 @@ static void streamDebug(QDebug dbg, const QVariant &v) { QVariant::Private *d = const_cast<QVariant::Private *>(&v.data_ptr()); QVariantDebugStream<GuiTypesFilter> stream(dbg, d); - QMetaTypeSwitcher::switcher<void>(stream, d->type, nullptr); + QMetaTypeSwitcher::switcher<void>(stream, d->type().id(), nullptr); } #endif const QVariant::Handler qt_gui_variant_handler = { - construct, - clear, isNull, #ifndef QT_NO_DATASTREAM nullptr, @@ -336,19 +323,41 @@ const QVariant::Handler qt_gui_variant_handler = { #define QT_IMPL_METATYPEINTERFACE_GUI_TYPES(MetaTypeName, MetaTypeId, RealName) \ QT_METATYPE_INTERFACE_INIT(RealName), -static const QMetaTypeInterface qVariantGuiHelper[] = { - QT_FOR_EACH_STATIC_GUI_CLASS(QT_IMPL_METATYPEINTERFACE_GUI_TYPES) -}; +static const struct : QMetaTypeModuleHelper +{ + QtPrivate::QMetaTypeInterface *interfaceForType(int type) const override { + switch (type) { + QT_FOR_EACH_STATIC_GUI_CLASS(QT_METATYPE_CONVERT_ID_TO_TYPE) + default: return nullptr; + } + } +#ifndef QT_NO_DATASTREAM + bool save(QDataStream &stream, int type, const void *data) const override { + switch (type) { + QT_FOR_EACH_STATIC_GUI_CLASS(QT_METATYPE_DATASTREAM_SAVE) + default: return false; + } + } + bool load(QDataStream &stream, int type, void *data) const override { + switch (type) { + QT_FOR_EACH_STATIC_GUI_CLASS(QT_METATYPE_DATASTREAM_LOAD) + default: return false; + } + } +#endif + +} qVariantGuiHelper; + #undef QT_IMPL_METATYPEINTERFACE_GUI_TYPES } // namespace used to hide QVariant handler -extern Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper; +extern Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeGuiHelper; void qRegisterGuiVariant() { QVariantPrivate::registerHandler(QModulesPrivate::Gui, &qt_gui_variant_handler); - qMetaTypeGuiHelper = qVariantGuiHelper; + qMetaTypeGuiHelper = &qVariantGuiHelper; } Q_CONSTRUCTOR_FUNCTION(qRegisterGuiVariant) diff --git a/src/gui/kernel/qkeymapper_p.h b/src/gui/kernel/qkeymapper_p.h index 8364557020..fd53747fdd 100644 --- a/src/gui/kernel/qkeymapper_p.h +++ b/src/gui/kernel/qkeymapper_p.h @@ -53,7 +53,6 @@ #include <QtGui/private/qtguiglobal_p.h> #include <qobject.h> #include <private/qobject_p.h> -#include <qkeysequence.h> #include <qlist.h> #include <qlocale.h> #include <qevent.h> diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index a75b8ef920..cdcb6e8faf 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -42,8 +42,6 @@ #include <qpa/qplatformtheme.h> #include "private/qguiapplication_p.h" -#if !defined(QT_NO_SHORTCUT) || defined(Q_CLANG_QDOC) - #include "qdebug.h" #include <QtCore/qhashfunctions.h> #ifndef QT_NO_DATASTREAM @@ -1679,9 +1677,6 @@ QDebug operator<<(QDebug dbg, const QKeySequence &p) } #endif -#endif // QT_NO_SHORTCUT - - /*! \typedef QKeySequence::DataPtr \internal diff --git a/src/gui/kernel/qkeysequence.h b/src/gui/kernel/qkeysequence.h index 3dcbbe5941..68f256c37a 100644 --- a/src/gui/kernel/qkeysequence.h +++ b/src/gui/kernel/qkeysequence.h @@ -44,10 +44,9 @@ #include <QtCore/qstring.h> #include <QtCore/qobjectdefs.h> -QT_BEGIN_NAMESPACE - +QT_REQUIRE_CONFIG(shortcut); -#if !defined(QT_NO_SHORTCUT) || defined(Q_CLANG_QDOC) +QT_BEGIN_NAMESPACE class QKeySequence; @@ -227,17 +226,6 @@ Q_DECLARE_SHARED(QKeySequence) Q_GUI_EXPORT QDebug operator<<(QDebug, const QKeySequence &); #endif -#else - -class Q_GUI_EXPORT QKeySequence -{ -public: - QKeySequence() {} - QKeySequence(int) {} -}; - -#endif // QT_NO_SHORTCUT - QT_END_NAMESPACE #endif // QKEYSEQUENCE_H diff --git a/src/gui/kernel/qkeysequence_p.h b/src/gui/kernel/qkeysequence_p.h index fbcab5d34e..8c59505561 100644 --- a/src/gui/kernel/qkeysequence_p.h +++ b/src/gui/kernel/qkeysequence_p.h @@ -56,9 +56,10 @@ #include <algorithm> +QT_REQUIRE_CONFIG(shortcut); + QT_BEGIN_NAMESPACE -#ifndef QT_NO_SHORTCUT struct QKeyBinding { QKeySequence::StandardKey standardKey; @@ -87,7 +88,6 @@ public: Q_GUI_EXPORT static QString keyName(int key, QKeySequence::SequenceFormat format); static int decodeString(QString accel, QKeySequence::SequenceFormat format); }; -#endif // QT_NO_SHORTCUT QT_END_NAMESPACE diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index ac5e279a79..b0474ceb3d 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -56,8 +56,6 @@ #include <private/qopenglextensions_p.h> #include <private/qopenglversionfunctionsfactory_p.h> -#include <private/qopengltexturehelper_p.h> - #include <QDebug> #ifndef QT_OPENGL_ES_2 @@ -67,158 +65,6 @@ QT_BEGIN_NAMESPACE -class QOpenGLVersionProfilePrivate -{ -public: - QOpenGLVersionProfilePrivate() - : majorVersion(0), - minorVersion(0), - profile(QSurfaceFormat::NoProfile) - {} - - int majorVersion; - int minorVersion; - QSurfaceFormat::OpenGLContextProfile profile; -}; - - -/*! - \class QOpenGLVersionProfile - \inmodule QtGui - \since 5.1 - \brief The QOpenGLVersionProfile class represents the version and if applicable - the profile of an OpenGL context. - - An object of this class can be passed to QOpenGLContext::versionFunctions() to - request a functions object for a specific version and profile of OpenGL. - - It also contains some helper functions to check if a version supports profiles - or is a legacy version. -*/ - -/*! - Creates a default invalid QOpenGLVersionProfile object. -*/ -QOpenGLVersionProfile::QOpenGLVersionProfile() - : d(new QOpenGLVersionProfilePrivate) -{ -} - -/*! - Creates a QOpenGLVersionProfile object initialised with the version and profile - from \a format. -*/ -QOpenGLVersionProfile::QOpenGLVersionProfile(const QSurfaceFormat &format) - : d(new QOpenGLVersionProfilePrivate) -{ - d->majorVersion = format.majorVersion(); - d->minorVersion = format.minorVersion(); - d->profile = format.profile(); -} - -/*! - Constructs a copy of \a other. -*/ -QOpenGLVersionProfile::QOpenGLVersionProfile(const QOpenGLVersionProfile &other) - : d(new QOpenGLVersionProfilePrivate) -{ - *d = *(other.d); -} - -/*! - Destroys the QOpenGLVersionProfile object. -*/ -QOpenGLVersionProfile::~QOpenGLVersionProfile() -{ - delete d; -} - -/*! - Assigns the version and profile of \a rhs to this QOpenGLVersionProfile object. -*/ -QOpenGLVersionProfile &QOpenGLVersionProfile::operator=(const QOpenGLVersionProfile &rhs) -{ - if (this == &rhs) - return *this; - *d = *(rhs.d); - return *this; -} - -/*! - Returns a QPair<int,int> where the components represent the major and minor OpenGL - version numbers respectively. - - \sa setVersion() -*/ -QPair<int, int> QOpenGLVersionProfile::version() const -{ - return qMakePair( d->majorVersion, d->minorVersion); -} - -/*! - Sets the major and minor version numbers to \a majorVersion and \a minorVersion respectively. - - \sa version() -*/ -void QOpenGLVersionProfile::setVersion(int majorVersion, int minorVersion) -{ - d->majorVersion = majorVersion; - d->minorVersion = minorVersion; -} - -/*! - Returns the OpenGL profile. Only makes sense if profiles are supported by this version. - - \sa setProfile() -*/ -QSurfaceFormat::OpenGLContextProfile QOpenGLVersionProfile::profile() const -{ - return d->profile; -} - -/*! - Sets the OpenGL profile \a profile. Only makes sense if profiles are supported by - this version. - - \sa profile() -*/ -void QOpenGLVersionProfile::setProfile(QSurfaceFormat::OpenGLContextProfile profile) -{ - d->profile = profile; -} - -/*! - Returns \c true if profiles are supported by the OpenGL version returned by version(). Only - OpenGL versions >= 3.2 support profiles. - - \sa profile(), version() -*/ -bool QOpenGLVersionProfile::hasProfiles() const -{ - return ( d->majorVersion > 3 - || (d->majorVersion == 3 && d->minorVersion > 1)); -} - -/*! - Returns \c true is the OpenGL version returned by version() contains deprecated functions - and does not support profiles i.e. if the OpenGL version is <= 3.1. -*/ -bool QOpenGLVersionProfile::isLegacyVersion() const -{ - return (d->majorVersion < 3 || (d->majorVersion == 3 && d->minorVersion == 0)); -} - -/*! - Returns \c true if the version number is valid. Note that for a default constructed - QOpenGLVersionProfile object this function will return \c false. - - \sa setVersion(), version() -*/ -bool QOpenGLVersionProfile::isValid() const -{ - return d->majorVersion > 0 && d->minorVersion >= 0; -} - class QGuiGLThreadContext { public: @@ -374,20 +220,8 @@ int QOpenGLContextPrivate::maxTextureSize() GLint next = 64; funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - QOpenGLFunctions_1_0 *gl1funcs = nullptr; - QOpenGLFunctions_3_2_Core *gl3funcs = nullptr; - - if (q->format().profile() == QSurfaceFormat::CoreProfile) - gl3funcs = q->versionFunctions<QOpenGLFunctions_3_2_Core>(); - else - gl1funcs = q->versionFunctions<QOpenGLFunctions_1_0>(); - - Q_ASSERT(gl1funcs || gl3funcs); - - if (gl1funcs) - gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); - else - gl3funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); + QOpenGLExtraFunctions *extraFuncs = q->extraFunctions(); + extraFuncs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); if (size == 0) { return max_texture_size; @@ -399,11 +233,7 @@ int QOpenGLContextPrivate::maxTextureSize() if (next > max_texture_size) break; funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - if (gl1funcs) - gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); - else - gl3funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); - + extraFuncs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); } while (next > size); max_texture_size = size; @@ -641,7 +471,6 @@ bool QOpenGLContext::create() */ void QOpenGLContext::destroy() { - deleteQGLContext(); Q_D(QOpenGLContext); if (d->platformGLContext) emit aboutToBeDestroyed(); @@ -664,7 +493,10 @@ void QOpenGLContext::destroy() qDeleteAll(d->versionFunctions); d->versionFunctions.clear(); - delete d->textureFunctions; + if (d->textureFunctionsDestroyCallback) { + d->textureFunctionsDestroyCallback(); + d->textureFunctionsDestroyCallback = nullptr; + } d->textureFunctions = nullptr; d->nativeHandle = QVariant(); @@ -1192,44 +1024,6 @@ QScreen *QOpenGLContext::screen() const } /*! - internal: Needs to have a pointer to qGLContext. But since this is in Qt GUI we can't - have any type information. - - \internal -*/ -void *QOpenGLContext::qGLContextHandle() const -{ - Q_D(const QOpenGLContext); - return d->qGLContextHandle; -} - -/*! - internal: If the delete function is specified QOpenGLContext "owns" - the passed context handle and will use the delete function to destroy it. - - \internal -*/ -void QOpenGLContext::setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *)) -{ - Q_D(QOpenGLContext); - d->qGLContextHandle = handle; - d->qGLContextDeleteFunction = qGLContextDeleteFunction; -} - -/*! - \internal -*/ -void QOpenGLContext::deleteQGLContext() -{ - Q_D(QOpenGLContext); - if (d->qGLContextDeleteFunction && d->qGLContextHandle) { - d->qGLContextDeleteFunction(d->qGLContextHandle); - d->qGLContextDeleteFunction = nullptr; - d->qGLContextHandle = nullptr; - } -} - -/*! Returns the platform-specific handle for the OpenGL implementation that is currently in use. (for example, a HMODULE on Windows) @@ -1388,10 +1182,11 @@ QOpenGLTextureHelper* QOpenGLContext::textureFunctions() const /*! \internal */ -void QOpenGLContext::setTextureFunctions(QOpenGLTextureHelper* textureFuncs) +void QOpenGLContext::setTextureFunctions(QOpenGLTextureHelper* textureFuncs, std::function<void()> destroyCallback) { Q_D(QOpenGLContext); d->textureFunctions = textureFuncs; + d->textureFunctionsDestroyCallback = destroyCallback; } /*! @@ -1682,21 +1477,6 @@ void QOpenGLMultiGroupSharedResource::cleanup(QOpenGLContextGroup *group, QOpenG } #ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug debug, const QOpenGLVersionProfile &vp) -{ - QDebugStateSaver saver(debug); - debug.nospace(); - debug << "QOpenGLVersionProfile("; - if (vp.isValid()) { - debug << vp.version().first << '.' << vp.version().second - << ", profile=" << vp.profile(); - } else { - debug << "invalid"; - } - debug << ')'; - return debug; -} - QDebug operator<<(QDebug debug, const QOpenGLContext *ctx) { QDebugStateSaver saver(debug); diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h index 9cfaa52f17..b26a3e2ede 100644 --- a/src/gui/kernel/qopenglcontext.h +++ b/src/gui/kernel/qopenglcontext.h @@ -59,12 +59,9 @@ #include <QtGui/qopengl.h> #include <QtGui/qopenglversionfunctions.h> +// TODO: ideally get rid of this include +#include <QtGui/qopenglversionprofile.h> -#if QT_DEPRECATED_SINCE(5, 6) -#include <QtCore/qhash.h> -#endif -#include <QtCore/qhashfunctions.h> -#include <QtCore/qpair.h> #include <QtCore/qvariant.h> QT_BEGIN_NAMESPACE @@ -79,50 +76,6 @@ class QPlatformOpenGLContext; class QScreen; class QSurface; -class QOpenGLVersionProfilePrivate; - -class Q_GUI_EXPORT QOpenGLVersionProfile -{ -public: - QOpenGLVersionProfile(); - explicit QOpenGLVersionProfile(const QSurfaceFormat &format); - QOpenGLVersionProfile(const QOpenGLVersionProfile &other); - ~QOpenGLVersionProfile(); - - QOpenGLVersionProfile &operator=(const QOpenGLVersionProfile &rhs); - - QPair<int, int> version() const; - void setVersion(int majorVersion, int minorVersion); - - QSurfaceFormat::OpenGLContextProfile profile() const; - void setProfile(QSurfaceFormat::OpenGLContextProfile profile); - - bool hasProfiles() const; - bool isLegacyVersion() const; - bool isValid() const; - -private: - QOpenGLVersionProfilePrivate* d; -}; - -inline uint qHash(const QOpenGLVersionProfile &v, uint seed = 0) -{ - return qHash(static_cast<int>(v.profile() * 1000) - + v.version().first * 100 + v.version().second * 10, seed); -} - -inline bool operator==(const QOpenGLVersionProfile &lhs, const QOpenGLVersionProfile &rhs) -{ - if (lhs.profile() != rhs.profile()) - return false; - return lhs.version() == rhs.version(); -} - -inline bool operator!=(const QOpenGLVersionProfile &lhs, const QOpenGLVersionProfile &rhs) -{ - return !operator==(lhs, rhs); -} - class Q_GUI_EXPORT QOpenGLContextGroup : public QObject { Q_OBJECT @@ -218,8 +171,6 @@ Q_SIGNALS: void aboutToBeDestroyed(); private: - friend class QGLContext; - friend class QGLPixelBuffer; friend class QOpenGLContextResourceBase; friend class QOpenGLPaintDevice; friend class QOpenGLGlyphTexture; @@ -234,16 +185,12 @@ private: friend class QAbstractOpenGLFunctionsPrivate; friend class QOpenGLTexturePrivate; - void *qGLContextHandle() const; - void setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *)); - void deleteQGLContext(); - QOpenGLVersionFunctionsStorage* functionsBackendStorage() const; void insertExternalFunctions(QAbstractOpenGLFunctions *f); void removeExternalFunctions(QAbstractOpenGLFunctions *f); QOpenGLTextureHelper* textureFunctions() const; - void setTextureFunctions(QOpenGLTextureHelper* textureFuncs); + void setTextureFunctions(QOpenGLTextureHelper* textureFuncs, std::function<void()> destroyCallback); void destroy(); @@ -251,7 +198,6 @@ private: }; #ifndef QT_NO_DEBUG_STREAM -Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QOpenGLVersionProfile &vp); Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QOpenGLContext *ctx); Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QOpenGLContextGroup *cg); #endif // !QT_NO_DEBUG_STREAM diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h index 833cfb20c3..d769f03fd3 100644 --- a/src/gui/kernel/qopenglcontext_p.h +++ b/src/gui/kernel/qopenglcontext_p.h @@ -197,9 +197,7 @@ class Q_GUI_EXPORT QOpenGLContextPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QOpenGLContext) public: QOpenGLContextPrivate() - : qGLContextHandle(nullptr) - , qGLContextDeleteFunction(nullptr) - , platformGLContext(nullptr) + : platformGLContext(nullptr) , shareContext(nullptr) , shareGroup(nullptr) , screen(nullptr) @@ -228,9 +226,6 @@ public: mutable QOpenGLVersionFunctionsStorage versionFunctionsStorage; mutable QSet<QAbstractOpenGLFunctions *> externalVersionFunctions; - void *qGLContextHandle; - void (*qGLContextDeleteFunction)(void *handle); - QSurfaceFormat requestedFormat; QPlatformOpenGLContext *platformGLContext; QOpenGLContext *shareContext; @@ -240,6 +235,7 @@ public: QOpenGLFunctions *functions; mutable QSet<QByteArray> extensionNames; QOpenGLTextureHelper* textureFunctions; + std::function<void()> textureFunctionsDestroyCallback; GLint max_texture_size; diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp deleted file mode 100644 index 2ea8f43711..0000000000 --- a/src/gui/kernel/qopenglwindow.cpp +++ /dev/null @@ -1,698 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qopenglwindow.h" -#include "qpaintdevicewindow_p.h" -#include <QtGui/QOpenGLFramebufferObject> -#include <QtGui/QOpenGLPaintDevice> -#include <QtGui/QOpenGLFunctions> -#include <QtGui/QOpenGLTextureBlitter> -#include <QtGui/private/qopenglextensions_p.h> -#include <QtGui/private/qopenglcontext_p.h> -#include <QtGui/QMatrix4x4> -#include <QtGui/QOffscreenSurface> - -QT_BEGIN_NAMESPACE - -/*! - \class QOpenGLWindow - \inmodule QtGui - \since 5.4 - \brief The QOpenGLWindow class is a convenience subclass of QWindow to perform OpenGL painting. - - QOpenGLWindow is an enhanced QWindow that allows easily creating windows that - perform OpenGL rendering using an API that is compatible with QOpenGLWidget - and is similar to the legacy QGLWidget. Unlike QOpenGLWidget, QOpenGLWindow - has no dependency on the widgets module and offers better performance. - - A typical application will subclass QOpenGLWindow and reimplement the following - virtual functions: - - \list - - \li initializeGL() to perform OpenGL resource initialization - - \li resizeGL() to set up the transformation matrices and other window size dependent resources - - \li paintGL() to issue OpenGL commands or draw using QPainter - - \endlist - - To schedule a repaint, call the update() function. Note that this will not - immediately result in a call to paintGL(). Calling update() multiple times in - a row will not change the behavior in any way. - - This is a slot so it can be connected to a \l QTimer::timeout() signal to - perform animation. Note however that in the modern OpenGL world it is a much - better choice to rely on synchronization to the vertical refresh rate of the - display. See \l{QSurfaceFormat::setSwapInterval()}{setSwapInterval()} on a - description of the swap interval. With a swap interval of \c 1, which is the - case on most systems by default, the - \l{QOpenGLContext::swapBuffers()}{swapBuffers()} call, that is executed - internally by QOpenGLWindow after each repaint, will block and wait for - vsync. This means that whenever the swap is done, an update can be scheduled - again by calling update(), without relying on timers. - - To request a specific configuration for the context, use setFormat() - like for any other QWindow. This allows, among others, requesting a - given OpenGL version and profile, or enabling depth and stencil - buffers. - - Unlike QWindow, QOpenGLWindow allows opening a painter on itself and perform - QPainter-based drawing. - - QOpenGLWindow supports multiple update behaviors. The default, - \c NoPartialUpdate is equivalent to a regular, OpenGL-based QWindow or the - legacy QGLWidget. In contrast, \c PartialUpdateBlit and \c PartialUpdateBlend are - more in line with QOpenGLWidget's way of working, where there is always an - extra, dedicated framebuffer object present. These modes allow, by - sacrificing some performance, redrawing only a smaller area on each paint and - having the rest of the content preserved from of the previous frame. This is - useful for applications than render incrementally using QPainter, because - this way they do not have to redraw the entire window content on each - paintGL() call. - - Similarly to QOpenGLWidget, QOpenGLWindow supports the Qt::AA_ShareOpenGLContexts - attribute. When enabled, the OpenGL contexts of all QOpenGLWindow instances will share - with each other. This allows accessing each other's shareable OpenGL resources. - - For more information on graphics in Qt, see \l {Graphics}. - */ - -/*! - \enum QOpenGLWindow::UpdateBehavior - - This enum describes the update strategy of the QOpenGLWindow. - - \value NoPartialUpdate Indicates that the entire window surface will - redrawn on each update and so no additional framebuffers are needed. - This is the setting used in most cases and is equivalent to how drawing - directly via QWindow would function. - - \value PartialUpdateBlit Indicates that the drawing performed in paintGL() - does not cover the entire window. In this case an extra framebuffer object - is created under the hood, and rendering performed in paintGL() will target - this framebuffer. This framebuffer is then blitted onto the window surface's - default framebuffer after each paint. This allows having QPainter-based drawing - code in paintGL() which only repaints a smaller area at a time, because, unlike - NoPartialUpdate, the previous content is preserved. - - \value PartialUpdateBlend Similar to PartialUpdateBlit, but instead of using - framebuffer blits, the contents of the extra framebuffer is rendered by - drawing a textured quad with blending enabled. This, unlike PartialUpdateBlit, - allows alpha blended content and works even when the glBlitFramebuffer is - not available. Performance-wise this setting is likely to be somewhat slower - than PartialUpdateBlit. - */ - -/*! - \fn void QOpenGLWindow::frameSwapped() - - This signal is emitted after the potentially blocking - \l{QOpenGLContext::swapBuffers()}{buffer swap} has been done. Applications - that wish to continuously repaint synchronized to the vertical refresh, - should issue an update() upon this signal. This allows for a much smoother - experience compared to the traditional usage of timers. -*/ - -// GLES2 builds won't have these constants with the suffixless names -#ifndef GL_READ_FRAMEBUFFER -#define GL_READ_FRAMEBUFFER 0x8CA8 -#endif -#ifndef GL_DRAW_FRAMEBUFFER -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#endif - -class QOpenGLWindowPaintDevice : public QOpenGLPaintDevice -{ -public: - QOpenGLWindowPaintDevice(QOpenGLWindow *window) : m_window(window) { } - void ensureActiveTarget() override; - - QOpenGLWindow *m_window; -}; - -class QOpenGLWindowPrivate : public QPaintDeviceWindowPrivate -{ - Q_DECLARE_PUBLIC(QOpenGLWindow) -public: - QOpenGLWindowPrivate(QOpenGLContext *shareContext, QOpenGLWindow::UpdateBehavior updateBehavior) - : updateBehavior(updateBehavior) - , hasFboBlit(false) - , shareContext(shareContext) - { - if (!shareContext) - this->shareContext = qt_gl_global_share_context(); - } - - ~QOpenGLWindowPrivate(); - - static QOpenGLWindowPrivate *get(QOpenGLWindow *w) { return w->d_func(); } - - void bindFBO(); - void initialize(); - - void beginPaint(const QRegion ®ion) override; - void endPaint() override; - void flush(const QRegion ®ion) override; - - QOpenGLWindow::UpdateBehavior updateBehavior; - bool hasFboBlit; - QScopedPointer<QOpenGLContext> context; - QOpenGLContext *shareContext; - QScopedPointer<QOpenGLFramebufferObject> fbo; - QScopedPointer<QOpenGLWindowPaintDevice> paintDevice; - QOpenGLTextureBlitter blitter; - QColor backgroundColor; - QScopedPointer<QOffscreenSurface> offscreenSurface; -}; - -QOpenGLWindowPrivate::~QOpenGLWindowPrivate() -{ - Q_Q(QOpenGLWindow); - if (q->isValid()) { - q->makeCurrent(); // this works even when the platformwindow is destroyed - paintDevice.reset(nullptr); - fbo.reset(nullptr); - blitter.destroy(); - q->doneCurrent(); - } -} - -void QOpenGLWindowPrivate::initialize() -{ - Q_Q(QOpenGLWindow); - - if (context) - return; - - if (!q->handle()) - qWarning("Attempted to initialize QOpenGLWindow without a platform window"); - - context.reset(new QOpenGLContext); - context->setShareContext(shareContext); - context->setFormat(q->requestedFormat()); - if (!context->create()) - qWarning("QOpenGLWindow::beginPaint: Failed to create context"); - if (!context->makeCurrent(q)) - qWarning("QOpenGLWindow::beginPaint: Failed to make context current"); - - paintDevice.reset(new QOpenGLWindowPaintDevice(q)); - if (updateBehavior == QOpenGLWindow::PartialUpdateBlit) - hasFboBlit = QOpenGLFramebufferObject::hasOpenGLFramebufferBlit(); - - q->initializeGL(); -} - -void QOpenGLWindowPrivate::beginPaint(const QRegion ®ion) -{ - Q_UNUSED(region); - Q_Q(QOpenGLWindow); - - initialize(); - context->makeCurrent(q); - - const int deviceWidth = q->width() * q->devicePixelRatio(); - const int deviceHeight = q->height() * q->devicePixelRatio(); - const QSize deviceSize(deviceWidth, deviceHeight); - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { - if (!fbo || fbo->size() != deviceSize) { - QOpenGLFramebufferObjectFormat fboFormat; - fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); - const int samples = q->requestedFormat().samples(); - if (samples > 0) { - if (updateBehavior != QOpenGLWindow::PartialUpdateBlend) - fboFormat.setSamples(samples); - else - qWarning("QOpenGLWindow: PartialUpdateBlend does not support multisampling"); - } - fbo.reset(new QOpenGLFramebufferObject(deviceSize, fboFormat)); - markWindowAsDirty(); - } - } else { - markWindowAsDirty(); - } - - paintDevice->setSize(QSize(deviceWidth, deviceHeight)); - paintDevice->setDevicePixelRatio(q->devicePixelRatio()); - context->functions()->glViewport(0, 0, deviceWidth, deviceHeight); - - context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); - - q->paintUnderGL(); - - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) - fbo->bind(); -} - -void QOpenGLWindowPrivate::endPaint() -{ - Q_Q(QOpenGLWindow); - - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) - fbo->release(); - - context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); - - if (updateBehavior == QOpenGLWindow::PartialUpdateBlit && hasFboBlit) { - const int deviceWidth = q->width() * q->devicePixelRatio(); - const int deviceHeight = q->height() * q->devicePixelRatio(); - QOpenGLExtensions extensions(context.data()); - extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->handle()); - extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, context->defaultFramebufferObject()); - extensions.glBlitFramebuffer(0, 0, deviceWidth, deviceHeight, - 0, 0, deviceWidth, deviceHeight, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } else if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { - if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) { - context->functions()->glEnable(GL_BLEND); - context->functions()->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - if (!blitter.isCreated()) - blitter.create(); - - QRect windowRect(QPoint(0, 0), fbo->size()); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect); - blitter.bind(); - blitter.blit(fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft); - blitter.release(); - - if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) - context->functions()->glDisable(GL_BLEND); - } - - q->paintOverGL(); -} - -void QOpenGLWindowPrivate::bindFBO() -{ - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) - fbo->bind(); - else - QOpenGLFramebufferObject::bindDefault(); -} - -void QOpenGLWindowPrivate::flush(const QRegion ®ion) -{ - Q_UNUSED(region); - Q_Q(QOpenGLWindow); - context->swapBuffers(q); - emit q->frameSwapped(); -} - -void QOpenGLWindowPaintDevice::ensureActiveTarget() -{ - QOpenGLWindowPrivate::get(m_window)->bindFBO(); -} - -/*! - Constructs a new QOpenGLWindow with the given \a parent and \a updateBehavior. - - \sa QOpenGLWindow::UpdateBehavior - */ -QOpenGLWindow::QOpenGLWindow(QOpenGLWindow::UpdateBehavior updateBehavior, QWindow *parent) - : QPaintDeviceWindow(*(new QOpenGLWindowPrivate(nullptr, updateBehavior)), parent) -{ - setSurfaceType(QSurface::OpenGLSurface); -} - -/*! - Constructs a new QOpenGLWindow with the given \a parent and \a updateBehavior. The QOpenGLWindow's context will share with \a shareContext. - - \sa QOpenGLWindow::UpdateBehavior shareContext -*/ -QOpenGLWindow::QOpenGLWindow(QOpenGLContext *shareContext, UpdateBehavior updateBehavior, QWindow *parent) - : QPaintDeviceWindow(*(new QOpenGLWindowPrivate(shareContext, updateBehavior)), parent) -{ - setSurfaceType(QSurface::OpenGLSurface); -} - -/*! - Destroys the QOpenGLWindow instance, freeing its resources. - - The OpenGLWindow's context is made current in the destructor, allowing for - safe destruction of any child object that may need to release OpenGL - resources belonging to the context provided by this window. - - \warning if you have objects wrapping OpenGL resources (such as - QOpenGLBuffer, QOpenGLShaderProgram, etc.) as members of a QOpenGLWindow - subclass, you may need to add a call to makeCurrent() in that subclass' - destructor as well. Due to the rules of C++ object destruction, those objects - will be destroyed \e{before} calling this function (but after that the - destructor of the subclass has run), therefore making the OpenGL context - current in this function happens too late for their safe disposal. - - \sa makeCurrent - - \since 5.5 -*/ -QOpenGLWindow::~QOpenGLWindow() -{ - makeCurrent(); -} - -/*! - \return the update behavior for this QOpenGLWindow. -*/ -QOpenGLWindow::UpdateBehavior QOpenGLWindow::updateBehavior() const -{ - Q_D(const QOpenGLWindow); - return d->updateBehavior; -} - -/*! - \return \c true if the window's OpenGL resources, like the context, have - been successfully initialized. Note that the return value is always \c false - until the window becomes exposed (shown). -*/ -bool QOpenGLWindow::isValid() const -{ - Q_D(const QOpenGLWindow); - return d->context && d->context->isValid(); -} - -/*! - Prepares for rendering OpenGL content for this window by making the - corresponding context current and binding the framebuffer object, if there is - one, in that context context. - - It is not necessary to call this function in most cases, because it is called - automatically before invoking paintGL(). It is provided nonetheless to support - advanced, multi-threaded scenarios where a thread different than the GUI or main - thread may want to update the surface or framebuffer contents. See QOpenGLContext - for more information on threading related issues. - - This function is suitable for calling also when the underlying platform window - is already destroyed. This means that it is safe to call this function from - a QOpenGLWindow subclass' destructor. If there is no native window anymore, - an offscreen surface is used instead. This ensures that OpenGL resource - cleanup operations in the destructor will always work, as long as - this function is called first. - - \sa QOpenGLContext, context(), paintGL(), doneCurrent() - */ -void QOpenGLWindow::makeCurrent() -{ - Q_D(QOpenGLWindow); - - if (!isValid()) - return; - - // The platform window may be destroyed at this stage and therefore - // makeCurrent() may not safely be called with 'this'. - if (handle()) { - d->context->makeCurrent(this); - } else { - if (!d->offscreenSurface) { - d->offscreenSurface.reset(new QOffscreenSurface(screen())); - d->offscreenSurface->setFormat(d->context->format()); - d->offscreenSurface->create(); - } - d->context->makeCurrent(d->offscreenSurface.data()); - } - - d->bindFBO(); -} - -/*! - Releases the context. - - It is not necessary to call this function in most cases, since the widget - will make sure the context is bound and released properly when invoking - paintGL(). - - \sa makeCurrent() - */ -void QOpenGLWindow::doneCurrent() -{ - Q_D(QOpenGLWindow); - - if (!isValid()) - return; - - d->context->doneCurrent(); -} - -/*! - \return The QOpenGLContext used by this window or \c 0 if not yet initialized. - */ -QOpenGLContext *QOpenGLWindow::context() const -{ - Q_D(const QOpenGLWindow); - return d->context.data(); -} - -/*! - \return The QOpenGLContext requested to be shared with this window's QOpenGLContext. -*/ -QOpenGLContext *QOpenGLWindow::shareContext() const -{ - Q_D(const QOpenGLWindow); - return d->shareContext; -} - -/*! - The framebuffer object handle used by this window. - - When the update behavior is set to \c NoPartialUpdate, there is no separate - framebuffer object. In this case the returned value is the ID of the - default framebuffer. - - Otherwise the value of the ID of the framebuffer object or \c 0 if not - yet initialized. - */ -GLuint QOpenGLWindow::defaultFramebufferObject() const -{ - Q_D(const QOpenGLWindow); - if (d->updateBehavior > NoPartialUpdate && d->fbo) - return d->fbo->handle(); - else if (QOpenGLContext *ctx = QOpenGLContext::currentContext()) - return ctx->defaultFramebufferObject(); - else - return 0; -} - -extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); - -/*! - Returns a copy of the framebuffer. - - \note This is a potentially expensive operation because it relies on - glReadPixels() to read back the pixels. This may be slow and can stall the - GPU pipeline. - - \note When used together with update behavior \c NoPartialUpdate, the returned - image may not contain the desired content when called after the front and back - buffers have been swapped (unless preserved swap is enabled in the underlying - windowing system interface). In this mode the function reads from the back - buffer and the contents of that may not match the content on the screen (the - front buffer). In this case the only place where this function can safely be - used is paintGL() or paintOverGL(). - */ -QImage QOpenGLWindow::grabFramebuffer() -{ - if (!isValid()) - return QImage(); - - makeCurrent(); - - const bool hasAlpha = format().hasAlpha(); - QImage img = qt_gl_read_framebuffer(size() * devicePixelRatio(), hasAlpha, hasAlpha); - img.setDevicePixelRatio(devicePixelRatio()); - return img; -} - -/*! - This virtual function is called once before the first call to paintGL() or - resizeGL(). Reimplement it in a subclass. - - This function should set up any required OpenGL resources and state. - - There is no need to call makeCurrent() because this has already been done - when this function is called. Note however that the framebuffer, in case - partial update mode is used, is not yet available at this stage, so avoid - issuing draw calls from here. Defer such calls to paintGL() instead. - - \sa paintGL(), resizeGL() - */ -void QOpenGLWindow::initializeGL() -{ -} - -/*! - This virtual function is called whenever the widget has been resized. - Reimplement it in a subclass. The new size is passed in \a w and \a h. - - \note This is merely a convenience function in order to provide an API that is - compatible with QOpenGLWidget. Unlike with QOpenGLWidget, derived classes are - free to choose to override resizeEvent() instead of this function. - - \note Avoid issuing OpenGL commands from this function as there may not be a - context current when it is invoked. If it cannot be avoided, call makeCurrent(). - - \note Scheduling updates from here is not necessary. The windowing systems - will send expose events that trigger an update automatically. - - \sa initializeGL(), paintGL() - */ -void QOpenGLWindow::resizeGL(int w, int h) -{ - Q_UNUSED(w); - Q_UNUSED(h); -} - -/*! - This virtual function is called whenever the window contents needs to be - painted. Reimplement it in a subclass. - - There is no need to call makeCurrent() because this has already - been done when this function is called. - - Before invoking this function, the context and the framebuffer, if there is - one, are bound, and the viewport is set up by a call to glViewport(). No - other state is set and no clearing or drawing is performed by the framework. - - \note When using a partial update behavior, like \c PartialUpdateBlend, the - output of the previous paintGL() call is preserved and, after the additional - drawing perfomed in the current invocation of the function, the content is - blitted or blended over the content drawn directly to the window in - paintUnderGL(). - - \sa initializeGL(), resizeGL(), paintUnderGL(), paintOverGL(), UpdateBehavior - */ -void QOpenGLWindow::paintGL() -{ -} - -/*! - The virtual function is called before each invocation of paintGL(). - - When the update mode is set to \c NoPartialUpdate, there is no difference - between this function and paintGL(), performing rendering in either of them - leads to the same result. - - The difference becomes significant when using \c PartialUpdateBlend, where an - extra framebuffer object is used. There, paintGL() targets this additional - framebuffer object, which preserves its contents, while paintUnderGL() and - paintOverGL() target the default framebuffer, i.e. directly the window - surface, the contents of which is lost after each displayed frame. - - \note Avoid relying on this function when the update behavior is - \c PartialUpdateBlit. This mode involves blitting the extra framebuffer used by - paintGL() onto the default framebuffer after each invocation of paintGL(), - thus overwriting all drawing generated in this function. - - \sa paintGL(), paintOverGL(), UpdateBehavior - */ -void QOpenGLWindow::paintUnderGL() -{ -} - -/*! - This virtual function is called after each invocation of paintGL(). - - When the update mode is set to NoPartialUpdate, there is no difference - between this function and paintGL(), performing rendering in either of them - leads to the same result. - - Like paintUnderGL(), rendering in this function targets the default - framebuffer of the window, regardless of the update behavior. It gets called - after paintGL() has returned and the blit (PartialUpdateBlit) or quad drawing - (PartialUpdateBlend) has been done. - - \sa paintGL(), paintUnderGL(), UpdateBehavior - */ -void QOpenGLWindow::paintOverGL() -{ -} - -/*! - Paint \a event handler. Calls paintGL(). - - \sa paintGL() - */ -void QOpenGLWindow::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - paintGL(); -} - -/*! - Resize \a event handler. Calls resizeGL(). - - \sa resizeGL() - */ -void QOpenGLWindow::resizeEvent(QResizeEvent *event) -{ - Q_UNUSED(event); - Q_D(QOpenGLWindow); - d->initialize(); - resizeGL(width(), height()); -} - -/*! - \internal - */ -int QOpenGLWindow::metric(PaintDeviceMetric metric) const -{ - Q_D(const QOpenGLWindow); - - switch (metric) { - case PdmDepth: - if (d->paintDevice) - return d->paintDevice->depth(); - break; - default: - break; - } - return QPaintDeviceWindow::metric(metric); -} - -/*! - \internal - */ -QPaintDevice *QOpenGLWindow::redirected(QPoint *) const -{ - Q_D(const QOpenGLWindow); - if (QOpenGLContext::currentContext() == d->context.data()) - return d->paintDevice.data(); - return nullptr; -} - -QT_END_NAMESPACE diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp index 397c50f3dc..f6180be8a8 100644 --- a/src/gui/kernel/qpalette.cpp +++ b/src/gui/kernel/qpalette.cpp @@ -44,10 +44,28 @@ #include "qvariant.h" #include "qdebug.h" +#include <QtCore/qmetaobject.h> + QT_BEGIN_NAMESPACE static int qt_palette_count = 1; +static constexpr QPalette::ResolveMask colorRoleOffset(QPalette::ColorGroup colorGroup) +{ + return QPalette::NColorRoles * colorGroup; +} + +static constexpr QPalette::ResolveMask bitPosition(QPalette::ColorGroup colorGroup, + QPalette::ColorRole colorRole) +{ + return colorRole + colorRoleOffset(colorGroup); +} + +Q_STATIC_ASSERT_X(bitPosition(QPalette::ColorGroup(QPalette::NColorGroups - 1), + QPalette::ColorRole(QPalette::NColorRoles - 1)) + < sizeof(QPalette::ResolveMask) * CHAR_BIT, + "The resolve mask type is not wide enough to fit the entire bit mask."); + class QPalettePrivate { public: QPalettePrivate() : ref(1), ser_no(qt_palette_count++), detach_no(0) { } @@ -321,11 +339,8 @@ static void qt_palette_from_color(QPalette &pal, const QColor &button) Returns the placeholder text brush of the current color group. - \note Before Qt 5.12, the placeholder text color was hard-coded in the code as - QPalette::text().color() where an alpha of 128 was applied. - We continue to support this behavior by default, unless you set your own brush. - One can get back the original placeholder color setting the special QBrush default - constructor as placeholder brush. + \note Before Qt 5.12, the placeholder text color was hard-coded as QPalette::text().color() + with an alpha of 128 applied. In Qt 6, it is an independent color. \sa ColorRole, brush() */ @@ -538,8 +553,6 @@ static void qt_palette_from_color(QPalette &pal, const QColor &button) QPalette::QPalette() : d(nullptr) { - data.current_group = Active; - data.resolve_mask = 0; // Initialize to application palette if present, else default to black. // This makes it possible to instantiate QPalette outside QGuiApplication, // for example in the platform plugins. @@ -549,7 +562,7 @@ QPalette::QPalette() } else { init(); qt_palette_from_color(*this, Qt::black); - data.resolve_mask = 0; + data.resolveMask = 0; } } @@ -681,8 +694,6 @@ QPalette::~QPalette() /*!\internal*/ void QPalette::init() { d = new QPalettePrivate; - data.resolve_mask = 0; - data.current_group = Active; //as a default.. } /*! @@ -739,7 +750,7 @@ const QBrush &QPalette::brush(ColorGroup gr, ColorRole cr) const Q_ASSERT(cr < NColorRoles); if(gr >= (int)NColorGroups) { if(gr == Current) { - gr = (ColorGroup)data.current_group; + gr = data.currentGroup; } else { qWarning("QPalette::brush: Unknown ColorGroup: %d", (int)gr); gr = Active; @@ -777,38 +788,18 @@ void QPalette::setBrush(ColorGroup cg, ColorRole cr, const QBrush &b) } if (cg == Current) { - cg = ColorGroup(data.current_group); + cg = data.currentGroup; } else if (cg >= NColorGroups) { qWarning("QPalette::setBrush: Unknown ColorGroup: %d", cg); cg = Active; } - // For placeholder we want to continue to respect the original behavior, which is - // derivating the text color, but only if user has not yet set his own brush. - // We then use Qt::NoBrush as an inernal way to know if the brush is customized or not. - - // ### Qt 6 - remove this special case - // Part 1 - Restore initial color to the given color group - if (cr == PlaceholderText && b == QBrush()) { - QColor col = brush(Text).color(); - col.setAlpha(128); - setBrush(cg, PlaceholderText, QBrush(col, Qt::NoBrush)); - return; - } - if (d->br[cg][cr] != b) { detach(); d->br[cg][cr] = b; } - data.resolve_mask |= (1<<cr); - - // ### Qt 6 - remove this special case - // Part 2 - Update initial color to the given color group - if (cr == Text && d->br[cg][PlaceholderText].style() == Qt::NoBrush) { - QColor col = brush(Text).color(); - col.setAlpha(128); - setBrush(cg, PlaceholderText, QBrush(col, Qt::NoBrush)); - } + + data.resolveMask |= ResolveMask(1) << bitPosition(cg, cr); } /*! @@ -817,12 +808,30 @@ void QPalette::setBrush(ColorGroup cg, ColorRole cr, const QBrush &b) Returns \c true if the ColorGroup \a cg and ColorRole \a cr has been set previously on this palette; otherwise returns \c false. - \sa setBrush() + The ColorGroup \a cg should be less than QPalette::NColorGroups, + but you can use QPalette::Current. In this case, the previously + set current color group will be used. + + The ColorRole \a cr should be less than QPalette::NColorRoles. + + \sa setBrush(), currentColorGroup() */ bool QPalette::isBrushSet(ColorGroup cg, ColorRole cr) const { - Q_UNUSED(cg); - return (data.resolve_mask & (1<<cr)); + if (cg == Current) + cg = data.currentGroup; + + if (cg >= NColorGroups) { + qWarning() << "Wrong color group:" << cg; + return false; + } + + if (cr >= NColorRoles) { + qWarning() << "Wrong color role:" << cr; + return false; + } + + return data.resolveMask & (ResolveMask(1) << bitPosition(cg, cr)); } /*! @@ -887,7 +896,7 @@ bool QPalette::isEqual(QPalette::ColorGroup group1, QPalette::ColorGroup group2) { if(group1 >= (int)NColorGroups) { if(group1 == Current) { - group1 = (ColorGroup)data.current_group; + group1 = data.currentGroup; } else { qWarning("QPalette::brush: Unknown ColorGroup(1): %d", (int)group1); group1 = Active; @@ -895,7 +904,7 @@ bool QPalette::isEqual(QPalette::ColorGroup group1, QPalette::ColorGroup group2) } if(group2 >= (int)NColorGroups) { if(group2 == Current) { - group2 = (ColorGroup)data.current_group; + group2 = data.currentGroup; } else { qWarning("QPalette::brush: Unknown ColorGroup(2): %d", (int)group2); group2 = Active; @@ -946,21 +955,25 @@ qint64 QPalette::cacheKey() const */ QPalette QPalette::resolve(const QPalette &other) const { - if ((*this == other && data.resolve_mask == other.data.resolve_mask) - || data.resolve_mask == 0) { + if ((*this == other && data.resolveMask == other.data.resolveMask) + || data.resolveMask == 0) { QPalette o = other; - o.data.resolve_mask = data.resolve_mask; + o.data.resolveMask = data.resolveMask; return o; } QPalette palette(*this); palette.detach(); - for(int role = 0; role < (int)NColorRoles; role++) - if (!(data.resolve_mask & (1<<role))) - for(int grp = 0; grp < (int)NColorGroups; grp++) + for (int role = 0; role < int(NColorRoles); ++role) { + for (int grp = 0; grp < int(NColorGroups); ++grp) { + if (!(data.resolveMask & (ResolveMask(1) << bitPosition(ColorGroup(grp), ColorRole(role))))) { palette.d->br[grp][role] = other.d->br[grp][role]; - palette.data.resolve_mask |= other.data.resolve_mask; + } + } + } + + palette.data.resolveMask |= other.data.resolveMask; return palette; } @@ -971,7 +984,12 @@ QPalette QPalette::resolve(const QPalette &other) const */ /*! - \fn void QPalette::resolve(uint mask) + \typedef ResolveMaskType + \internal + */ + +/*! + \fn void QPalette::resolve(ResolveMaskType mask) \internal */ @@ -1105,10 +1123,15 @@ void QPalette::setColorGroup(ColorGroup cg, const QBrush &windowText, const QBru QBrush(Qt::blue), QBrush(Qt::magenta), QBrush(toolTipBase), QBrush(toolTipText)); - data.resolve_mask &= ~(1 << Highlight); - data.resolve_mask &= ~(1 << HighlightedText); - data.resolve_mask &= ~(1 << LinkVisited); - data.resolve_mask &= ~(1 << Link); + for (int cr = Highlight; cr <= LinkVisited; ++cr) { + if (cg == All) { + for (int group = Active; group < NColorGroups; ++group) { + data.resolveMask &= ~(ResolveMask(1) << bitPosition(ColorGroup(group), ColorRole(cr))); + } + } else { + data.resolveMask &= ~(ResolveMask(1) << bitPosition(ColorGroup(cg), ColorRole(cr))); + } + } } @@ -1177,6 +1200,8 @@ Q_GUI_EXPORT QPalette qt_fusionPalette() QColor button = backGround; QColor shadow = dark.darker(135); QColor disabledShadow = shadow.lighter(150); + QColor placeholder = text; + placeholder.setAlpha(128); QPalette fusionPalette(Qt::black,backGround,light,dark,mid,text,base); fusionPalette.setBrush(QPalette::Midlight, midLight); @@ -1194,40 +1219,65 @@ Q_GUI_EXPORT QPalette qt_fusionPalette() fusionPalette.setBrush(QPalette::Active, QPalette::Highlight, QColor(48, 140, 198)); fusionPalette.setBrush(QPalette::Inactive, QPalette::Highlight, QColor(48, 140, 198)); fusionPalette.setBrush(QPalette::Disabled, QPalette::Highlight, QColor(145, 145, 145)); + + fusionPalette.setBrush(QPalette::PlaceholderText, placeholder); + return fusionPalette; } #ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug dbg, const QPalette &p) +static QString groupsToString(const QPalette &p, QPalette::ColorRole cr) { - const char *colorGroupNames[] = {"Active", "Disabled", "Inactive"}; - const char *colorRoleNames[] = - {"WindowText", "Button", "Light", "Midlight", "Dark", "Mid", "Text", - "BrightText", "ButtonText", "Base", "Window", "Shadow", "Highlight", - "HighlightedText", "Link", "LinkVisited", "AlternateBase", "NoRole", - "ToolTipBase","ToolTipText", "PlaceholderText" }; - QDebugStateSaver saver(dbg); - QDebug nospace = dbg.nospace(); - const uint mask = p.resolve(); - nospace << "QPalette(resolve=" << Qt::hex << Qt::showbase << mask << ','; - for (int role = 0; role < (int)QPalette::NColorRoles; ++role) { - if (mask & (1<<role)) { - if (role) - nospace << ','; - nospace << colorRoleNames[role] << ":["; - for (int group = 0; group < (int)QPalette::NColorGroups; ++group) { - if (group) - nospace << ','; - const QRgb color = p.color(static_cast<QPalette::ColorGroup>(group), - static_cast<QPalette::ColorRole>(role)).rgba(); - nospace << colorGroupNames[group] << ':' << color; - } - nospace << ']'; + const auto groupEnum = QMetaEnum::fromType<QPalette::ColorGroup>(); + + QString groupString; + for (int group = 0; group < QPalette::NColorGroups; ++group) { + const auto cg = QPalette::ColorGroup(group); + + if (p.isBrushSet(cg, cr)) { + const auto &color = p.color(cg, cr); + groupString += QString::fromUtf8(groupEnum.valueToKey(cg)) + QLatin1Char(':') + + color.name(QColor::HexArgb) + QLatin1Char(','); } } - nospace << ')' << Qt::noshowbase << Qt::dec; - return dbg; + groupString.chop(1); + + return groupString; } + +static QString rolesToString(const QPalette &p) +{ + const auto roleEnum = QMetaEnum::fromType<QPalette::ColorRole>(); + + QString roleString; + for (int role = 0; role < QPalette::NColorRoles; ++role) { + const auto cr = QPalette::ColorRole(role); + + auto groupString = groupsToString(p, cr); + if (!groupString.isEmpty()) + roleString += QString::fromUtf8(roleEnum.valueToKey(cr)) + QStringLiteral(":[") + + groupString + QStringLiteral("],"); + } + roleString.chop(1); + + return roleString; +} + +QDebug operator<<(QDebug dbg, const QPalette &p) +{ + QDebugStateSaver saver(dbg); + dbg.nospace(); + + dbg << "QPalette(resolve=" << Qt::hex << Qt::showbase << p.resolve(); + + auto roleString = rolesToString(p); + if (!roleString.isEmpty()) + dbg << ',' << roleString; + + dbg << ')'; + + return dbg; + } #endif QT_END_NAMESPACE diff --git a/src/gui/kernel/qpalette.h b/src/gui/kernel/qpalette.h index d3a840d9ad..fd0ef2e2d9 100644 --- a/src/gui/kernel/qpalette.h +++ b/src/gui/kernel/qpalette.h @@ -72,14 +72,13 @@ public: { other.d = nullptr; } inline QPalette &operator=(QPalette &&other) noexcept { - for_faster_swapping_dont_use = other.for_faster_swapping_dont_use; - qSwap(d, other.d); return *this; + swap(other); return *this; } void swap(QPalette &other) noexcept { + qSwap(data, other.data); qSwap(d, other.d); - qSwap(for_faster_swapping_dont_use, other.for_faster_swapping_dont_use); } operator QVariant() const; @@ -103,8 +102,8 @@ public: }; Q_ENUM(ColorRole) - inline ColorGroup currentColorGroup() const { return static_cast<ColorGroup>(data.current_group); } - inline void setCurrentColorGroup(ColorGroup cg) { data.current_group = cg; } + inline ColorGroup currentColorGroup() const { return data.currentGroup; } + inline void setCurrentColorGroup(ColorGroup cg) { data.currentGroup = cg; } inline const QColor &color(ColorGroup cg, ColorRole cr) const { return brush(cg, cr).color(); } @@ -158,9 +157,11 @@ public: #endif qint64 cacheKey() const; - QPalette resolve(const QPalette &) const; - inline uint resolve() const { return data.resolve_mask; } - inline void resolve(uint mask) { data.resolve_mask = mask; } + QPalette resolve(const QPalette &other) const; + + using ResolveMask = quint64; + inline ResolveMask resolve() const { return data.resolveMask; } + inline void resolve(ResolveMask mask) { data.resolveMask = mask; } private: void setColorGroup(ColorGroup cr, const QBrush &windowText, const QBrush &button, @@ -185,13 +186,11 @@ private: QPalettePrivate *d; struct Data { - uint current_group : 4; - uint resolve_mask : 28; - }; - union { - Data data; - quint32 for_faster_swapping_dont_use; + ResolveMask resolveMask{0}; + ColorGroup currentGroup{Active}; }; + Data data; + friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &s, const QPalette &p); }; diff --git a/src/gui/kernel/qplatformcursor.cpp b/src/gui/kernel/qplatformcursor.cpp index 5a438a54a2..1330b5bf31 100644 --- a/src/gui/kernel/qplatformcursor.cpp +++ b/src/gui/kernel/qplatformcursor.cpp @@ -622,7 +622,7 @@ void QPlatformCursorImage::set(const uchar *data, const uchar *mask, int x = -1, w = 0; uchar *cursor_data = cursorImage.bits(); - int bpl = cursorImage.bytesPerLine(); + qsizetype bpl = cursorImage.bytesPerLine(); for (int i = 0; i < height; i++) { for (int j = 0; j < bytesPerLine; j++, data++, mask++) diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp index 33cd004234..443f5d2552 100644 --- a/src/gui/kernel/qplatformdialoghelper.cpp +++ b/src/gui/kernel/qplatformdialoghelper.cpp @@ -790,6 +790,7 @@ QStringList QPlatformFileDialogHelper::cleanFilterList(const QString &filter) f = match.captured(2); return f.split(QLatin1Char(' '), Qt::SkipEmptyParts); #else + Q_UNUSED(filter) return QStringList(); #endif } diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.h b/src/gui/kernel/qplatformgraphicsbufferhelper.h index bfe61713d4..36afd4877b 100644 --- a/src/gui/kernel/qplatformgraphicsbufferhelper.h +++ b/src/gui/kernel/qplatformgraphicsbufferhelper.h @@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE namespace QPlatformGraphicsBufferHelper { - bool lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB, bool *premultipliedB, const QRect &rect = QRect()); + Q_GUI_EXPORT bool lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB, bool *premultipliedB, const QRect &rect = QRect()); bool bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB = nullptr, bool *premultipliedB = nullptr, const QRect &rect = QRect()); } diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h index 28c29a704c..8e470aefd3 100644 --- a/src/gui/kernel/qplatformmenu.h +++ b/src/gui/kernel/qplatformmenu.h @@ -52,7 +52,9 @@ #include <QtGui/qtguiglobal.h> #include <QtCore/qpointer.h> #include <QtGui/QFont> -#include <QtGui/QKeySequence> +#if QT_CONFIG(shortcut) +# include <QtGui/QKeySequence> +#endif #include <QtGui/QIcon> QT_BEGIN_NAMESPACE @@ -85,7 +87,7 @@ public: virtual void setRole(MenuRole role) = 0; virtual void setCheckable(bool checkable) = 0; virtual void setChecked(bool isChecked) = 0; -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) virtual void setShortcut(const QKeySequence& shortcut) = 0; #endif virtual void setEnabled(bool enabled) = 0; diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp index 71521c0339..93fd59e53f 100644 --- a/src/gui/kernel/qplatformtheme.cpp +++ b/src/gui/kernel/qplatformtheme.cpp @@ -167,7 +167,7 @@ QT_BEGIN_NAMESPACE */ -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) // Table of key bindings. It must be sorted on key sequence: // The integer value of VK_KEY | Modifier Keys (e.g., VK_META, and etc.) // A priority of 1 indicates that this is the primary key binding when multiple are defined. @@ -623,7 +623,7 @@ static inline int maybeSwapShortcut(int shortcut) } #endif -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) // mixed-mode predicate: all of these overloads are actually needed (but not all for every compiler) struct ByStandardKey { typedef bool result_type; @@ -688,6 +688,7 @@ QString QPlatformTheme::standardButtonText(int button) const return QPlatformTheme::defaultStandardButtonText(button); } +#if QT_CONFIG(shortcut) /*! Returns the mnemonic that should be used for a standard \a button. @@ -700,6 +701,7 @@ QKeySequence QPlatformTheme::standardButtonShortcut(int button) const Q_UNUSED(button) return QKeySequence(); } +#endif // QT_CONFIG(shortcut) QString QPlatformTheme::defaultStandardButtonText(int button) { @@ -784,7 +786,7 @@ unsigned QPlatformThemePrivate::currentKeyPlatforms() { const uint keyboardScheme = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::KeyboardScheme).toInt(); unsigned result = 1u << keyboardScheme; -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) if (keyboardScheme == QPlatformTheme::KdeKeyboardScheme || keyboardScheme == QPlatformTheme::GnomeKeyboardScheme || keyboardScheme == QPlatformTheme::CdeKeyboardScheme) diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h index 3185fc4541..6ed612b785 100644 --- a/src/gui/kernel/qplatformtheme.h +++ b/src/gui/kernel/qplatformtheme.h @@ -51,7 +51,9 @@ #include <QtGui/qtguiglobal.h> #include <QtCore/QScopedPointer> -#include <QtGui/QKeySequence> +#if QT_CONFIG(shortcut) +# include <QtGui/QKeySequence> +#endif QT_BEGIN_NAMESPACE @@ -312,12 +314,14 @@ public: QPlatformTheme::IconOptions iconOptions = { }) const; virtual QIconEngine *createIconEngine(const QString &iconName) const; -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) virtual QList<QKeySequence> keyBindings(QKeySequence::StandardKey key) const; #endif virtual QString standardButtonText(int button) const; +#if QT_CONFIG(shortcut) virtual QKeySequence standardButtonShortcut(int button) const; +#endif static QVariant defaultThemeHint(ThemeHint hint); static QString defaultStandardButtonText(int button); diff --git a/src/gui/kernel/qplatformtheme_p.h b/src/gui/kernel/qplatformtheme_p.h index 73deb890bb..2c16fec141 100644 --- a/src/gui/kernel/qplatformtheme_p.h +++ b/src/gui/kernel/qplatformtheme_p.h @@ -52,7 +52,9 @@ // #include <QtGui/private/qtguiglobal_p.h> -#include "private/qkeysequence_p.h" +#if QT_CONFIG(shortcut) +# include "private/qkeysequence_p.h" +#endif QT_BEGIN_NAMESPACE @@ -67,7 +69,7 @@ public: void initializeSystemPalette(); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) static const QKeyBinding keyBindings[]; static const uint numberOfKeyBindings; #endif diff --git a/src/gui/kernel/qshortcut.cpp b/src/gui/kernel/qshortcut.cpp new file mode 100644 index 0000000000..c4305d5a7f --- /dev/null +++ b/src/gui/kernel/qshortcut.cpp @@ -0,0 +1,483 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qshortcut.h" +#include "qshortcut_p.h" + +#include <qevent.h> +#include <qguiapplication.h> +#include <qwindow.h> +#include <private/qguiapplication_p.h> +#include <qpa/qplatformmenu.h> + +QT_BEGIN_NAMESPACE + +#define QAPP_CHECK(functionName) \ + if (Q_UNLIKELY(!qApp)) { \ + qWarning("QShortcut: Initialize QGuiApplication before calling '" functionName "'."); \ + return; \ + } + +/*! + \class QShortcut + \brief The QShortcut class is used to create keyboard shortcuts. + + \ingroup events + \inmodule QtGui + + The QShortcut class provides a way of connecting keyboard + shortcuts to Qt's \l{signals and slots} mechanism, so that + objects can be informed when a shortcut is executed. The shortcut + can be set up to contain all the key presses necessary to + describe a keyboard shortcut, including the states of modifier + keys such as \uicontrol Shift, \uicontrol Ctrl, and \uicontrol Alt. + + \target mnemonic + + In widget applications, certain widgets can use '&' in front of a character. + This will automatically create a mnemonic (a shortcut) for that character, + e.g. "E&xit" will create the shortcut \uicontrol Alt+X (use '&&' + to display an actual ampersand). The widget might consume and perform + an action on a given shortcut. On X11 the ampersand will not be + shown and the character will be underlined. On Windows, shortcuts + are normally not displayed until the user presses the \uicontrol Alt + key, but this is a setting the user can change. On Mac, shortcuts + are disabled by default. Call \l qt_set_sequence_auto_mnemonic() to + enable them. However, because mnemonic shortcuts do not fit in + with Aqua's guidelines, Qt will not show the shortcut character + underlined. + + For applications that use menus, it may be more convenient to + use the convenience functions provided in the QMenu class to + assign keyboard shortcuts to menu items as they are created. + Alternatively, shortcuts may be associated with other types of + actions in the QAction class. + + The simplest way to create a shortcut for a particular widget is + to construct the shortcut with a key sequence. For example: + + \snippet code/src_gui_kernel_qshortcut.cpp 0 + + When the user types the \l{QKeySequence}{key sequence} + for a given shortcut, the shortcut's activated() signal is + emitted. (In the case of ambiguity, the activatedAmbiguously() + signal is emitted.) A shortcut is "listened for" by Qt's event + loop when the shortcut's parent widget is receiving events. + + A shortcut's key sequence can be set with setKey() and retrieved + with key(). A shortcut can be enabled or disabled with + setEnabled(), and can have "What's This?" help text set with + setWhatsThis(). + + \sa QShortcutEvent, QKeySequence, QAction +*/ + +/*! + \fn void QShortcut::activated() + + This signal is emitted when the user types the shortcut's key + sequence. + + \sa activatedAmbiguously() +*/ + +/*! + \fn void QShortcut::activatedAmbiguously() + + When a key sequence is being typed at the keyboard, it is said to + be ambiguous as long as it matches the start of more than one + shortcut. + + When a shortcut's key sequence is completed, + activatedAmbiguously() is emitted if the key sequence is still + ambiguous (i.e., it is the start of one or more other shortcuts). + The activated() signal is not emitted in this case. + + \sa activated() +*/ + +static bool simpleContextMatcher(QObject *object, Qt::ShortcutContext context) +{ + auto guiShortcut = qobject_cast<QShortcut *>(object); + if (QGuiApplication::applicationState() != Qt::ApplicationActive || guiShortcut == nullptr) + return false; + if (context == Qt::ApplicationShortcut) + return true; + auto focusWindow = QGuiApplication::focusWindow(); + if (!focusWindow) + return false; + auto window = qobject_cast<const QWindow *>(guiShortcut->parent()); + if (!window) + return false; + if (focusWindow == window && focusWindow->isTopLevel()) + return context == Qt::WindowShortcut || context == Qt::WidgetWithChildrenShortcut; + return focusWindow->isAncestorOf(window, QWindow::ExcludeTransients); +} + +QShortcutMap::ContextMatcher QShortcutPrivate::contextMatcher() const +{ + return simpleContextMatcher; +} + +void QShortcutPrivate::redoGrab(QShortcutMap &map) +{ + Q_Q(QShortcut); + if (Q_UNLIKELY(!parent)) { + qWarning("QShortcut: No window parent defined"); + return; + } + + if (sc_id) + map.removeShortcut(sc_id, q); + if (sc_sequence.isEmpty()) + return; + sc_id = map.addShortcut(q, sc_sequence, sc_context, contextMatcher()); + if (!sc_enabled) + map.setShortcutEnabled(false, sc_id, q); + if (!sc_autorepeat) + map.setShortcutAutoRepeat(false, sc_id, q); +} + +QShortcutPrivate *QGuiApplicationPrivate::createShortcutPrivate() const +{ + return new QShortcutPrivate; +} + +/*! + Constructs a QShortcut object for the \a parent, which should be a + QWindow or a QWidget. + + Since no shortcut key sequence is specified, the shortcut will not emit any + signals. + + \sa setKey() +*/ +QShortcut::QShortcut(QObject *parent) + : QObject(*QGuiApplicationPrivate::instance()->createShortcutPrivate(), parent) +{ + Q_ASSERT(parent != nullptr); +} + +/*! + Constructs a QShortcut object for the \a parent, which should be a + QWindow or a QWidget. + + The shortcut operates on its parent, listening for \l{QShortcutEvent}s that + match the \a key sequence. Depending on the ambiguity of the event, the + shortcut will call the \a member function, or the \a ambiguousMember function, + if the key press was in the shortcut's \a context. +*/ +QShortcut::QShortcut(const QKeySequence &key, QObject *parent, + const char *member, const char *ambiguousMember, + Qt::ShortcutContext context) + : QShortcut(parent) +{ + Q_D(QShortcut); + d->sc_context = context; + d->sc_sequence = key; + d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap); + if (member) + connect(this, SIGNAL(activated()), parent, member); + if (ambiguousMember) + connect(this, SIGNAL(activatedAmbiguously()), parent, ambiguousMember); +} + + +/*! + \fn template<typename Functor> + QShortcut(const QKeySequence &key, QObject *parent, + Functor functor, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + \since 5.15 + \overload + + This is a QShortcut convenience constructor which connects the shortcut's + \l{QShortcut::activated()}{activated()} signal to the \a functor. +*/ +/*! + \fn template<typename Functor> + QShortcut(const QKeySequence &key, QObject *parent, + const QObject *context, Functor functor, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + \since 5.15 + \overload + + This is a QShortcut convenience constructor which connects the shortcut's + \l{QShortcut::activated()}{activated()} signal to the \a functor. + + The \a functor can be a pointer to a member function of the \a context object. + + If the \a context object is destroyed, the \a functor will not be called. +*/ +/*! + \fn template<typename Functor, typename FunctorAmbiguous> + QShortcut(const QKeySequence &key, QObject *parent, + const QObject *context1, Functor functor, + FunctorAmbiguous functorAmbiguous, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + \since 5.15 + \overload + + This is a QShortcut convenience constructor which connects the shortcut's + \l{QShortcut::activated()}{activated()} signal to the \a functor and + \l{QShortcut::activatedAmbiguously()}{activatedAmbiguously()} + signal to the \a FunctorAmbiguous. + + The \a functor and \a FunctorAmbiguous can be a pointer to a member + function of the \a context object. + + If the \a context object is destroyed, the \a functor and + \a FunctorAmbiguous will not be called. +*/ +/*! + \fn template<typename Functor, typename FunctorAmbiguous> + QShortcut(const QKeySequence &key, QObject *parent, + const QObject *context1, Functor functor, + const QObject *context2, FunctorAmbiguous functorAmbiguous, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + \since 5.15 + \overload + + This is a QShortcut convenience constructor which connects the shortcut's + \l{QShortcut::activated()}{activated()} signal to the \a functor and + \l{QShortcut::activatedAmbiguously()}{activatedAmbiguously()} + signal to the \a FunctorAmbiguous. + + The \a functor can be a pointer to a member function of the + \a context1 object. + The \a FunctorAmbiguous can be a pointer to a member function of the + \a context2 object. + + If the \a context1 object is destroyed, the \a functor will not be called. + If the \a context2 object is destroyed, the \a FunctorAmbiguous + will not be called. +*/ + +/*! + Destroys the shortcut. +*/ +QShortcut::~QShortcut() +{ + Q_D(QShortcut); + if (qApp) + QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(d->sc_id, this); +} + +/*! + \property QShortcut::key + \brief the shortcut's key sequence + + This is a key sequence with an optional combination of Shift, Ctrl, + and Alt. The key sequence may be supplied in a number of ways: + + \snippet code/src_gui_kernel_qshortcut.cpp 1 + + By default, this property contains an empty key sequence. +*/ +void QShortcut::setKey(const QKeySequence &key) +{ + Q_D(QShortcut); + if (d->sc_sequence == key) + return; + QAPP_CHECK("setKey"); + d->sc_sequence = key; + d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap); +} + +QKeySequence QShortcut::key() const +{ + Q_D(const QShortcut); + return d->sc_sequence; +} + +/*! + \property QShortcut::enabled + \brief whether the shortcut is enabled + + An enabled shortcut emits the activated() or activatedAmbiguously() + signal when a QShortcutEvent occurs that matches the shortcut's + key() sequence. + + If the application is in \c WhatsThis mode the shortcut will not emit + the signals, but will show the "What's This?" text instead. + + By default, this property is \c true. + + \sa whatsThis +*/ +void QShortcut::setEnabled(bool enable) +{ + Q_D(QShortcut); + if (d->sc_enabled == enable) + return; + QAPP_CHECK("setEnabled"); + d->sc_enabled = enable; + QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(enable, d->sc_id, this); +} + +bool QShortcut::isEnabled() const +{ + Q_D(const QShortcut); + return d->sc_enabled; +} + +/*! + \property QShortcut::context + \brief the context in which the shortcut is valid + + A shortcut's context decides in which circumstances a shortcut is + allowed to be triggered. The normal context is Qt::WindowShortcut, + which allows the shortcut to trigger if the parent (the widget + containing the shortcut) is a subwidget of the active top-level + window. + + By default, this property is set to Qt::WindowShortcut. +*/ +void QShortcut::setContext(Qt::ShortcutContext context) +{ + Q_D(QShortcut); + if (d->sc_context == context) + return; + QAPP_CHECK("setContext"); + d->sc_context = context; + d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap); +} + +Qt::ShortcutContext QShortcut::context() const +{ + Q_D(const QShortcut); + return d->sc_context; +} + +/*! + \property QShortcut::autoRepeat + \brief whether the shortcut can auto repeat + + If true, the shortcut will auto repeat when the keyboard shortcut + combination is held down, provided that keyboard auto repeat is + enabled on the system. + The default value is true. +*/ +void QShortcut::setAutoRepeat(bool on) +{ + Q_D(QShortcut); + if (d->sc_autorepeat == on) + return; + QAPP_CHECK("setAutoRepeat"); + d->sc_autorepeat = on; + QGuiApplicationPrivate::instance()->shortcutMap.setShortcutAutoRepeat(on, d->sc_id, this); +} + +bool QShortcut::autoRepeat() const +{ + Q_D(const QShortcut); + return d->sc_autorepeat; +} + + +/*! + \property QShortcut::whatsThis + \brief the shortcut's "What's This?" help text + + The text will be shown when a widget application is in "What's + This?" mode and the user types the shortcut key() sequence. + + To set "What's This?" help on a menu item (with or without a + shortcut key), set the help on the item's action. + + By default, this property contains an empty string. + + This property has no effect in applications that don't use + widgets. + + \sa QWhatsThis::inWhatsThisMode(), QAction::setWhatsThis() +*/ +void QShortcut::setWhatsThis(const QString &text) +{ + Q_D(QShortcut); + d->sc_whatsthis = text; +} + +QString QShortcut::whatsThis() const +{ + Q_D(const QShortcut); + return d->sc_whatsthis; +} + + +/*! + Returns the shortcut's ID. + + \sa QShortcutEvent::shortcutId() +*/ +int QShortcut::id() const +{ + Q_D(const QShortcut); + return d->sc_id; +} + +/*! + \fn QWidget *QShortcut::parentWidget() const + + Returns the shortcut's parent widget. +*/ + +/*! + \internal +*/ +bool QShortcut::event(QEvent *e) +{ + Q_D(QShortcut); + if (d->sc_enabled && e->type() == QEvent::Shortcut) { + auto se = static_cast<QShortcutEvent *>(e); + if (se->shortcutId() == d->sc_id && se->key() == d->sc_sequence + && !d->handleWhatsThis()) { + if (se->isAmbiguous()) + emit activatedAmbiguously(); + else + emit activated(); + return true; + } + } + return QObject::event(e); +} + +QT_END_NAMESPACE + +#include "moc_qshortcut.cpp" diff --git a/src/gui/kernel/qshortcut.h b/src/gui/kernel/qshortcut.h new file mode 100644 index 0000000000..1b90a21925 --- /dev/null +++ b/src/gui/kernel/qshortcut.h @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSHORTCUT_H +#define QSHORTCUT_H + +#include <QtGui/qtguiglobal.h> +#include <QtGui/qkeysequence.h> +#include <QtCore/qobject.h> + +QT_REQUIRE_CONFIG(shortcut); + +QT_BEGIN_NAMESPACE + +class QShortcutPrivate; +class QWindow; + +class Q_GUI_EXPORT QShortcut : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QShortcut) + Q_PROPERTY(QKeySequence key READ key WRITE setKey) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) + Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat) + Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext) +public: + explicit QShortcut(QObject *parent); + explicit QShortcut(const QKeySequence& key, QObject *parent, + const char *member = nullptr, const char *ambiguousMember = nullptr, + Qt::ShortcutContext context = Qt::WindowShortcut); + +#ifdef Q_CLANG_QDOC + template<typename Functor> + QShortcut(const QKeySequence &key, QObject *parent, + Functor functor, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + template<typename Functor> + QShortcut(const QKeySequence &key, QObject *parent, + const QObject *context, Functor functor, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + template<typename Functor, typename FunctorAmbiguous> + QShortcut(const QKeySequence &key, QObject *parent, + const QObject *context1, Functor functor, + FunctorAmbiguous functorAmbiguous, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); + template<typename Functor, typename FunctorAmbiguous> + QShortcut(const QKeySequence &key, QObject *parent, + const QObject *context1, Functor functor, + const QObject *context2, FunctorAmbiguous functorAmbiguous, + Qt::ShortcutContext shortcutContext = Qt::WindowShortcut); +#else + template<typename Func1> + QShortcut(const QKeySequence &key, QObject *parent, + Func1 slot1, + Qt::ShortcutContext context = Qt::WindowShortcut) + : QShortcut(key, parent, static_cast<const char*>(nullptr), static_cast<const char*>(nullptr), context) + { + connect(this, &QShortcut::activated, std::move(slot1)); + } + template<class Obj1, typename Func1> + QShortcut(const QKeySequence &key, QObject *parent, + const Obj1 *object1, Func1 slot1, + Qt::ShortcutContext context = Qt::WindowShortcut, + typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<Obj1*>::Value>::type* = 0) + : QShortcut(key, parent, static_cast<const char*>(nullptr), static_cast<const char*>(nullptr), context) + { + connect(this, &QShortcut::activated, object1, std::move(slot1)); + } + template<class Obj1, typename Func1, typename Func2> + QShortcut(const QKeySequence &key, QObject *parent, + const Obj1 *object1, Func1 slot1, Func2 slot2, + Qt::ShortcutContext context = Qt::WindowShortcut, + typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<Obj1*>::Value>::type* = 0) + : QShortcut(key, parent, static_cast<const char*>(nullptr), static_cast<const char*>(nullptr), context) + { + connect(this, &QShortcut::activated, object1, std::move(slot1)); + connect(this, &QShortcut::activatedAmbiguously, object1, std::move(slot2)); + } + template<class Obj1, typename Func1, class Obj2, typename Func2> + QShortcut(const QKeySequence &key, QObject *parent, + const Obj1 *object1, Func1 slot1, + const Obj2 *object2, Func2 slot2, + Qt::ShortcutContext context = Qt::WindowShortcut, + typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<Obj1*>::Value>::type* = 0, + typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<Obj2*>::Value>::type* = 0) + : QShortcut(key, parent, static_cast<const char*>(nullptr), static_cast<const char*>(nullptr), context) + { + connect(this, &QShortcut::activated, object1, std::move(slot1)); + connect(this, &QShortcut::activatedAmbiguously, object2, std::move(slot2)); + } +#endif + + ~QShortcut(); + + void setKey(const QKeySequence& key); + QKeySequence key() const; + + void setEnabled(bool enable); + bool isEnabled() const; + + void setContext(Qt::ShortcutContext context); + Qt::ShortcutContext context() const; + + void setAutoRepeat(bool on); + bool autoRepeat() const; + + int id() const; + + void setWhatsThis(const QString &text); + QString whatsThis() const; + +#if QT_DEPRECATED_SINCE(6,0) +#ifdef Q_CLANG_QDOC + QWidget *parentWidget() const; +#else + template<typename T = QWidget*> + inline T parentWidget() const + { return static_cast<T>(QObject::parent()); } +#endif +#endif + +Q_SIGNALS: + void activated(); + void activatedAmbiguously(); + +protected: + bool event(QEvent *e) override; +}; + +QT_END_NAMESPACE + +#endif // QSHORTCUT_H diff --git a/src/gui/kernel/qshortcut_p.h b/src/gui/kernel/qshortcut_p.h new file mode 100644 index 0000000000..254745960f --- /dev/null +++ b/src/gui/kernel/qshortcut_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSHORTCUT_P_H +#define QSHORTCUT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/private/qtguiglobal_p.h> +#include "qshortcut.h" +#include <QtGui/qkeysequence.h> + +#include <QtCore/qstring.h> +#include <QtCore/private/qobject_p.h> + +#include <private/qshortcutmap_p.h> + + + +QT_BEGIN_NAMESPACE + +class QShortcutMap; + +/* + \internal + Private data accessed through d-pointer. +*/ +class Q_GUI_EXPORT QShortcutPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QShortcut) +public: + QShortcutPrivate() = default; + + virtual QShortcutMap::ContextMatcher contextMatcher() const; + virtual bool handleWhatsThis() { return false; } + + QKeySequence sc_sequence; + QString sc_whatsthis; + Qt::ShortcutContext sc_context = Qt::WindowShortcut; + bool sc_enabled = true; + bool sc_autorepeat = true; + int sc_id = 0; + void redoGrab(QShortcutMap &map); +}; + +QT_END_NAMESPACE + +#endif // QSHORTCUT_P_H diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp index a7ea20266b..6039101cf4 100644 --- a/src/gui/kernel/qshortcutmap.cpp +++ b/src/gui/kernel/qshortcutmap.cpp @@ -49,8 +49,6 @@ #include <algorithm> -#ifndef QT_NO_SHORTCUT - QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcShortcutMap, "qt.gui.shortcutmap") @@ -689,5 +687,3 @@ void QShortcutMap::dumpMap() const #endif QT_END_NAMESPACE - -#endif // QT_NO_SHORTCUT diff --git a/src/gui/kernel/qshortcutmap_p.h b/src/gui/kernel/qshortcutmap_p.h index 8fc68229fb..aa3dd969f0 100644 --- a/src/gui/kernel/qshortcutmap_p.h +++ b/src/gui/kernel/qshortcutmap_p.h @@ -56,9 +56,9 @@ #include "QtCore/qvector.h" #include "QtCore/qscopedpointer.h" -QT_BEGIN_NAMESPACE +QT_REQUIRE_CONFIG(shortcut); -#ifndef QT_NO_SHORTCUT +QT_BEGIN_NAMESPACE // To enable dump output uncomment below //#define Dump_QShortcutMap @@ -106,8 +106,6 @@ private: QScopedPointer<QShortcutMapPrivate> d_ptr; }; -#endif // QT_NO_SHORTCUT - QT_END_NAMESPACE #endif // QSHORTCUTMAP_P_H diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h index 7aae7ffffa..de6d7ffd31 100644 --- a/src/gui/kernel/qwindow.h +++ b/src/gui/kernel/qwindow.h @@ -119,11 +119,11 @@ class Q_GUI_EXPORT QWindow : public QObject, public QSurface Q_PROPERTY(int maximumWidth READ maximumWidth WRITE setMaximumWidth NOTIFY maximumWidthChanged) Q_PROPERTY(int maximumHeight READ maximumHeight WRITE setMaximumHeight NOTIFY maximumHeightChanged) Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged) - Q_PROPERTY(bool active READ isActive NOTIFY activeChanged REVISION 1) - Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged REVISION 1) + Q_PROPERTY(bool active READ isActive NOTIFY activeChanged REVISION(2, 1)) + Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged REVISION(2, 1)) Q_PROPERTY(Qt::ScreenOrientation contentOrientation READ contentOrientation WRITE reportContentOrientationChange NOTIFY contentOrientationChanged) - Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged REVISION 1) - Q_PRIVATE_PROPERTY(QWindow::d_func(), QWindow* transientParent MEMBER transientParent WRITE setTransientParent NOTIFY transientParentChanged REVISION 13) + Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged REVISION(2, 1)) + Q_PRIVATE_PROPERTY(QWindow::d_func(), QWindow* transientParent MEMBER transientParent WRITE setTransientParent NOTIFY transientParentChanged REVISION(2, 13)) public: enum Visibility { @@ -277,7 +277,7 @@ public: #endif public Q_SLOTS: - Q_REVISION(1) void requestActivate(); + Q_REVISION(2, 1) void requestActivate(); void setVisible(bool visible); @@ -309,15 +309,15 @@ public Q_SLOTS: void setMaximumWidth(int w); void setMaximumHeight(int h); - Q_REVISION(1) void alert(int msec); + Q_REVISION(2, 1) void alert(int msec); - Q_REVISION(3) void requestUpdate(); + Q_REVISION(2 ,3) void requestUpdate(); Q_SIGNALS: void screenChanged(QScreen *screen); void modalityChanged(Qt::WindowModality modality); void windowStateChanged(Qt::WindowState windowState); - Q_REVISION(2) void windowTitleChanged(const QString &title); + Q_REVISION(2, 2) void windowTitleChanged(const QString &title); void xChanged(int arg); void yChanged(int arg); @@ -331,15 +331,15 @@ Q_SIGNALS: void maximumHeightChanged(int arg); void visibleChanged(bool arg); - Q_REVISION(1) void visibilityChanged(QWindow::Visibility visibility); - Q_REVISION(1) void activeChanged(); + Q_REVISION(2, 1) void visibilityChanged(QWindow::Visibility visibility); + Q_REVISION(2, 1) void activeChanged(); void contentOrientationChanged(Qt::ScreenOrientation orientation); void focusObjectChanged(QObject *object); - Q_REVISION(1) void opacityChanged(qreal opacity); + Q_REVISION(2, 1) void opacityChanged(qreal opacity); - Q_REVISION(13) void transientParentChanged(QWindow *transientParent); + Q_REVISION(2, 13) void transientParentChanged(QWindow *transientParent); protected: virtual void exposeEvent(QExposeEvent *); diff --git a/src/gui/kernel/qwindowdefs.h b/src/gui/kernel/qwindowdefs.h index b4f3ed4712..5d4955c436 100644 --- a/src/gui/kernel/qwindowdefs.h +++ b/src/gui/kernel/qwindowdefs.h @@ -43,6 +43,7 @@ #include <QtGui/qtguiglobal.h> #include <QtCore/qobjectdefs.h> #include <QtCore/qnamespace.h> +#include <QtCore/qcontainerfwd.h> QT_BEGIN_NAMESPACE @@ -67,7 +68,6 @@ class QFontMetrics; class QFontInfo; class QPen; class QBrush; -class QMatrix; class QPixmap; class QBitmap; class QMovie; @@ -80,7 +80,6 @@ class QString; class QByteArray; class QApplication; -template<typename T> class QList; typedef QList<QWidget *> QWidgetList; typedef QList<QWindow *> QWindowList; diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index aefb377683..e8f0892b95 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -449,7 +449,7 @@ bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, ulong t bool QWindowSystemInterface::handleShortcutEvent(QWindow *window, ulong timestamp, int keyCode, Qt::KeyboardModifiers modifiers, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, const QString &text, bool autorepeat, ushort count) { -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) if (!window) window = QGuiApplication::focusWindow(); @@ -1256,7 +1256,7 @@ Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *window, QEvent::Type t, int k, Qt:: Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1) { -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) // FIXME: This method should not allow targeting a specific object, but should // instead forward the event to a window, which then takes care of normal event |