summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets/qmainwindowlayout_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/widgets/qmainwindowlayout_p.h')
-rw-r--r--src/widgets/widgets/qmainwindowlayout_p.h181
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