diff options
Diffstat (limited to 'src/widgets/widgets/qmainwindowlayout_p.h')
-rw-r--r-- | src/widgets/widgets/qmainwindowlayout_p.h | 181 |
1 files changed, 104 insertions, 77 deletions
diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h index 72cbec2350..55a27e4849 100644 --- a/src/widgets/widgets/qmainwindowlayout_p.h +++ b/src/widgets/widgets/qmainwindowlayout_p.h @@ -1,44 +1,8 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef QDYNAMICMAINWINDOWLAYOUT_P_H -#define QDYNAMICMAINWINDOWLAYOUT_P_H +// 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 + +#ifndef QMAINWINDOWLAYOUT_P_H +#define QMAINWINDOWLAYOUT_P_H // // W A R N I N G @@ -60,23 +24,36 @@ #include "QtGui/qpainter.h" #include "QtGui/qevent.h" #endif -#include "QtCore/qvector.h" -#include "QtCore/qset.h" #include "QtCore/qbasictimer.h" +#include "QtCore/qlist.h" +#include "QtCore/qset.h" #include "private/qlayoutengine_p.h" #include "private/qwidgetanimator_p.h" - #if QT_CONFIG(dockwidget) +#include "private/qdockwidget_p.h" + #include "qdockarealayout_p.h" +#include "qdockwidget.h" +#else +struct QDockWidgetPrivate { + enum class DragScope { + Group + }; +}; #endif #if QT_CONFIG(toolbar) #include "qtoolbararealayout_p.h" #endif +#include <QtCore/qloggingcategory.h> +#include <QtCore/qpointer.h> + QT_REQUIRE_CONFIG(mainwindow); QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcQpaDockWidgets); + class QToolBar; class QRubberBand; @@ -88,6 +65,10 @@ class QMainWindowLayoutSeparatorHelper QWidget *window() { return layout()->parentWidget(); } public: + Q_DISABLE_COPY_MOVE(QMainWindowLayoutSeparatorHelper) + + QMainWindowLayoutSeparatorHelper() = default; + QList<int> hoverSeparator; QPoint hoverPos; @@ -122,7 +103,7 @@ template <typename Layout> QCursor QMainWindowLayoutSeparatorHelper<Layout>::separatorCursor(const QList<int> &path) { const QDockAreaLayoutInfo *info = layout()->dockAreaLayoutInfo()->info(path); - Q_ASSERT(info != 0); + Q_ASSERT(info != nullptr); if (path.size() == 1) { // is this the "top-level" separator which separates a dock area // from the central widget? switch (path.first()) { @@ -206,7 +187,7 @@ bool QMainWindowLayoutSeparatorHelper<Layout>::windowEvent(QEvent *event) #if QT_CONFIG(cursor) case QEvent::HoverMove: { - adjustCursor(static_cast<QHoverEvent *>(event)->pos()); + adjustCursor(static_cast<QHoverEvent *>(event)->position().toPoint()); break; } @@ -224,7 +205,7 @@ bool QMainWindowLayoutSeparatorHelper<Layout>::windowEvent(QEvent *event) case QEvent::MouseButtonPress: { QMouseEvent *e = static_cast<QMouseEvent *>(event); - if (e->button() == Qt::LeftButton && startSeparatorMove(e->pos())) { + if (e->button() == Qt::LeftButton && startSeparatorMove(e->position().toPoint())) { // The click was on a separator, eat this event e->accept(); return true; @@ -236,10 +217,10 @@ bool QMainWindowLayoutSeparatorHelper<Layout>::windowEvent(QEvent *event) QMouseEvent *e = static_cast<QMouseEvent *>(event); #if QT_CONFIG(cursor) - adjustCursor(e->pos()); + adjustCursor(e->position().toPoint()); #endif if (e->buttons() & Qt::LeftButton) { - if (separatorMove(e->pos())) { + if (separatorMove(e->position().toPoint())) { // We're moving a separator, eat this event e->accept(); return true; @@ -251,7 +232,7 @@ bool QMainWindowLayoutSeparatorHelper<Layout>::windowEvent(QEvent *event) case QEvent::MouseButtonRelease: { QMouseEvent *e = static_cast<QMouseEvent *>(event); - if (endSeparatorMove(e->pos())) { + if (endSeparatorMove(e->position().toPoint())) { // We've released a separator, eat this event e->accept(); return true; @@ -330,16 +311,21 @@ bool QMainWindowLayoutSeparatorHelper<Layout>::endSeparatorMove(const QPoint &) return true; } -class QDockWidgetGroupWindow : public QWidget +class Q_AUTOTEST_EXPORT QDockWidgetGroupWindow : public QWidget { Q_OBJECT public: - explicit QDockWidgetGroupWindow(QWidget* parent = 0, Qt::WindowFlags f = 0) - : QWidget(parent, f) {} + explicit QDockWidgetGroupWindow(QWidget *parent = nullptr, Qt::WindowFlags f = {}) + : QWidget(parent, f) + { + } QDockAreaLayoutInfo *layoutInfo() const; +#if QT_CONFIG(tabbar) const QDockAreaLayoutInfo *tabLayoutInfo() const; QDockWidget *activeTabbedDockWidget() const; +#endif void destroyOrHideIfEmpty(); + bool hasVisibleDockWidgets() const; void adjustFlags(); bool hasNativeDecos() const; @@ -347,6 +333,10 @@ public: void updateCurrentGapRect(); void restore(); void apply(); + void childEvent(QChildEvent *event) override; + void reparent(QDockWidget *dockWidget); + void destroyIfSingleItemLeft(); + QList<QDockWidget *> dockWidgets() const { return findChildren<QDockWidget *>(); } QRect currentGapRect; QList<int> currentGapPos; @@ -356,6 +346,7 @@ signals: protected: bool event(QEvent *) override; + bool eventFilter(QObject *obj, QEvent *event) override; void paintEvent(QPaintEvent*) override; private: @@ -363,14 +354,35 @@ private: }; // This item will be used in the layout for the gap item. We cannot use QWidgetItem directly -// because QWidgetItem functions return an empty size for widgets that are are floating. +// because QWidgetItem functions return an empty size for widgets that are floating. class QDockWidgetGroupWindowItem : public QWidgetItem { public: explicit QDockWidgetGroupWindowItem(QDockWidgetGroupWindow *parent) : QWidgetItem(parent) {} - QSize minimumSize() const override { return lay()->minimumSize(); } - QSize maximumSize() const override { return lay()->maximumSize(); } - QSize sizeHint() const override { return lay()->sizeHint(); } + + // when the item contains a dock widget, obtain its size (to prevent infinite loop) + // ask the layout otherwise + QSize minimumSize() const override + { + if (auto dw = widget()->findChild<QDockWidget *>()) + return dw->minimumSize(); + return lay()->minimumSize(); + } + QSize maximumSize() const override + { + auto dw = widget()->findChild<QDockWidget *>(); + if (dw) + return dw->maximumSize(); + return lay()->maximumSize(); + } + QSize sizeHint() const override + { + auto dw = widget()->findChild<QDockWidget *>(); + if (dw) + return dw->sizeHint(); + return lay()->sizeHint(); + } + QWidget* widget() const override { return wid; } private: QLayout *lay() const { return const_cast<QDockWidgetGroupWindowItem *>(this)->widget()->layout(); } @@ -378,12 +390,12 @@ private: #endif // QT_CONFIG(dockwidget) /* This data structure represents the state of all the tool-bars and dock-widgets. It's value based - so it can be easilly copied into a temporary variable. All operations are performed without moving + so it can be easily copied into a temporary variable. All operations are performed without moving any widgets. Only when we are sure we have the desired state, we call apply(), which moves the widgets. */ -class QMainWindowLayoutState +class Q_AUTOTEST_EXPORT QMainWindowLayoutState { public: QRect rect; @@ -408,6 +420,7 @@ public: QSize sizeHint() const; QSize minimumSize() const; + bool fits() const; void fitLayout(); QLayoutItem *itemAt(int index, int *x) const; @@ -430,13 +443,14 @@ public: bool isValid() const; QLayoutItem *plug(const QList<int> &path); - QLayoutItem *unplug(const QList<int> &path, QMainWindowLayoutState *savedState = 0); + QLayoutItem *unplug(const QList<int> &path, QMainWindowLayoutState *savedState = nullptr); void saveState(QDataStream &stream) const; bool checkFormat(QDataStream &stream); bool restoreState(QDataStream &stream, const QMainWindowLayoutState &oldState); }; +class QMainWindowTabBar; class Q_AUTOTEST_EXPORT QMainWindowLayout : public QLayout, public QMainWindowLayoutSeparatorHelper<QMainWindowLayout> @@ -445,6 +459,7 @@ class Q_AUTOTEST_EXPORT QMainWindowLayout public: QMainWindowLayoutState layoutState, savedState; + std::unique_ptr<QMainWindowLayoutState> restoredState; QMainWindowLayout(QMainWindow *mainwindow, QLayout *parentLayout); ~QMainWindowLayout(); @@ -452,22 +467,19 @@ public: QMainWindow::DockOptions dockOptions; void setDockOptions(QMainWindow::DockOptions opts); - // status bar - QLayoutItem *statusbar; + // status bar #if QT_CONFIG(statusbar) QStatusBar *statusBar() const; void setStatusBar(QStatusBar *sb); #endif // central widget - QWidget *centralWidget() const; void setCentralWidget(QWidget *cw); // toolbars - #if QT_CONFIG(toolbar) void addToolBarBreak(Qt::ToolBarArea area); void insertToolBarBreak(QToolBar *before); @@ -475,7 +487,7 @@ public: void addToolBar(Qt::ToolBarArea area, QToolBar *toolbar, bool needAddChildWidget = true); void insertToolBar(QToolBar *before, QToolBar *toolbar); - Qt::ToolBarArea toolBarArea(QToolBar *toolbar) const; + Qt::ToolBarArea toolBarArea(const QToolBar *toolbar) const; bool toolBarBreak(QToolBar *toolBar) const; void getStyleOptionInfo(QStyleOptionToolBar *option, QToolBar *toolBar) const; void removeToolBar(QToolBar *toolbar); @@ -484,23 +496,24 @@ public: #endif // dock widgets - #if QT_CONFIG(dockwidget) void setCorner(Qt::Corner corner, Qt::DockWidgetArea area); Qt::DockWidgetArea corner(Qt::Corner corner) const; + enum DockWidgetAreaSize {Visible, Maximum}; + QRect dockWidgetAreaRect(Qt::DockWidgetArea area, DockWidgetAreaSize size = Maximum) const; void addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget, Qt::Orientation orientation); void splitDockWidget(QDockWidget *after, QDockWidget *dockwidget, Qt::Orientation orientation); - void tabifyDockWidget(QDockWidget *first, QDockWidget *second); Qt::DockWidgetArea dockWidgetArea(QWidget* widget) const; + bool restoreDockWidget(QDockWidget *dockwidget); +#if QT_CONFIG(tabbar) + void tabifyDockWidget(QDockWidget *first, QDockWidget *second); void raise(QDockWidget *widget); void setVerticalTabsEnabled(bool enabled); - bool restoreDockWidget(QDockWidget *dockwidget); -#if QT_CONFIG(tabbar) QDockAreaLayoutInfo *dockInfo(QWidget *w); bool _documentMode; bool documentMode() const; @@ -517,7 +530,7 @@ public: int sep; // separator extent #if QT_CONFIG(tabwidget) - QTabWidget::TabPosition tabPositions[4]; + QTabWidget::TabPosition tabPositions[QInternal::DockCount]; QTabWidget::TabShape _tabShape; QTabWidget::TabShape tabShape() const; @@ -534,15 +547,14 @@ public: #endif // QT_CONFIG(dockwidget) // save/restore - enum VersionMarkers { // sentinel values used to validate state data VersionMarker = 0xff }; void saveState(QDataStream &stream) const; bool restoreState(QDataStream &stream); + QBasicTimer discardRestoredStateTimer; // QLayout interface - void addItem(QLayoutItem *item) override; void setGeometry(const QRect &r) override; QLayoutItem *itemAt(int index) const override; @@ -556,7 +568,6 @@ public: void invalidate() override; // animations - QWidgetAnimator widgetAnimator; QList<int> currentGapPos; QRect currentGapRect; @@ -567,17 +578,32 @@ public: #if QT_CONFIG(dockwidget) QPointer<QDockWidgetGroupWindow> currentHoveredFloat; // set when dragging over a floating dock widget void setCurrentHoveredFloat(QDockWidgetGroupWindow *w); +#if QT_CONFIG(tabbar) + bool isDockWidgetTabbed(const QDockWidget *dockWidget) const; + QList<QDockWidget *> tabifiedDockWidgets(const QDockWidget *dockWidget) const; + QMainWindowTabBar *findTabBar(const QDockWidget *dockWidget) const; #endif +#endif + bool isInApplyState = false; - void hover(QLayoutItem *widgetItem, const QPoint &mousePos); + void hover(QLayoutItem *hoverTarget, const QPoint &mousePos); bool plug(QLayoutItem *widgetItem); - QLayoutItem *unplug(QWidget *widget, bool group = false); + QLayoutItem *unplug(QWidget *widget, QDockWidgetPrivate::DragScope scope); void revert(QLayoutItem *widgetItem); - void paintDropIndicator(QPainter *p, QWidget *widget, const QRegion &clip); void applyState(QMainWindowLayoutState &newState, bool animate = true); + void applyRestoredState(); void restore(bool keepSavedState = false); void animationFinished(QWidget *widget); +#if QT_CONFIG(draganddrop) + static bool needsPlatformDrag(); + Qt::DropAction performPlatformWidgetDrag(QLayoutItem *widgetItem, const QPoint &pressPosition); + QLayoutItem *draggingWidget = nullptr; +#endif + +protected: + void timerEvent(QTimerEvent *e) override; + private Q_SLOTS: void updateGapIndicator(); #if QT_CONFIG(dockwidget) @@ -590,6 +616,7 @@ private: #if QT_CONFIG(tabbar) void updateTabBarShapes(); #endif + bool isInRestoreState = false; }; #if QT_CONFIG(dockwidget) && !defined(QT_NO_DEBUG_STREAM) @@ -600,4 +627,4 @@ QDebug operator<<(QDebug debug, const QMainWindowLayout *layout); QT_END_NAMESPACE -#endif // QDYNAMICMAINWINDOWLAYOUT_P_H +#endif // QMAINWINDOWLAYOUT_P_H |