diff options
Diffstat (limited to 'src/widgets/widgets/qtoolbutton.cpp')
-rw-r--r-- | src/widgets/widgets/qtoolbutton.cpp | 127 |
1 files changed, 55 insertions, 72 deletions
diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp index ee58797d3c..e0775afd26 100644 --- a/src/widgets/widgets/qtoolbutton.cpp +++ b/src/widgets/widgets/qtoolbutton.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWidgets 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qtoolbutton.h" @@ -67,20 +31,22 @@ QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + class QToolButtonPrivate : public QAbstractButtonPrivate { Q_DECLARE_PUBLIC(QToolButton) public: void init(); #if QT_CONFIG(menu) - void _q_buttonPressed(); - void _q_buttonReleased(); + void onButtonPressed(); + void onButtonReleased(); void popupTimerDone(); - void _q_updateButtonDown(); - void _q_menuTriggered(QAction *); + void updateButtonDown(); + void onMenuTriggered(QAction *); #endif bool updateHoverControl(const QPoint &pos); - void _q_actionTriggered(); + void onActionTriggered(); QStyle::SubControl newHoverControl(const QPoint &pos); QStyle::SubControl hoverControl; QRect hoverRect; @@ -169,8 +135,7 @@ bool QToolButtonPrivate::hasMenu() const with actions used in other parts of the main window. \endtable - \sa QPushButton, QToolBar, QMainWindow, QAction, - {fowler}{GUI Design Handbook: Push Button} + \sa QPushButton, QToolBar, QMainWindow, QAction */ /*! @@ -222,8 +187,10 @@ void QToolButtonPrivate::init() QSizePolicy::ToolButton)); #if QT_CONFIG(menu) - QObject::connect(q, SIGNAL(pressed()), q, SLOT(_q_buttonPressed())); - QObject::connect(q, SIGNAL(released()), q, SLOT(_q_buttonReleased())); + QObjectPrivate::connect(q, &QAbstractButton::pressed, + this, &QToolButtonPrivate::onButtonPressed); + QObjectPrivate::connect(q, &QAbstractButton::released, + this, &QToolButtonPrivate::onButtonReleased); #endif setLayoutItemMargins(QStyle::SE_ToolButtonLayoutItem); @@ -348,7 +315,7 @@ QSize QToolButton::sizeHint() const if (opt.toolButtonStyle != Qt::ToolButtonIconOnly) { QSize textSize = fm.size(Qt::TextShowMnemonic, text()); - textSize.setWidth(textSize.width() + fm.horizontalAdvance(QLatin1Char(' '))*2); + textSize.setWidth(textSize.width() + fm.horizontalAdvance(u' ') * 2); if (opt.toolButtonStyle == Qt::ToolButtonTextUnderIcon) { h += 4 + textSize.height(); if (textSize.width() > w) @@ -470,7 +437,8 @@ void QToolButton::actionEvent(QActionEvent *event) setDefaultAction(action); // update button state break; case QEvent::ActionAdded: - connect(action, SIGNAL(triggered()), this, SLOT(_q_actionTriggered())); + QObjectPrivate::connect(action, &QAction::triggered, d, + &QToolButtonPrivate::onActionTriggered); break; case QEvent::ActionRemoved: if (d->defaultAction == action) @@ -515,7 +483,7 @@ bool QToolButtonPrivate::updateHoverControl(const QPoint &pos) return !doesHover; } -void QToolButtonPrivate::_q_actionTriggered() +void QToolButtonPrivate::onActionTriggered() { Q_Q(QToolButton); if (QAction *action = qobject_cast<QAction *>(q->sender())) @@ -616,8 +584,10 @@ void QToolButton::mousePressEvent(QMouseEvent *e) void QToolButton::mouseReleaseEvent(QMouseEvent *e) { Q_D(QToolButton); + QPointer<QAbstractButton> guard(this); QAbstractButton::mouseReleaseEvent(e); - d->buttonPressed = QToolButtonPrivate::NoButtonPressed; + if (guard) + d->buttonPressed = QToolButtonPrivate::NoButtonPressed; } /*! @@ -702,7 +672,7 @@ void QToolButton::showMenu() d->popupTimerDone(); } -void QToolButtonPrivate::_q_buttonPressed() +void QToolButtonPrivate::onButtonPressed() { Q_Q(QToolButton); if (!hasMenu()) @@ -715,7 +685,7 @@ void QToolButtonPrivate::_q_buttonPressed() q->showMenu(); } -void QToolButtonPrivate::_q_buttonReleased() +void QToolButtonPrivate::onButtonReleased() { popupTimer.stop(); } @@ -725,7 +695,7 @@ static QPoint positionMenu(const QToolButton *q, bool horizontal, { QPoint p; const QRect rect = q->rect(); // Find screen via point in case of QGraphicsProxyWidget. - const QRect screen = QWidgetPrivate::availableScreenGeometry(q); + const QRect screen = QWidgetPrivate::availableScreenGeometry(q, q->mapToGlobal(rect.center())); if (horizontal) { if (q->isRightToLeft()) { if (q->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.bottom()) { @@ -757,8 +727,13 @@ static QPoint positionMenu(const QToolButton *q, bool horizontal, } } } + + // QTBUG-118695 Force point inside the current screen. If the returned point + // is not found inside any screen, QMenu's positioning logic kicks in without + // taking the QToolButton's screen into account. This can cause the menu to + // end up on primary monitor, even if the QToolButton is on a non-primary monitor. p.rx() = qMax(screen.left(), qMin(p.x(), screen.right() - sh.width())); - p.ry() += 1; + p.ry() = qMax(screen.top(), qMin(p.y() + 1, screen.bottom())); return p; } @@ -792,9 +767,12 @@ void QToolButtonPrivate::popupTimerDone() #endif QPointer<QToolButton> that = q; actualMenu->setNoReplayFor(q); - if (!mustDeleteActualMenu) //only if action are not in this widget - QObject::connect(actualMenu, SIGNAL(triggered(QAction*)), q, SLOT(_q_menuTriggered(QAction*))); - QObject::connect(actualMenu, SIGNAL(aboutToHide()), q, SLOT(_q_updateButtonDown())); + if (!mustDeleteActualMenu) { //only if action are not in this widget + QObjectPrivate::connect(actualMenu, &QMenu::triggered, + this, &QToolButtonPrivate::onMenuTriggered); + } + QObjectPrivate::connect(actualMenu, &QMenu::aboutToHide, + this, &QToolButtonPrivate::updateButtonDown); actualMenu->d_func()->causedPopup.widget = q; actualMenu->d_func()->causedPopup.action = defaultAction; actionsCopy = q->actions(); //(the list of action may be modified in slots) @@ -808,11 +786,14 @@ void QToolButtonPrivate::popupTimerDone() if (!that) return; - QObject::disconnect(actualMenu, SIGNAL(aboutToHide()), q, SLOT(_q_updateButtonDown())); - if (mustDeleteActualMenu) + QObjectPrivate::disconnect(actualMenu, &QMenu::aboutToHide, + this, &QToolButtonPrivate::updateButtonDown); + if (mustDeleteActualMenu) { delete actualMenu; - else - QObject::disconnect(actualMenu, SIGNAL(triggered(QAction*)), q, SLOT(_q_menuTriggered(QAction*))); + } else { + QObjectPrivate::disconnect(actualMenu, &QMenu::triggered, + this, &QToolButtonPrivate::onMenuTriggered); + } actionsCopy.clear(); @@ -820,7 +801,7 @@ void QToolButtonPrivate::popupTimerDone() q->setAutoRepeat(true); } -void QToolButtonPrivate::_q_updateButtonDown() +void QToolButtonPrivate::updateButtonDown() { Q_Q(QToolButton); menuButtonDown = false; @@ -830,7 +811,7 @@ void QToolButtonPrivate::_q_updateButtonDown() q->repaint(); } -void QToolButtonPrivate::_q_menuTriggered(QAction *action) +void QToolButtonPrivate::onMenuTriggered(QAction *action) { Q_Q(QToolButton); if (action && !actionsCopy.contains(action)) @@ -940,7 +921,7 @@ void QToolButton::setDefaultAction(QAction *action) // If iconText() is generated from text(), we need to escape any '&'s so they // don't turn into shortcuts if (QActionPrivate::get(action)->iconText.isEmpty()) - buttonText.replace(QLatin1String("&"), QLatin1String("&&")); + buttonText.replace("&"_L1, "&&"_L1); setText(buttonText); setIcon(action->icon()); #if QT_CONFIG(tooltip) @@ -961,12 +942,6 @@ void QToolButton::setDefaultAction(QAction *action) } #endif setCheckable(action->isCheckable()); - if (action->isCheckable()) { - connect(this, &QAbstractButton::toggled, this, [this](bool checked) { - if (defaultAction()) - defaultAction()->setChecked(checked); - }, Qt::UniqueConnection); - } setChecked(action->isChecked()); setEnabled(action->isEnabled()); if (action->d_func()->fontSet) @@ -985,7 +960,15 @@ QAction *QToolButton::defaultAction() const return d->defaultAction; } - +/*! + \reimp + */ +void QToolButton::checkStateSet() +{ + Q_D(QToolButton); + if (d->defaultAction && d->defaultAction->isCheckable()) + d->defaultAction->setChecked(isChecked()); +} /*! \reimp |