Merge MultiSplitterLayout into MultiSplitter

No need to have two. It's a leftover from the old layouting engine
This commit is contained in:
Sergio Martins
2020-06-11 14:55:31 +01:00
parent e54ef787ed
commit 86e58dd8a7
24 changed files with 784 additions and 938 deletions

View File

@@ -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

View File

@@ -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.";

View File

@@ -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;

View File

@@ -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 <QApplication>

View File

@@ -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;

View File

@@ -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.

View File

@@ -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) {

View File

@@ -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<MultiSplitter*>(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<MultiSplitterLayout *> DockRegistry::layouts() const
const QVector<MultiSplitter *> 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();
}
}
}

View File

@@ -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<MultiSplitterLayout*> layouts() const;
///@brief returns the list of MultiSplitter instances
const QVector<MultiSplitter*> 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<FloatingWindow*> m_nestedWindows;
QVector<MultiSplitterLayout*> m_layouts;
QVector<MultiSplitter*> m_layouts;
};
}

View File

@@ -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<Frame*>(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<Frame*>(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<FloatingWindow *>(droppedWindow)) {
if (!validateAffinity(floatingWindow))
return false;
m_layout->addMultiSplitter(floatingWindow->dropArea(), location, relativeTo);
addMultiSplitter(floatingWindow->dropArea(), location, relativeTo);
floatingWindow->scheduleDeleteLater();
return true;
} else {

View File

@@ -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()

View File

@@ -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)

View File

@@ -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();

View File

@@ -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

View File

@@ -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())

View File

@@ -26,7 +26,6 @@
#include "Position_p.h"
#include "DockRegistry_p.h"
#include "widgets/MultiSplitterLayout_p.h"
#include "widgets/MultiSplitter_p.h"
#include <algorithm>
@@ -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;

View File

@@ -184,7 +184,7 @@ struct LastPositions
lastPosition->removePlaceholders();
}
void removePlaceholders(MultiSplitter *hostWidget) const {
void removePlaceholders(const MultiSplitter *hostWidget) const {
lastPosition->removePlaceholders(hostWidget);
}

View File

@@ -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);

View File

@@ -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 <QScopedValueRollback>
@@ -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<FloatingWindow*>(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<DockWidgetBase*>(widget);
const bool isStartHidden = option & AddingOption_StartHidden;
if (!qobject_cast<Frame*>(widget) && !qobject_cast<MultiSplitter*>(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<Frame*>(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<Frame*>(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<DockWidgetBase*>(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<MultiSplitter*>(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<Frame*>(frameOrMultiSplitter))
return { frame };
if (auto msw = qobject_cast<MultiSplitter*>(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<Frame*>(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<Frame*>(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<QString, Layouting::Widget*> 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<Frame*>(item->guestAsQObject()))
l.frames.insert(QString::number(qint64(frame)), frame->serialize());
}
}
return l;
}

View File

@@ -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 <sergio.martins@kdab.com>
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 <http://www.gnu.org/licenses/>.
*/
#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<DockWidgetBase*>(widget);
const bool isStartHidden = option & AddingOption_StartHidden;
if (!qobject_cast<Frame*>(widget) && !qobject_cast<MultiSplitter*>(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<Frame*>(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<Frame*>(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<DockWidgetBase*>(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<MultiSplitter*>(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<Frame*>(frameOrMultiSplitter))
return { frame };
if (auto msw = qobject_cast<MultiSplitter*>(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<Frame*>(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<Frame*>(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<QString, Layouting::Widget*> 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<Frame*>(item->guestAsQObject()))
l.frames.insert(QString::number(qint64(frame)), frame->serialize());
}
}
return l;
}

View File

@@ -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 <sergio.martins@kdab.com>
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 <http://www.gnu.org/licenses/>.
*/
/**
* @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 \<sergio.martins@kdab.com\>
*/
#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 <QPointer>
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<Layouting::Item*> 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<Layouting::Separator*> 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<Frame*> 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<Frame*> 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<Frame*> &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

View File

@@ -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 \<sergio.martins@kdab.com\>
*/
@@ -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<Layouting::Item*> 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<Layouting::Separator*> 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<Frame*> 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<Frame*> 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<Frame*> &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;
};
}

View File

@@ -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<Frame> centralFrame = static_cast<Frame*>(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<Frame*>(dropArea->multiSplitterLayout()->items()[0]->guestAsQObject());
auto centralWidget = static_cast<Frame*>(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<Frame> frame1 = dock1->frame();
QPointer<Frame> frame2 = dock2->frame();
QPointer<Item> 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<DockWidgetBase> 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<DockWidgetBase> 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<DockWidgetBase> dock1 = createDockWidget("1", new QPushButton("1"));
QPointer<DockWidgetBase> 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<DockWidgetBase> dock1 = createDockWidget("1", new QPushButton("1"));
QPointer<DockWidgetBase> dock2 = createDockWidget("2", new QPushButton("2"));
QPointer<DockWidgetBase> 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<Item> item2 = layout1->itemForFrame(dock2->frame());
QPointer<Item> 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<Frame> 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());

View File

@@ -116,7 +116,7 @@ std::unique_ptr<MainWindow> KDDockWidgets::Tests::createMainWindow(QVector<DockD
static int count = 0;
count++;
auto m = std::unique_ptr<MainWindow>(new MainWindow(QStringLiteral("MyMainWindow%1").arg(count), MainWindowOption_None));
auto layout = m->multiSplitterLayout();
auto layout = m->multiSplitter();
m->show();
m->resize(QSize(700, 700));