diff --git a/src/private/multisplitter/Item.cpp b/src/private/multisplitter/Item.cpp index 07574fdf..330a73bb 100644 --- a/src/private/multisplitter/Item.cpp +++ b/src/private/multisplitter/Item.cpp @@ -44,6 +44,8 @@ int Layouting::Item::separatorThickness = 5; const QSize Layouting::Item::hardcodedMinimumSize = QSize(KDDOCKWIDGETS_MIN_WIDTH, KDDOCKWIDGETS_MIN_HEIGHT); const QSize Layouting::Item::hardcodedMaximumSize = QSize(KDDOCKWIDGETS_MAX_WIDTH, KDDOCKWIDGETS_MAX_HEIGHT); +bool Layouting::ItemContainer::s_inhibitSimplify = false; + inline bool locationIsVertical(Item::Location loc) { return loc == Item::Location_OnTop || loc == Item::Location_OnBottom; @@ -882,7 +884,6 @@ struct ItemContainer::Private void updateSeparators_recursive(); QSize minSize(const Item::List &items) const; int excessLength() const; - void simplify(); mutable bool m_checkSanityScheduled = false; QVector m_separators; @@ -1698,8 +1699,8 @@ void ItemContainer::insertItem(Item *item, int index, DefaultSizeMode defaultSiz const bool shouldEmitVisibleChanged = item->isVisible(); - if (!d->m_convertingItemToContainer) - d->simplify(); + if (!d->m_convertingItemToContainer && !s_inhibitSimplify) + simplify(); if (shouldEmitVisibleChanged) Q_EMIT root()->numVisibleItemsChanged(root()->numVisibleChildren()); @@ -3123,23 +3124,23 @@ int ItemContainer::Private::excessLength() const return qMax(0, Layouting::length(q->size(), m_orientation) - q->maxLengthHint(m_orientation)); } -void ItemContainer::Private::simplify() +void ItemContainer::simplify() { // Removes unneeded nesting. For example, a vertical layout doesn't need to have vertical layouts // inside. It can simply have the contents of said sub-layouts Item::List newChildren; - newChildren.reserve(m_children.size() + 20); // over-reserve a bit + newChildren.reserve(d->m_children.size() + 20); // over-reserve a bit - for (Item *child : qAsConst(m_children)) { + for (Item *child : qAsConst(d->m_children)) { if (ItemContainer *childContainer = child->asContainer()) { - childContainer->d->simplify(); // recurse down the hierarchy + childContainer->simplify(); // recurse down the hierarchy - if (childContainer->orientation() == m_orientation) { + if (childContainer->orientation() == d->m_orientation) { // This sub-container is reduntant, as it has the same orientation as its parent // Canibalize it. for (Item *child2 : childContainer->childItems()) { - child2->setParentContainer(q); + child2->setParentContainer(this); newChildren.push_back(child2); } @@ -3152,10 +3153,10 @@ void ItemContainer::Private::simplify() } } - if (m_children != newChildren) { - m_children = newChildren; - q->positionItems(); - q->updateChildPercentages(); + if (d->m_children != newChildren) { + d->m_children = newChildren; + positionItems(); + updateChildPercentages(); } } diff --git a/src/private/multisplitter/Item_p.h b/src/private/multisplitter/Item_p.h index 1eebf734..2b5a8349 100644 --- a/src/private/multisplitter/Item_p.h +++ b/src/private/multisplitter/Item_p.h @@ -512,6 +512,8 @@ public: QVector separators_recursive() const; QVector separators() const; private: + void simplify(); + static bool s_inhibitSimplify; friend class Layouting::Item; friend class ::TestMultiSplitter; struct Private; diff --git a/src/private/multisplitter/tests/tst_multisplitter.cpp b/src/private/multisplitter/tests/tst_multisplitter.cpp index b60b420e..5a8d9d84 100644 --- a/src/private/multisplitter/tests/tst_multisplitter.cpp +++ b/src/private/multisplitter/tests/tst_multisplitter.cpp @@ -201,6 +201,7 @@ private Q_SLOTS: void tst_maxSizeHonoured3(); void tst_requestEqualSize(); void tst_maxSizeHonouredWhenAnotherRemoved(); + void tst_simplify(); }; class MyHostWidget : public QWidget @@ -1821,6 +1822,31 @@ void TestMultiSplitter::tst_maxSizeHonouredWhenAnotherRemoved() root->dumpLayout(); } +void TestMultiSplitter::tst_simplify() +{ + QScopedValueRollback inhibitSimplify(ItemContainer::s_inhibitSimplify, true); + + auto root = createRoot(); + auto item1 = createItem(); + auto item2 = createItem(); + root->insertItem(item1, Item::Location_OnTop); + root->insertItem(item2, Item::Location_OnBottom); + + auto root2 = createRoot(); + auto root22 = createRoot(); + auto item21 = createItem(); + root22->insertItem(item21, Item::Location_OnLeft); + root2->insertItem(root22.release(), Item::Location_OnLeft); + root->insertItem(root2.release(), Item::Location_OnBottom); + + QVERIFY(root->childItems().at(2)->isContainer()); + + root->simplify(); + + for (Item *item : root->childItems()) + QVERIFY(!item->isContainer()); +} + int main(int argc, char *argv[]) { bool qpaPassed = false;