diff options
Diffstat (limited to 'src/widgets/graphicsview/qgraphicswidget.cpp')
-rw-r--r-- | src/widgets/graphicsview/qgraphicswidget.cpp | 199 |
1 files changed, 76 insertions, 123 deletions
diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp index cf041b9817..3679723bc4 100644 --- a/src/widgets/graphicsview/qgraphicswidget.cpp +++ b/src/widgets/graphicsview/qgraphicswidget.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) 2021 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 "qglobal.h" @@ -55,16 +19,20 @@ #include <private/qshortcutmap_p.h> #endif #include <QtCore/qmutex.h> +#include <QtCore/QScopeGuard> #include <QtWidgets/qapplication.h> #include <QtWidgets/qgraphicsview.h> #include <QtWidgets/qgraphicsproxywidget.h> #include <QtGui/qpalette.h> +#include <QtGui/qpainterpath.h> #include <QtWidgets/qstyleoption.h> #include <qdebug.h> QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + /*! \class QGraphicsWidget \brief The QGraphicsWidget class is the base class for all widget @@ -172,7 +140,7 @@ QT_BEGIN_NAMESPACE window, a tool, a popup, etc). */ QGraphicsWidget::QGraphicsWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags) - : QGraphicsObject(*new QGraphicsWidgetPrivate, 0), QGraphicsLayoutItem(0, false) + : QGraphicsObject(*new QGraphicsWidgetPrivate, nullptr), QGraphicsLayoutItem(nullptr, false) { Q_D(QGraphicsWidget); d->init(parent, wFlags); @@ -184,7 +152,7 @@ QGraphicsWidget::QGraphicsWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags) Constructs a new QGraphicsWidget, using \a dd as parent. */ QGraphicsWidget::QGraphicsWidget(QGraphicsWidgetPrivate &dd, QGraphicsItem *parent, Qt::WindowFlags wFlags) - : QGraphicsObject(dd, 0), QGraphicsLayoutItem(0, false) + : QGraphicsObject(dd, nullptr), QGraphicsLayoutItem(nullptr, false) { Q_D(QGraphicsWidget); d->init(parent, wFlags); @@ -231,9 +199,9 @@ QGraphicsWidget::~QGraphicsWidget() Q_D(QGraphicsWidget); #ifndef QT_NO_ACTION // Remove all actions from this widget - for (int i = 0; i < d->actions.size(); ++i) { - QActionPrivate *apriv = d->actions.at(i)->d_func(); - apriv->graphicsWidgets.removeAll(this); + for (auto action : std::as_const(d->actions)) { + QActionPrivate *apriv = action->d_func(); + apriv->associatedObjects.removeAll(this); } d->actions.clear(); #endif @@ -241,7 +209,7 @@ QGraphicsWidget::~QGraphicsWidget() if (QGraphicsScene *scn = scene()) { QGraphicsScenePrivate *sceneD = scn->d_func(); if (sceneD->tabFocusFirst == this) - sceneD->tabFocusFirst = (d->focusNext == this ? 0 : d->focusNext); + sceneD->tabFocusFirst = (d->focusNext == this ? nullptr : d->focusNext); } d->focusPrev->d_func()->focusNext = d->focusNext; d->focusNext->d_func()->focusPrev = d->focusPrev; @@ -263,15 +231,15 @@ QGraphicsWidget::~QGraphicsWidget() if (item->isWidget()) { QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item); if (widget->parentLayoutItem() == d->layout) - widget->setParentLayoutItem(0); + widget->setParentLayoutItem(nullptr); } } - d->layout = 0; + d->layout = nullptr; delete temp; } // Remove this graphics widget from widgetStyles - widgetStyles()->setStyleForWidget(this, 0); + widgetStyles()->setStyleForWidget(this, nullptr); // Unset the parent here, when we're still a QGraphicsWidget. // It is otherwise done in ~QGraphicsItem() where we'd be @@ -351,6 +319,19 @@ void QGraphicsWidget::resize(const QSizeF &size) void QGraphicsWidget::setGeometry(const QRectF &rect) { QGraphicsWidgetPrivate *wd = QGraphicsWidget::d_func(); + // Package relayout of children in a scope guard so we can just return early + // when this widget's geometry is sorted out. + const auto relayoutChildren = qScopeGuard([this, wd]() { + if (QGraphicsLayout::instantInvalidatePropagation()) { + if (QGraphicsLayout *lay = wd->layout) { + if (!lay->isActivated()) { + QEvent layoutRequest(QEvent::LayoutRequest); + QCoreApplication::sendEvent(this, &layoutRequest); + } + } + } + }); + QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr.data(); QRectF newGeom; QPointF oldPos = d->geom.topLeft(); @@ -360,9 +341,8 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize)) .boundedTo(effectiveSizeHint(Qt::MaximumSize))); - if (newGeom == d->geom) { - goto relayoutChildrenAndReturn; - } + if (newGeom == d->geom) + return; // setPos triggers ItemPositionChange, which can adjust position wd->inSetGeometry = 1; @@ -370,67 +350,48 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) wd->inSetGeometry = 0; newGeom.moveTopLeft(pos()); - if (newGeom == d->geom) { - goto relayoutChildrenAndReturn; - } + if (newGeom == d->geom) + return; - // Update and prepare to change the geometry (remove from index) if the size has changed. - if (wd->scene) { - if (rect.topLeft() == d->geom.topLeft()) { - prepareGeometryChange(); - } - } + // Update and prepare to change the geometry (remove from index) if + // the size has changed. + if (wd->scene && rect.topLeft() == d->geom.topLeft()) + prepareGeometryChange(); } // Update the layout item geometry - { - bool moved = oldPos != pos(); - if (moved) { - // Send move event. - QGraphicsSceneMoveEvent event; - event.setOldPos(oldPos); - event.setNewPos(pos()); - QCoreApplication::sendEvent(this, &event); - if (wd->inSetPos) { - //set the new pos - d->geom.moveTopLeft(pos()); - emit geometryChanged(); - goto relayoutChildrenAndReturn; - } + if (oldPos != pos()) { + // Send move event. + QGraphicsSceneMoveEvent event; + event.setOldPos(oldPos); + event.setNewPos(pos()); + QCoreApplication::sendEvent(this, &event); + if (wd->inSetPos) { + // Set the new position: + d->geom.moveTopLeft(pos()); + emit geometryChanged(); + return; } - QSizeF oldSize = size(); - QGraphicsLayoutItem::setGeometry(newGeom); - // Send resize event - bool resized = newGeom.size() != oldSize; - if (resized) { + } + + QSizeF oldSize = size(); + QGraphicsLayoutItem::setGeometry(newGeom); + // Send resize event, if appropriate: + if (newGeom.size() != oldSize) { + if (oldSize.width() != newGeom.size().width()) + emit widthChanged(); + if (oldSize.height() != newGeom.size().height()) + emit heightChanged(); + QGraphicsLayout *lay = wd->layout; + if (!QGraphicsLayout::instantInvalidatePropagation() || !lay || lay->isActivated()) { QGraphicsSceneResizeEvent re; re.setOldSize(oldSize); re.setNewSize(newGeom.size()); - if (oldSize.width() != newGeom.size().width()) - emit widthChanged(); - if (oldSize.height() != newGeom.size().height()) - emit heightChanged(); - QGraphicsLayout *lay = wd->layout; - if (QGraphicsLayout::instantInvalidatePropagation()) { - if (!lay || lay->isActivated()) { - QCoreApplication::sendEvent(this, &re); - } - } else { - QCoreApplication::sendEvent(this, &re); - } + QCoreApplication::sendEvent(this, &re); } } emit geometryChanged(); -relayoutChildrenAndReturn: - if (QGraphicsLayout::instantInvalidatePropagation()) { - if (QGraphicsLayout *lay = wd->layout) { - if (!lay->isActivated()) { - QEvent layoutRequest(QEvent::LayoutRequest); - QCoreApplication::sendEvent(this, &layoutRequest); - } - } - } } /*! @@ -615,7 +576,7 @@ void QGraphicsWidget::unsetWindowFrameMargins() QStyleOptionTitleBar bar; d->initStyleOptionTitleBar(&bar); QStyle *style = this->style(); - qreal margin = style->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth); + const qreal margin = style->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, &bar); qreal titleBarHeight = d->titleBarHeight(bar); setWindowFrameMargins(margin, titleBarHeight, margin, margin); } else { @@ -942,7 +903,7 @@ QStyle *QGraphicsWidget::style() const */ void QGraphicsWidget::setStyle(QStyle *style) { - setAttribute(Qt::WA_SetStyle, style != 0); + setAttribute(Qt::WA_SetStyle, style != nullptr); widgetStyles()->setStyleForWidget(this, style); // Deliver StyleChange to the widget itself (doesn't propagate). @@ -976,13 +937,13 @@ QFont QGraphicsWidget::font() const { Q_D(const QGraphicsWidget); QFont fnt = d->font; - fnt.resolve(fnt.resolve() | d->inheritedFontResolveMask); + fnt.setResolveMask(fnt.resolveMask() | d->inheritedFontResolveMask); return fnt; } void QGraphicsWidget::setFont(const QFont &font) { Q_D(QGraphicsWidget); - setAttribute(Qt::WA_SetFont, font.resolve() != 0); + setAttribute(Qt::WA_SetFont, font.resolveMask() != 0); QFont naturalFont = d->naturalWidgetFont(); QFont resolvedFont = font.resolve(naturalFont); @@ -1022,7 +983,7 @@ QPalette QGraphicsWidget::palette() const void QGraphicsWidget::setPalette(const QPalette &palette) { Q_D(QGraphicsWidget); - setAttribute(Qt::WA_SetPalette, palette.resolve() != 0); + setAttribute(Qt::WA_SetPalette, palette.resolveMask() != 0); QPalette naturalPalette = d->naturalWidgetPalette(); QPalette resolvedPalette = palette.resolve(naturalPalette); @@ -1557,7 +1518,7 @@ bool QGraphicsWidget::focusNextPrevChild(bool next) { Q_D(QGraphicsWidget); // Let the parent's focusNextPrevChild implementation decide what to do. - QGraphicsWidget *parent = 0; + QGraphicsWidget *parent = nullptr; if (!isWindow() && (parent = parentWidget())) return parent->focusNextPrevChild(next); if (!d->scene) @@ -1995,7 +1956,7 @@ void QGraphicsWidget::setShortcutAutoRepeat(int id, bool enabled) */ void QGraphicsWidget::addAction(QAction *action) { - insertAction(0, action); + insertAction(nullptr, action); } /*! @@ -2005,14 +1966,10 @@ void QGraphicsWidget::addAction(QAction *action) \sa removeAction(), QMenu, addAction(), QWidget::addActions() */ -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) void QGraphicsWidget::addActions(const QList<QAction *> &actions) -#else -void QGraphicsWidget::addActions(QList<QAction *> actions) -#endif { - for (int i = 0; i < actions.count(); ++i) - insertAction(0, actions.at(i)); + for (int i = 0; i < actions.size(); ++i) + insertAction(nullptr, actions.at(i)); } /*! @@ -2041,14 +1998,14 @@ void QGraphicsWidget::insertAction(QAction *before, QAction *action) int pos = d->actions.indexOf(before); if (pos < 0) { - before = 0; + before = nullptr; pos = d->actions.size(); } d->actions.insert(pos, action); if (index == -1) { QActionPrivate *apriv = action->d_func(); - apriv->graphicsWidgets.append(this); + apriv->associatedObjects.append(this); } QActionEvent e(QEvent::ActionAdded, action, before); @@ -2066,13 +2023,9 @@ void QGraphicsWidget::insertAction(QAction *before, QAction *action) \sa removeAction(), QMenu, insertAction(), QWidget::insertActions() */ -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) void QGraphicsWidget::insertActions(QAction *before, const QList<QAction *> &actions) -#else -void QGraphicsWidget::insertActions(QAction *before, QList<QAction *> actions) -#endif { - for (int i = 0; i < actions.count(); ++i) + for (int i = 0; i < actions.size(); ++i) insertAction(before, actions.at(i)); } @@ -2091,7 +2044,7 @@ void QGraphicsWidget::removeAction(QAction *action) Q_D(QGraphicsWidget); QActionPrivate *apriv = action->d_func(); - apriv->graphicsWidgets.removeAll(this); + apriv->associatedObjects.removeAll(this); if (d->actions.removeAll(action)) { QActionEvent e(QEvent::ActionRemoved, action); @@ -2150,7 +2103,7 @@ void QGraphicsWidget::setTabOrder(QGraphicsWidget *first, QGraphicsWidget *secon return; } QGraphicsScene *scene = first ? first->scene() : second->scene(); - if (!scene && (!first || !second)) { + if (!scene) { qWarning("QGraphicsWidget::setTabOrder: assigning tab order from/to the" " scene requires the item to be in a scene."); return; @@ -2346,7 +2299,7 @@ void QGraphicsWidget::paintWindowFrame(QPainter *painter, const QStyleOptionGrap frameOptions.palette.setCurrentColorGroup(isActive ? QPalette::Active : QPalette::Normal); frameOptions.rect = windowFrameRect; - frameOptions.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, widget); + frameOptions.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, nullptr, widget); frameOptions.midLineWidth = 1; style()->drawPrimitive(QStyle::PE_FrameWindow, &frameOptions, painter, widget); @@ -2414,7 +2367,7 @@ void QGraphicsWidget::dumpFocusChain() qWarning("Found a focus chain that is not circular, (next == 0)"); break; } - qDebug() << i++ << QString::number(uint(next), 16) << next->className() << next->data(0) << QString::fromLatin1("focusItem:%1").arg(next->hasFocus() ? '1' : '0') << QLatin1String("next:") << next->d_func()->focusNext->data(0) << QLatin1String("prev:") << next->d_func()->focusPrev->data(0); + qDebug() << i++ << QString::number(uint(next), 16) << next->className() << next->data(0) << QString::fromLatin1("focusItem:%1").arg(next->hasFocus() ? '1' : '0') << "next:"_L1 << next->d_func()->focusNext->data(0) << "prev:"_L1 << next->d_func()->focusPrev->data(0); if (visited.contains(next)) { qWarning("Already visited this node. However, I expected to dump until I found myself."); break; |