From 86e58dd8a7721d5eb749153dd8366e72d8a7a0f7 Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Thu, 11 Jun 2020 14:55:31 +0100 Subject: [PATCH] Merge MultiSplitterLayout into MultiSplitter No need to have two. It's a leftover from the old layouting engine --- src/CMakeLists.txt | 1 - src/DockWidgetBase.cpp | 4 +- src/DockWidgetBase.h | 2 +- src/MainWindow.cpp | 1 - src/MainWindowBase.cpp | 9 +- src/MainWindowBase.h | 6 +- src/private/DebugWindow.cpp | 10 +- src/private/DockRegistry.cpp | 17 +- src/private/DockRegistry_p.h | 14 +- src/private/DropArea.cpp | 30 +- src/private/DropAreaWithCentralFrame.cpp | 2 +- src/private/DropArea_p.h | 3 - src/private/FloatingWindow.cpp | 21 +- src/private/FloatingWindow_p.h | 6 +- src/private/Frame.cpp | 2 +- src/private/Position.cpp | 13 +- src/private/Position_p.h | 2 +- src/private/indicators/ClassicIndicators.cpp | 8 +- src/private/widgets/MultiSplitter.cpp | 403 +++++++++++++++++- src/private/widgets/MultiSplitterLayout.cpp | 424 ------------------- src/private/widgets/MultiSplitterLayout_p.h | 284 ------------- src/private/widgets/MultiSplitter_p.h | 215 +++++++++- tests/tst_docks.cpp | 243 ++++++----- tests/utils.cpp | 2 +- 24 files changed, 784 insertions(+), 938 deletions(-) delete mode 100644 src/private/widgets/MultiSplitterLayout.cpp delete mode 100644 src/private/widgets/MultiSplitterLayout_p.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0db9edc5..c1e0709c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -91,7 +91,6 @@ else() private/widgets/DockWidget.cpp private/widgets/QWidgetAdapter_widgets.cpp private/widgets/MultiSplitter.cpp - private/widgets/MultiSplitterLayout.cpp ) set(DOCKS_INSTALLABLE_INCLUDES diff --git a/src/DockWidgetBase.cpp b/src/DockWidgetBase.cpp index c4b093fa..303dbece 100644 --- a/src/DockWidgetBase.cpp +++ b/src/DockWidgetBase.cpp @@ -611,7 +611,7 @@ void DockWidgetBase::Private::restoreToPreviousPosition() Layouting::Item *item = m_lastPositions.lastItem(); - MultiSplitterLayout *layout = DockRegistry::self()->layoutForItem(item); + MultiSplitter *layout = DockRegistry::self()->layoutForItem(item); Q_ASSERT(layout); layout->restorePlaceholder(q, item, m_lastPositions.lastTabIndex()); } @@ -633,7 +633,7 @@ void DockWidgetBase::Private::maybeRestoreToPreviousPosition() Frame *frame = q->frame(); - if (frame && frame->QWidget::parentWidget() == DockRegistry::self()->layoutForItem(layoutItem)->multiSplitter()) { + if (frame && frame->QWidget::parentWidget() == DockRegistry::self()->layoutForItem(layoutItem)) { // There's a frame already. Means the DockWidget was hidden instead of closed. // Nothing to do, the dock widget will simply be shown qCDebug(placeholder) << Q_FUNC_INFO << "Already had frame."; diff --git a/src/DockWidgetBase.h b/src/DockWidgetBase.h index 0373ea7f..669e53ed 100644 --- a/src/DockWidgetBase.h +++ b/src/DockWidgetBase.h @@ -354,7 +354,7 @@ public: private: #endif Q_DISABLE_COPY(DockWidgetBase) - friend class MultiSplitterLayout; + friend class MultiSplitter; friend class Frame; friend class DropArea; friend class TestDocks; diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 95cd0908..371c4d16 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -30,7 +30,6 @@ #include "Frame_p.h" #include "Logging_p.h" #include "DropAreaWithCentralFrame_p.h" -#include "widgets/MultiSplitterLayout_p.h" #include "widgets/MultiSplitter_p.h" #include diff --git a/src/MainWindowBase.cpp b/src/MainWindowBase.cpp index 7469ddd7..e05d7b82 100644 --- a/src/MainWindowBase.cpp +++ b/src/MainWindowBase.cpp @@ -33,7 +33,6 @@ #include "Utils_p.h" #include "Logging_p.h" #include "DropAreaWithCentralFrame_p.h" -#include "widgets/MultiSplitterLayout_p.h" #include "widgets/MultiSplitter_p.h" using namespace KDDockWidgets; @@ -113,9 +112,9 @@ MainWindowOptions MainWindowBase::options() const return d->m_options; } -MultiSplitterLayout *MainWindowBase::multiSplitterLayout() const +MultiSplitter *MainWindowBase::multiSplitter() const { - return dropArea()->multiSplitterLayout(); + return dropArea(); } void MainWindowBase::setAffinities(const QStringList &affinityNames) @@ -180,7 +179,7 @@ bool MainWindowBase::deserialize(const LayoutSaver::MainWindow &mw) d->affinities = mw.affinities; } - return dropArea()->multiSplitterLayout()->deserialize(mw.multiSplitterLayout); + return dropArea()->deserialize(mw.multiSplitterLayout); } LayoutSaver::MainWindow MainWindowBase::serialize() const @@ -193,7 +192,7 @@ LayoutSaver::MainWindow MainWindowBase::serialize() const m.uniqueName = uniqueName(); m.screenIndex = screenNumberForWidget(this); m.screenSize = screenSizeForWidget(this); - m.multiSplitterLayout = dropArea()->multiSplitterLayout()->serialize(); + m.multiSplitterLayout = dropArea()->serialize(); m.affinities = d->affinities; return m; diff --git a/src/MainWindowBase.h b/src/MainWindowBase.h index 942460c2..d1b833a7 100644 --- a/src/MainWindowBase.h +++ b/src/MainWindowBase.h @@ -41,7 +41,7 @@ namespace KDDockWidgets { class DockWidgetBase; class Frame; class DropArea; -class MultiSplitterLayout; +class MultiSplitter; class DropAreaWithCentralFrame; /** @@ -97,8 +97,8 @@ public: virtual DropAreaWithCentralFrame *dropArea() const = 0; ///@internal - ///@brief returns the MultiSplitterLayout. - MultiSplitterLayout* multiSplitterLayout() const; + ///@brief returns the MultiSplitter. + MultiSplitter* multiSplitter() const; /** * @brief Sets the affinities names. Dock widgets can only dock into main windows of the same affinity. diff --git a/src/private/DebugWindow.cpp b/src/private/DebugWindow.cpp index cb5cd5b8..cf7f2043 100644 --- a/src/private/DebugWindow.cpp +++ b/src/private/DebugWindow.cpp @@ -201,12 +201,12 @@ DebugWindow::DebugWindow(QWidget *parent) connect(button, &QPushButton::clicked, this, [] { const auto mainWindows = DockRegistry::self()->mainwindows(); for (MainWindowBase *mainWindow : mainWindows) { - mainWindow->multiSplitterLayout()->checkSanity(); + mainWindow->multiSplitter()->checkSanity(); } const auto floatingWindows = DockRegistry::self()->nestedwindows(); for (FloatingWindow *floatingWindow : floatingWindows) { - floatingWindow->multiSplitterLayout()->checkSanity(); + floatingWindow->multiSplitter()->checkSanity(); } }); @@ -239,7 +239,7 @@ DebugWindow::DebugWindow(QWidget *parent) connect(button, &QPushButton::clicked, this, [] { const auto layouts = DockRegistry::self()->layouts(); for (auto l : layouts) { - QWidget *tlw = l->multiSplitter()->window(); + QWidget *tlw = l->window(); tlw->resize(tlw->size() + QSize(1, 1)); } }); @@ -318,12 +318,12 @@ void DebugWindow::dumpDockWidgetInfo() for (FloatingWindow *fw : floatingWindows) { qDebug() << fw << "; affinities=" << fw->affinities(); - fw->dropArea()->multiSplitterLayout()->dumpDebug(); + fw->dropArea()->dumpDebug(); } for (MainWindowBase *mw : mainWindows) { qDebug() << mw << "; affinities=" << mw->affinities(); - mw->multiSplitterLayout()->dumpDebug(); + mw->multiSplitter()->dumpDebug(); } for (DockWidgetBase *dw : dockWidgets) { diff --git a/src/private/DockRegistry.cpp b/src/private/DockRegistry.cpp index e3c52b9a..9ca8249a 100644 --- a/src/private/DockRegistry.cpp +++ b/src/private/DockRegistry.cpp @@ -23,7 +23,6 @@ #include "Logging_p.h" #include "DebugWindow_p.h" #include "Position_p.h" -#include "widgets/MultiSplitterLayout_p.h" #include "widgets/MultiSplitter_p.h" #include "quick/QmlTypes.h" @@ -129,13 +128,13 @@ MainWindowBase::List DockRegistry::mainWindowsWithAffinity(const QStringList &af return result; } -MultiSplitterLayout *DockRegistry::layoutForItem(const Layouting::Item *item) const +MultiSplitter *DockRegistry::layoutForItem(const Layouting::Item *item) const { if (!item->hostWidget()) return nullptr; if (auto ms = qobject_cast(item->hostWidget()->asQWidget())) - return ms->multiSplitterLayout(); + return ms; return nullptr; } @@ -143,7 +142,7 @@ MultiSplitterLayout *DockRegistry::layoutForItem(const Layouting::Item *item) co bool DockRegistry::itemIsInMainWindow(const Layouting::Item *item) const { if (auto layout = layoutForItem(item)) - return layout->multiSplitter()->isInMainWindow(); + return layout->isInMainWindow(); return false; } @@ -204,12 +203,12 @@ void DockRegistry::unregisterNestedWindow(FloatingWindow *window) maybeDelete(); } -void DockRegistry::registerLayout(MultiSplitterLayout *layout) +void DockRegistry::registerLayout(MultiSplitter *layout) { m_layouts << layout; } -void DockRegistry::unregisterLayout(MultiSplitterLayout *layout) +void DockRegistry::unregisterLayout(MultiSplitter *layout) { m_layouts.removeOne(layout); } @@ -286,7 +285,7 @@ bool DockRegistry::isSane() const names.insert(name); } - if (!mainwindow->multiSplitterLayout()->checkSanity()) + if (!mainwindow->multiSplitter()->checkSanity()) return false; } @@ -342,7 +341,7 @@ const MainWindowBase::List DockRegistry::mainwindows() const return m_mainWindows; } -const QVector DockRegistry::layouts() const +const QVector DockRegistry::layouts() const { return m_layouts; } @@ -414,7 +413,7 @@ void DockRegistry::clear(const DockWidgetBase::List &dockWidgets, for (auto mw : qAsConst(mainWindows)) { if (affinities.isEmpty() || affinitiesMatch(affinities, mw->affinities())) { - mw->multiSplitterLayout()->rootItem()->clear(); + mw->multiSplitter()->rootItem()->clear(); } } } diff --git a/src/private/DockRegistry_p.h b/src/private/DockRegistry_p.h index 32f2d53e..597fd923 100644 --- a/src/private/DockRegistry_p.h +++ b/src/private/DockRegistry_p.h @@ -51,8 +51,8 @@ public: void registerNestedWindow(FloatingWindow *); void unregisterNestedWindow(FloatingWindow *); - void registerLayout(MultiSplitterLayout *); - void unregisterLayout(MultiSplitterLayout *); + void registerLayout(MultiSplitter *); + void unregisterLayout(MultiSplitter *); void registerFrame(Frame *); void unregisterFrame(Frame *); @@ -80,8 +80,8 @@ public: ///@brief overload returning only the ones with the specified names const MainWindowBase::List mainWindows(const QStringList &names); - ///@brief returns the list of MultiSplitterLayout instances - const QVector layouts() const; + ///@brief returns the list of MultiSplitter instances + const QVector layouts() const; ///@brief returns a list of all Frame instances const Frame::List frames() const; @@ -132,7 +132,7 @@ public: bool isEmpty() const; /** - * @brief Calls MultisplitterLayout::checkSanity() on all layouts. + * @brief Calls MultiSplitter::checkSanity() on all layouts. * * @param dumpDebug If true then each layout is dumped too * @@ -154,7 +154,7 @@ public: MainWindowBase::List mainWindowsWithAffinity(const QStringList &affinities) const; // TODO: docs - MultiSplitterLayout* layoutForItem(const Layouting::Item *) const; + MultiSplitter* layoutForItem(const Layouting::Item *) const; // TODO: docs bool itemIsInMainWindow(const Layouting::Item *) const; @@ -178,7 +178,7 @@ private: MainWindowBase::List m_mainWindows; Frame::List m_frames; QVector m_nestedWindows; - QVector m_layouts; + QVector m_layouts; }; } diff --git a/src/private/DropArea.cpp b/src/private/DropArea.cpp index b79bf2f4..915391ec 100644 --- a/src/private/DropArea.cpp +++ b/src/private/DropArea.cpp @@ -56,12 +56,12 @@ DropArea::~DropArea() int DropArea::numFrames() const { - return m_layout->visibleCount(); + return visibleCount(); } Frame *DropArea::frameContainingPos(QPoint globalPos) const { - const Layouting::Item::List &items = m_layout->items(); + const Layouting::Item::List &items = this->items(); for (Layouting::Item *item : items) { auto frame = static_cast(item->guestAsQObject()); if (!frame || !frame->QWidget::isVisible()) { @@ -76,7 +76,7 @@ Frame *DropArea::frameContainingPos(QPoint globalPos) const Layouting::Item *DropArea::centralFrame() const { - for (Layouting::Item *item : m_layout->items()) { + for (Layouting::Item *item : this->items()) { if (auto f = static_cast(item->guestAsQObject())) { if (f->isCentralFrame()) return item; @@ -123,20 +123,15 @@ void DropArea::addDockWidget(DockWidgetBase *dw, Location location, DockWidgetBa } if (option & AddingOption_StartHidden) { - m_layout->addWidget(dw, location, relativeToFrame, DefaultSizeMode::Fair, option); + addWidget(dw, location, relativeToFrame, DefaultSizeMode::Fair, option); } else { - m_layout->addWidget(frame, location, relativeToFrame, DefaultSizeMode::Fair, option); + addWidget(frame, location, relativeToFrame, DefaultSizeMode::Fair, option); } } -bool DropArea::checkSanity() -{ - return m_layout->checkSanity(); -} - bool DropArea::contains(DockWidgetBase *dw) const { - return dw->frame() && m_layout->contains(dw->frame()); + return dw->frame() && MultiSplitter::contains(dw->frame()); } QStringList DropArea::affinities() const @@ -150,20 +145,15 @@ QStringList DropArea::affinities() const return {}; } -void DropArea::layoutEqually() -{ - m_layout->layoutEqually(); -} - void DropArea::layoutParentContainerEqually(DockWidgetBase *dw) { - Layouting::Item *item = m_layout->itemForFrame(dw->frame()); + Layouting::Item *item = itemForFrame(dw->frame()); if (!item) { qWarning() << Q_FUNC_INFO << "Item not found for" << dw << dw->frame(); return; } - m_layout->layoutEqually(item->parentContainer()); + layoutEqually(item->parentContainer()); } void DropArea::hover(FloatingWindow *floatingWindow, QPoint globalPos) @@ -256,12 +246,12 @@ bool DropArea::drop(QWidgetOrQuick *droppedWindow, KDDockWidgets::Location locat auto frame = Config::self().frameworkWidgetFactory()->createFrame(); frame->addWidget(dock); - m_layout->addWidget(frame, location, relativeTo, DefaultSizeMode::FairButFloor); + addWidget(frame, location, relativeTo, DefaultSizeMode::FairButFloor); } else if (auto floatingWindow = qobject_cast(droppedWindow)) { if (!validateAffinity(floatingWindow)) return false; - m_layout->addMultiSplitter(floatingWindow->dropArea(), location, relativeTo); + addMultiSplitter(floatingWindow->dropArea(), location, relativeTo); floatingWindow->scheduleDeleteLater(); return true; } else { diff --git a/src/private/DropAreaWithCentralFrame.cpp b/src/private/DropAreaWithCentralFrame.cpp index 11265ef5..9d8ab817 100644 --- a/src/private/DropAreaWithCentralFrame.cpp +++ b/src/private/DropAreaWithCentralFrame.cpp @@ -29,7 +29,7 @@ DropAreaWithCentralFrame::DropAreaWithCentralFrame(QWidgetOrQuick *parent, MainW , m_centralFrame(createCentralFrame(options)) { if (m_centralFrame) - m_layout->addWidget(m_centralFrame, KDDockWidgets::Location_OnTop, {}); + addWidget(m_centralFrame, KDDockWidgets::Location_OnTop, {}); } DropAreaWithCentralFrame::~DropAreaWithCentralFrame() diff --git a/src/private/DropArea_p.h b/src/private/DropArea_p.h index 49c825f1..e21f313d 100644 --- a/src/private/DropArea_p.h +++ b/src/private/DropArea_p.h @@ -32,7 +32,6 @@ #include "Frame_p.h" #include "KDDockWidgets.h" #include "widgets/MultiSplitter_p.h" -#include "widgets/MultiSplitterLayout_p.h" #include "DropIndicatorOverlayInterface_p.h" namespace KDDockWidgets { @@ -62,11 +61,9 @@ public: DropIndicatorOverlayInterface *dropIndicatorOverlay() const { return m_dropIndicatorOverlay; } void addDockWidget(DockWidgetBase *, KDDockWidgets::Location location, DockWidgetBase *relativeTo, AddingOption option = {}); - bool checkSanity(); bool contains(DockWidgetBase *) const; QStringList affinities() const; - void layoutEqually(); void layoutParentContainerEqually(DockWidgetBase *); private: Q_DISABLE_COPY(DropArea) diff --git a/src/private/FloatingWindow.cpp b/src/private/FloatingWindow.cpp index 4e93d0b1..66d9a401 100644 --- a/src/private/FloatingWindow.cpp +++ b/src/private/FloatingWindow.cpp @@ -22,7 +22,6 @@ #include "MainWindowBase.h" #include "Logging_p.h" #include "Frame_p.h" -#include "widgets/MultiSplitterLayout_p.h" #include "DropArea_p.h" #include "TitleBar_p.h" #include "WindowBeingDragged_p.h" @@ -96,8 +95,6 @@ FloatingWindow::FloatingWindow(MainWindowBase *parent) } #endif - auto ms = m_dropArea->multiSplitterLayout(); - DockRegistry::self()->registerNestedWindow(this); qCDebug(creation) << "FloatingWindow()" << this; @@ -112,10 +109,10 @@ FloatingWindow::FloatingWindow(MainWindowBase *parent) maybeCreateResizeHandler(); updateTitleBarVisibility(); - connect(ms, &MultiSplitterLayout::visibleWidgetCountChanged, this, &FloatingWindow::onFrameCountChanged); - connect(ms, &MultiSplitterLayout::visibleWidgetCountChanged, this, &FloatingWindow::numFramesChanged); - connect(ms, &MultiSplitterLayout::visibleWidgetCountChanged, this, &FloatingWindow::onVisibleFrameCountChanged); - m_layoutDestroyedConnection = connect(ms, &MultiSplitterLayout::destroyed, this, &FloatingWindow::scheduleDeleteLater); + connect(m_dropArea, &MultiSplitter::visibleWidgetCountChanged, this, &FloatingWindow::onFrameCountChanged); + connect(m_dropArea, &MultiSplitter::visibleWidgetCountChanged, this, &FloatingWindow::numFramesChanged); + connect(m_dropArea, &MultiSplitter::visibleWidgetCountChanged, this, &FloatingWindow::onVisibleFrameCountChanged); + m_layoutDestroyedConnection = connect(m_dropArea, &QObject::destroyed, this, &FloatingWindow::scheduleDeleteLater); } static MainWindowBase* hackFindParentHarder(Frame *frame, MainWindowBase *candidateParent) @@ -160,7 +157,7 @@ FloatingWindow::FloatingWindow(Frame *frame, MainWindowBase *parent) // Adding a widget will trigger onFrameCountChanged, which triggers a setVisible(true). // The problem with setVisible(true) will forget about or requested geometry and place the window at 0,0 // So disable the setVisible(true) call while in the ctor. - m_dropArea->multiSplitterLayout()->addWidget(frame, KDDockWidgets::Location_OnTop, {}); + m_dropArea->addWidget(frame, KDDockWidgets::Location_OnTop, {}); m_disableSetVisible = false; } @@ -248,9 +245,9 @@ void FloatingWindow::scheduleDeleteLater() deleteLater(); } -MultiSplitterLayout *FloatingWindow::multiSplitterLayout() const +MultiSplitter *FloatingWindow::multiSplitter() const { - return m_dropArea->multiSplitterLayout(); + return m_dropArea; } bool FloatingWindow::isInTitleBar(QPoint globalPoint) const @@ -405,7 +402,7 @@ void FloatingWindow::onCloseEvent(QCloseEvent *e) bool FloatingWindow::deserialize(const LayoutSaver::FloatingWindow &fw) { - if (dropArea()->multiSplitterLayout()->deserialize(fw.multiSplitterLayout)) { + if (dropArea()->deserialize(fw.multiSplitterLayout)) { updateTitleBarVisibility(); show(); return true; @@ -420,7 +417,7 @@ LayoutSaver::FloatingWindow FloatingWindow::serialize() const fw.geometry = geometry(); fw.isVisible = isVisible(); - fw.multiSplitterLayout = dropArea()->multiSplitterLayout()->serialize(); + fw.multiSplitterLayout = dropArea()->serialize(); fw.screenIndex = screenNumberForWidget(this); fw.screenSize = screenSizeForWidget(this); fw.affinities = affinities(); diff --git a/src/private/FloatingWindow_p.h b/src/private/FloatingWindow_p.h index bc2c1f6f..35f49638 100644 --- a/src/private/FloatingWindow_p.h +++ b/src/private/FloatingWindow_p.h @@ -37,7 +37,7 @@ namespace KDDockWidgets { class MainWindowBase; class DropArea; class Frame; -class MultiSplitterLayout; +class MultiSplitter; class DOCKS_EXPORT FloatingWindow : public QWidgetAdapter , public Draggable @@ -106,9 +106,9 @@ public: void scheduleDeleteLater(); /** - * @brief Returns the MultiSplitterLayout + * @brief Returns the MultiSplitter */ - MultiSplitterLayout *multiSplitterLayout() const; + MultiSplitter *multiSplitter() const; /** * @brief Returns whether @p globalPoint is inside the title bar diff --git a/src/private/Frame.cpp b/src/private/Frame.cpp index 8efe3ff7..b98405b7 100644 --- a/src/private/Frame.cpp +++ b/src/private/Frame.cpp @@ -515,7 +515,7 @@ void Frame::setDropArea(DropArea *dt) if (m_dropArea) { // We keep the connect result so we don't dereference m_dropArea at shutdown - m_visibleWidgetCountChangedConnection = connect(m_dropArea->multiSplitterLayout(), &MultiSplitterLayout::visibleWidgetCountChanged, + m_visibleWidgetCountChangedConnection = connect(m_dropArea, &MultiSplitter::visibleWidgetCountChanged, this, &Frame::updateTitleBarVisibility); updateTitleBarVisibility(); if (wasInMainWindow != isInMainWindow()) diff --git a/src/private/Position.cpp b/src/private/Position.cpp index f58870a9..f7c8f060 100644 --- a/src/private/Position.cpp +++ b/src/private/Position.cpp @@ -26,7 +26,6 @@ #include "Position_p.h" #include "DockRegistry_p.h" -#include "widgets/MultiSplitterLayout_p.h" #include "widgets/MultiSplitter_p.h" #include @@ -128,18 +127,18 @@ void Position::removePlaceholder(Layouting::Item *placeholder) void Position::deserialize(const LayoutSaver::Position &lp) { for (const auto &placeholder : qAsConst(lp.placeholders)) { - MultiSplitterLayout *layout; + MultiSplitter *layout; int itemIndex = placeholder.itemIndex; if (placeholder.isFloatingWindow) { if (placeholder.indexOfFloatingWindow == -1) { continue; // Skip } else { FloatingWindow *fw = DockRegistry::self()->nestedwindows().at(placeholder.indexOfFloatingWindow); - layout = fw->multiSplitterLayout(); + layout = fw->multiSplitter(); } } else { MainWindowBase *mainWindow = DockRegistry::self()->mainWindowByName(placeholder.mainWindowUniqueName); - layout = mainWindow->multiSplitterLayout(); + layout = mainWindow->multiSplitter(); } const Layouting::Item::List &items = layout->items(); @@ -165,11 +164,11 @@ LayoutSaver::Position Position::serialize() const LayoutSaver::Placeholder p; Layouting::Item *item = itemRef->item; - MultiSplitterLayout *layout = DockRegistry::self()->layoutForItem(item); + MultiSplitter *layout = DockRegistry::self()->layoutForItem(item); const int itemIndex = layout->items().indexOf(item); - auto fw = layout->multiSplitter()->floatingWindow(); - auto mainWindow = layout->multiSplitter()->mainWindow(); + auto fw = layout->floatingWindow(); + auto mainWindow = layout->mainWindow(); Q_ASSERT(mainWindow || fw); p.isFloatingWindow = fw; diff --git a/src/private/Position_p.h b/src/private/Position_p.h index 97e385b0..06382008 100644 --- a/src/private/Position_p.h +++ b/src/private/Position_p.h @@ -184,7 +184,7 @@ struct LastPositions lastPosition->removePlaceholders(); } - void removePlaceholders(MultiSplitter *hostWidget) const { + void removePlaceholders(const MultiSplitter *hostWidget) const { lastPosition->removePlaceholders(hostWidget); } diff --git a/src/private/indicators/ClassicIndicators.cpp b/src/private/indicators/ClassicIndicators.cpp index c2d8e553..844e80f1 100644 --- a/src/private/indicators/ClassicIndicators.cpp +++ b/src/private/indicators/ClassicIndicators.cpp @@ -367,8 +367,6 @@ void ClassicIndicators::setDropLocation(ClassicIndicators::DropLocation location KDDockWidgets::Location multisplitterLocation = locationToMultisplitterLocation(location); Frame *relativeToFrame = nullptr; - MultiSplitterLayout *layout = m_dropArea->multiSplitterLayout(); - switch (location) { case DropLocation_Left: case DropLocation_Top: @@ -377,7 +375,7 @@ void ClassicIndicators::setDropLocation(ClassicIndicators::DropLocation location if (!m_hoveredFrame) { qWarning() << "ClassicIndicators::setCurrentDropLocation: frame is null. location=" << location << "; windowBeingDragged=" << m_windowBeingDragged - << "; dropArea->widgets=" << layout->items(); + << "; dropArea->widgets=" << m_dropArea->items(); Q_ASSERT(false); return; } @@ -392,8 +390,8 @@ void ClassicIndicators::setDropLocation(ClassicIndicators::DropLocation location break; } - QRect rect = layout->rectForDrop(m_windowBeingDragged, multisplitterLocation, - layout->itemForFrame(relativeToFrame)); + QRect rect = m_dropArea->rectForDrop(m_windowBeingDragged, multisplitterLocation, + m_dropArea->itemForFrame(relativeToFrame)); m_rubberBand->setGeometry(geometryForRubberband(rect)); m_rubberBand->setVisible(true); diff --git a/src/private/widgets/MultiSplitter.cpp b/src/private/widgets/MultiSplitter.cpp index 42d7b64a..9f22d3f3 100644 --- a/src/private/widgets/MultiSplitter.cpp +++ b/src/private/widgets/MultiSplitter.cpp @@ -28,11 +28,18 @@ #include "MultiSplitter_p.h" -#include "MultiSplitterLayout_p.h" -#include "../Logging_p.h" // TODO #include "MainWindowBase.h" #include "FloatingWindow_p.h" #include "LayoutSaver.h" +#include "Logging_p.h" +#include "Frame_p.h" +#include "DockWidgetBase.h" +#include "Position_p.h" +#include "DockRegistry_p.h" +#include "Config.h" +#include "FrameworkWidgetFactory.h" +#include "LayoutSaver.h" +#include "multisplitter/Widget_qwidget.h" #include @@ -41,27 +48,33 @@ using namespace KDDockWidgets; MultiSplitter::MultiSplitter(QWidgetOrQuick *parent) : QWidgetAdapter(parent) , Layouting::Widget_qwidget(this) - , m_layout(new MultiSplitterLayout(this)) { - connect(m_layout, &MultiSplitterLayout::minimumSizeChanged, this, [this] (QSize sz) { - setMinimumSize(sz); - }); - connect(m_layout, &MultiSplitterLayout::sizeChanged, this, [this] (QSize sz) { - if (!m_inResizeEvent && !LayoutSaver::restoreInProgress()) - resize(sz); - }); + Q_ASSERT(parent); + setRootItem(new Layouting::ItemContainer(this)); + DockRegistry::self()->registerLayout(this); - setMinimumSize(m_layout->minimumSize()); + setSize(parent->QWidget::size()); + + qCDebug(multisplittercreation()) << "MultiSplitter"; + + // Initialize min size + updateSizeConstraints(); + + setMinimumSize(minimumSize()); } MultiSplitter::~MultiSplitter() { + qCDebug(multisplittercreation) << "~MultiSplitter" << this; + if (m_rootItem->hostWidget()->asQObject() == this) + delete m_rootItem; + DockRegistry::self()->unregisterLayout(this); } void MultiSplitter::onLayoutRequest() { - m_layout->updateSizeConstraints(); + updateSizeConstraints(); } bool MultiSplitter::onResize(QSize newSize) @@ -73,7 +86,7 @@ bool MultiSplitter::onResize(QSize newSize) if (!LayoutSaver::restoreInProgress()) { // don't resize anything while we're restoring the layout - m_layout->setSize(newSize); + setSize(newSize); } return false; // So QWidget::resizeEvent is called @@ -99,3 +112,367 @@ FloatingWindow *MultiSplitter::floatingWindow() const { return qobject_cast(QWidget::parentWidget()); } + + +bool MultiSplitter::validateInputs(QWidgetOrQuick *widget, + Location location, + const Frame *relativeToFrame, AddingOption option) const +{ + if (!widget) { + qWarning() << Q_FUNC_INFO << "Widget is null"; + return false; + } + + const bool isDockWidget = qobject_cast(widget); + const bool isStartHidden = option & AddingOption_StartHidden; + + if (!qobject_cast(widget) && !qobject_cast(widget) && !isDockWidget) { + qWarning() << "Unknown widget type" << widget; + return false; + } + + if (isDockWidget != isStartHidden) { + qWarning() << "Wrong parameters" << isDockWidget << isStartHidden; + return false; + } + + if (relativeToFrame && relativeToFrame == widget) { + qWarning() << "widget can't be relative to itself"; + return false; + } + + Layouting::Item *item = itemForFrame(qobject_cast(widget)); + + if (contains(item)) { + qWarning() << "MultiSplitter::addWidget: Already contains" << widget; + return false; + } + + if (location == Location_None) { + qWarning() << "MultiSplitter::addWidget: not adding to location None"; + return false; + } + + const bool relativeToThis = relativeToFrame == nullptr; + + Layouting::Item *relativeToItem = itemForFrame(relativeToFrame); + if (!relativeToThis && !contains(relativeToItem)) { + qWarning() << "MultiSplitter::addWidget: Doesn't contain relativeTo:" + << "; relativeToFrame=" << relativeToFrame + << "; relativeToItem=" << relativeToItem + << "; options=" << option; + return false; + } + + return true; +} + +void MultiSplitter::addWidget(QWidgetOrQuick *w, Location location, + Frame *relativeToWidget, DefaultSizeMode defaultSizeMode, + AddingOption option) +{ + auto frame = qobject_cast(w); + qCDebug(addwidget) << Q_FUNC_INFO << w + << "; location=" << locationStr(location) + << "; relativeTo=" << relativeToWidget + << "; size=" << size() + << "; w.size=" << w->size() + << "; frame=" << frame + << "; option=" << option; + + if (itemForFrame(frame) != nullptr) { + // Item already exists, remove it. + // Changing the frame parent will make the item clean itself up. It turns into a placeholder and is removed by unrefOldPlaceholders + frame->QWidget::setParent(nullptr); // so ~Item doesn't delete it + frame->setLayoutItem(nullptr); // so Item is destroyed, as there's no refs to it + } + + // Make some sanity checks: + if (!validateInputs(w, location, relativeToWidget, option)) + return; + + Layouting::Item *relativeTo = itemForFrame(relativeToWidget); + if (!relativeTo) + relativeTo = m_rootItem; + + Layouting::Item *newItem = nullptr; + + Frame::List frames = framesFrom(w); + unrefOldPlaceholders(frames); + auto dw = qobject_cast(w); + + if (frame) { + newItem = new Layouting::Item(this); + newItem->setGuestWidget(frame); + } else if (dw) { + newItem = new Layouting::Item(this); + frame = Config::self().frameworkWidgetFactory()->createFrame(); + newItem->setGuestWidget(frame); + frame->addWidget(dw, option); + } else if (auto ms = qobject_cast(w)) { + newItem = ms->rootItem(); + Q_ASSERT(newItem->hostWidget()->asQWidget() != this); + newItem->setHostWidget(this); + delete ms; + } + + Q_ASSERT(!newItem->geometry().isEmpty()); + relativeTo->insertItem(newItem, Layouting::Item::Location(location), + Layouting::Item::DefaultSizeMode(defaultSizeMode), Layouting::Item::AddingOption(option)); + + if (dw && option && AddingOption_StartHidden) + delete frame; +} + +void MultiSplitter::addMultiSplitter(MultiSplitter *sourceMultiSplitter, + Location location, + Frame *relativeTo) +{ + qCDebug(addwidget) << Q_FUNC_INFO << sourceMultiSplitter << location << relativeTo; + addWidget(sourceMultiSplitter, location, relativeTo); +} + +void MultiSplitter::removeItem(Layouting::Item *item) +{ + if (!item) + qWarning() << Q_FUNC_INFO << "nullptr item"; + + if (!item) + return; + + item->parentContainer()->removeItem(item); +} + +bool MultiSplitter::contains(const Layouting::Item *item) const +{ + return m_rootItem->contains_recursive(item); +} + +bool MultiSplitter::contains(const Frame *frame) const +{ + return itemForFrame(frame) != nullptr; +} + +int MultiSplitter::count() const +{ + return m_rootItem->count_recursive(); +} + +int MultiSplitter::visibleCount() const +{ + return m_rootItem->visibleCount_recursive(); +} + +int MultiSplitter::placeholderCount() const +{ + return count() - visibleCount(); +} + +Layouting::Separator::List MultiSplitter::separators() const +{ + return m_rootItem->separators_recursive(); +} + +void MultiSplitter::updateSizeConstraints() +{ + const QSize newMinSize = m_rootItem->minSize(); + qCDebug(sizing) << Q_FUNC_INFO << "Updating size constraints from" << minimumSize() + << "to" << newMinSize; + + setLayoutMinimumSize(newMinSize); +} + +int MultiSplitter::availableLengthForOrientation(Qt::Orientation orientation) const +{ + if (orientation == Qt::Vertical) + return availableSize().height(); + else + return availableSize().width(); +} + +QSize MultiSplitter::availableSize() const +{ + return m_rootItem->availableSize(); +} + +Layouting::Item *MultiSplitter::itemForFrame(const Frame *frame) const +{ + if (!frame) + return nullptr; + + return m_rootItem->itemForWidget(frame); +} + +Frame::List MultiSplitter::framesFrom(QWidgetOrQuick *frameOrMultiSplitter) const +{ + if (auto frame = qobject_cast(frameOrMultiSplitter)) + return { frame }; + + if (auto msw = qobject_cast(frameOrMultiSplitter)) + return msw->frames(); + + return {}; +} + +Frame::List MultiSplitter::frames() const +{ + const Layouting::Item::List items = m_rootItem->items_recursive(); + + Frame::List result; + result.reserve(items.size()); + + for (Layouting::Item *item : items) { + if (auto f = static_cast(item->guestAsQObject())) + result.push_back(f); + } + + return result; +} + +void MultiSplitter::restorePlaceholder(DockWidgetBase *dw, Layouting::Item *item, int tabIndex) +{ + if (item->isPlaceholder()) { + Frame *newFrame = Config::self().frameworkWidgetFactory()->createFrame(this); + item->restore(newFrame); + } + + auto frame = qobject_cast(item->guestAsQObject()); + Q_ASSERT(frame); + + if (tabIndex != -1 && frame->dockWidgetCount() >= tabIndex) { + frame->insertWidget(dw, tabIndex); + } else { + frame->addWidget(dw); + } + + frame->QWidget::setVisible(true); +} + +void MultiSplitter::layoutEqually() +{ + layoutEqually(m_rootItem); +} + +void MultiSplitter::layoutEqually(Layouting::ItemContainer *container) +{ + if (container) { + container->layoutEqually_recursive(); + } else { + qWarning() << Q_FUNC_INFO << "null container"; + } +} + +bool MultiSplitter::checkSanity() const +{ + return m_rootItem->checkSanity(); +} + +void MultiSplitter::unrefOldPlaceholders(const Frame::List &framesBeingAdded) const +{ + for (Frame *frame : framesBeingAdded) { + for (DockWidgetBase *dw : frame->dockWidgets()) { + dw->lastPositions().removePlaceholders(this); + } + } +} + +void MultiSplitter::dumpDebug() const +{ + m_rootItem->dumpLayout(); +} + +void MultiSplitter::setSize(QSize size) +{ + if (size != this->size()) { + m_rootItem->setSize_recursive(size); + if (!m_inResizeEvent && !LayoutSaver::restoreInProgress()) + resize(size); + } +} + +QSize MultiSplitter::layoutMinimumSize() const +{ + return m_rootItem->minSize(); +} + +QSize MultiSplitter::size() const { return m_rootItem->size(); } + +void MultiSplitter::setLayoutMinimumSize(QSize sz) +{ + if (sz != m_rootItem->minSize()) { + setSize(size().expandedTo(m_rootItem->minSize())); // Increase size in case we need to + m_rootItem->setMinSize(sz); + } + + qCDebug(sizing) << Q_FUNC_INFO << "minSize = " << m_rootItem->minSize(); +} + +void MultiSplitter::setRootItem(Layouting::ItemContainer *root) +{ + delete m_rootItem; + m_rootItem = root; + connect(m_rootItem, &Layouting::ItemContainer::numVisibleItemsChanged, + this, &MultiSplitter::visibleWidgetCountChanged); + connect(m_rootItem, &Layouting::ItemContainer::minSizeChanged, this, [this] { + setMinimumSize(layoutMinimumSize()); + }); +} + +const Layouting::Item::List MultiSplitter::items() const +{ + return m_rootItem->items_recursive(); +} + +Layouting::ItemContainer *MultiSplitter::rootItem() const +{ + return m_rootItem; +} + +QRect MultiSplitter::rectForDrop(const QWidgetOrQuick *widget, Location location, + const Layouting::Item *relativeTo) const +{ + Layouting::Item item(nullptr); + item.setSize(widget->size()); + item.setMinSize(Layouting::Widget_qwidget::widgetMinSize(widget)); + item.setMaxSizeHint(widget->maximumSize()); + + Layouting::ItemContainer *container = relativeTo ? relativeTo->parentContainer() + : m_rootItem; + + return container->suggestedDropRect(&item, relativeTo, Layouting::Item::Location(location)); +} + +bool MultiSplitter::deserialize(const LayoutSaver::MultiSplitterLayout &l) +{ + setRootItem(new Layouting::ItemContainer(this)); + + QHash frames; + for (const LayoutSaver::Frame &frame : qAsConst(l.frames)) { + Frame *f = Frame::deserialize(frame); + Q_ASSERT(!frame.id.isEmpty()); + frames.insert(frame.id, f); + } + + m_rootItem->fillFromVariantMap(l.layout, frames); + + updateSizeConstraints(); + m_rootItem->setSize_recursive(QWidget::size()); + + return true; +} + +LayoutSaver::MultiSplitterLayout MultiSplitter::serialize() const +{ + LayoutSaver::MultiSplitterLayout l; + l.layout = m_rootItem->toVariantMap(); + const Layouting::Item::List items = m_rootItem->items_recursive(); + l.frames.reserve(items.size()); + for (Layouting::Item *item : items) { + if (!item->isContainer()) { + if (auto frame = qobject_cast(item->guestAsQObject())) + l.frames.insert(QString::number(qint64(frame)), frame->serialize()); + } + } + + return l; +} diff --git a/src/private/widgets/MultiSplitterLayout.cpp b/src/private/widgets/MultiSplitterLayout.cpp deleted file mode 100644 index ea0a5a06..00000000 --- a/src/private/widgets/MultiSplitterLayout.cpp +++ /dev/null @@ -1,424 +0,0 @@ -/* - This file is part of KDDockWidgets. - - Copyright (C) 2018-2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com - Author: Sérgio Martins - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "MultiSplitterLayout_p.h" -#include "Logging_p.h" -#include "MultiSplitter_p.h" -#include "Frame_p.h" -#include "DockWidgetBase.h" -#include "Position_p.h" -#include "DockRegistry_p.h" -#include "Config.h" -#include "FrameworkWidgetFactory.h" -#include "LayoutSaver.h" -#include "multisplitter/Widget_qwidget.h" - -using namespace KDDockWidgets; - -MultiSplitterLayout::MultiSplitterLayout(MultiSplitter *parent) - : QObject(parent) - , m_multiSplitter(parent) -{ - Q_ASSERT(parent); - setRootItem(new Layouting::ItemContainer(m_multiSplitter)); - DockRegistry::self()->registerLayout(this); - - setSize(parent->QWidget::size()); - - qCDebug(multisplittercreation()) << "MultiSplitter"; - - // Initialize min size - updateSizeConstraints(); -} - -MultiSplitterLayout::~MultiSplitterLayout() -{ - qCDebug(multisplittercreation) << "~MultiSplitter" << this; - if (m_rootItem->hostWidget()->asQObject() == multiSplitter()) - delete m_rootItem; - DockRegistry::self()->unregisterLayout(this); -} - -MultiSplitter *MultiSplitterLayout::multiSplitter() const -{ - return m_multiSplitter; -} - -bool MultiSplitterLayout::validateInputs(QWidgetOrQuick *widget, - Location location, - const Frame *relativeToFrame, AddingOption option) const -{ - if (!widget) { - qWarning() << Q_FUNC_INFO << "Widget is null"; - return false; - } - - const bool isDockWidget = qobject_cast(widget); - const bool isStartHidden = option & AddingOption_StartHidden; - - if (!qobject_cast(widget) && !qobject_cast(widget) && !isDockWidget) { - qWarning() << "Unknown widget type" << widget; - return false; - } - - if (isDockWidget != isStartHidden) { - qWarning() << "Wrong parameters" << isDockWidget << isStartHidden; - return false; - } - - if (relativeToFrame && relativeToFrame == widget) { - qWarning() << "widget can't be relative to itself"; - return false; - } - - Layouting::Item *item = itemForFrame(qobject_cast(widget)); - - if (contains(item)) { - qWarning() << "MultiSplitterLayout::addWidget: Already contains" << widget; - return false; - } - - if (location == Location_None) { - qWarning() << "MultiSplitterLayout::addWidget: not adding to location None"; - return false; - } - - const bool relativeToThis = relativeToFrame == nullptr; - - Layouting::Item *relativeToItem = itemForFrame(relativeToFrame); - if (!relativeToThis && !contains(relativeToItem)) { - qWarning() << "MultiSplitterLayout::addWidget: Doesn't contain relativeTo:" - << "; relativeToFrame=" << relativeToFrame - << "; relativeToItem=" << relativeToItem - << "; options=" << option; - return false; - } - - return true; -} - -void MultiSplitterLayout::addWidget(QWidgetOrQuick *w, Location location, - Frame *relativeToWidget, DefaultSizeMode defaultSizeMode, - AddingOption option) -{ - auto frame = qobject_cast(w); - qCDebug(addwidget) << Q_FUNC_INFO << w - << "; location=" << locationStr(location) - << "; relativeTo=" << relativeToWidget - << "; size=" << size() - << "; w.size=" << w->size() - << "; frame=" << frame - << "; option=" << option; - - if (itemForFrame(frame) != nullptr) { - // Item already exists, remove it. - // Changing the frame parent will make the item clean itself up. It turns into a placeholder and is removed by unrefOldPlaceholders - frame->QWidget::setParent(nullptr); // so ~Item doesn't delete it - frame->setLayoutItem(nullptr); // so Item is destroyed, as there's no refs to it - } - - // Make some sanity checks: - if (!validateInputs(w, location, relativeToWidget, option)) - return; - - Layouting::Item *relativeTo = itemForFrame(relativeToWidget); - if (!relativeTo) - relativeTo = m_rootItem; - - Layouting::Item *newItem = nullptr; - - Frame::List frames = framesFrom(w); - unrefOldPlaceholders(frames); - auto dw = qobject_cast(w); - - if (frame) { - newItem = new Layouting::Item(m_multiSplitter); - newItem->setGuestWidget(frame); - } else if (dw) { - newItem = new Layouting::Item(m_multiSplitter); - frame = Config::self().frameworkWidgetFactory()->createFrame(); - newItem->setGuestWidget(frame); - frame->addWidget(dw, option); - } else if (auto ms = qobject_cast(w)) { - newItem = ms->multiSplitterLayout()->rootItem(); - Q_ASSERT(newItem->hostWidget()->asQWidget() != multiSplitter()); - newItem->setHostWidget(m_multiSplitter); - delete ms; - } - - Q_ASSERT(!newItem->geometry().isEmpty()); - relativeTo->insertItem(newItem, Layouting::Item::Location(location), - Layouting::Item::DefaultSizeMode(defaultSizeMode), Layouting::Item::AddingOption(option)); - - if (dw && option && AddingOption_StartHidden) - delete frame; -} - -void MultiSplitterLayout::addMultiSplitter(MultiSplitter *sourceMultiSplitter, - Location location, - Frame *relativeTo) -{ - qCDebug(addwidget) << Q_FUNC_INFO << sourceMultiSplitter << location << relativeTo; - addWidget(sourceMultiSplitter, location, relativeTo); -} - -void MultiSplitterLayout::removeItem(Layouting::Item *item) -{ - if (!item) - qWarning() << Q_FUNC_INFO << "nullptr item"; - - if (!item) - return; - - item->parentContainer()->removeItem(item); -} - -bool MultiSplitterLayout::contains(const Layouting::Item *item) const -{ - return m_rootItem->contains_recursive(item); -} - -bool MultiSplitterLayout::contains(const Frame *frame) const -{ - return itemForFrame(frame) != nullptr; -} - -int MultiSplitterLayout::count() const -{ - return m_rootItem->count_recursive(); -} - -int MultiSplitterLayout::visibleCount() const -{ - return m_rootItem->visibleCount_recursive(); -} - -int MultiSplitterLayout::placeholderCount() const -{ - return count() - visibleCount(); -} - -Layouting::Separator::List MultiSplitterLayout::separators() const -{ - return m_rootItem->separators_recursive(); -} - -void MultiSplitterLayout::updateSizeConstraints() -{ - const QSize newMinSize = m_rootItem->minSize(); - qCDebug(sizing) << Q_FUNC_INFO << "Updating size constraints from" << minimumSize() - << "to" << newMinSize; - - setMinimumSize(newMinSize); -} - -int MultiSplitterLayout::availableLengthForOrientation(Qt::Orientation orientation) const -{ - if (orientation == Qt::Vertical) - return availableSize().height(); - else - return availableSize().width(); -} - -QSize MultiSplitterLayout::availableSize() const -{ - return m_rootItem->availableSize(); -} - -Layouting::Item *MultiSplitterLayout::itemForFrame(const Frame *frame) const -{ - if (!frame) - return nullptr; - - return m_rootItem->itemForWidget(frame); -} - -Frame::List MultiSplitterLayout::framesFrom(QWidgetOrQuick *frameOrMultiSplitter) const -{ - if (auto frame = qobject_cast(frameOrMultiSplitter)) - return { frame }; - - if (auto msw = qobject_cast(frameOrMultiSplitter)) - return msw->multiSplitterLayout()->frames(); - - return {}; -} - -Frame::List MultiSplitterLayout::frames() const -{ - const Layouting::Item::List items = m_rootItem->items_recursive(); - - Frame::List result; - result.reserve(items.size()); - - for (Layouting::Item *item : items) { - if (auto f = static_cast(item->guestAsQObject())) - result.push_back(f); - } - - return result; -} - -void MultiSplitterLayout::restorePlaceholder(DockWidgetBase *dw, Layouting::Item *item, int tabIndex) -{ - if (item->isPlaceholder()) { - Frame *newFrame = Config::self().frameworkWidgetFactory()->createFrame(multiSplitter()); - item->restore(newFrame); - } - - auto frame = qobject_cast(item->guestAsQObject()); - Q_ASSERT(frame); - - if (tabIndex != -1 && frame->dockWidgetCount() >= tabIndex) { - frame->insertWidget(dw, tabIndex); - } else { - frame->addWidget(dw); - } - - frame->QWidget::setVisible(true); -} - -void MultiSplitterLayout::layoutEqually() -{ - layoutEqually(m_rootItem); -} - -void MultiSplitterLayout::layoutEqually(Layouting::ItemContainer *container) -{ - if (container) { - container->layoutEqually_recursive(); - } else { - qWarning() << Q_FUNC_INFO << "null container"; - } -} - -bool MultiSplitterLayout::checkSanity() const -{ - return m_rootItem->checkSanity(); -} - -void MultiSplitterLayout::unrefOldPlaceholders(const Frame::List &framesBeingAdded) const -{ - for (Frame *frame : framesBeingAdded) { - for (DockWidgetBase *dw : frame->dockWidgets()) { - dw->lastPositions().removePlaceholders(multiSplitter()); - } - } -} - -void MultiSplitterLayout::dumpDebug() const -{ - m_rootItem->dumpLayout(); -} - -void MultiSplitterLayout::setSize(QSize size) -{ - if (size != this->size()) { - m_rootItem->setSize_recursive(size); - Q_EMIT sizeChanged(size); - } -} - -QSize MultiSplitterLayout::minimumSize() const -{ - return m_rootItem->minSize(); -} - -QSize MultiSplitterLayout::size() const { return m_rootItem->size(); } - -void MultiSplitterLayout::setMinimumSize(QSize sz) -{ - if (sz != m_rootItem->minSize()) { - setSize(size().expandedTo(m_rootItem->minSize())); // Increase size in case we need to - m_rootItem->setMinSize(sz); - } - - qCDebug(sizing) << Q_FUNC_INFO << "minSize = " << m_rootItem->minSize(); -} - -void MultiSplitterLayout::setRootItem(Layouting::ItemContainer *root) -{ - delete m_rootItem; - m_rootItem = root; - connect(m_rootItem, &Layouting::ItemContainer::numVisibleItemsChanged, - this, &MultiSplitterLayout::visibleWidgetCountChanged); - connect(m_rootItem, &Layouting::ItemContainer::minSizeChanged, this, [this] { - Q_EMIT minimumSizeChanged(minimumSize()); - }); -} - -const Layouting::Item::List MultiSplitterLayout::items() const -{ - return m_rootItem->items_recursive(); -} - -Layouting::ItemContainer *MultiSplitterLayout::rootItem() const -{ - return m_rootItem; -} - -QRect MultiSplitterLayout::rectForDrop(const QWidgetOrQuick *widget, Location location, - const Layouting::Item *relativeTo) const -{ - Layouting::Item item(nullptr); - item.setSize(widget->size()); - item.setMinSize(Layouting::Widget_qwidget::widgetMinSize(widget)); - item.setMaxSizeHint(widget->maximumSize()); - - Layouting::ItemContainer *container = relativeTo ? relativeTo->parentContainer() - : m_rootItem; - - return container->suggestedDropRect(&item, relativeTo, Layouting::Item::Location(location)); -} - -bool MultiSplitterLayout::deserialize(const LayoutSaver::MultiSplitterLayout &l) -{ - setRootItem(new Layouting::ItemContainer(m_multiSplitter)); - - QHash frames; - for (const LayoutSaver::Frame &frame : qAsConst(l.frames)) { - Frame *f = Frame::deserialize(frame); - Q_ASSERT(!frame.id.isEmpty()); - frames.insert(frame.id, f); - } - - m_rootItem->fillFromVariantMap(l.layout, frames); - - updateSizeConstraints(); - m_rootItem->setSize_recursive(multiSplitter()->QWidget::size()); - - return true; -} - -LayoutSaver::MultiSplitterLayout MultiSplitterLayout::serialize() const -{ - LayoutSaver::MultiSplitterLayout l; - l.layout = m_rootItem->toVariantMap(); - const Layouting::Item::List items = m_rootItem->items_recursive(); - l.frames.reserve(items.size()); - for (Layouting::Item *item : items) { - if (!item->isContainer()) { - if (auto frame = qobject_cast(item->guestAsQObject())) - l.frames.insert(QString::number(qint64(frame)), frame->serialize()); - } - } - - return l; -} diff --git a/src/private/widgets/MultiSplitterLayout_p.h b/src/private/widgets/MultiSplitterLayout_p.h deleted file mode 100644 index 95a27f8e..00000000 --- a/src/private/widgets/MultiSplitterLayout_p.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - This file is part of KDDockWidgets. - - Copyright (C) 2018-2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com - Author: Sérgio Martins - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file - * @brief A class to layout widgets in any place relative to another widget. - * - * Widgets can be inserted to the left,right,top,bottom in relation to another widget or in relation - * to the window. Each two neighbour widgets have a separator in between, which the user can use - * to resize. - * - * @author Sérgio Martins \ - */ - -#ifndef KD_MULTISPLITTER_LAYOUT_P_H -#define KD_MULTISPLITTER_LAYOUT_P_H - - -#include "multisplitter/Separator_p.h" -#include "docks_export.h" -#include "KDDockWidgets.h" -#include "LayoutSaver_p.h" -#include "QWidgetAdapter.h" - -#include - -namespace Layouting { -class Item; -class Separator; -class Widget_qwidget; -} - -namespace KDDockWidgets { - -class MultiSplitter; -class Frame; - -namespace Debug { -class DebugWindow; -} - -/** - * MultiSplitterLayout is simply a wrapper around Layouting::Item in which the hosted widgets are - * of class KDDockWidgets::Frame. The stuff in Layouting:: being agnostic and generic, not specific - * to KDDW. - * - * A MultiSplitter is like a QSplitter but supports mixing vertical and horizontal splitters in - * any combination. - * - * It supports adding a widget to the left/top/bottom/right of the whole MultiSplitter or adding - * relative to a single widget. - */ -class DOCKS_EXPORT_FOR_UNIT_TESTS MultiSplitterLayout : public QObject // clazy:exclude=ctor-missing-parent-argument -{ - Q_OBJECT -public: - /** - * @brief Constructor. MultiSplitterLayout is created by MultiSplitter only. - */ - explicit MultiSplitterLayout(MultiSplitter *parent); - ~MultiSplitterLayout() override; - - /** - * @brief returns the widget that this layout manages - */ - MultiSplitter *multiSplitter() const; - - /** - * @brief Adds a widget to this MultiSplitter. - */ - void addWidget(QWidgetOrQuick *widget, KDDockWidgets::Location location, - Frame *relativeTo = nullptr, DefaultSizeMode = DefaultSizeMode::Fair, AddingOption option = {}); - - /** - * Adds an entire MultiSplitter into this layout. The donor MultiSplitter will be deleted - * after all its Frames are stolen. All added Frames will preserve their original layout, so, - * if widgetFoo was at the left of widgetBar when in the donor splitter, then it will still be at left - * of widgetBar when the whole splitter is dropped into this one. - */ - void addMultiSplitter(MultiSplitter *splitter, KDDockWidgets::Location location, - Frame *relativeTo = nullptr); - - /** - * @brief Removes an item from this MultiSplitter. - */ - void removeItem(Layouting::Item *item); - - /** - * @brief Returns true if this layout contains the specified item. - */ - bool contains(const Layouting::Item *) const; - - /** - * @brief Returns true if this layout contains the specified frame. - */ - bool contains(const Frame *) const; - - /** - * @brief Returns the number of Item objects in this layout. - * This includes non-visible (placeholder) Items too. - * @sa visibleCount - */ - int count() const; - - /** - * @brief Returns the number of visible Items in this layout. - * Which is @ref count minus @ref placeholderCount - * @sa count - */ - int visibleCount() const; - - /** - * @brief Returns the number of placeholder items in this layout. - * This is the same as @ref count minus @ref visibleCount - * @sa count, visibleCount - */ - int placeholderCount() const; - - /** - * @brief The list of items in this layout. - */ - const QVector items() const; - - /** - * @brief Returns the root container item - */ - Layouting::ItemContainer *rootItem() const; - - /** - * Called by the indicators, so they draw the drop rubber band at the correct place. - * The rect for the rubberband when dropping a widget at the specified location. - * Excludes the Separator thickness, result is actually smaller than what needed. In other words, - * the result will be exactly the same as the geometry the widget will get. - */ - QRect rectForDrop(const QWidgetOrQuick *widget, KDDockWidgets::Location location, const Layouting::Item *relativeTo) const; - - bool deserialize(const LayoutSaver::MultiSplitterLayout &); - LayoutSaver::MultiSplitterLayout serialize() const; - - ///@brief returns the list of separators - QVector separators() const; - - /** - * @brief Updates the min size of this layout. - */ - void updateSizeConstraints(); - - /** - * @brief setter for the contents size - * The "contents size" is just the size() of this layout. However, since resizing - * QWidgets is async and we need it to be sync. As sometimes adding widgets will increase - * the MultiSplitterLayout size (due to widget's min-size constraints). - */ - void setSize(QSize); - - /** - * @brief returns the contents width. - * Usually it's the same width as the respective parent MultiSplitter. - */ - int width() const { return size().width(); } - - /** - * @brief returns the contents height. - * Usually it's the same height as the respective parent MultiSplitter. - */ - int height() const { return size().height(); } - - /** - * @brief returns the layout's minimum size - * @ref setMinimumSize - */ - QSize minimumSize() const; - - /** - * @brief getter for the size - */ - QSize size() const; - - /// @brief Runs some sanity checks. Returns true if everything is OK - bool checkSanity() const; - - /// @brief dumps the layout to stderr - void dumpDebug() const; - - /** - * @brief returns the Item that holds @p frame in this layout - */ - Layouting::Item *itemForFrame(const Frame *frame) const; - - /** - * @brief Returns a list of Frame objects contained in this layout - */ - QList frames() const; - - /// @brief restores the dockwidget @p dw to its previous position - void restorePlaceholder(DockWidgetBase *dw, Layouting::Item *, int tabIndex); - - /// @brief See docs for MainWindowBase::layoutEqually() - void layoutEqually(); - - /// @brief overload that just resizes widgets within a sub-tree - void layoutEqually(Layouting::ItemContainer *); - -Q_SIGNALS: - void visibleWidgetCountChanged(int count); - - ///@brief emitted when the size changes - ///@sa size - void sizeChanged(QSize sz); - - ///@brief emitted when the minimumSize changes - ///@sa minimumSize - void minimumSizeChanged(QSize); - -private: - friend class TestDocks; - - /** - * @brief returns the frames contained in @p frameOrMultiSplitter - * If frameOrMultiSplitter is a Frame, it returns a list of 1 element, with that frame - * If frameOrMultiSplitter is a MultiSplitterLayout then it returns a list of all frames it contains - */ - QList framesFrom(QWidgetOrQuick *frameOrMultiSplitter) const; - - - // For debug/hardening - bool validateInputs(QWidgetOrQuick *widget, KDDockWidgets::Location location, - const Frame *relativeToFrame, AddingOption option) const; - - /** - * @brief Removes unneeded placeholder items when adding new frames. - * - * A floating frame A might have a placeholder in the main window (for example to remember its position on the Left), - * but then the user might attach it to the right, so the left placeholder is no longer need. - * Right before adding the frame to the right we remove the left placeholder, otherwise it's unrefed while we're adding - * causing a segfault. So what this does is making the unrefing happen a bit earlier. - */ - void unrefOldPlaceholders(const QList &framesBeingAdded) const; - - /** - * @brief setter for the minimum size - * @ref minimumSize - */ - void setMinimumSize(QSize); - - void setRootItem(Layouting::ItemContainer *); - - /** - * @brief Like @ref availableLengthForDrop but just returns the total available width or height (depending on @p orientation) - * So no need to receive any location. - * @param orientation If Qt::Vertical then returns the available height. Width otherwise. - */ - int availableLengthForOrientation(Qt::Orientation orientation) const; - - /** - * @brief Equivalent to @ref availableLengthForOrientation but returns for both orientations. - * width is for Qt::Vertical. - */ - QSize availableSize() const; - - MultiSplitter *const m_multiSplitter; - Layouting::ItemContainer *m_rootItem = nullptr; -}; - -} - -#endif diff --git a/src/private/widgets/MultiSplitter_p.h b/src/private/widgets/MultiSplitter_p.h index 9b5d9049..cfa60844 100644 --- a/src/private/widgets/MultiSplitter_p.h +++ b/src/private/widgets/MultiSplitter_p.h @@ -23,6 +23,8 @@ * @brief A widget that supports an arbitrary number of splitters (called Separators) in any * combination of vertical/horizontal. * + * This is a widget wrapper around the multisplitter layout (Layouting::Item) + * * @author Sérgio Martins \ */ @@ -31,19 +33,35 @@ #include "docks_export.h" #include "multisplitter/Widget_qwidget.h" +#include "multisplitter/Separator_p.h" #include "QWidgetAdapter.h" +#include "KDDockWidgets.h" +#include "LayoutSaver_p.h" + + +namespace Layouting { +class Item; +class Separator; +class Widget_qwidget; +} namespace KDDockWidgets { -class MultiSplitterLayout; class MainWindowBase; class FloatingWindow; +class Frame; + /** - * @brief A widget that supports an arbitrary number of splitters (called Separators) in any - * combination of vertical/horizontal. + * MultiSplitter is simply a wrapper around Layouting::Item in which the hosted widgets are + * of class KDDockWidgets::Frame. The stuff in Layouting:: being agnostic and generic, not specific + * to KDDW. * - * The actual layouting is done by @ref Layouting::Item. + * A MultiSplitter is like a QSplitter but supports mixing vertical and horizontal splitters in + * any combination. + * + * It supports adding a widget to the left/top/bottom/right of the whole MultiSplitter or adding + * relative to a single widget. */ class DOCKS_EXPORT_FOR_UNIT_TESTS MultiSplitter : public QWidgetAdapter @@ -53,16 +71,201 @@ class DOCKS_EXPORT_FOR_UNIT_TESTS MultiSplitter public: explicit MultiSplitter(QWidgetOrQuick *parent = nullptr); ~MultiSplitter() override; - MultiSplitterLayout *multiSplitterLayout() const { return m_layout; } bool isInMainWindow() const; MainWindowBase* mainWindow() const; FloatingWindow* floatingWindow() const; + + /** + * @brief Adds a widget to this MultiSplitter. + */ + void addWidget(QWidgetOrQuick *widget, KDDockWidgets::Location location, + Frame *relativeTo = nullptr, DefaultSizeMode = DefaultSizeMode::Fair, AddingOption option = {}); + + /** + * Adds an entire MultiSplitter into this layout. The donor MultiSplitter will be deleted + * after all its Frames are stolen. All added Frames will preserve their original layout, so, + * if widgetFoo was at the left of widgetBar when in the donor splitter, then it will still be at left + * of widgetBar when the whole splitter is dropped into this one. + */ + void addMultiSplitter(MultiSplitter *splitter, KDDockWidgets::Location location, + Frame *relativeTo = nullptr); + + /** + * @brief Removes an item from this MultiSplitter. + */ + void removeItem(Layouting::Item *item); + + /** + * @brief Returns true if this layout contains the specified item. + */ + bool contains(const Layouting::Item *) const; + + /** + * @brief Returns true if this layout contains the specified frame. + */ + bool contains(const Frame *) const; + + /** + * @brief Returns the number of Item objects in this layout. + * This includes non-visible (placeholder) Items too. + * @sa visibleCount + */ + int count() const; + + /** + * @brief Returns the number of visible Items in this layout. + * Which is @ref count minus @ref placeholderCount + * @sa count + */ + int visibleCount() const; + + /** + * @brief Returns the number of placeholder items in this layout. + * This is the same as @ref count minus @ref visibleCount + * @sa count, visibleCount + */ + int placeholderCount() const; + + /** + * @brief The list of items in this layout. + */ + const QVector items() const; + + /** + * @brief Returns the root container item + */ + Layouting::ItemContainer *rootItem() const; + + /** + * Called by the indicators, so they draw the drop rubber band at the correct place. + * The rect for the rubberband when dropping a widget at the specified location. + * Excludes the Separator thickness, result is actually smaller than what needed. In other words, + * the result will be exactly the same as the geometry the widget will get. + */ + QRect rectForDrop(const QWidgetOrQuick *widget, KDDockWidgets::Location location, const Layouting::Item *relativeTo) const; + + bool deserialize(const LayoutSaver::MultiSplitterLayout &); + LayoutSaver::MultiSplitterLayout serialize() const; + + ///@brief returns the list of separators + QVector separators() const; + + /** + * @brief Updates the min size of this layout. + */ + void updateSizeConstraints(); + + /** + * @brief setter for the contents size + * The "contents size" is just the size() of this layout. However, since resizing + * QWidgets is async and we need it to be sync. As sometimes adding widgets will increase + * the MultiSplitter size (due to widget's min-size constraints). + */ + void setSize(QSize); + + /** + * @brief returns the contents width. + * Usually it's the same width as the respective parent MultiSplitter. + */ + int width() const { return size().width(); } + + /** + * @brief returns the contents height. + * Usually it's the same height as the respective parent MultiSplitter. + */ + int height() const { return size().height(); } + + /** + * @brief returns the layout's minimum size + * @ref setLayoutMinimumSize + */ + QSize layoutMinimumSize() const; + + /** + * @brief getter for the size + */ + QSize size() const; + + /// @brief Runs some sanity checks. Returns true if everything is OK + bool checkSanity() const; + + /// @brief dumps the layout to stderr + void dumpDebug() const; + + /** + * @brief returns the Item that holds @p frame in this layout + */ + Layouting::Item *itemForFrame(const Frame *frame) const; + + /** + * @brief Returns a list of Frame objects contained in this layout + */ + QList frames() const; + + /// @brief restores the dockwidget @p dw to its previous position + void restorePlaceholder(DockWidgetBase *dw, Layouting::Item *, int tabIndex); + + /// @brief See docs for MainWindowBase::layoutEqually() + void layoutEqually(); + + /// @brief overload that just resizes widgets within a sub-tree + void layoutEqually(Layouting::ItemContainer *); + +Q_SIGNALS: + void visibleWidgetCountChanged(int count); + protected: void onLayoutRequest() override; bool onResize(QSize newSize) override; - MultiSplitterLayout *const m_layout; private: bool m_inResizeEvent = false; + + friend class TestDocks; + + /** + * @brief returns the frames contained in @p frameOrMultiSplitter + * If frameOrMultiSplitter is a Frame, it returns a list of 1 element, with that frame + * If frameOrMultiSplitter is a MultiSplitter then it returns a list of all frames it contains + */ + QList framesFrom(QWidgetOrQuick *frameOrMultiSplitter) const; + + + // For debug/hardening + bool validateInputs(QWidgetOrQuick *widget, KDDockWidgets::Location location, + const Frame *relativeToFrame, AddingOption option) const; + + /** + * @brief Removes unneeded placeholder items when adding new frames. + * + * A floating frame A might have a placeholder in the main window (for example to remember its position on the Left), + * but then the user might attach it to the right, so the left placeholder is no longer need. + * Right before adding the frame to the right we remove the left placeholder, otherwise it's unrefed while we're adding + * causing a segfault. So what this does is making the unrefing happen a bit earlier. + */ + void unrefOldPlaceholders(const QList &framesBeingAdded) const; + + /** + * @brief setter for the minimum size + * @ref minimumSize + */ + void setLayoutMinimumSize(QSize); + + void setRootItem(Layouting::ItemContainer *); + + /** + * @brief Like @ref availableLengthForDrop but just returns the total available width or height (depending on @p orientation) + * So no need to receive any location. + * @param orientation If Qt::Vertical then returns the available height. Width otherwise. + */ + int availableLengthForOrientation(Qt::Orientation orientation) const; + + /** + * @brief Equivalent to @ref availableLengthForOrientation but returns for both orientations. + * width is for Qt::Vertical. + */ + QSize availableSize() const; + + Layouting::ItemContainer *m_rootItem = nullptr; }; } diff --git a/tests/tst_docks.cpp b/tests/tst_docks.cpp index 83c3f661..66fa3278 100644 --- a/tests/tst_docks.cpp +++ b/tests/tst_docks.cpp @@ -462,7 +462,7 @@ void TestDocks::nestDockWidget(DockWidgetBase *dock, DropArea *dropArea, Frame * frame->addWidget(dock); dock->frame()->setObjectName(dock->objectName()); - dropArea->multiSplitterLayout()->addWidget(frame, location, relativeTo); + dropArea->addWidget(frame, location, relativeTo); QVERIFY(dropArea->checkSanity()); } @@ -951,14 +951,14 @@ void TestDocks::tst_mainWindowAlwaysHasCentralWidget() QPointer centralFrame = static_cast(dropArea->centralFrame()->guestAsQObject()); QVERIFY(central); QVERIFY(dropArea); - QCOMPARE(dropArea->multiSplitterLayout()->count(), 1); + QCOMPARE(dropArea->count(), 1); QVERIFY(centralFrame); QCOMPARE(centralFrame->dockWidgetCount(), 0); // Add a tab auto dock = createDockWidget("doc1", Qt::green); m->addDockWidgetAsTab(dock); - QCOMPARE(dropArea->multiSplitterLayout()->count(), 1); + QCOMPARE(dropArea->count(), 1); QCOMPARE(centralFrame->dockWidgetCount(), 1); qDebug() << "Central widget width=" << central->size() << "; mainwindow=" @@ -972,7 +972,7 @@ void TestDocks::tst_mainWindowAlwaysHasCentralWidget() drag(tabBar, globalPressPos, m->geometry().bottomRight() + QPoint(30, 30)); QVERIFY(centralFrame); - QCOMPARE(dropArea->multiSplitterLayout()->count(), 1); + QCOMPARE(dropArea->count(), 1); QCOMPARE(centralFrame->dockWidgetCount(), 0); QVERIFY(dropArea->checkSanity()); @@ -1008,7 +1008,7 @@ void TestDocks::tst_dockInternal() auto dock1 = createDockWidget("dock1", new QPushButton("one")); auto dropArea = m->dropArea(); - auto centralWidget = static_cast(dropArea->multiSplitterLayout()->items()[0]->guestAsQObject()); + auto centralWidget = static_cast(dropArea->items()[0]->guestAsQObject()); nestDockWidget(dock1, dropArea, centralWidget, KDDockWidgets::Location_OnRight); QVERIFY(dock1->width() < dropArea->width() - centralWidget->width()); @@ -1042,7 +1042,7 @@ void TestDocks::tst_closeAllDockWidgets() QCOMPARE(dock4->window(), m.get()); QCOMPARE(dock5->window(), m.get()); QCOMPARE(dock6->window(), fw.data()); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); layout->checkSanity(); DockRegistry::self()->clear(); layout->checkSanity(); @@ -1096,7 +1096,7 @@ void TestDocks::tst_propagateSizeHonoursMinSize() min1 = widgetMinLength(dock1, Qt::Horizontal); min2 = widgetMinLength(dock2, Qt::Horizontal); - auto l = m->dropArea()->multiSplitterLayout(); + auto l = m->dropArea(); l->checkSanity(); if (dock1->width() < min1) { @@ -1129,12 +1129,12 @@ void TestDocks::tst_restoreEmpty() // Create an empty main window, save it to disk. auto m = createMainWindow(QSize(800, 500), MainWindowOption_None); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); LayoutSaver saver; const QSize oldSize = m->size(); QVERIFY(saver.saveToFile(QStringLiteral("layout.json"))); saver.restoreFromFile(QStringLiteral("layout.json")); - QVERIFY(m->multiSplitterLayout()->checkSanity()); + QVERIFY(m->multiSplitter()->checkSanity()); QCOMPARE(layout->separators().size(), 0); QCOMPARE(layout->count(), 0); QCOMPARE(m->size(), oldSize); @@ -1146,7 +1146,7 @@ void TestDocks::tst_restoreSimplest() EnsureTopLevelsDeleted e; // Tests restoring a very simple layout, composed of just 1 docked widget auto m = createMainWindow(QSize(800, 500), MainWindowOption_None); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); auto dock1 = createDockWidget("one", new QTextEdit()); m->addDockWidget(dock1, Location_OnTop); @@ -1164,7 +1164,7 @@ void TestDocks::tst_restoreSimple() // Tests restoring a very simple layout, composed of just 1 docked widget auto m = createMainWindow(QSize(800, 500), MainWindowOption_None); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); auto dock1 = createDockWidget("one", new QTextEdit()); auto dock2 = createDockWidget("two", new QTextEdit()); auto dock3 = createDockWidget("three", new QTextEdit()); @@ -1237,7 +1237,7 @@ void TestDocks::tst_restoreNestedAndTabbed() auto m = createMainWindow(QSize(800, 500), MainWindowOption_None, "tst_restoreNestedAndTabbed"); m->move(500, 500); oldGeo = m->geometry(); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); auto dock1 = createDockWidget("1", new QTextEdit()); auto dock2 = createDockWidget("2", new QTextEdit()); auto dock3 = createDockWidget("3", new QTextEdit()); @@ -1261,7 +1261,7 @@ void TestDocks::tst_restoreNestedAndTabbed() } auto m = createMainWindow(QSize(800, 500), MainWindowOption_None, "tst_restoreNestedAndTabbed"); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); auto dock1 = createDockWidget("1", new QTextEdit()); auto dock2 = createDockWidget("2", new QTextEdit()); auto dock3 = createDockWidget("3", new QTextEdit()); @@ -1292,7 +1292,7 @@ void TestDocks::tst_restoreCentralFrame() { EnsureTopLevelsDeleted e; auto m = createMainWindow(QSize(800, 500)); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); QCOMPARE(layout->count(), 1); Item *item = m->dropArea()->centralFrame(); @@ -1329,7 +1329,7 @@ void TestDocks::tst_restoreCrash() // Restore qDebug() << Q_FUNC_INFO << "Restoring"; auto m = createMainWindow({}, {}, "tst_restoreCrash"); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); auto dock1 = createDockWidget("dock1", new QPushButton("one")); QVERIFY(dock1->isFloating()); QVERIFY(layout->checkSanity()); @@ -1387,14 +1387,14 @@ void TestDocks::tst_restoreSideBySide() auto m = createMainWindow(QSize(500, 500), MainWindowOption_HasCentralFrame, "tst_restoreTwice"); auto dock1 = createDockWidget("1", new QPushButton("1")); m->addDockWidgetAsTab(dock1); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); // FloatingWindow: auto dock2 = createDockWidget("2", new QPushButton("2")); auto dock3 = createDockWidget("3", new QPushButton("3")); dock2->addDockWidgetToContainingWindow(dock3, Location_OnRight); auto fw2 = dock2->floatingWindow(); - item2MinSize = fw2->multiSplitterLayout()->itemForFrame(dock2->frame())->minSize(); + item2MinSize = fw2->multiSplitter()->itemForFrame(dock2->frame())->minSize(); LayoutSaver saver; QVERIFY(saver.saveToFile(QStringLiteral("layout.json"))); QVERIFY(layout->checkSanity()); @@ -1426,7 +1426,7 @@ void TestDocks::tst_restoreWithPlaceholder() auto dock1 = createDockWidget("1", new QPushButton("1")); m->addDockWidget(dock1, Location_OnLeft); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); dock1->setFloating(true); LayoutSaver saver; @@ -1454,7 +1454,7 @@ void TestDocks::tst_restoreWithPlaceholder() // Try again, but on a different main window auto m = createMainWindow(QSize(500, 500), {}, "tst_restoreWithPlaceholder"); auto dock1 = createDockWidget("1", new QPushButton("1")); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); LayoutSaver saver; QVERIFY(saver.restoreFromFile(QStringLiteral("layout.json"))); @@ -1479,7 +1479,7 @@ void TestDocks::tst_restoreWithNonClosableWidget() auto m = createMainWindow(QSize(500, 500), {}, "tst_restoreWithNonClosableWidget"); auto dock1 = createDockWidget("1", new NonClosableWidget(), DockWidgetBase::Option_NotClosable); m->addDockWidget(dock1, Location_OnLeft); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); LayoutSaver saver; QVERIFY(saver.saveToFile(QStringLiteral("layout.json"))); @@ -1495,7 +1495,7 @@ void TestDocks::tst_restoreAfterResize() auto m = createMainWindow(QSize(500, 500), {}, "tst_restoreAfterResize"); auto dock1 = createDockWidget("1", new QPushButton("1")); m->addDockWidget(dock1, Location_OnLeft); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); const QSize oldContentsSize = layout->size(); const QSize oldWindowSize = m->size(); LayoutSaver saver; @@ -1557,7 +1557,7 @@ void TestDocks::tst_marginsAfterRestore() auto m = createMainWindow(QSize(500, 500), {}, "tst_marginsAfterRestore"); auto dock1 = createDockWidget("1", new QPushButton("1")); m->addDockWidget(dock1, Location_OnLeft); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); LayoutSaver saver; QVERIFY(saver.saveToFile(QStringLiteral("layout.json"))); @@ -1760,9 +1760,9 @@ void TestDocks::tst_addToSmallMainWindow2() m->addDockWidget(dock2, KDDockWidgets::Location_OnRight); QVERIFY(Testing::waitForResize(m.get())); - QVERIFY(dropArea->multiSplitterLayout()->width() > osWindowMinWidth()); + QVERIFY(dropArea->width() > osWindowMinWidth()); QMargins margins = m->centralWidget()->layout()->contentsMargins(); - QCOMPARE(dropArea->multiSplitterLayout()->width(), m->width() - margins.left() - margins.right()); + QCOMPARE(dropArea->width(), m->width() - margins.left() - margins.right()); QVERIFY(m->dropArea()->checkSanity()); } @@ -1793,7 +1793,7 @@ void TestDocks::tst_addToSmallMainWindow4() auto dropArea = m->dropArea(); auto dock1 = createDockWidget("dock1", new MyWidget2(QSize(50, 50))); auto dock2 = createDockWidget("dock2", new MyWidget2(QSize(50, 50))); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; m->addDockWidget(dock1, KDDockWidgets::Location_OnBottom); Testing::waitForResize(m.get()); @@ -1862,7 +1862,7 @@ void TestDocks::tst_fairResizeAfterRemoveWidget() const int oldWidth1 = dock1->frame()->width(); const int oldWidth2 = dock2->frame()->width(); const int oldWidth3 = dock3->frame()->width(); - MultiSplitterLayout *layout = fw->dropArea()->multiSplitterLayout(); + MultiSplitter *layout = fw->dropArea(); QCOMPARE(layout->count(), 3); QCOMPARE(layout->visibleCount(), 3); QCOMPARE(layout->placeholderCount(), 0); @@ -2009,7 +2009,7 @@ void TestDocks::tst_constraintsAfterPlaceholder() auto dock2 = createDockWidget("dock2", new MyWidget2(QSize(400, minHeight))); auto dock3 = createDockWidget("dock3", new MyWidget2(QSize(400, minHeight))); auto dropArea = m->dropArea(); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; // Stack 3, 2, 1 m->addDockWidget(dock1, Location_OnTop); @@ -2049,7 +2049,7 @@ void TestDocks::tst_crash() auto m = createMainWindow(QSize(800, 500), MainWindowOption_None); auto dock1 = createDockWidget("dock1", new QPushButton("one")); auto dock2 = createDockWidget("dock2", new QPushButton("two")); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft); Item *item1 = layout->itemForFrame(dock1->frame()); @@ -2088,7 +2088,7 @@ void TestDocks::tst_crash2() { EnsureTopLevelsDeleted e; auto m = new MainWindow("m1", MainWindowOption_None); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); m->setVisible(show); DockWidget::List docks; @@ -2119,7 +2119,7 @@ void TestDocks::tst_crash2() { EnsureTopLevelsDeleted e; auto m = new MainWindow("m1", MainWindowOption_HasCentralFrame); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); m->show(); const int num = 3; @@ -2160,7 +2160,7 @@ void TestDocks::tst_setFloatingSimple() auto m = createMainWindow(); auto dock1 = createDockWidget("dock1", new QPushButton("one")); m->addDockWidget(dock1, Location_OnTop); - auto l = m->multiSplitterLayout(); + auto l = m->multiSplitter(); dock1->setFloating(true); QVERIFY(l->checkSanity()); dock1->setFloating(false); @@ -2312,7 +2312,7 @@ void TestDocks::tst_setFloatingWhenSideBySide() auto dock2 = createDockWidget("dock2", new QPushButton("two")); auto dock3 = createDockWidget("dock3", new QPushButton("three")); auto dropArea = m->dropArea(); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft); m->addDockWidget(dock2, KDDockWidgets::Location_OnRight); m->addDockWidget(dock3, KDDockWidgets::Location_OnRight); @@ -2342,7 +2342,7 @@ void TestDocks::tst_setFloatingAfterDraggedFromTabToSideBySide() auto dock1 = createDockWidget("dock1", new QPushButton("one")); auto dock2 = createDockWidget("dock2", new QPushButton("two")); auto dropArea = m->dropArea(); - auto layout = dropArea->multiSplitterLayout(); + auto layout = dropArea; m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft); dock1->addDockWidgetAsTab(dock2); @@ -2367,7 +2367,7 @@ void TestDocks::tst_setFloatingAfterDraggedFromTabToSideBySide() auto dock1 = createDockWidget("dock1", new QPushButton("one")); auto dock2 = createDockWidget("dock2", new QPushButton("two")); auto dropArea = m->dropArea(); - auto layout = dropArea->multiSplitterLayout(); + auto layout = dropArea; m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft); dock1->addDockWidgetAsTab(dock2); @@ -2381,7 +2381,7 @@ void TestDocks::tst_setFloatingAfterDraggedFromTabToSideBySide() auto fw2 = dock2->floatingWindow(); QVERIFY(fw2); QCOMPARE(dock2->lastPositions().lastItem(), oldItem2); - Item *item2 = fw2->dropArea()->multiSplitterLayout()->itemForFrame(dock2->frame()); + Item *item2 = fw2->dropArea()->itemForFrame(dock2->frame()); QVERIFY(item2); QCOMPARE(item2->hostWidget()->asQWidget(), fw2->dropArea()); QVERIFY(!layout->itemForFrame(dock2->frame())); @@ -2412,7 +2412,7 @@ void TestDocks::tst_setFloatingAFrameWithTabs() EnsureTopLevelsDeleted e; auto m = createMainWindow(); auto dropArea = m->dropArea(); - auto layout = dropArea->multiSplitterLayout(); + auto layout = dropArea; auto dock1 = createDockWidget("dock1", new QPushButton("one")); auto dock2 = createDockWidget("dock2", new QPushButton("two")); m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft); @@ -2478,7 +2478,7 @@ void TestDocks::tst_simple1() // Simply create a MainWindow EnsureTopLevelsDeleted e; auto m = createMainWindow(); - m->multiSplitterLayout()->checkSanity(); + m->multiSplitter()->checkSanity(); } void TestDocks::tst_simple2() @@ -2488,7 +2488,7 @@ void TestDocks::tst_simple2() auto m = createMainWindow(); auto dw = createDockWidget("dw", new QPushButton("dw")); m->addDockWidget(dw, KDDockWidgets::Location_OnTop); - m->multiSplitterLayout()->checkSanity(); + m->multiSplitter()->checkSanity(); } void TestDocks::tst_refUnrefItem() @@ -2500,7 +2500,7 @@ void TestDocks::tst_refUnrefItem() m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft); m->addDockWidget(dock2, KDDockWidgets::Location_OnRight); auto dropArea = m->dropArea(); - auto layout = dropArea->multiSplitterLayout(); + auto layout = dropArea; QPointer frame1 = dock1->frame(); QPointer frame2 = dock2->frame(); QPointer item1 = layout->itemForFrame(frame1); @@ -2553,7 +2553,7 @@ void TestDocks::tst_refUnrefItem() auto m2 = createMainWindow(); m2->addDockWidget(dock4, KDDockWidgets::Location_OnLeft); - m2->multiSplitterLayout()->checkSanity(); + m2->multiSplitter()->checkSanity(); QVERIFY(!item4.data()); } @@ -2569,13 +2569,13 @@ void TestDocks::tst_addAndReadd() auto dock1 = createDockWidget("dock1", new QPushButton("1")); m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft); dock1->setFloating(true); - m->multiSplitterLayout()->checkSanity(); + m->multiSplitter()->checkSanity(); m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft); dock1->frame()->titleBar()->makeWindow(); - m->multiSplitterLayout()->checkSanity(); + m->multiSplitter()->checkSanity(); m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft); dock1->frame()->titleBar()->makeWindow(); - m->multiSplitterLayout()->checkSanity(); + m->multiSplitter()->checkSanity(); auto fw = dock1->floatingWindow(); QVERIFY(fw); @@ -2583,7 +2583,7 @@ void TestDocks::tst_addAndReadd() dragFloatingWindowTo(fw, dropArea, DropIndicatorOverlayInterface::DropLocation_OutterRight); QVERIFY(!dock1->frame()->titleBar()->isVisible()); fw->titleBar()->makeWindow(); - m->multiSplitterLayout()->checkSanity(); + m->multiSplitter()->checkSanity(); //Cleanup delete dock1; @@ -2600,7 +2600,7 @@ void TestDocks::tst_placeholderCount() auto dock1 = createDockWidget("1", new QPushButton("1")); auto dock2 = createDockWidget("2", new QPushButton("2")); auto dropArea = m->dropArea(); - auto layout = dropArea->multiSplitterLayout(); + auto layout = dropArea; QCOMPARE(layout->count(), 1); QCOMPARE(layout->visibleCount(), 1); @@ -2652,7 +2652,7 @@ void TestDocks::tst_availableLengthForOrientation() // 1. Test a completely empty window, it's available space is its size minus the static separators thickness auto m = createMainWindow(QSize(800, 500), MainWindowOption_None); // Remove central frame auto dropArea = m->dropArea(); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; int availableWidth = layout->availableLengthForOrientation(Qt::Horizontal); int availableHeight = layout->availableLengthForOrientation(Qt::Vertical); @@ -2671,7 +2671,7 @@ void TestDocks::tst_availableLengthForOrientation() availableHeight = layout->availableLengthForOrientation(Qt::Vertical); QCOMPARE(availableWidth, layout->width() - dock1MinWidth); QCOMPARE(availableHeight, layout->height() - dock1MinHeight); - m->multiSplitterLayout()->checkSanity(); + m->multiSplitter()->checkSanity(); } void TestDocks::tst_setAstCurrentTab() @@ -2696,7 +2696,7 @@ void TestDocks::tst_setAstCurrentTab() auto fw = dock1->floatingWindow(); QVERIFY(fw); - fw->multiSplitterLayout()->checkSanity(); + fw->multiSplitter()->checkSanity(); delete dock1; delete dock2; Testing::waitForDeleted(fw); @@ -2711,13 +2711,13 @@ void TestDocks::tst_closeShowWhenNoCentralFrame() QPointer dock1 = createDockWidget("1", new QPushButton("1")); m->addDockWidget(dock1, Location_OnLeft); dock1->close(); - m->multiSplitterLayout()->checkSanity(); + m->multiSplitter()->checkSanity(); QVERIFY(!dock1->frame()); QVERIFY(!Testing::waitForDeleted(dock1)); // It was being deleted due to a bug QVERIFY(dock1); dock1->show(); - m->multiSplitterLayout()->checkSanity(); + m->multiSplitter()->checkSanity(); } void TestDocks::tst_placeholderDisappearsOnReadd() @@ -2729,7 +2729,7 @@ void TestDocks::tst_placeholderDisappearsOnReadd() EnsureTopLevelsDeleted e; auto m = createMainWindow(QSize(800, 500), MainWindowOption_None); // Remove central frame - MultiSplitterLayout *layout = m->multiSplitterLayout(); + MultiSplitter *layout = m->multiSplitter(); QPointer dock1 = createDockWidget("1", new QPushButton("1")); m->addDockWidget(dock1, Location_OnLeft); @@ -2761,7 +2761,7 @@ void TestDocks::tst_placeholdersAreRemovedProperly() { EnsureTopLevelsDeleted e; auto m = createMainWindow(QSize(800, 500), MainWindowOption_None); // Remove central frame - MultiSplitterLayout *layout = m->multiSplitterLayout(); + MultiSplitter *layout = m->multiSplitter(); QPointer dock1 = createDockWidget("1", new QPushButton("1")); QPointer dock2 = createDockWidget("2", new QPushButton("2")); m->addDockWidget(dock1, Location_OnLeft); @@ -2809,7 +2809,7 @@ void TestDocks::tst_embeddedMainWindow() dragFloatingWindowTo(fw, dropArea, DropIndicatorOverlayInterface::DropLocation_Left); - auto layout = dropArea->multiSplitterLayout(); + auto layout = dropArea; QVERIFY(Testing::waitForDeleted(fw)); QCOMPARE(layout->count(), 2); // 2, as it has the central frame QCOMPARE(layout->visibleCount(), 2); @@ -2822,7 +2822,7 @@ void TestDocks::tst_toggleMiddleDockCrash() { EnsureTopLevelsDeleted e; auto m = createMainWindow(QSize(800, 500), MainWindowOption_None); // Remove central frame - MultiSplitterLayout *layout = m->multiSplitterLayout(); + MultiSplitter *layout = m->multiSplitter(); QPointer dock1 = createDockWidget("1", new QPushButton("1")); QPointer dock2 = createDockWidget("2", new QPushButton("2")); QPointer dock3 = createDockWidget("3", new QPushButton("3")); @@ -2866,7 +2866,7 @@ void TestDocks::tst_invalidPlaceholderPosition() auto dock2 = createDockWidget("2", new QPushButton("2")); auto dock3 = createDockWidget("3", new QPushButton("3")); - MultiSplitterLayout *layout = m->multiSplitterLayout(); + MultiSplitter *layout = m->multiSplitter(); // Stack: 1, 2, 3 vertically m->addDockWidget(dock3, Location_OnTop); @@ -3142,7 +3142,7 @@ void TestDocks::tst_28NestedWidgets() EnsureTopLevelsDeleted e; auto m = createMainWindow(QSize(800, 500), MainWindowOption_None); auto dropArea = m->dropArea(); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; int i = 0; for (DockDescriptor &desc : docksToCreate) { @@ -3213,7 +3213,7 @@ void TestDocks::tst_invalidAnchorGroup() dock1->close(); Testing::waitForResize(dock2); - auto layout = fw->dropArea()->multiSplitterLayout(); + auto layout = fw->dropArea(); layout->checkSanity(); dock2->close(); @@ -3250,7 +3250,7 @@ void TestDocks::tst_resizeViaAnchorsAfterPlaceholderCreation() // Stack 1, 2, 3, close 2, close 2 { auto m = createMainWindow(QSize(800, 500), MainWindowOption_None); - MultiSplitterLayout *layout = m->multiSplitterLayout(); + MultiSplitter *layout = m->multiSplitter(); auto dock1 = createDockWidget("dock1", new QPushButton("one")); auto dock2 = createDockWidget("dock2", new QPushButton("two")); auto dock3 = createDockWidget("dock3", new QPushButton("three")); @@ -3279,7 +3279,7 @@ void TestDocks::tst_resizeViaAnchorsAfterPlaceholderCreation() m->addDockWidget(dock3, Location_OnRight); m->addDockWidget(dock4, Location_OnRight); - MultiSplitterLayout *layout = m->multiSplitterLayout(); + MultiSplitter *layout = m->multiSplitter(); Item *item1 = layout->itemForFrame(dock1->frame()); Item *item2 = layout->itemForFrame(dock2->frame()); @@ -3334,7 +3334,7 @@ void TestDocks::tst_negativeAnchorPosition() auto w3 = new MyWidget2(QSize(133, 343)); w3->resize(392, 362); - MultiSplitterLayout *layout = m->multiSplitterLayout(); + MultiSplitter *layout = m->multiSplitter(); auto d1 = createDockWidget("1", w1); auto d2 = createDockWidget("2", w2); @@ -3371,7 +3371,7 @@ void TestDocks::tst_negativeAnchorPosition2() EnsureTopLevelsDeleted e; auto m = createMainWindow(QSize(800, 500), MainWindowOption_None); auto dropArea = m->dropArea(); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; auto dock1 = createDockWidget("1", new QPushButton("1"), {}, /*show=*/false); auto dock2 = createDockWidget("2", new QPushButton("2"), {}, /*show=*/false); @@ -3401,7 +3401,7 @@ void TestDocks::tst_negativeAnchorPosition3() {Location_OnRight, -1, nullptr, AddingOption_None } }; auto m = createMainWindow(docks); auto dropArea = m->dropArea(); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; layout->checkSanity(); auto dock1 = docks.at(1).createdDock; @@ -3428,18 +3428,18 @@ void TestDocks::tst_negativeAnchorPosition4() auto m = createMainWindow(docks); auto dropArea = m->dropArea(); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; layout->checkSanity(); auto dock1 = docks.at(1).createdDock; auto dock2 = docks.at(2).createdDock; dock2->setFloating(true); auto fw2 = dock2->floatingWindow(); - dropArea->multiSplitterLayout()->addWidget(fw2->dropArea(), Location_OnLeft, dock1->frame()); + dropArea->addWidget(fw2->dropArea(), Location_OnLeft, dock1->frame()); dock2->setFloating(true); fw2 = dock2->floatingWindow(); - dropArea->multiSplitterLayout()->addWidget(fw2->dropArea(), Location_OnRight, dock1->frame()); + dropArea->addWidget(fw2->dropArea(), Location_OnRight, dock1->frame()); layout->checkSanity(); docks.at(0).createdDock->deleteLater(); @@ -3458,7 +3458,7 @@ void TestDocks::tst_negativeAnchorPosition5() auto m = createMainWindow(docks); auto dropArea = m->dropArea(); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; layout->checkSanity(); auto dock0 = docks.at(0).createdDock; @@ -3485,7 +3485,7 @@ void TestDocks::tst_negativeAnchorPosition6() m->resize(QSize(100, 100)); m->show(); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); auto w1 = new MyWidget2(QSize(400,100)); auto w2 = new MyWidget2(QSize(400,100)); @@ -3540,7 +3540,7 @@ void TestDocks::tst_negativeAnchorPosition7() // Stack: 1, 3, 2 m->addDockWidget(d3, Location_OnTop, d2); - m->multiSplitterLayout()->checkSanity(); + m->multiSplitter()->checkSanity(); delete m; } @@ -3568,7 +3568,7 @@ void TestDocks::tst_negativeAnchorPositionWhenEmbedded() m->resize(QSize(500, 500)); m->show(); } - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); auto w1 = new MyWidget2(QSize(400,400)); auto w2 = new MyWidget2(QSize(400,400)); @@ -3637,7 +3637,7 @@ void TestDocks::tst_tabBarWithHiddenTitleBar() QVERIFY(d2->frame()->titleBar()->isVisible() ^ hiddenTitleBar); d2->close(); - m->multiSplitterLayout()->checkSanity(); + m->multiSplitter()->checkSanity(); delete d2; if (tabsAlwaysVisible) { if (hiddenTitleBar) @@ -3749,7 +3749,7 @@ void TestDocks::tst_addToHiddenMainWindow() QVERIFY(!m->isVisible()); d1->setFloating(true); d2->setFloating(false); - m->multiSplitterLayout()->checkSanity(); + m->multiSplitter()->checkSanity(); delete m; } @@ -3769,7 +3769,7 @@ void TestDocks::tst_minSizeChanges() m->addDockWidget(d1, Location_OnTop); m->addDockWidget(d2, Location_OnTop, nullptr, AddingOption_StartHidden); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); // 1. d2 is a placeholder, let's change its min size before showing it w2->setMinSize(QSize(800, 800)); @@ -3810,7 +3810,7 @@ void TestDocks::tst_complex() EnsureTopLevelsDeleted e; auto m = new MainWindow("m1", MainWindowOption_None); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); m->resize(3266, 2239); m->show(); // TODO: Remove and see if it crashes @@ -3984,7 +3984,7 @@ void TestDocks::tst_dockNotFillingSpace() d2->close(); Testing::waitForDeleted(frame2); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); QVERIFY(layout->checkSanity()); delete d1; @@ -4012,7 +4012,7 @@ void TestDocks::tst_rectForDropCrash() m->resize(QSize(500, 500)); m->show(); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); auto w1 = new MyWidget2(QSize(400,400)); auto w2 = new MyWidget2(QSize(400,400)); @@ -4050,9 +4050,9 @@ void TestDocks::tst_availableSizeWithPlaceholders() auto m2 = createMainWindow(docks2); auto m3 = createMainWindow(empty); - auto layout1 = m1->multiSplitterLayout(); - auto layout2 = m2->multiSplitterLayout(); - auto layout3 = m3->multiSplitterLayout(); + auto layout1 = m1->multiSplitter(); + auto layout2 = m2->multiSplitter(); + auto layout3 = m3->multiSplitter(); auto f20 = docks2.at(0).createdDock->frame(); @@ -4111,17 +4111,17 @@ void TestDocks::tst_anchorFollowingItselfAssert() auto m = createMainWindow(docks); auto dropArea = m->dropArea(); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; layout->checkSanity(); auto dock1 = docks.at(1).createdDock; auto dock2 = docks.at(2).createdDock; dock2->setFloating(true); auto fw2 = dock2->floatingWindow(); - dropArea->multiSplitterLayout()->addWidget(fw2->dropArea(), Location_OnLeft, dock1->frame()); + dropArea->addWidget(fw2->dropArea(), Location_OnLeft, dock1->frame()); dock2->setFloating(true); fw2 = dock2->floatingWindow(); - dropArea->multiSplitterLayout()->addWidget(fw2->dropArea(), Location_OnRight, dock1->frame()); + dropArea->addWidget(fw2->dropArea(), Location_OnRight, dock1->frame()); docks.at(0).createdDock->deleteLater(); docks.at(4).createdDock->deleteLater(); @@ -4142,7 +4142,7 @@ void TestDocks::tst_positionWhenShown() dock1->show(); QCOMPARE(dock1->window()->pos(), QPoint(100, 100)); - window->multiSplitterLayout()->checkSanity(); + window->multiSplitter()->checkSanity(); // Cleanup dock1->deleteLater(); @@ -4327,7 +4327,7 @@ void TestDocks::tst_invalidLayoutAfterRestore() auto dock2 = createDockWidget("dock2", new QPushButton("two")); auto dock3 = createDockWidget("dock3", new QPushButton("three")); auto dropArea = m->dropArea(); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; // Stack 1, 2, 3 m->addDockWidget(dock1, Location_OnLeft); m->addDockWidget(dock2, Location_OnRight); @@ -4419,10 +4419,7 @@ void TestDocks::tst_stealFrame() auto dock4 = createDockWidget("dock4", new QPushButton("four")); auto dropArea1 = m1->dropArea(); - MultiSplitterLayout *layout1 = dropArea1->multiSplitterLayout(); - auto dropArea2 = m2->dropArea(); - MultiSplitterLayout *layout2 = dropArea2->multiSplitterLayout(); m1->addDockWidget(dock1, Location_OnRight); m1->addDockWidget(dock2, Location_OnRight); @@ -4433,14 +4430,14 @@ void TestDocks::tst_stealFrame() m1->addDockWidget(dock3, Location_OnRight); m1->addDockWidget(dock4, Location_OnRight); m2->addDockWidget(dock1, Location_OnRight); - QPointer item2 = layout1->itemForFrame(dock2->frame()); + QPointer item2 = dropArea1->itemForFrame(dock2->frame()); m2->addDockWidget(dock2, Location_OnRight); QVERIFY(!item2.data()); - QCOMPARE(layout1->count(), 2); - QCOMPARE(layout2->count(), 2); - QCOMPARE(layout1->placeholderCount(), 0); - QCOMPARE(layout2->placeholderCount(), 0); + QCOMPARE(dropArea1->count(), 2); + QCOMPARE(dropArea2->count(), 2); + QCOMPARE(dropArea1->placeholderCount(), 0); + QCOMPARE(dropArea2->placeholderCount(), 0); // 2. MainWindow #1 steals a widget from MainWindow2 and vice-versa, but adds as tabs dock1->addDockWidgetAsTab(dock3); @@ -4449,10 +4446,10 @@ void TestDocks::tst_stealFrame() QVERIFY(Testing::waitForDeleted(f2.data())); QVERIFY(!f2.data()); - QCOMPARE(layout1->count(), 1); - QCOMPARE(layout2->count(), 1); - QCOMPARE(layout1->placeholderCount(), 0); - QCOMPARE(layout2->placeholderCount(), 0); + QCOMPARE(dropArea1->count(), 1); + QCOMPARE(dropArea2->count(), 1); + QCOMPARE(dropArea1->placeholderCount(), 0); + QCOMPARE(dropArea2->placeholderCount(), 0); // 3. Test stealing a tab from the same tab-widget we're in. Nothing happens { @@ -4468,31 +4465,31 @@ void TestDocks::tst_stealFrame() QCOMPARE(dock1->frame()->dockWidgetCount(), 2); QCOMPARE(dock4->frame()->dockWidgetCount(), 1); - QCOMPARE(layout1->count(), 2); - QCOMPARE(layout1->placeholderCount(), 0); + QCOMPARE(dropArea1->count(), 2); + QCOMPARE(dropArea1->placeholderCount(), 0); // 5. And also steal a side-by-side one into the tab QPointer f4 = dock4->frame(); dock1->addDockWidgetAsTab(dock4); QVERIFY(Testing::waitForDeleted(f4.data())); - QCOMPARE(layout1->count(), 1); - QCOMPARE(layout1->placeholderCount(), 0); + QCOMPARE(dropArea1->count(), 1); + QCOMPARE(dropArea1->placeholderCount(), 0); // 6. Steal from tab to side-by-side within the same MainWindow m1->addDockWidget(dock1, Location_OnLeft); - QCOMPARE(layout1->count(), 2); - QCOMPARE(layout1->placeholderCount(), 0); + QCOMPARE(dropArea1->count(), 2); + QCOMPARE(dropArea1->placeholderCount(), 0); // 6. side-by-side to side-by-side within same MainWindow m2->addDockWidget(dock1, Location_OnRight); - QCOMPARE(layout2->count(), 2); - QCOMPARE(layout2->placeholderCount(), 0); + QCOMPARE(dropArea2->count(), 2); + QCOMPARE(dropArea2->placeholderCount(), 0); { SetExpectedWarning sew("Invalid parameters KDDockWidgets::DockWidget"); // Suppress the qFatal this time m2->addDockWidget(dock1, Location_OnLeft, dock1); - QCOMPARE(layout2->count(), 2); // Nothing happened - QCOMPARE(layout2->placeholderCount(), 0); + QCOMPARE(dropArea2->count(), 2); // Nothing happened + QCOMPARE(dropArea2->placeholderCount(), 0); QVERIFY(dock1->isVisible()); } @@ -4500,15 +4497,15 @@ void TestDocks::tst_stealFrame() m2->addDockWidget(dock1, Location_OnLeft, nullptr); // Should not warn QVERIFY(dock1->isVisible()); - QCOMPARE(layout2->count(), 2); // Nothing happened - QCOMPARE(layout2->placeholderCount(), 0); + QCOMPARE(dropArea2->count(), 2); // Nothing happened + QCOMPARE(dropArea2->placeholderCount(), 0); m2->addDockWidget(dock1, Location_OnLeft, nullptr); QVERIFY(dock1->isVisible()); - QCOMPARE(layout2->count(), 2); // Nothing happened - QCOMPARE(layout2->placeholderCount(), 0); - layout1->checkSanity(); - layout2->checkSanity(); + QCOMPARE(dropArea2->count(), 2); // Nothing happened + QCOMPARE(dropArea2->placeholderCount(), 0); + dropArea1->checkSanity(); + dropArea2->checkSanity(); } void TestDocks::tst_addAsPlaceholder() @@ -4522,7 +4519,7 @@ void TestDocks::tst_addAsPlaceholder() m->addDockWidget(dock2, Location_OnTop, nullptr, AddingOption_StartHidden); auto dropArea = m->dropArea(); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; QCOMPARE(layout->count(), 2); QCOMPARE(layout->placeholderCount(), 1); @@ -4553,7 +4550,7 @@ void TestDocks::tst_removeItem() Item *item2 = dock2->lastPositions().lastItem(); auto dropArea = m->dropArea(); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; QCOMPARE(layout->count(), 2); QCOMPARE(layout->placeholderCount(), 1); @@ -4647,7 +4644,7 @@ void TestDocks::tst_startHidden() auto dock2 = createDockWidget("dock2", new QPushButton("two"), {}, false); auto dropArea = m->dropArea(); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; m->addDockWidget(dock1, Location_OnTop, nullptr, AddingOption_StartHidden); QVERIFY(layout->checkSanity()); @@ -4677,7 +4674,7 @@ void TestDocks::tst_startHidden() auto dock3 = createDockWidget("dock3", new QPushButton("three"), {}, false); auto dropArea = m->dropArea(); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; m->addDockWidget(dock1, Location_OnLeft, nullptr, AddingOption_StartHidden); m->addDockWidget(dock2, Location_OnBottom, nullptr, AddingOption_StartHidden); @@ -4703,7 +4700,7 @@ void TestDocks::tst_startClosed() auto dock2 = createDockWidget("dock2", new QPushButton("two")); auto dropArea = m->dropArea(); - MultiSplitterLayout *layout = dropArea->multiSplitterLayout(); + MultiSplitter *layout = dropArea; m->addDockWidget(dock1, Location_OnTop); Frame *frame1 = dock1->frame(); @@ -4743,7 +4740,7 @@ void TestDocks::tst_samePositionAfterHideRestore() dock2->setFloating(false); QVERIFY(Testing::waitForDeleted(fw2)); QCOMPARE(geo2, dock2->frame()->QWidget::geometry()); - m->multiSplitterLayout()->checkSanity(); + m->multiSplitter()->checkSanity(); } @@ -4767,7 +4764,7 @@ void TestDocks::tst_clear() QCOMPARE(Frame::dbg_numFrames(), 3); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); layout->rootItem()->clear(); QCOMPARE(layout->count(), 0); @@ -4803,7 +4800,7 @@ void TestDocks::tst_restoreEmbeddedMainWindow() QCOMPARE(window->pos(), originalPos); QCOMPARE(window->size(), originalSize); - window->mainWindow->multiSplitterLayout()->checkSanity(); + window->mainWindow->multiSplitter()->checkSanity(); delete window; } @@ -4816,7 +4813,7 @@ void TestDocks::tst_restoreWithDockFactory() auto m = createMainWindow(QSize(501, 500), MainWindowOption_None); auto dock1 = createDockWidget("1", new QPushButton("1")); m->addDockWidget(dock1, Location_OnLeft); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); QCOMPARE(layout->count(), 1); QCOMPARE(layout->placeholderCount(), 0); @@ -4864,7 +4861,7 @@ void TestDocks::tst_restoreResizesLayout() // Now resize the window, and then restore. The layout should have the new size - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); m->resize(1050, 1050); QCOMPARE(m->size(), QSize(1050, 1050)); @@ -4894,7 +4891,7 @@ void TestDocks::tst_resizeWindow() m->addDockWidget(dock1, Location_OnLeft); m->addDockWidget(dock2, Location_OnRight); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); layout->checkSanity(); @@ -4941,7 +4938,7 @@ void TestDocks::tst_resizeWindow2() m->addDockWidget(dock1, Location_OnTop); m->addDockWidget(dock2, Location_OnBottom); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); Separator *anchor = layout->separators().at(0); const int oldPosY = anchor->position(); m->resize(m->width() + 10, m->height()); diff --git a/tests/utils.cpp b/tests/utils.cpp index 43a16fd6..c3b0251d 100644 --- a/tests/utils.cpp +++ b/tests/utils.cpp @@ -116,7 +116,7 @@ std::unique_ptr KDDockWidgets::Tests::createMainWindow(QVector(new MainWindow(QStringLiteral("MyMainWindow%1").arg(count), MainWindowOption_None)); - auto layout = m->multiSplitterLayout(); + auto layout = m->multiSplitter(); m->show(); m->resize(QSize(700, 700));