diff options
Diffstat (limited to 'src/widgets/widgets/qdockarealayout.cpp')
-rw-r--r-- | src/widgets/widgets/qdockarealayout.cpp | 706 |
1 files changed, 363 insertions, 343 deletions
diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index 54504d124b..da0e987171 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com> -** 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. +// Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "QtWidgets/qapplication.h" #include "QtWidgets/qwidget.h" @@ -44,8 +8,6 @@ #include "QtWidgets/qtabbar.h" #endif #include "QtWidgets/qstyle.h" -#include "QtWidgets/qdesktopwidget.h" -#include <private/qdesktopwidget_p.h> #include "QtWidgets/qapplication.h" #include "QtCore/qvariant.h" #include "qdockarealayout_p.h" @@ -62,6 +24,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaDockWidgets, "qt.widgets.dockwidgets"); + // qmainwindow.cpp extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window); @@ -85,27 +49,27 @@ QPlaceHolderItem::QPlaceHolderItem(QWidget *w) */ QDockAreaLayoutItem::QDockAreaLayoutItem(QLayoutItem *_widgetItem) - : widgetItem(_widgetItem), subinfo(0), placeHolderItem(0), pos(0), size(-1), flags(NoFlags) + : widgetItem(_widgetItem), subinfo(nullptr), placeHolderItem(nullptr), pos(0), size(-1), flags(NoFlags) { } QDockAreaLayoutItem::QDockAreaLayoutItem(QDockAreaLayoutInfo *_subinfo) - : widgetItem(0), subinfo(_subinfo), placeHolderItem(0), pos(0), size(-1), flags(NoFlags) + : widgetItem(nullptr), subinfo(_subinfo), placeHolderItem(nullptr), pos(0), size(-1), flags(NoFlags) { } QDockAreaLayoutItem::QDockAreaLayoutItem(QPlaceHolderItem *_placeHolderItem) - : widgetItem(0), subinfo(0), placeHolderItem(_placeHolderItem), pos(0), size(-1), flags(NoFlags) + : widgetItem(nullptr), subinfo(nullptr), placeHolderItem(_placeHolderItem), pos(0), size(-1), flags(NoFlags) { } QDockAreaLayoutItem::QDockAreaLayoutItem(const QDockAreaLayoutItem &other) - : widgetItem(other.widgetItem), subinfo(0), placeHolderItem(0), pos(other.pos), + : widgetItem(other.widgetItem), subinfo(nullptr), placeHolderItem(nullptr), pos(other.pos), size(other.size), flags(other.flags) { - if (other.subinfo != 0) + if (other.subinfo != nullptr) subinfo = new QDockAreaLayoutInfo(*other.subinfo); - else if (other.placeHolderItem != 0) + else if (other.placeHolderItem != nullptr) placeHolderItem = new QPlaceHolderItem(*other.placeHolderItem); } @@ -117,17 +81,17 @@ QDockAreaLayoutItem::~QDockAreaLayoutItem() bool QDockAreaLayoutItem::skip() const { - if (placeHolderItem != 0) + if (placeHolderItem != nullptr) return true; if (flags & GapItem) return false; - if (widgetItem != 0) + if (widgetItem != nullptr) return widgetItem->isEmpty(); - if (subinfo != 0) { - for (int i = 0; i < subinfo->item_list.count(); ++i) { + if (subinfo != nullptr) { + for (int i = 0; i < subinfo->item_list.size(); ++i) { if (!subinfo->item_list.at(i).skip()) return false; } @@ -138,24 +102,18 @@ bool QDockAreaLayoutItem::skip() const QSize QDockAreaLayoutItem::minimumSize() const { - if (widgetItem != 0) { - int left, top, right, bottom; - widgetItem->widget()->getContentsMargins(&left, &top, &right, &bottom); - return widgetItem->minimumSize() + QSize(left+right, top+bottom); - } - if (subinfo != 0) + if (widgetItem) + return widgetItem->minimumSize().grownBy(widgetItem->widget()->contentsMargins()); + if (subinfo != nullptr) return subinfo->minimumSize(); return QSize(0, 0); } QSize QDockAreaLayoutItem::maximumSize() const { - if (widgetItem != 0) { - int left, top, right, bottom; - widgetItem->widget()->getContentsMargins(&left, &top, &right, &bottom); - return widgetItem->maximumSize()+ QSize(left+right, top+bottom); - } - if (subinfo != 0) + if (widgetItem) + return widgetItem->maximumSize().grownBy(widgetItem->widget()->contentsMargins()); + if (subinfo != nullptr) return subinfo->maximumSize(); return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); } @@ -167,25 +125,22 @@ bool QDockAreaLayoutItem::hasFixedSize(Qt::Orientation o) const bool QDockAreaLayoutItem::expansive(Qt::Orientation o) const { - if ((flags & GapItem) || placeHolderItem != 0) + if ((flags & GapItem) || placeHolderItem != nullptr) return false; - if (widgetItem != 0) + if (widgetItem != nullptr) return ((widgetItem->expandingDirections() & o) == o); - if (subinfo != 0) + if (subinfo != nullptr) return subinfo->expansive(o); return false; } QSize QDockAreaLayoutItem::sizeHint() const { - if (placeHolderItem != 0) + if (placeHolderItem != nullptr) return QSize(0, 0); - if (widgetItem != 0) { - int left, top, right, bottom; - widgetItem->widget()->getContentsMargins(&left, &top, &right, &bottom); - return widgetItem->sizeHint() + QSize(left+right, top+bottom); - } - if (subinfo != 0) + if (widgetItem) + return widgetItem->sizeHint().grownBy(widgetItem->widget()->contentsMargins()); + if (subinfo != nullptr) return subinfo->sizeHint(); return QSize(-1, -1); } @@ -193,15 +148,19 @@ QSize QDockAreaLayoutItem::sizeHint() const QDockAreaLayoutItem &QDockAreaLayoutItem::operator = (const QDockAreaLayoutItem &other) { + if (this == &other) + return *this; + widgetItem = other.widgetItem; - if (other.subinfo == 0) - subinfo = 0; + delete subinfo; + if (other.subinfo == nullptr) + subinfo = nullptr; else subinfo = new QDockAreaLayoutInfo(*other.subinfo); delete placeHolderItem; - if (other.placeHolderItem == 0) - placeHolderItem = 0; + if (other.placeHolderItem == nullptr) + placeHolderItem = nullptr; else placeHolderItem = new QPlaceHolderItem(*other.placeHolderItem); @@ -212,6 +171,38 @@ QDockAreaLayoutItem return *this; } +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug dbg, const QDockAreaLayoutItem *item) +{ + QDebugStateSaver saver(dbg); + dbg.nospace(); + return item ? dbg << *item : dbg << "QDockAreaLayoutItem(0x0)"; +} + +QDebug operator<<(QDebug dbg, const QDockAreaLayoutItem &item) +{ + QDebugStateSaver saver(dbg); + dbg.nospace(); + dbg << "QDockAreaLayoutItem(" << static_cast<const void *>(&item) << "->"; + if (item.widgetItem) { + QWidget *widget = item.widgetItem->widget(); + if (auto *dockWidget = qobject_cast<QDockWidget *>(widget)) { + dbg << "widgetItem(" << dockWidget << ")"; + } else if (auto *groupWindow = qobject_cast<QDockWidgetGroupWindow *>(widget)) { + dbg << "widgetItem(" << groupWindow << "->(" << groupWindow->dockWidgets() << "))"; + } else { + dbg << "widgetItem(" << widget << ")"; + } + } else if (item.subinfo) { + dbg << "subInfo(" << item.subinfo << "->(" << item.subinfo->item_list << ")"; + } else if (item.placeHolderItem) { + dbg << "placeHolderItem(" << item.placeHolderItem << ")"; + } + dbg << ")"; + return dbg; +} +#endif // QT_NO_DEBUG_STREAM + /****************************************************************************** ** QDockAreaLayoutInfo */ @@ -219,7 +210,7 @@ QDockAreaLayoutItem #if QT_CONFIG(tabbar) static quintptr tabId(const QDockAreaLayoutItem &item) { - if (item.widgetItem == 0) + if (item.widgetItem == nullptr) return 0; return reinterpret_cast<quintptr>(item.widgetItem->widget()); } @@ -228,9 +219,9 @@ static quintptr tabId(const QDockAreaLayoutItem &item) static const int zero = 0; QDockAreaLayoutInfo::QDockAreaLayoutInfo() - : sep(&zero), dockPos(QInternal::LeftDock), o(Qt::Horizontal), mainWindow(0) + : sep(&zero), dockPos(QInternal::LeftDock), o(Qt::Horizontal), mainWindow(nullptr) #if QT_CONFIG(tabbar) - , tabbed(false), tabBar(0), tabBarShape(QTabBar::RoundedSouth) + , tabbed(false), tabBar(nullptr), tabBarShape(QTabBar::RoundedSouth) #endif { } @@ -240,7 +231,7 @@ QDockAreaLayoutInfo::QDockAreaLayoutInfo(const int *_sep, QInternal::DockPositio QMainWindow *window) : sep(_sep), dockPos(_dockPos), o(_o), mainWindow(window) #if QT_CONFIG(tabbar) - , tabbed(false), tabBar(0), tabBarShape(static_cast<QTabBar::Shape>(tbshape)) + , tabbed(false), tabBar(nullptr), tabBarShape(static_cast<QTabBar::Shape>(tbshape)) #endif { #if !QT_CONFIG(tabbar) @@ -259,7 +250,7 @@ void QDockAreaLayoutInfo::clear() rect = QRect(); #if QT_CONFIG(tabbar) tabbed = false; - tabBar = 0; + tabBar = nullptr; #endif } @@ -412,7 +403,7 @@ QSize QDockAreaLayoutInfo::sizeHint() const int a = 0, b = 0; int min_perp = 0; int max_perp = QWIDGETSIZE_MAX; - const QDockAreaLayoutItem *previous = 0; + const QDockAreaLayoutItem *previous = nullptr; for (int i = 0; i < item_list.size(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); if (item.skip()) @@ -553,7 +544,7 @@ void QDockAreaLayoutInfo::fitItems() } #endif - QVector<QLayoutStruct> layout_struct_list(item_list.size()*2); + QList<QLayoutStruct> layout_struct_list(item_list.size() * 2); int j = 0; int size = pick(o, rect.size()); @@ -561,7 +552,7 @@ void QDockAreaLayoutInfo::fitItems() int max_size = realMaxSize(*this); int last_index = -1; - const QDockAreaLayoutItem *previous = 0; + const QDockAreaLayoutItem *previous = nullptr; for (int i = 0; i < item_list.size(); ++i) { QDockAreaLayoutItem &item = item_list[i]; if (item.skip()) @@ -642,7 +633,7 @@ void QDockAreaLayoutInfo::fitItems() item.size = ls.size; item.pos = ls.pos; - if (item.subinfo != 0) { + if (item.subinfo != nullptr) { item.subinfo->rect = itemRect(i); item.subinfo->fitItems(); } @@ -780,7 +771,7 @@ QList<int> QDockAreaLayoutInfo::gapIndex(const QPoint& _pos, if (item.pos + item.size < pos) continue; - if (item.subinfo != 0 + if (item.subinfo != nullptr #if QT_CONFIG(tabbar) && !item.subinfo->tabbed #endif @@ -863,7 +854,7 @@ static inline int grow(QLayoutStruct &ls, int delta) return ls.size - old_size; } -static int separatorMoveHelper(QVector<QLayoutStruct> &list, int index, int delta, int sep) +static int separatorMoveHelper(QList<QLayoutStruct> &list, int index, int delta, int sep) { // adjust sizes int pos = -1; @@ -893,7 +884,7 @@ static int separatorMoveHelper(QVector<QLayoutStruct> &list, int index, int delt delta = growlimit; int d = 0; - for (int i = index + 1; d < delta && i < list.count(); ++i) + for (int i = index + 1; d < delta && i < list.size(); ++i) d += shrink(list[i], delta - d); delta = d; d = 0; @@ -901,7 +892,7 @@ static int separatorMoveHelper(QVector<QLayoutStruct> &list, int index, int delt d += grow(list[i], delta - d); } else if (delta < 0) { int growlimit = 0; - for (int i = index + 1; i < list.count(); ++i) { + for (int i = index + 1; i < list.size(); ++i) { const QLayoutStruct &ls = list.at(i); if (ls.empty) continue; @@ -919,7 +910,7 @@ static int separatorMoveHelper(QVector<QLayoutStruct> &list, int index, int delt d += shrink(list[i], -delta - d); delta = -d; d = 0; - for (int i = index + 1; d < -delta && i < list.count(); ++i) + for (int i = index + 1; d < -delta && i < list.size(); ++i) d += grow(list[i], -delta - d); } @@ -947,7 +938,7 @@ int QDockAreaLayoutInfo::separatorMove(int index, int delta) Q_ASSERT(!tabbed); #endif - QVector<QLayoutStruct> list(item_list.size()); + QList<QLayoutStruct> list(item_list.size()); for (int i = 0; i < list.size(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); QLayoutStruct &ls = list[i]; @@ -976,7 +967,7 @@ int QDockAreaLayoutInfo::separatorMove(int index, int delta) const int separatorSpace = item.hasFixedSize(o) ? 0 : *sep; item.size = ls.size - separatorSpace; item.pos = ls.pos; - if (item.subinfo != 0) { + if (item.subinfo != nullptr) { item.subinfo->rect = itemRect(i); item.subinfo->fitItems(); } @@ -988,23 +979,23 @@ int QDockAreaLayoutInfo::separatorMove(int index, int delta) void QDockAreaLayoutInfo::unnest(int index) { QDockAreaLayoutItem &item = item_list[index]; - if (item.subinfo == 0) + if (item.subinfo == nullptr) return; - if (item.subinfo->item_list.count() > 1) + if (item.subinfo->item_list.size() > 1) return; - if (item.subinfo->item_list.count() == 0) { + if (item.subinfo->item_list.size() == 0) { item_list.removeAt(index); - } else if (item.subinfo->item_list.count() == 1) { + } else if (item.subinfo->item_list.size() == 1) { QDockAreaLayoutItem &child = item.subinfo->item_list.first(); - if (child.widgetItem != 0) { + if (child.widgetItem != nullptr) { item.widgetItem = child.widgetItem; delete item.subinfo; - item.subinfo = 0; - } else if (child.subinfo != 0) { + item.subinfo = nullptr; + } else if (child.subinfo != nullptr) { QDockAreaLayoutInfo *tmp = item.subinfo; item.subinfo = child.subinfo; - child.subinfo = 0; + child.subinfo = nullptr; tmp->item_list.clear(); delete tmp; } @@ -1015,10 +1006,10 @@ void QDockAreaLayoutInfo::remove(const QList<int> &path) { Q_ASSERT(!path.isEmpty()); - if (path.count() > 1) { + if (path.size() > 1) { const int index = path.first(); QDockAreaLayoutItem &item = item_list[index]; - Q_ASSERT(item.subinfo != 0); + Q_ASSERT(item.subinfo != nullptr); item.subinfo->remove(path.mid(1)); unnest(index); } else { @@ -1027,6 +1018,14 @@ void QDockAreaLayoutInfo::remove(const QList<int> &path) } } +void QDockAreaLayoutInfo::remove(QWidget *widget) +{ + const QList<int> path = indexOf(widget); + if (path.isEmpty()) + return; + remove(path); +} + QLayoutItem *QDockAreaLayoutInfo::plug(const QList<int> &path) { Q_ASSERT(!path.isEmpty()); @@ -1035,15 +1034,15 @@ QLayoutItem *QDockAreaLayoutInfo::plug(const QList<int> &path) if (index < 0) index = -index - 1; - if (path.count() > 1) { + if (path.size() > 1) { QDockAreaLayoutItem &item = item_list[index]; - Q_ASSERT(item.subinfo != 0); + Q_ASSERT(item.subinfo != nullptr); return item.subinfo->plug(path.mid(1)); } QDockAreaLayoutItem &item = item_list[index]; - Q_ASSERT(item.widgetItem != 0); + Q_ASSERT(item.widgetItem != nullptr); Q_ASSERT(item.flags & QDockAreaLayoutItem::GapItem); item.flags &= ~QDockAreaLayoutItem::GapItem; return item.widgetItem; @@ -1054,9 +1053,9 @@ QLayoutItem *QDockAreaLayoutInfo::unplug(const QList<int> &path) Q_ASSERT(!path.isEmpty()); const int index = path.first(); - if (path.count() > 1) { + if (path.size() > 1) { QDockAreaLayoutItem &item = item_list[index]; - Q_ASSERT(item.subinfo != 0); + Q_ASSERT(item.subinfo != nullptr); return item.subinfo->unplug(path.mid(1)); } @@ -1087,7 +1086,7 @@ QLayoutItem *QDockAreaLayoutInfo::unplug(const QList<int> &path) quintptr QDockAreaLayoutInfo::currentTabId() const { - if (!tabbed || tabBar == 0) + if (!tabbed || tabBar == nullptr) return 0; int index = tabBar->currentIndex(); @@ -1104,7 +1103,7 @@ void QDockAreaLayoutInfo::setCurrentTab(QWidget *widget) void QDockAreaLayoutInfo::setCurrentTabId(quintptr id) { - if (!tabbed || tabBar == 0) + if (!tabbed || tabBar == nullptr) return; for (int i = 0; i < tabBar->count(); ++i) { @@ -1123,7 +1122,7 @@ static QRect dockedGeometry(QWidget *widget) QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(widget->layout()); - if(layout != 0 && layout->nativeWindowDeco()) + if (layout && layout->nativeWindowDeco()) titleHeight = layout->titleHeight(); QRect result = widget->geometry(); @@ -1131,6 +1130,21 @@ static QRect dockedGeometry(QWidget *widget) return result; } +bool QDockAreaLayoutInfo::hasGapItem(const QList<int> &path) const +{ + // empty path has no gap item + if (path.isEmpty()) + return false; + + // Index -1 isn't a gap + // Index out of range points at a position to be created. That isn't a gap either. + const int index = path.constFirst(); + if (index < 0 || index >= item_list.count()) + return false; + + return item_list[index].flags & QDockAreaLayoutItem::GapItem; +} + bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem) { Q_ASSERT(!path.isEmpty()); @@ -1142,12 +1156,10 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid index = -index - 1; } -// dump(qDebug() << "insertGap() before:" << index << tabIndex, *this, QString()); - - if (path.count() > 1) { + if (path.size() > 1) { QDockAreaLayoutItem &item = item_list[index]; - if (item.subinfo == 0 + if (item.subinfo == nullptr #if QT_CONFIG(tabbar) || (item.subinfo->tabbed && !insert_tabbed) #endif @@ -1158,7 +1170,7 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid QDockAreaLayoutInfo *subinfo = item.subinfo; QLayoutItem *widgetItem = item.widgetItem; QPlaceHolderItem *placeHolderItem = item.placeHolderItem; - QRect r = subinfo == 0 ? widgetItem ? dockedGeometry(widgetItem->widget()) : placeHolderItem->topLevelRect : subinfo->rect; + QRect r = subinfo == nullptr ? widgetItem ? dockedGeometry(widgetItem->widget()) : placeHolderItem->topLevelRect : subinfo->rect; Qt::Orientation opposite = o == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal; #if !QT_CONFIG(tabbar) @@ -1169,11 +1181,11 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid //item become a new top-level item.subinfo = new_info; - item.widgetItem = 0; - item.placeHolderItem = 0; + item.widgetItem = nullptr; + item.placeHolderItem = nullptr; QDockAreaLayoutItem new_item - = widgetItem == 0 + = widgetItem == nullptr ? QDockAreaLayoutItem(subinfo) : widgetItem ? QDockAreaLayoutItem(widgetItem) : QDockAreaLayoutItem(placeHolderItem); new_item.size = pick(opposite, r.size()); @@ -1226,12 +1238,14 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid break; } } else { - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); if (item.skip()) continue; - Q_ASSERT(!(item.flags & QDockAreaLayoutItem::GapItem)); + Q_ASSERT_X(!(item.flags & QDockAreaLayoutItem::GapItem), + "QDockAreaLayoutInfo::insertGap", "inserting two gaps after each other"); space += item.size - pick(o, item.minimumSize()); + qCDebug(lcQpaDockWidgets) << "Item space:" << item.flags << this; } } @@ -1256,15 +1270,14 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid // finally, insert the gap item_list.insert(index, gap_item); - -// dump(qDebug() << "insertGap() after:" << index << tabIndex, *this, QString()); + qCDebug(lcQpaDockWidgets) << "Insert gap after:" << index << this; return true; } QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(QWidget *widget) { - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); if (item.skip()) continue; @@ -1274,16 +1287,16 @@ QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(QWidget *widget) return this; #endif - if (item.widgetItem != 0 && item.widgetItem->widget() == widget) + if (item.widgetItem != nullptr && item.widgetItem->widget() == widget) return this; - if (item.subinfo != 0) { + if (item.subinfo != nullptr) { if (QDockAreaLayoutInfo *result = item.subinfo->info(widget)) return result; } } - return 0; + return nullptr; } QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(const QList<int> &path) @@ -1291,9 +1304,9 @@ QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(const QList<int> &path) int index = path.first(); if (index < 0) index = -index - 1; - if (index >= item_list.count()) + if (index >= item_list.size()) return this; - if (path.count() == 1 || item_list[index].subinfo == 0) + if (path.size() == 1 || item_list[index].subinfo == nullptr) return this; return item_list[index].subinfo->info(path.mid(1)); } @@ -1348,9 +1361,9 @@ QRect QDockAreaLayoutInfo::itemRect(const QList<int> &path) const Q_ASSERT(!path.isEmpty()); const int index = path.first(); - if (path.count() > 1) { + if (path.size() > 1) { const QDockAreaLayoutItem &item = item_list.at(index); - Q_ASSERT(item.subinfo != 0); + Q_ASSERT(item.subinfo != nullptr); return item.subinfo->itemRect(path.mid(1)); } @@ -1381,9 +1394,9 @@ QRect QDockAreaLayoutInfo::separatorRect(const QList<int> &path) const Q_ASSERT(!path.isEmpty()); const int index = path.first(); - if (path.count() > 1) { + if (path.size() > 1) { const QDockAreaLayoutItem &item = item_list.at(index); - Q_ASSERT(item.subinfo != 0); + Q_ASSERT(item.subinfo != nullptr); return item.subinfo->separatorRect(path.mid(1)); } return separatorRect(index); @@ -1404,7 +1417,7 @@ QList<int> QDockAreaLayoutInfo::findSeparator(const QPoint &_pos) const continue; if (item.pos + item.size > pos) { - if (item.subinfo != 0) { + if (item.subinfo != nullptr) { QList<int> result = item.subinfo->findSeparator(_pos); if (!result.isEmpty()) { result.prepend(i); @@ -1437,7 +1450,7 @@ QList<int> QDockAreaLayoutInfo::indexOfPlaceHolder(const QString &objectName) co for (int i = 0; i < item_list.size(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); - if (item.subinfo != 0) { + if (item.subinfo != nullptr) { QList<int> result = item.subinfo->indexOfPlaceHolder(objectName); if (!result.isEmpty()) { result.prepend(i); @@ -1446,7 +1459,7 @@ QList<int> QDockAreaLayoutInfo::indexOfPlaceHolder(const QString &objectName) co continue; } - if (item.placeHolderItem != 0 && item.placeHolderItem->objectName == objectName) { + if (item.placeHolderItem != nullptr && item.placeHolderItem->objectName == objectName) { QList<int> result; result << i; return result; @@ -1461,10 +1474,10 @@ QList<int> QDockAreaLayoutInfo::indexOf(QWidget *widget) const for (int i = 0; i < item_list.size(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); - if (item.placeHolderItem != 0) + if (item.placeHolderItem != nullptr) continue; - if (item.subinfo != 0) { + if (item.subinfo != nullptr) { QList<int> result = item.subinfo->indexOf(widget); if (!result.isEmpty()) { result.prepend(i); @@ -1486,7 +1499,7 @@ QList<int> QDockAreaLayoutInfo::indexOf(QWidget *widget) const QMainWindowLayout *QDockAreaLayoutInfo::mainWindowLayout() const { QMainWindowLayout *result = qt_mainwindow_layout(mainWindow); - Q_ASSERT(result != 0); + Q_ASSERT(result != nullptr); return result; } @@ -1545,7 +1558,7 @@ QDockWidget *QDockAreaLayoutInfo::apply(bool animate) if (item.flags & QDockAreaLayoutItem::GapItem) continue; - if (item.subinfo != 0) { + if (item.subinfo != nullptr) { item.subinfo->apply(animate); continue; } @@ -1606,7 +1619,7 @@ QRegion QDockAreaLayoutInfo::separatorRegion() const return result; #endif - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); if (item.skip()) @@ -1636,7 +1649,7 @@ void QDockAreaLayoutInfo::paintSeparators(QPainter *p, QWidget *widget, return; #endif - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); if (item.skip()) @@ -1678,12 +1691,9 @@ int QDockAreaLayoutInfo::prev(int index) const return -1; } +#if QT_CONFIG(tabbar) void QDockAreaLayoutInfo::tab(int index, QLayoutItem *dockWidgetItem) { -#if !QT_CONFIG(tabbar) - Q_UNUSED(index); - Q_UNUSED(dockWidgetItem); -#else if (tabbed) { item_list.append(QDockAreaLayoutItem(dockWidgetItem)); updateTabBar(); @@ -1693,14 +1703,14 @@ void QDockAreaLayoutInfo::tab(int index, QLayoutItem *dockWidgetItem) = new QDockAreaLayoutInfo(sep, dockPos, o, tabBarShape, mainWindow); item_list[index].subinfo = new_info; new_info->item_list.append(QDockAreaLayoutItem(item_list.at(index).widgetItem)); - item_list[index].widgetItem = 0; + item_list[index].widgetItem = nullptr; new_info->item_list.append(QDockAreaLayoutItem(dockWidgetItem)); new_info->tabbed = true; new_info->updateTabBar(); new_info->setCurrentTab(dockWidgetItem->widget()); } -#endif // QT_CONFIG(tabbar) } +#endif // QT_CONFIG(tabbar) void QDockAreaLayoutInfo::split(int index, Qt::Orientation orientation, QLayoutItem *dockWidgetItem) @@ -1715,7 +1725,7 @@ void QDockAreaLayoutInfo::split(int index, Qt::Orientation orientation, = new QDockAreaLayoutInfo(sep, dockPos, orientation, tabBarShape, mainWindow); item_list[index].subinfo = new_info; new_info->item_list.append(QDockAreaLayoutItem(item_list.at(index).widgetItem)); - item_list[index].widgetItem = 0; + item_list[index].widgetItem = nullptr; new_info->item_list.append(QDockAreaLayoutItem(dockWidgetItem)); } } @@ -1724,9 +1734,9 @@ QDockAreaLayoutItem &QDockAreaLayoutInfo::item(const QList<int> &path) { Q_ASSERT(!path.isEmpty()); const int index = path.first(); - if (path.count() > 1) { + if (path.size() > 1) { const QDockAreaLayoutItem &item = item_list[index]; - Q_ASSERT(item.subinfo != 0); + Q_ASSERT(item.subinfo != nullptr); return item.subinfo->item(path.mid(1)); } return item_list[index]; @@ -1734,9 +1744,9 @@ QDockAreaLayoutItem &QDockAreaLayoutInfo::item(const QList<int> &path) QLayoutItem *QDockAreaLayoutInfo::itemAt(int *x, int index) const { - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); - if (item.placeHolderItem != 0) + if (item.placeHolderItem != nullptr) continue; if (item.subinfo) { if (QLayoutItem *ret = item.subinfo->itemAt(x, index)) @@ -1746,14 +1756,14 @@ QLayoutItem *QDockAreaLayoutInfo::itemAt(int *x, int index) const return item.widgetItem; } } - return 0; + return nullptr; } QLayoutItem *QDockAreaLayoutInfo::takeAt(int *x, int index) { - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { QDockAreaLayoutItem &item = item_list[i]; - if (item.placeHolderItem != 0) + if (item.placeHolderItem != nullptr) continue; else if (item.subinfo) { if (QLayoutItem *ret = item.subinfo->takeAt(x, index)) { @@ -1764,25 +1774,45 @@ QLayoutItem *QDockAreaLayoutInfo::takeAt(int *x, int index) if ((*x)++ == index) { item.placeHolderItem = new QPlaceHolderItem(item.widgetItem->widget()); QLayoutItem *ret = item.widgetItem; - item.widgetItem = 0; + item.widgetItem = nullptr; if (item.size != -1) item.flags |= QDockAreaLayoutItem::KeepSize; return ret; } } } - return 0; + return nullptr; +} + +// Add a dock widget or dock widget group window to the item list +void QDockAreaLayoutInfo::add(QWidget *widget) +{ + // Do not add twice + if (!indexOf(widget).isEmpty()) + return; + + if (auto *dockWidget = qobject_cast<QDockWidget *>(widget)) { + item_list.append(QDockAreaLayoutItem(new QDockWidgetItem(dockWidget))); + return; + } + + if (auto *groupWindow = qobject_cast<QDockWidgetGroupWindow *>(widget)) { + item_list.append(QDockAreaLayoutItem(new QDockWidgetGroupWindowItem(groupWindow))); + return; + } + + qFatal("Coding error. Add supports only QDockWidget and QDockWidgetGroupWindow"); } void QDockAreaLayoutInfo::deleteAllLayoutItems() { - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { QDockAreaLayoutItem &item= item_list[i]; if (item.subinfo) { item.subinfo->deleteAllLayoutItems(); } else { delete item.widgetItem; - item.widgetItem = 0; + item.widgetItem = nullptr; } } } @@ -1796,7 +1826,7 @@ void QDockAreaLayoutInfo::saveState(QDataStream &stream) const // write the index in item_list of the widget that's currently on top. quintptr id = currentTabId(); int index = -1; - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { if (tabId(item_list.at(i)) == id) { index = i; break; @@ -1809,11 +1839,11 @@ void QDockAreaLayoutInfo::saveState(QDataStream &stream) const stream << (uchar) SequenceMarker; } - stream << (uchar) o << item_list.count(); + stream << (uchar) o << int(item_list.size()); - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); - if (item.widgetItem != 0) { + if (item.widgetItem != nullptr) { stream << (uchar) WidgetMarker; QWidget *w = item.widgetItem->widget(); QString name = w->objectName(); @@ -1837,7 +1867,7 @@ void QDockAreaLayoutInfo::saveState(QDataStream &stream) const stream << item.pos << item.size << pick(o, item.minimumSize()) << pick(o, item.maximumSize()); } - } else if (item.placeHolderItem != 0) { + } else if (item.placeHolderItem != nullptr) { stream << (uchar) WidgetMarker; stream << item.placeHolderItem->objectName; uchar flags = 0; @@ -1852,7 +1882,7 @@ void QDockAreaLayoutInfo::saveState(QDataStream &stream) const } else { stream << item.pos << item.size << (int)0 << (int)0; } - } else if (item.subinfo != 0) { + } else if (item.subinfo != nullptr) { stream << (uchar) SequenceMarker << item.pos << item.size << pick(o, item.minimumSize()) << pick(o, item.maximumSize()); item.subinfo->saveState(stream); } @@ -1906,15 +1936,15 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*> continue; } - QDockWidget *widget = 0; - for (int j = 0; j < widgets.count(); ++j) { + QDockWidget *widget = nullptr; + for (int j = 0; j < widgets.size(); ++j) { if (widgets.at(j)->objectName() == name) { widget = widgets.takeAt(j); break; } } - if (widget == 0) { + if (widget == nullptr) { QPlaceHolderItem *placeHolder = new QPlaceHolderItem; QDockAreaLayoutItem item(placeHolder); @@ -1937,11 +1967,6 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*> QDockAreaLayoutItem item(new QDockWidgetItem(widget)); if (flags & StateFlagFloating) { bool drawer = false; -#if 0 // Used to be included in Qt4 for Q_WS_MAC // drawer support - extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp - extern bool qt_mac_set_drawer_preferred_edge(QWidget *, Qt::DockWidgetArea); //qwidget_mac.cpp - drawer = qt_mac_is_macdrawer(widget); -#endif if (!testing) { widget->hide(); @@ -1952,13 +1977,6 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*> int x, y, w, h; stream >> x >> y >> w >> h; -#if 0 // Used to be included in Qt4 for Q_WS_MAC // drawer support - if (drawer) { - mainWindow->window()->createWinId(); - widget->window()->createWinId(); - qt_mac_set_drawer_preferred_edge(widget, toDockWidgetArea(dockPos)); - } else -#endif if (!testing) widget->setGeometry(QDockAreaLayout::constrainedRect(QRect(x, y, w, h), widget)); @@ -1979,6 +1997,7 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*> if (testing) { //was it is not really added to the layout, we need to delete the object here delete item.widgetItem; + item.widgetItem = nullptr; } } } else if (nextMarker == SequenceMarker) { @@ -2005,7 +2024,7 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*> } #if QT_CONFIG(tabbar) - if (!testing && tabbed && index >= 0 && index < item_list.count()) { + if (!testing && tabbed && index >= 0 && index < item_list.size()) { updateTabBar(); setCurrentTabId(tabId(item_list.at(index))); } @@ -2025,7 +2044,7 @@ void QDockAreaLayoutInfo::updateSeparatorWidgets() const } int j = 0; - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); if (item.skip()) @@ -2044,17 +2063,22 @@ void QDockAreaLayoutInfo::updateSeparatorWidgets() const break; QWidget *sepWidget; - if (j < separatorWidgets.size() && separatorWidgets.at(j)) { + if (j < separatorWidgets.size()) { sepWidget = separatorWidgets.at(j); + if (!sepWidget) { + qWarning("QDockAreaLayoutInfo::updateSeparatorWidgets: null separator widget"); + sepWidget = mainWindowLayout()->getSeparatorWidget(); + separatorWidgets[j] = sepWidget; + } } else { sepWidget = mainWindowLayout()->getSeparatorWidget(); separatorWidgets.append(sepWidget); } j++; -#if 1 // Used to be excluded in Qt4 for Q_WS_MAC + Q_ASSERT(sepWidget); sepWidget->raise(); -#endif + QRect sepRect = separatorRect(i).adjusted(-2, -2, 2, 2); sepWidget->setGeometry(sepRect); sepWidget->setMask( QRegion(separatorRect(i).translated( - sepRect.topLeft()))); @@ -2065,7 +2089,6 @@ void QDockAreaLayoutInfo::updateSeparatorWidgets() const separatorWidgets[k]->hide(); } separatorWidgets.resize(j); - Q_ASSERT(separatorWidgets.size() == j); } /*! \internal @@ -2078,7 +2101,7 @@ void QDockAreaLayoutInfo::reparentWidgets(QWidget *parent) if (tabBar) tabBar->setParent(parent); - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); if (item.flags & QDockAreaLayoutItem::GapItem) continue; @@ -2106,7 +2129,7 @@ bool QDockAreaLayoutInfo::updateTabBar() const QDockAreaLayoutInfo *that = const_cast<QDockAreaLayoutInfo*>(this); - if (that->tabBar == 0) { + if (that->tabBar == nullptr) { that->tabBar = mainWindowLayout()->getTabBar(); that->tabBar->setShape(static_cast<QTabBar::Shape>(tabBarShape)); that->tabBar->setDrawBase(true); @@ -2118,7 +2141,7 @@ bool QDockAreaLayoutInfo::updateTabBar() const const quintptr oldCurrentId = currentTabId(); int tab_idx = 0; - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); if (item.skip()) continue; @@ -2126,7 +2149,7 @@ bool QDockAreaLayoutInfo::updateTabBar() const gap = true; continue; } - if (item.widgetItem == 0) + if (item.widgetItem == nullptr) continue; QDockWidget *dw = qobject_cast<QDockWidget*>(item.widgetItem->widget()); @@ -2134,7 +2157,7 @@ bool QDockAreaLayoutInfo::updateTabBar() const quintptr id = tabId(item); if (tab_idx == tabBar->count()) { tabBar->insertTab(tab_idx, title); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) tabBar->setTabToolTip(tab_idx, title); #endif tabBar->setTabData(tab_idx, id); @@ -2144,7 +2167,7 @@ bool QDockAreaLayoutInfo::updateTabBar() const tabBar->removeTab(tab_idx); else { tabBar->insertTab(tab_idx, title); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) tabBar->setTabToolTip(tab_idx, title); #endif tabBar->setTabData(tab_idx, id); @@ -2153,7 +2176,7 @@ bool QDockAreaLayoutInfo::updateTabBar() const if (title != tabBar->tabText(tab_idx)) { tabBar->setTabText(tab_idx, title); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) tabBar->setTabToolTip(tab_idx, title); #endif } @@ -2180,12 +2203,12 @@ void QDockAreaLayoutInfo::setTabBarShape(int shape) if (shape == tabBarShape) return; tabBarShape = shape; - if (tabBar != 0) + if (tabBar != nullptr) tabBar->setShape(static_cast<QTabBar::Shape>(shape)); - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { QDockAreaLayoutItem &item = item_list[i]; - if (item.subinfo != 0) + if (item.subinfo != nullptr) item.subinfo->setTabBarShape(shape); } } @@ -2215,9 +2238,9 @@ QSet<QTabBar*> QDockAreaLayoutInfo::usedTabBars() const result.insert(tabBar); } - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); - if (item.subinfo != 0) + if (item.subinfo != nullptr) result += item.subinfo->usedTabBars(); } @@ -2229,15 +2252,15 @@ QSet<QTabBar*> QDockAreaLayoutInfo::usedTabBars() const QSet<QWidget*> QDockAreaLayoutInfo::usedSeparatorWidgets() const { QSet<QWidget*> result; - const int numSeparatorWidgets = separatorWidgets.count(); + const int numSeparatorWidgets = separatorWidgets.size(); result.reserve(numSeparatorWidgets); for (int i = 0; i < numSeparatorWidgets; ++i) result << separatorWidgets.at(i); - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); - if (item.subinfo != 0) + if (item.subinfo != nullptr) result += item.subinfo->usedSeparatorWidgets(); } @@ -2282,7 +2305,7 @@ int QDockAreaLayoutInfo::tabIndexToListIndex(int tabIndex) const { Q_ASSERT(tabbed && tabBar); quintptr data = qvariant_cast<quintptr>(tabBar->tabData(tabIndex)); - for (int i = 0; i < item_list.count(); ++i) { + for (int i = 0; i < item_list.size(); ++i) { if (tabId(item_list.at(i)) == data) return i; } @@ -2302,7 +2325,7 @@ void QDockAreaLayoutInfo::moveTab(int from, int to) QDockAreaLayout::QDockAreaLayout(QMainWindow *win) : fallbackToSizeHints(true) { mainWindow = win; - sep = win->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, win); + sep = win->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, nullptr, win); #if QT_CONFIG(tabbar) const int tabShape = QTabBar::RoundedSouth; #else @@ -2316,7 +2339,7 @@ QDockAreaLayout::QDockAreaLayout(QMainWindow *win) : fallbackToSizeHints(true) = QDockAreaLayoutInfo(&sep, QInternal::TopDock, Qt::Horizontal, tabShape, win); docks[QInternal::BottomDock] = QDockAreaLayoutInfo(&sep, QInternal::BottomDock, Qt::Horizontal, tabShape, win); - centralWidgetItem = 0; + centralWidgetItem = nullptr; corners[Qt::TopLeftCorner] = Qt::TopDockWidgetArea; @@ -2452,23 +2475,7 @@ QList<int> QDockAreaLayout::gapIndex(const QPoint &pos, bool disallowTabs) const const QDockAreaLayoutInfo &info = docks[i]; if (info.isEmpty()) { - QRect r; - switch (i) { - case QInternal::LeftDock: - r = QRect(rect.left(), rect.top(), EmptyDropAreaSize, rect.height()); - break; - case QInternal::RightDock: - r = QRect(rect.right() - EmptyDropAreaSize, rect.top(), - EmptyDropAreaSize, rect.height()); - break; - case QInternal::TopDock: - r = QRect(rect.left(), rect.top(), rect.width(), EmptyDropAreaSize); - break; - case QInternal::BottomDock: - r = QRect(rect.left(), rect.bottom() - EmptyDropAreaSize, - rect.width(), EmptyDropAreaSize); - break; - } + const QRect r = gapRect(static_cast<QInternal::DockPosition>(i)); if (r.contains(pos)) { if (opts & QMainWindow::ForceTabbedDocks && !info.item_list.isEmpty()) { //in case of ForceTabbedDocks, we pass -1 in order to force the gap to be tabbed @@ -2484,6 +2491,43 @@ QList<int> QDockAreaLayout::gapIndex(const QPoint &pos, bool disallowTabs) const return QList<int>(); } +QRect QDockAreaLayout::gapRect(QInternal::DockPosition dockPos) const +{ + Q_ASSERT_X(mainWindow, "QDockAreaLayout::gapRect", "Called without valid mainWindow pointer."); + + // Determine gap size depending on MainWindow size (QTBUG-101657) + const QSize gapSize = (mainWindow->size()/2).boundedTo(QSize(EmptyDropAreaSize, EmptyDropAreaSize)); + + // Warn if main window is too small to create proper docks. + // Do not fail because this can be triggered by a user making MainWindow too small + if (mainWindow->height() < (2 * sep)) { + qCWarning(lcQpaDockWidgets, + "QDockAreaLayout::gapRect: Main window height %i is too small. Docking will not be possible.", + mainWindow->height()); + + } + if (mainWindow->width() < (2 * sep)) { + qCWarning(lcQpaDockWidgets, + "QDockAreaLayout::gapRect: Main window width %i is too small. Docking will not be possible.", + mainWindow->width()); + } + + // Calculate rectangle of requested dock + switch (dockPos) { + case QInternal::LeftDock: + return QRect(rect.left(), rect.top(), gapSize.width(), rect.height()); + case QInternal::RightDock: + return QRect(rect.right() - gapSize.width(), rect.top(), gapSize.width(), rect.height()); + case QInternal::TopDock: + return QRect(rect.left(), rect.top(), rect.width(), gapSize.height()); + case QInternal::BottomDock: + return QRect(rect.left(), rect.bottom() - gapSize.height(), rect.width(), gapSize.height()); + case QInternal::DockCount: + break; + } + return QRect(); +} + QList<int> QDockAreaLayout::findSeparator(const QPoint &pos) const { QList<int> result; @@ -2516,7 +2560,7 @@ QDockAreaLayoutInfo *QDockAreaLayout::info(QWidget *widget) return result; } - return 0; + return nullptr; } QDockAreaLayoutInfo *QDockAreaLayout::info(const QList<int> &path) @@ -2525,7 +2569,7 @@ QDockAreaLayoutInfo *QDockAreaLayout::info(const QList<int> &path) const int index = path.first(); Q_ASSERT(index >= 0 && index < QInternal::DockCount); - if (path.count() == 1) + if (path.size() == 1) return &docks[index]; return docks[index].info(path.mid(1)); @@ -2580,7 +2624,7 @@ QRect QDockAreaLayout::separatorRect(const QList<int> &path) const const int index = path.first(); Q_ASSERT(index >= 0 && index < QInternal::DockCount); - if (path.count() == 1) + if (path.size() == 1) return separatorRect(index); else return docks[index].separatorRect(path.mid(1)); @@ -2630,7 +2674,7 @@ void QDockAreaLayout::removePlaceHolder(const QString &name) if (!index.isEmpty()) remove(index); const auto groups = - mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly); + mainWindow->findChildren<QDockWidgetGroupWindow *>(Qt::FindDirectChildrenOnly); for (QDockWidgetGroupWindow *dwgw : groups) { index = dwgw->layoutInfo()->indexOfPlaceHolder(name); if (!index.isEmpty()) { @@ -2642,13 +2686,13 @@ void QDockAreaLayout::removePlaceHolder(const QString &name) static inline int qMax(int i1, int i2, int i3) { return qMax(i1, qMax(i2, i3)); } -void QDockAreaLayout::getGrid(QVector<QLayoutStruct> *_ver_struct_list, - QVector<QLayoutStruct> *_hor_struct_list) +void QDockAreaLayout::getGrid(QList<QLayoutStruct> *_ver_struct_list, + QList<QLayoutStruct> *_hor_struct_list) { QSize center_hint(0, 0); QSize center_min(0, 0); QSize center_max(0, 0); - const bool have_central = centralWidgetItem != 0 && !centralWidgetItem->isEmpty(); + const bool have_central = centralWidgetItem != nullptr && !centralWidgetItem->isEmpty(); if (have_central) { center_hint = centralWidgetRect.size(); if (!center_hint.isValid()) @@ -2695,8 +2739,8 @@ void QDockAreaLayout::getGrid(QVector<QLayoutStruct> *_ver_struct_list, QSize bottom_max = docks[QInternal::BottomDock].maximumSize(); bottom_hint = bottom_hint.boundedTo(bottom_max).expandedTo(bottom_min); - if (_ver_struct_list != 0) { - QVector<QLayoutStruct> &ver_struct_list = *_ver_struct_list; + if (_ver_struct_list != nullptr) { + QList<QLayoutStruct> &ver_struct_list = *_ver_struct_list; ver_struct_list.resize(3); // top -------------------------------------------------- @@ -2757,8 +2801,8 @@ void QDockAreaLayout::getGrid(QVector<QLayoutStruct> *_ver_struct_list, ver_struct_list[1].maximumSize = QWIDGETSIZE_MAX; } - if (_hor_struct_list != 0) { - QVector<QLayoutStruct> &hor_struct_list = *_hor_struct_list; + if (_hor_struct_list != nullptr) { + QList<QLayoutStruct> &hor_struct_list = *_hor_struct_list; hor_struct_list.resize(3); // left -------------------------------------------------- @@ -2820,15 +2864,15 @@ void QDockAreaLayout::getGrid(QVector<QLayoutStruct> *_ver_struct_list, } } -void QDockAreaLayout::setGrid(QVector<QLayoutStruct> *ver_struct_list, - QVector<QLayoutStruct> *hor_struct_list) +void QDockAreaLayout::setGrid(QList<QLayoutStruct> *ver_struct_list, + QList<QLayoutStruct> *hor_struct_list) { // top --------------------------------------------------- if (!docks[QInternal::TopDock].isEmpty()) { QRect r = docks[QInternal::TopDock].rect; - if (hor_struct_list != 0) { + if (hor_struct_list != nullptr) { r.setLeft(corners[Qt::TopLeftCorner] == Qt::TopDockWidgetArea || docks[QInternal::LeftDock].isEmpty() ? rect.left() : hor_struct_list->at(1).pos); @@ -2836,7 +2880,7 @@ void QDockAreaLayout::setGrid(QVector<QLayoutStruct> *ver_struct_list, || docks[QInternal::RightDock].isEmpty() ? rect.right() : hor_struct_list->at(2).pos - sep - 1); } - if (ver_struct_list != 0) { + if (ver_struct_list != nullptr) { r.setTop(rect.top()); r.setBottom(ver_struct_list->at(1).pos - sep - 1); } @@ -2848,7 +2892,7 @@ void QDockAreaLayout::setGrid(QVector<QLayoutStruct> *ver_struct_list, if (!docks[QInternal::BottomDock].isEmpty()) { QRect r = docks[QInternal::BottomDock].rect; - if (hor_struct_list != 0) { + if (hor_struct_list != nullptr) { r.setLeft(corners[Qt::BottomLeftCorner] == Qt::BottomDockWidgetArea || docks[QInternal::LeftDock].isEmpty() ? rect.left() : hor_struct_list->at(1).pos); @@ -2856,7 +2900,7 @@ void QDockAreaLayout::setGrid(QVector<QLayoutStruct> *ver_struct_list, || docks[QInternal::RightDock].isEmpty() ? rect.right() : hor_struct_list->at(2).pos - sep - 1); } - if (ver_struct_list != 0) { + if (ver_struct_list != nullptr) { r.setTop(ver_struct_list->at(2).pos); r.setBottom(rect.bottom()); } @@ -2868,11 +2912,11 @@ void QDockAreaLayout::setGrid(QVector<QLayoutStruct> *ver_struct_list, if (!docks[QInternal::LeftDock].isEmpty()) { QRect r = docks[QInternal::LeftDock].rect; - if (hor_struct_list != 0) { + if (hor_struct_list != nullptr) { r.setLeft(rect.left()); r.setRight(hor_struct_list->at(1).pos - sep - 1); } - if (ver_struct_list != 0) { + if (ver_struct_list != nullptr) { r.setTop(corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea || docks[QInternal::TopDock].isEmpty() ? rect.top() : ver_struct_list->at(1).pos); @@ -2888,11 +2932,11 @@ void QDockAreaLayout::setGrid(QVector<QLayoutStruct> *ver_struct_list, if (!docks[QInternal::RightDock].isEmpty()) { QRect r = docks[QInternal::RightDock].rect; - if (hor_struct_list != 0) { + if (hor_struct_list != nullptr) { r.setLeft(hor_struct_list->at(2).pos); r.setRight(rect.right()); } - if (ver_struct_list != 0) { + if (ver_struct_list != nullptr) { r.setTop(corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea || docks[QInternal::TopDock].isEmpty() ? rect.top() : ver_struct_list->at(1).pos); @@ -2906,11 +2950,11 @@ void QDockAreaLayout::setGrid(QVector<QLayoutStruct> *ver_struct_list, // center --------------------------------------------------- - if (hor_struct_list != 0) { + if (hor_struct_list != nullptr) { centralWidgetRect.setLeft(hor_struct_list->at(1).pos); centralWidgetRect.setWidth(hor_struct_list->at(1).size); } - if (ver_struct_list != 0) { + if (ver_struct_list != nullptr) { centralWidgetRect.setTop(ver_struct_list->at(1).pos); centralWidgetRect.setHeight(ver_struct_list->at(1).size); } @@ -2918,8 +2962,8 @@ void QDockAreaLayout::setGrid(QVector<QLayoutStruct> *ver_struct_list, void QDockAreaLayout::fitLayout() { - QVector<QLayoutStruct> ver_struct_list(3); - QVector<QLayoutStruct> hor_struct_list(3); + QList<QLayoutStruct> ver_struct_list(3); + QList<QLayoutStruct> hor_struct_list(3); getGrid(&ver_struct_list, &hor_struct_list); qGeomCalc(ver_struct_list, 0, 3, rect.top(), rect.height(), sep); @@ -2937,25 +2981,27 @@ void QDockAreaLayout::clear() centralWidgetRect = QRect(); } -QSize QDockAreaLayout::sizeHint() const +template<typename SizePMF, typename CenterPMF> +QSize QDockAreaLayout::size_helper(SizePMF sizeFn, CenterPMF centerFn) const { int left_sep = 0; int right_sep = 0; int top_sep = 0; int bottom_sep = 0; - if (centralWidgetItem != 0) { + if (centralWidgetItem != nullptr) { left_sep = docks[QInternal::LeftDock].isEmpty() ? 0 : sep; right_sep = docks[QInternal::RightDock].isEmpty() ? 0 : sep; top_sep = docks[QInternal::TopDock].isEmpty() ? 0 : sep; bottom_sep = docks[QInternal::BottomDock].isEmpty() ? 0 : sep; } - QSize left = docks[QInternal::LeftDock].sizeHint() + QSize(left_sep, 0); - QSize right = docks[QInternal::RightDock].sizeHint() + QSize(right_sep, 0); - QSize top = docks[QInternal::TopDock].sizeHint() + QSize(0, top_sep); - QSize bottom = docks[QInternal::BottomDock].sizeHint() + QSize(0, bottom_sep); - QSize center = centralWidgetItem == 0 ? QSize(0, 0) : centralWidgetItem->sizeHint(); + const QSize left = (docks[QInternal::LeftDock].*sizeFn)() + QSize(left_sep, 0); + const QSize right = (docks[QInternal::RightDock].*sizeFn)() + QSize(right_sep, 0); + const QSize top = (docks[QInternal::TopDock].*sizeFn)() + QSize(0, top_sep); + const QSize bottom = (docks[QInternal::BottomDock].*sizeFn)() + QSize(0, bottom_sep); + const QSize center = centralWidgetItem == nullptr + ? QSize(0, 0) : (centralWidgetItem->*centerFn)(); int row1 = top.width(); int row2 = left.width() + center.width() + right.width(); @@ -2987,54 +3033,24 @@ QSize QDockAreaLayout::sizeHint() const return QSize(qMax(row1, row2, row3), qMax(col1, col2, col3)); } -QSize QDockAreaLayout::minimumSize() const +QSize QDockAreaLayout::sizeHint() const { - int left_sep = 0; - int right_sep = 0; - int top_sep = 0; - int bottom_sep = 0; - - if (centralWidgetItem != 0) { - left_sep = docks[QInternal::LeftDock].isEmpty() ? 0 : sep; - right_sep = docks[QInternal::RightDock].isEmpty() ? 0 : sep; - top_sep = docks[QInternal::TopDock].isEmpty() ? 0 : sep; - bottom_sep = docks[QInternal::BottomDock].isEmpty() ? 0 : sep; - } - - QSize left = docks[QInternal::LeftDock].minimumSize() + QSize(left_sep, 0); - QSize right = docks[QInternal::RightDock].minimumSize() + QSize(right_sep, 0); - QSize top = docks[QInternal::TopDock].minimumSize() + QSize(0, top_sep); - QSize bottom = docks[QInternal::BottomDock].minimumSize() + QSize(0, bottom_sep); - QSize center = centralWidgetItem == 0 ? QSize(0, 0) : centralWidgetItem->minimumSize(); - - int row1 = top.width(); - int row2 = left.width() + center.width() + right.width(); - int row3 = bottom.width(); - int col1 = left.height(); - int col2 = top.height() + center.height() + bottom.height(); - int col3 = right.height(); - - if (corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea) - row1 += left.width(); - else - col1 += top.height(); - - if (corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea) - row1 += right.width(); - else - col3 += top.height(); + return size_helper(&QDockAreaLayoutInfo::sizeHint, &QLayoutItem::sizeHint); +} - if (corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea) - row3 += left.width(); - else - col1 += bottom.height(); +QSize QDockAreaLayout::minimumSize() const +{ + return size_helper(&QDockAreaLayoutInfo::minimumSize, &QLayoutItem::minimumSize); +} - if (corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea) - row3 += right.width(); - else - col3 += bottom.height(); +/*! + \internal - return QSize(qMax(row1, row2, row3), qMax(col1, col2, col3)); + Returns the smallest size that doesn't change the size of any of the dock areas. +*/ +QSize QDockAreaLayout::minimumStableSize() const +{ + return size_helper(&QDockAreaLayoutInfo::size, &QLayoutItem::minimumSize); } /*! \internal @@ -3045,19 +3061,20 @@ QSize QDockAreaLayout::minimumSize() const */ QRect QDockAreaLayout::constrainedRect(QRect rect, QWidget* widget) { - QRect desktop; - if (QDesktopWidgetPrivate::isVirtualDesktop()) - desktop = QDesktopWidgetPrivate::screenGeometry(rect.topLeft()); - else - desktop = QDesktopWidgetPrivate::screenGeometry(widget); + QScreen *screen = nullptr; + if (QGuiApplication::primaryScreen()->virtualSiblings().size() > 1) + screen = QGuiApplication::screenAt(rect.topLeft()); + if (!screen) + screen = widget->screen(); - if (desktop.isValid()) { - rect.setWidth(qMin(rect.width(), desktop.width())); - rect.setHeight(qMin(rect.height(), desktop.height())); - rect.moveLeft(qMax(rect.left(), desktop.left())); - rect.moveTop(qMax(rect.top(), desktop.top())); - rect.moveRight(qMin(rect.right(), desktop.right())); - rect.moveBottom(qMin(rect.bottom(), desktop.bottom())); + const QRect screenRect = screen->geometry(); + if (screenRect.isValid()) { + rect.setWidth(qMin(rect.width(), screenRect.width())); + rect.setHeight(qMin(rect.height(), screenRect.height())); + rect.moveLeft(qMax(rect.left(), screenRect.left())); + rect.moveTop(qMax(rect.top(), screenRect.top())); + rect.moveRight(qMin(rect.right(), screenRect.right())); + rect.moveBottom(qMin(rect.bottom(), screenRect.bottom())); } return rect; @@ -3065,9 +3082,9 @@ QRect QDockAreaLayout::constrainedRect(QRect rect, QWidget* widget) bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget) { - QDockAreaLayoutItem *item = 0; + QDockAreaLayoutItem *item = nullptr; const auto groups = - mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly); + mainWindow->findChildren<QDockWidgetGroupWindow *>(Qt::FindDirectChildrenOnly); for (QDockWidgetGroupWindow *dwgw : groups) { QList<int> index = dwgw->layoutInfo()->indexOfPlaceHolder(dockWidget->objectName()); if (!index.isEmpty()) { @@ -3084,7 +3101,7 @@ bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget) } QPlaceHolderItem *placeHolder = item->placeHolderItem; - Q_ASSERT(placeHolder != 0); + Q_ASSERT(placeHolder != nullptr); item->widgetItem = new QDockWidgetItem(dockWidget); @@ -3093,12 +3110,8 @@ bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget) dockWidget->d_func()->setWindowState(true, true, r); } dockWidget->setVisible(!placeHolder->hidden); -#if 0 // Used to be included in Qt4 for Q_WS_X11 - if (placeHolder->window) // gets rid of the X11BypassWindowManager window flag - dockWidget->d_func()->setWindowState(true); -#endif - item->placeHolderItem = 0; + item->placeHolderItem = nullptr; delete placeHolder; return true; @@ -3109,7 +3122,7 @@ void QDockAreaLayout::addDockWidget(QInternal::DockPosition pos, QDockWidget *do { QLayoutItem *dockWidgetItem = new QDockWidgetItem(dockWidget); QDockAreaLayoutInfo &info = docks[pos]; - if (orientation == info.o || info.item_list.count() <= 1) { + if (orientation == info.o || info.item_list.size() <= 1) { // empty dock areas, or dock areas containing exactly one widget can have their orientation // switched. info.o = orientation; @@ -3137,6 +3150,7 @@ void QDockAreaLayout::addDockWidget(QInternal::DockPosition pos, QDockWidget *do removePlaceHolder(dockWidget->objectName()); } +#if QT_CONFIG(tabbar) void QDockAreaLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second) { const QList<int> path = indexOf(first); @@ -3144,20 +3158,21 @@ void QDockAreaLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second) return; QDockAreaLayoutInfo *info = this->info(path); - Q_ASSERT(info != 0); + Q_ASSERT(info != nullptr); info->tab(path.last(), new QDockWidgetItem(second)); removePlaceHolder(second->objectName()); } +#endif // QT_CONFIG(tabbar) void QDockAreaLayout::resizeDocks(const QList<QDockWidget *> &docks, const QList<int> &sizes, Qt::Orientation o) { - if (Q_UNLIKELY(docks.count() != sizes.count())) { + if (Q_UNLIKELY(docks.size() != sizes.size())) { qWarning("QMainWidget::resizeDocks: size of the lists are not the same"); return; } - int count = docks.count(); + int count = docks.size(); fallbackToSizeHints = false; for (int i = 0; i < count; ++i) { QList<int> path = indexOf(docks[i]); @@ -3177,7 +3192,7 @@ void QDockAreaLayout::resizeDocks(const QList<QDockWidget *> &docks, if (!info->tabbed && info->o == o) { info->item_list[path.constLast()].size = size; int totalSize = 0; - for (const QDockAreaLayoutItem &item : qAsConst(info->item_list)) { + for (const QDockAreaLayoutItem &item : std::as_const(info->item_list)) { if (!item.skip()) { if (totalSize != 0) totalSize += sep; @@ -3208,7 +3223,7 @@ void QDockAreaLayout::splitDockWidget(QDockWidget *after, return; QDockAreaLayoutInfo *info = this->info(path); - Q_ASSERT(info != 0); + Q_ASSERT(info != nullptr); info->split(path.last(), orientation, new QDockWidgetItem(dockWidget)); removePlaceHolder(dockWidget->objectName()); @@ -3220,7 +3235,7 @@ void QDockAreaLayout::apply(bool animate) for (int i = 0; i < QInternal::DockCount; ++i) docks[i].apply(animate); - if (centralWidgetItem != 0 && !centralWidgetItem->isEmpty()) { + if (centralWidgetItem != nullptr && !centralWidgetItem->isEmpty()) { widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect, animate); } @@ -3270,7 +3285,7 @@ int QDockAreaLayout::separatorMove(const QList<int> &separator, const QPoint &or int delta = 0; int index = separator.last(); - if (separator.count() > 1) { + if (separator.size() > 1) { QDockAreaLayoutInfo *info = this->info(separator); delta = pick(info->o, dest - origin); if (delta != 0) @@ -3279,12 +3294,12 @@ int QDockAreaLayout::separatorMove(const QList<int> &separator, const QPoint &or return delta; } - QVector<QLayoutStruct> list; + QList<QLayoutStruct> list; if (index == QInternal::LeftDock || index == QInternal::RightDock) - getGrid(0, &list); + getGrid(nullptr, &list); else - getGrid(&list, 0); + getGrid(&list, nullptr); int sep_index = index == QInternal::LeftDock || index == QInternal::TopDock ? 0 : 1; @@ -3298,9 +3313,9 @@ int QDockAreaLayout::separatorMove(const QList<int> &separator, const QPoint &or fallbackToSizeHints = false; if (index == QInternal::LeftDock || index == QInternal::RightDock) - setGrid(0, &list); + setGrid(nullptr, &list); else - setGrid(&list, 0); + setGrid(&list, nullptr); apply(false); @@ -3322,7 +3337,7 @@ int QDockAreaLayoutInfo::separatorMove(const QList<int> &separator, const QPoint #if QT_CONFIG(tabbar) // Sets the correct positions for the separator widgets -// Allocates new sepearator widgets with getSeparatorWidget +// Allocates new separator widgets with getSeparatorWidget void QDockAreaLayout::updateSeparatorWidgets() const { int j = 0; @@ -3335,15 +3350,20 @@ void QDockAreaLayout::updateSeparatorWidgets() const QWidget *sepWidget; if (j < separatorWidgets.size()) { sepWidget = separatorWidgets.at(j); + if (!sepWidget) { + qWarning("QDockAreaLayout::updateSeparatorWidgets: null separator widget"); + sepWidget = qt_mainwindow_layout(mainWindow)->getSeparatorWidget(); + separatorWidgets[j] = sepWidget; + } } else { sepWidget = qt_mainwindow_layout(mainWindow)->getSeparatorWidget(); separatorWidgets.append(sepWidget); } j++; -#if 1 // Used to be excluded in Qt4 for Q_WS_MAC + Q_ASSERT(sepWidget); sepWidget->raise(); -#endif + QRect sepRect = separatorRect(i).adjusted(-2, -2, 2, 2); sepWidget->setGeometry(sepRect); sepWidget->setMask( QRegion(separatorRect(i).translated( - sepRect.topLeft()))); @@ -3358,7 +3378,7 @@ void QDockAreaLayout::updateSeparatorWidgets() const QLayoutItem *QDockAreaLayout::itemAt(int *x, int index) const { - Q_ASSERT(x != 0); + Q_ASSERT(x != nullptr); for (int i = 0; i < QInternal::DockCount; ++i) { const QDockAreaLayoutInfo &dock = docks[i]; @@ -3369,12 +3389,12 @@ QLayoutItem *QDockAreaLayout::itemAt(int *x, int index) const if (centralWidgetItem && (*x)++ == index) return centralWidgetItem; - return 0; + return nullptr; } QLayoutItem *QDockAreaLayout::takeAt(int *x, int index) { - Q_ASSERT(x != 0); + Q_ASSERT(x != nullptr); for (int i = 0; i < QInternal::DockCount; ++i) { QDockAreaLayoutInfo &dock = docks[i]; @@ -3384,11 +3404,11 @@ QLayoutItem *QDockAreaLayout::takeAt(int *x, int index) if (centralWidgetItem && (*x)++ == index) { QLayoutItem *ret = centralWidgetItem; - centralWidgetItem = 0; + centralWidgetItem = nullptr; return ret; } - return 0; + return nullptr; } void QDockAreaLayout::deleteAllLayoutItems() @@ -3412,7 +3432,7 @@ QSet<QTabBar*> QDockAreaLayout::usedTabBars() const QSet<QWidget*> QDockAreaLayout::usedSeparatorWidgets() const { QSet<QWidget*> result; - const int numSeparators = separatorWidgets.count(); + const int numSeparators = separatorWidgets.size(); result.reserve(numSeparators); for (int i = 0; i < numSeparators; ++i) result << separatorWidgets.at(i); @@ -3427,10 +3447,10 @@ QSet<QWidget*> QDockAreaLayout::usedSeparatorWidgets() const QRect QDockAreaLayout::gapRect(const QList<int> &path) const { const QDockAreaLayoutInfo *info = this->info(path); - if (info == 0) + if (info == nullptr) return QRect(); int index = path.last(); - if (index < 0 || index >= info->item_list.count()) + if (index < 0 || index >= info->item_list.size()) return QRect(); return info->itemRect(index, true); } @@ -3447,7 +3467,7 @@ void QDockAreaLayout::keepSize(QDockWidget *w) void QDockAreaLayout::styleChangedEvent() { - sep = mainWindow->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, mainWindow); + sep = mainWindow->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, nullptr, mainWindow); if (isValid()) fitLayout(); } |