From 17e5d9d7cadb4fceb39cfc875162add57e962db8 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 24 Jun 2016 10:57:10 +0200 Subject: Fix QMainWindow::restoreDockWidget() with GroupedDragging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to account for the fact that the placeholder might be in a floating tab. Task-number: QTBUG-50491 Change-Id: I03d8e49cc40f58691154f5c3984f3b0670a974d5 Reviewed-by: Friedemann Kleint Reviewed-by: Sérgio Martins --- src/widgets/widgets/qdockarealayout.cpp | 53 ++++++++++++++++------- src/widgets/widgets/qdockarealayout_p.h | 1 + src/widgets/widgets/qmainwindowlayout.cpp | 70 ++++++++++++++++++------------- src/widgets/widgets/qmainwindowlayout_p.h | 2 +- 4 files changed, 80 insertions(+), 46 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index d22e89c6e1..1d10de904d 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -2604,6 +2604,21 @@ void QDockAreaLayout::remove(const QList &path) docks[index].remove(path.mid(1)); } +void QDockAreaLayout::removePlaceHolder(const QString &name) +{ + QList index = indexOfPlaceHolder(name); + if (!index.isEmpty()) + remove(index); + foreach (QDockWidgetGroupWindow *dwgw, mainWindow->findChildren( + QString(), Qt::FindDirectChildrenOnly)) { + index = dwgw->layoutInfo()->indexOfPlaceHolder(name); + if (!index.isEmpty()) { + dwgw->layoutInfo()->remove(index); + dwgw->destroyOrHideIfEmpty(); + } + } +} + static inline int qMax(int i1, int i2, int i3) { return qMax(i1, qMax(i2, i3)); } void QDockAreaLayout::getGrid(QVector *_ver_struct_list, @@ -3030,15 +3045,27 @@ QRect QDockAreaLayout::constrainedRect(QRect rect, QWidget* widget) bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget) { - QList index = indexOfPlaceHolder(dockWidget->objectName()); - if (index.isEmpty()) - return false; + QDockAreaLayoutItem *item = 0; + foreach (QDockWidgetGroupWindow *dwgw, mainWindow->findChildren( + QString(), Qt::FindDirectChildrenOnly)) { + QList index = dwgw->layoutInfo()->indexOfPlaceHolder(dockWidget->objectName()); + if (!index.isEmpty()) { + dockWidget->setParent(dwgw); + item = const_cast(&dwgw->layoutInfo()->item(index)); + break; + } + } + if (!item) { + QList index = indexOfPlaceHolder(dockWidget->objectName()); + if (index.isEmpty()) + return false; + item = const_cast(&this->item(index)); + } - QDockAreaLayoutItem &item = this->item(index); - QPlaceHolderItem *placeHolder = item.placeHolderItem; + QPlaceHolderItem *placeHolder = item->placeHolderItem; Q_ASSERT(placeHolder != 0); - item.widgetItem = new QDockWidgetItem(dockWidget); + item->widgetItem = new QDockWidgetItem(dockWidget); if (placeHolder->window) { const QRect r = constrainedRect(placeHolder->topLevelRect, dockWidget); @@ -3050,7 +3077,7 @@ bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget) dockWidget->d_func()->setWindowState(true); #endif - item.placeHolderItem = 0; + item->placeHolderItem = 0; delete placeHolder; return true; @@ -3086,9 +3113,7 @@ void QDockAreaLayout::addDockWidget(QInternal::DockPosition pos, QDockWidget *do info = new_info; } - QList index = indexOfPlaceHolder(dockWidget->objectName()); - if (!index.isEmpty()) - remove(index); + removePlaceHolder(dockWidget->objectName()); } void QDockAreaLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second) @@ -3101,9 +3126,7 @@ void QDockAreaLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second) Q_ASSERT(info != 0); info->tab(path.last(), new QDockWidgetItem(second)); - QList index = indexOfPlaceHolder(second->objectName()); - if (!index.isEmpty()) - remove(index); + removePlaceHolder(second->objectName()); } void QDockAreaLayout::resizeDocks(const QList &docks, @@ -3165,9 +3188,7 @@ void QDockAreaLayout::splitDockWidget(QDockWidget *after, Q_ASSERT(info != 0); info->split(path.last(), orientation, new QDockWidgetItem(dockWidget)); - QList index = indexOfPlaceHolder(dockWidget->objectName()); - if (!index.isEmpty()) - remove(index); + removePlaceHolder(dockWidget->objectName()); } void QDockAreaLayout::apply(bool animate) diff --git a/src/widgets/widgets/qdockarealayout_p.h b/src/widgets/widgets/qdockarealayout_p.h index 5d352f0124..8a35d8b035 100644 --- a/src/widgets/widgets/qdockarealayout_p.h +++ b/src/widgets/widgets/qdockarealayout_p.h @@ -255,6 +255,7 @@ public: QLayoutItem *plug(const QList &path); QLayoutItem *unplug(const QList &path); void remove(const QList &path); + void removePlaceHolder(const QString &name); void fitLayout(); diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index 6b247d8d11..f581fe4d88 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -215,11 +215,10 @@ public: } void setGeometry(const QRect&r) Q_DECL_OVERRIDE { + static_cast(parent())->destroyOrHideIfEmpty(); QDockAreaLayoutInfo *li = layoutInfo(); - if (li->isEmpty()) { - static_cast(parent())->destroyIfEmpty(); + if (li->isEmpty()) return; - } int fw = frameWidth(); li->reparentWidgets(parentWidget()); li->rect = r.adjusted(fw, fw, -fw, -fw); @@ -272,6 +271,10 @@ bool QDockWidgetGroupWindow::event(QEvent *e) if (qobject_cast(static_cast(e)->child())) adjustFlags(); break; + case QEvent::LayoutRequest: + // We might need to show the widget again + destroyOrHideIfEmpty(); + break; default: break; } @@ -325,34 +328,43 @@ QDockWidget *QDockWidgetGroupWindow::topDockWidget() const } /*! \internal - Destroy this window if there is no more QDockWidget in it. + Destroy or hide this window if there is no more QDockWidget in it. + Otherwise make sure it is shown. */ -void QDockWidgetGroupWindow::destroyIfEmpty() -{ - if (layoutInfo()->isEmpty()) { - // Make sure to reparent the possibly floating or hidden QDockWidgets to the parent - foreach (QDockWidget *dw, - findChildren(QString(), Qt::FindDirectChildrenOnly)) { - bool wasFloating = dw->isFloating(); - bool wasHidden = dw->isHidden(); - dw->setParent(parentWidget()); - if (wasFloating) { - dw->setFloating(true); - } else { - // maybe it was hidden, we still have to put it back in the main layout. - QMainWindowLayout *ml = qt_mainwindow_layout(static_cast(parentWidget())); - Qt::DockWidgetArea area = ml->dockWidgetArea(this); - if (area == Qt::NoDockWidgetArea) - area = Qt::LeftDockWidgetArea; - static_cast(parentWidget())->addDockWidget(area, dw); - } - if (!wasHidden) - dw->show(); +void QDockWidgetGroupWindow::destroyOrHideIfEmpty() +{ + if (!layoutInfo()->isEmpty()) { + show(); // It might have been hidden, + return; + } + // There might still be placeholders + if (!layoutInfo()->item_list.isEmpty()) { + hide(); + return; + } + + // Make sure to reparent the possibly floating or hidden QDockWidgets to the parent + foreach (QDockWidget *dw, findChildren(QString(), Qt::FindDirectChildrenOnly)) { + bool wasFloating = dw->isFloating(); + bool wasHidden = dw->isHidden(); + dw->setParent(parentWidget()); + if (wasFloating) { + dw->setFloating(true); + } else { + // maybe it was hidden, we still have to put it back in the main layout. + QMainWindowLayout *ml = + qt_mainwindow_layout(static_cast(parentWidget())); + Qt::DockWidgetArea area = ml->dockWidgetArea(this); + if (area == Qt::NoDockWidgetArea) + area = Qt::LeftDockWidgetArea; + static_cast(parentWidget())->addDockWidget(area, dw); } - foreach (QTabBar *tb, findChildren(QString(), Qt::FindDirectChildrenOnly)) - tb->setParent(parentWidget()); - deleteLater(); + if (!wasHidden) + dw->show(); } + foreach (QTabBar *tb, findChildren(QString(), Qt::FindDirectChildrenOnly)) + tb->setParent(parentWidget()); + deleteLater(); } /*! \internal @@ -2075,7 +2087,7 @@ void QMainWindowLayout::animationFinished(QWidget *widget) item.subinfo->reparentWidgets(parentWidget()); item.subinfo->setTabBarShape(parentInfo->tabBarShape); } - dwgw->destroyIfEmpty(); + dwgw->destroyOrHideIfEmpty(); } if (QDockWidget *dw = qobject_cast(widget)) { diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h index 9a13e5f5ce..7475da8bdc 100644 --- a/src/widgets/widgets/qmainwindowlayout_p.h +++ b/src/widgets/widgets/qmainwindowlayout_p.h @@ -86,7 +86,7 @@ public: : QWidget(parent, f) {} QDockAreaLayoutInfo *layoutInfo() const; QDockWidget *topDockWidget() const; - void destroyIfEmpty(); + void destroyOrHideIfEmpty(); void adjustFlags(); protected: bool event(QEvent *) Q_DECL_OVERRIDE; -- cgit v1.2.3