diff --git a/src/private/LayoutWidget.cpp b/src/private/LayoutWidget.cpp index e9845027..d328e9aa 100644 --- a/src/private/LayoutWidget.cpp +++ b/src/private/LayoutWidget.cpp @@ -31,6 +31,8 @@ LayoutWidget::LayoutWidget(QWidgetOrQuick *parent) LayoutWidget::~LayoutWidget() { + m_minSizeChangedHandler.disconnect(); + if (m_rootItem->hostWidget()->asQObject() == this) delete m_rootItem; DockRegistry::self()->unregisterLayout(this); @@ -74,10 +76,11 @@ void LayoutWidget::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()); }); + m_rootItem->numVisibleItemsChanged.connect([this] (int count) { + Q_EMIT visibleWidgetCountChanged(count); + }); + + m_minSizeChangedHandler = m_rootItem->minSizeChanged.connect([this] { setMinimumSize(layoutMinimumSize()); }); } QSize LayoutWidget::layoutMinimumSize() const diff --git a/src/private/LayoutWidget_p.h b/src/private/LayoutWidget_p.h index 0828267b..78913645 100644 --- a/src/private/LayoutWidget_p.h +++ b/src/private/LayoutWidget_p.h @@ -28,6 +28,7 @@ #include "kddockwidgets/KDDockWidgets.h" #include "kddockwidgets/LayoutSaver.h" #include "kddockwidgets/QWidgetAdapter.h" +#include "kdbindings/signal.h" #include @@ -224,6 +225,7 @@ Q_SIGNALS: private: bool m_inResizeEvent = false; Layouting::ItemContainer *m_rootItem = nullptr; + KDBindings::ConnectionHandle m_minSizeChangedHandler; }; } diff --git a/src/private/multisplitter/Item.cpp b/src/private/multisplitter/Item.cpp index a1f083fa..e72889e7 100644 --- a/src/private/multisplitter/Item.cpp +++ b/src/private/multisplitter/Item.cpp @@ -14,6 +14,7 @@ #include "MultiSplitterConfig.h" #include "Widget.h" #include "ItemFreeContainer_p.h" +#include "kdbindings/signal.h" #include #include @@ -387,9 +388,9 @@ void Item::setParentContainer(ItemContainer *parent) return; if (m_parent) { - disconnect(this, &Item::minSizeChanged, m_parent, &ItemContainer::onChildMinSizeChanged); - disconnect(this, &Item::visibleChanged, m_parent, &ItemContainer::onChildVisibleChanged); - Q_EMIT visibleChanged(this, false); + m_minSizeChangedHandle.disconnect(); + m_visibleChangedHandle.disconnect(); + visibleChanged.emit(this, false); } if (auto c = asContainer()) { @@ -410,13 +411,13 @@ void Item::setParentContainer(ItemContainer *parent) void Item::connectParent(ItemContainer *parent) { if (parent) { - connect(this, &Item::minSizeChanged, parent, &ItemContainer::onChildMinSizeChanged); - connect(this, &Item::visibleChanged, parent, &ItemContainer::onChildVisibleChanged); + m_minSizeChangedHandle = minSizeChanged.connect(&ItemContainer::onChildMinSizeChanged, parent); + m_visibleChangedHandle = visibleChanged.connect(&ItemContainer::onChildVisibleChanged, parent); setHostWidget(parent->hostWidget()); updateWidgetGeometries(); - Q_EMIT visibleChanged(this, isVisible()); + visibleChanged.emit(this, isVisible()); } } @@ -449,7 +450,7 @@ void Item::setMinSize(QSize sz) { if (sz != m_sizingInfo.minSize) { m_sizingInfo.minSize = sz; - Q_EMIT minSizeChanged(this); + minSizeChanged.emit(this); if (!m_isSettingGuest) setSize_recursive(size().expandedTo(sz)); } @@ -459,7 +460,7 @@ void Item::setMaxSizeHint(QSize sz) { if (sz != m_sizingInfo.maxSizeHint) { m_sizingInfo.maxSizeHint = sz; - Q_EMIT maxSizeChanged(this); + maxSizeChanged.emit(this); } } @@ -598,7 +599,7 @@ void Item::setIsVisible(bool is) { if (is != m_isVisible) { m_isVisible = is; - Q_EMIT visibleChanged(this, is); + visibleChanged.emit(this, is); } if (is && m_guest) { @@ -701,16 +702,16 @@ void Item::setGeometry(QRect rect) << ": parent=" << parentContainer(); } - Q_EMIT geometryChanged(); + geometryChanged.emit(); if (oldGeo.x() != x()) - Q_EMIT xChanged(); + xChanged.emit(); if (oldGeo.y() != y()) - Q_EMIT yChanged(); + yChanged.emit(); if (oldGeo.width() != width()) - Q_EMIT widthChanged(); + widthChanged.emit(); if (oldGeo.height() != height()) - Q_EMIT heightChanged(); + heightChanged.emit(); updateWidgetGeometries(); } @@ -763,6 +764,8 @@ Item::Item(bool isContainer, Widget *hostWidget, ItemContainer *parent) Item::~Item() { + m_minSizeChangedHandle.disconnect(); + m_visibleChangedHandle.disconnect(); } bool Item::eventFilter(QObject *widget, QEvent *e) @@ -1214,7 +1217,7 @@ void ItemBoxContainer::removeItem(Item *item, bool hardRemove) m_children.removeOne(item); delete item; if (!isContainer) - Q_EMIT root()->numItemsChanged(); + root()->numItemsChanged.emit(); } else { item->setIsVisible(false); item->setGuestWidget(nullptr); @@ -1226,7 +1229,7 @@ void ItemBoxContainer::removeItem(Item *item, bool hardRemove) } if (wasVisible) { - Q_EMIT root()->numVisibleItemsChanged(root()->numVisibleChildren()); + root()->numVisibleItemsChanged.emit(root()->numVisibleChildren()); } if (isEmpty()) { @@ -1241,7 +1244,7 @@ void ItemBoxContainer::removeItem(Item *item, bool hardRemove) } else { // Neighbours will occupy the space of the deleted item growNeighbours(side1Item, side2Item); - Q_EMIT itemsChanged(); + itemsChanged.emit(); updateSizeConstraints(); d->updateSeparators_recursive(); @@ -1270,7 +1273,7 @@ ItemBoxContainer *ItemBoxContainer::convertChildToContainer(Item *leaf) m_children.removeOne(leaf); container->setGeometry(leaf->geometry()); container->insertItem(leaf, Location_OnTop, DefaultSizeMode::NoDefaultSizeMode); - Q_EMIT itemsChanged(); + itemsChanged.emit(); d->updateSeparators_recursive(); return container; @@ -1400,7 +1403,7 @@ void ItemBoxContainer::updateSizeConstraints() } // Our min-size changed, notify our parent, and so on until it reaches root() - Q_EMIT minSizeChanged(this); + minSizeChanged.emit(this); } void ItemBoxContainer::onChildVisibleChanged(Item *, bool visible) @@ -1411,9 +1414,9 @@ void ItemBoxContainer::onChildVisibleChanged(Item *, bool visible) const int numVisible = numVisibleChildren(); if (visible && numVisible == 1) { // Child became visible and there's only 1 visible child. Meaning there were 0 visible before. - Q_EMIT visibleChanged(this, true); + visibleChanged.emit(this, true); } else if (!visible && numVisible == 0) { - Q_EMIT visibleChanged(this, false); + visibleChanged.emit(this, false); } } @@ -1699,7 +1702,7 @@ void ItemBoxContainer::insertItem(Item *item, int index, InitialOption option) m_children.insert(index, item); item->setParentContainer(this); - Q_EMIT itemsChanged(); + itemsChanged.emit(); if (!d->m_convertingItemToContainer && item->isVisible()) restoreChild(item); @@ -1710,8 +1713,8 @@ void ItemBoxContainer::insertItem(Item *item, int index, InitialOption option) simplify(); if (shouldEmitVisibleChanged) - Q_EMIT root()->numVisibleItemsChanged(root()->numVisibleChildren()); - Q_EMIT root()->numItemsChanged(); + root()->numVisibleItemsChanged.emit(root()->numVisibleChildren()); + root()->numItemsChanged.emit(); } bool ItemBoxContainer::hasOrientationFor(Location loc) const @@ -3258,7 +3261,7 @@ void ItemBoxContainer::fillFromVariantMap(const QVariantMap &map, d->relayoutIfNeeded(); positionItems_recursive(); - Q_EMIT minSizeChanged(this); + minSizeChanged.emit(this); #ifdef DOCKS_DEVELOPER_MODE if (!checkSanity()) qWarning() << Q_FUNC_INFO << "Resulting layout is invalid"; @@ -3536,15 +3539,15 @@ ItemContainer::ItemContainer(Widget *hostWidget, ItemContainer *parent) : Item(true, hostWidget, parent) , d(new Private(this)) { - connect(this, &Item::xChanged, this, [this] { + xChanged.connect([this] { for (Item *item : qAsConst(m_children)) { - Q_EMIT item->xChanged(); + item->xChanged.emit(); } }); - connect(this, &Item::yChanged, this, [this] { + yChanged.connect([this] { for (Item *item : qAsConst(m_children)) { - Q_EMIT item->yChanged(); + item->yChanged.emit(); } }); } diff --git a/src/private/multisplitter/ItemFreeContainer.cpp b/src/private/multisplitter/ItemFreeContainer.cpp index 3a0ebb4f..4715e6a0 100644 --- a/src/private/multisplitter/ItemFreeContainer.cpp +++ b/src/private/multisplitter/ItemFreeContainer.cpp @@ -40,12 +40,12 @@ void ItemFreeContainer::addDockWidget(Item *item, QPoint localPt) item->setParentContainer(this); item->setPos(localPt); - Q_EMIT itemsChanged(); + itemsChanged.emit(); if (item->isVisible()) - Q_EMIT numVisibleItemsChanged(numVisibleChildren()); + numVisibleItemsChanged.emit(numVisibleChildren()); - Q_EMIT numItemsChanged(); + numItemsChanged.emit(); } void ItemFreeContainer::clear() @@ -67,9 +67,9 @@ void ItemFreeContainer::removeItem(Item *item, bool hardRemove) } if (wasVisible) - Q_EMIT numVisibleItemsChanged(numVisibleChildren()); + numVisibleItemsChanged.emit(numVisibleChildren()); - Q_EMIT itemsChanged(); + itemsChanged.emit(); } void ItemFreeContainer::restore(Item *child) diff --git a/src/private/multisplitter/Item_p.h b/src/private/multisplitter/Item_p.h index 2bbc4fbe..1ea5b842 100644 --- a/src/private/multisplitter/Item_p.h +++ b/src/private/multisplitter/Item_p.h @@ -20,6 +20,8 @@ #include #include +#include "kdbindings/signal.h" + #include class TestMultiSplitter; @@ -248,12 +250,6 @@ struct SizingInfo class DOCKS_EXPORT_FOR_UNIT_TESTS Item : public QObject { Q_OBJECT - Q_PROPERTY(int x READ x NOTIFY xChanged) - Q_PROPERTY(int y READ y NOTIFY yChanged) - Q_PROPERTY(int width READ width NOTIFY widthChanged) - Q_PROPERTY(int height READ height NOTIFY heightChanged) - Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged) - Q_PROPERTY(bool isContainer READ isContainer CONSTANT) public: typedef QVector List; @@ -339,15 +335,14 @@ public: static Item *createFromVariantMap(Widget *hostWidget, ItemContainer *parent, const QVariantMap &map, const QHash &widgets); -Q_SIGNALS: - void geometryChanged(); - void xChanged(); - void yChanged(); - void widthChanged(); - void heightChanged(); - void visibleChanged(Layouting::Item *thisItem, bool visible); - void minSizeChanged(Layouting::Item *thisItem); - void maxSizeChanged(Layouting::Item *thisItem); + KDBindings::Signal<> geometryChanged; + KDBindings::Signal<> xChanged; + KDBindings::Signal<> yChanged; + KDBindings::Signal<> widthChanged; + KDBindings::Signal<> heightChanged; + KDBindings::Signal visibleChanged; + KDBindings::Signal minSizeChanged; + KDBindings::Signal maxSizeChanged; protected: friend class ::TestMultiSplitter; @@ -388,6 +383,9 @@ private: bool m_isVisible = false; Widget *m_hostWidget = nullptr; Widget *m_guest = nullptr; + + KDBindings::ConnectionHandle m_minSizeChangedHandle; + KDBindings::ConnectionHandle m_visibleChangedHandle; }; /// @brief And Item which can contain other Items @@ -420,16 +418,15 @@ public: int count_recursive() const; virtual void clear() = 0; +public: + KDBindings::Signal<> itemsChanged; + KDBindings::Signal<> numItemsChanged; + KDBindings::Signal numVisibleItemsChanged; + protected: bool hasSingleVisibleItem() const; - Item::List m_children; -Q_SIGNALS: - void itemsChanged(); - void numVisibleItemsChanged(int); - void numItemsChanged(); - private: struct Private; Private *const d; diff --git a/tests/tst_multisplitter.cpp b/tests/tst_multisplitter.cpp index d73c0d2b..708bfcc9 100644 --- a/tests/tst_multisplitter.cpp +++ b/tests/tst_multisplitter.cpp @@ -812,7 +812,7 @@ void TestMultiSplitter::tst_turnIntoPlaceholder() auto root = createRoot(); int numVisibleItems = 0; - QObject::connect(root.get(), &ItemBoxContainer::numVisibleItemsChanged, this, [&numVisibleItems] (int count) { + root->numVisibleItemsChanged.connect([&numVisibleItems] (int count) { numVisibleItems = count; });