diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2020-04-19 19:56:18 +0200 |
---|---|---|
committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2020-09-03 07:00:31 +0200 |
commit | 25351dcc549f1daddf5e2ae8a242191174342a3e (patch) | |
tree | 97436200219470e7eee4096038e4da6e8df06835 /examples/widgets | |
parent | f03b2f7711e3a0e90fb21672273959a2a9ed1c38 (diff) |
Long live QKeyCombination!
C++20 via P1120 is deprecating arithmetic operations between
unrelated enumeration types, and GCC 10 is already complaining.
Hence, these operations might become illegal in C++23 or C++26 at
the latest.
A case of this that affects Qt is in key combinations: a
QKeySequence can be constructed by summing / ORing modifiers and a
key, for instance:
Qt::CTRL + Qt::Key_A
Qt::SHIFT | Qt::CTRL | Qt::Key_G (recommended, see below)
The problem is that the modifiers and the key belong to different
enumerations (and there's 2 enumerations for the modifier, and one
for the key).
To solve this: add a dedicated class to represent a combination of
keys, and operators between those enumerations to build instances
of this class.
I would've simply defined operator|, but again docs and pre-existing
code use operator+ as well, so added both to at least tackle simple
cases (modifier + key).
Multiple modifiers create a problem: operator+ between them yields
int, not the corresponding flags type (because operator+ is not
overloaded for this use case):
Qt::CTRL + Qt::SHIFT + Qt::Key_A
\__________________/ /
int /
\______________/
int
Not only this loses track of the datatypes involved, but it would
also then "add" the key (with NO warnings, now its int + enum, so
it's not mixing enums!) and yielding int again.
I don't want to special-case this; the point of the class is
that int is the wrong datatype. Everything works just fine when
using operator| instead:
Qt::CTRL | Qt::SHIFT | Qt::Key_A
\__________________/ /
Qt::Modifiers /
\______________/
QKeyCombination
So I'm defining operator+ so that the simple cases still work,
but also deprecating it.
Port some code around Qt to the new class. In certain cases,
it's a huge win for clarity. In some others, I've just added
the necessary casts to make it still compile without warnings,
without attempting refactorings.
[ChangeLog][QtCore][QKeyCombination] New class to represent
a combination of a key and zero or more modifiers, to be used
when defining shortcuts or similar.
[ChangeLog][Potentially Source-Incompatible Changes] A keyboard
modifier (such as Qt::CTRL, Qt::AltModifier, etc.) should be
combined with a key (such as Qt::Key_A, Qt::Key_F1, etc.) by using
operator|, not operator+. The result is now an object of type
QKeyCombination, that stores the key and the modifiers.
Change-Id: I657a3a328232f059023fff69c5031ee31cc91dd6
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'examples/widgets')
-rw-r--r-- | examples/widgets/desktop/screenshot/screenshot.cpp | 2 | ||||
-rw-r--r-- | examples/widgets/itemviews/storageview/main.cpp | 2 | ||||
-rw-r--r-- | examples/widgets/richtext/textedit/textedit.cpp | 24 |
3 files changed, 14 insertions, 14 deletions
diff --git a/examples/widgets/desktop/screenshot/screenshot.cpp b/examples/widgets/desktop/screenshot/screenshot.cpp index af344db1d2..522b1123b5 100644 --- a/examples/widgets/desktop/screenshot/screenshot.cpp +++ b/examples/widgets/desktop/screenshot/screenshot.cpp @@ -90,7 +90,7 @@ Screenshot::Screenshot() connect(saveScreenshotButton, &QPushButton::clicked, this, &Screenshot::saveScreenshot); buttonsLayout->addWidget(saveScreenshotButton); QPushButton *quitScreenshotButton = new QPushButton(tr("Quit"), this); - quitScreenshotButton->setShortcut(Qt::CTRL + Qt::Key_Q); + quitScreenshotButton->setShortcut(Qt::CTRL | Qt::Key_Q); connect(quitScreenshotButton, &QPushButton::clicked, this, &QWidget::close); buttonsLayout->addWidget(quitScreenshotButton); buttonsLayout->addStretch(); diff --git a/examples/widgets/itemviews/storageview/main.cpp b/examples/widgets/itemviews/storageview/main.cpp index 8f23a4820a..fe916b039d 100644 --- a/examples/widgets/itemviews/storageview/main.cpp +++ b/examples/widgets/itemviews/storageview/main.cpp @@ -66,7 +66,7 @@ int main(int argc, char *argv[]) StorageModel *model = new StorageModel(&view); model->refresh(); - QShortcut *refreshShortcut = new QShortcut(Qt::CTRL + Qt::Key_R, &view); + QShortcut *refreshShortcut = new QShortcut(Qt::CTRL | Qt::Key_R, &view); QObject::connect(refreshShortcut, &QShortcut::activated, model, &StorageModel::refresh); view.setModel(model); diff --git a/examples/widgets/richtext/textedit/textedit.cpp b/examples/widgets/richtext/textedit/textedit.cpp index 9504c8769d..74b8e1c2b4 100644 --- a/examples/widgets/richtext/textedit/textedit.cpp +++ b/examples/widgets/richtext/textedit/textedit.cpp @@ -209,14 +209,14 @@ void TextEdit::setupFileActions() const QIcon exportPdfIcon = QIcon::fromTheme("exportpdf", QIcon(rsrcPath + "/exportpdf.png")); a = menu->addAction(exportPdfIcon, tr("&Export PDF..."), this, &TextEdit::filePrintPdf); a->setPriority(QAction::LowPriority); - a->setShortcut(Qt::CTRL + Qt::Key_D); + a->setShortcut(Qt::CTRL | Qt::Key_D); tb->addAction(a); menu->addSeparator(); #endif a = menu->addAction(tr("&Quit"), this, &QWidget::close); - a->setShortcut(Qt::CTRL + Qt::Key_Q); + a->setShortcut(Qt::CTRL | Qt::Key_Q); } void TextEdit::setupEditActions() @@ -266,7 +266,7 @@ void TextEdit::setupTextActions() const QIcon boldIcon = QIcon::fromTheme("format-text-bold", QIcon(rsrcPath + "/textbold.png")); actionTextBold = menu->addAction(boldIcon, tr("&Bold"), this, &TextEdit::textBold); - actionTextBold->setShortcut(Qt::CTRL + Qt::Key_B); + actionTextBold->setShortcut(Qt::CTRL | Qt::Key_B); actionTextBold->setPriority(QAction::LowPriority); QFont bold; bold.setBold(true); @@ -277,7 +277,7 @@ void TextEdit::setupTextActions() const QIcon italicIcon = QIcon::fromTheme("format-text-italic", QIcon(rsrcPath + "/textitalic.png")); actionTextItalic = menu->addAction(italicIcon, tr("&Italic"), this, &TextEdit::textItalic); actionTextItalic->setPriority(QAction::LowPriority); - actionTextItalic->setShortcut(Qt::CTRL + Qt::Key_I); + actionTextItalic->setShortcut(Qt::CTRL | Qt::Key_I); QFont italic; italic.setItalic(true); actionTextItalic->setFont(italic); @@ -286,7 +286,7 @@ void TextEdit::setupTextActions() const QIcon underlineIcon = QIcon::fromTheme("format-text-underline", QIcon(rsrcPath + "/textunder.png")); actionTextUnderline = menu->addAction(underlineIcon, tr("&Underline"), this, &TextEdit::textUnderline); - actionTextUnderline->setShortcut(Qt::CTRL + Qt::Key_U); + actionTextUnderline->setShortcut(Qt::CTRL | Qt::Key_U); actionTextUnderline->setPriority(QAction::LowPriority); QFont underline; underline.setUnderline(true); @@ -298,31 +298,31 @@ void TextEdit::setupTextActions() const QIcon leftIcon = QIcon::fromTheme("format-justify-left", QIcon(rsrcPath + "/textleft.png")); actionAlignLeft = new QAction(leftIcon, tr("&Left"), this); - actionAlignLeft->setShortcut(Qt::CTRL + Qt::Key_L); + actionAlignLeft->setShortcut(Qt::CTRL | Qt::Key_L); actionAlignLeft->setCheckable(true); actionAlignLeft->setPriority(QAction::LowPriority); const QIcon centerIcon = QIcon::fromTheme("format-justify-center", QIcon(rsrcPath + "/textcenter.png")); actionAlignCenter = new QAction(centerIcon, tr("C&enter"), this); - actionAlignCenter->setShortcut(Qt::CTRL + Qt::Key_E); + actionAlignCenter->setShortcut(Qt::CTRL | Qt::Key_E); actionAlignCenter->setCheckable(true); actionAlignCenter->setPriority(QAction::LowPriority); const QIcon rightIcon = QIcon::fromTheme("format-justify-right", QIcon(rsrcPath + "/textright.png")); actionAlignRight = new QAction(rightIcon, tr("&Right"), this); - actionAlignRight->setShortcut(Qt::CTRL + Qt::Key_R); + actionAlignRight->setShortcut(Qt::CTRL | Qt::Key_R); actionAlignRight->setCheckable(true); actionAlignRight->setPriority(QAction::LowPriority); const QIcon fillIcon = QIcon::fromTheme("format-justify-fill", QIcon(rsrcPath + "/textjustify.png")); actionAlignJustify = new QAction(fillIcon, tr("&Justify"), this); - actionAlignJustify->setShortcut(Qt::CTRL + Qt::Key_J); + actionAlignJustify->setShortcut(Qt::CTRL | Qt::Key_J); actionAlignJustify->setCheckable(true); actionAlignJustify->setPriority(QAction::LowPriority); const QIcon indentMoreIcon = QIcon::fromTheme("format-indent-more", QIcon(rsrcPath + "/format-indent-more.png")); actionIndentMore = menu->addAction(indentMoreIcon, tr("&Indent"), this, &TextEdit::indent); - actionIndentMore->setShortcut(Qt::CTRL + Qt::Key_BracketRight); + actionIndentMore->setShortcut(Qt::CTRL | Qt::Key_BracketRight); actionIndentMore->setPriority(QAction::LowPriority); const QIcon indentLessIcon = QIcon::fromTheme("format-indent-less", QIcon(rsrcPath + "/format-indent-less.png")); actionIndentLess = menu->addAction(indentLessIcon, tr("&Unindent"), this, &TextEdit::unindent); - actionIndentLess->setShortcut(Qt::CTRL + Qt::Key_BracketLeft); + actionIndentLess->setShortcut(Qt::CTRL | Qt::Key_BracketLeft); actionIndentLess->setPriority(QAction::LowPriority); // Make sure the alignLeft is always left of the alignRight @@ -358,7 +358,7 @@ void TextEdit::setupTextActions() const QIcon checkboxIcon = QIcon::fromTheme("status-checkbox-checked", QIcon(rsrcPath + "/checkbox-checked.png")); actionToggleCheckState = menu->addAction(checkboxIcon, tr("Chec&ked"), this, &TextEdit::setChecked); - actionToggleCheckState->setShortcut(Qt::CTRL + Qt::Key_K); + actionToggleCheckState->setShortcut(Qt::CTRL | Qt::Key_K); actionToggleCheckState->setCheckable(true); actionToggleCheckState->setPriority(QAction::LowPriority); tb->addAction(actionToggleCheckState); |