From 9bbc5e41a380d3e9bb28296e207aa135ee2c3a0c Mon Sep 17 00:00:00 2001 From: mfreiholz Date: Tue, 8 Mar 2016 10:58:56 +0100 Subject: [PATCH] Better implementation of empty QSplitter deletion (no longer crashes). Call it after restore, because sometimes one splitter was left ?-/ --- AdvancedDockingSystem/src/API.cpp | 35 ++++++++++++++++--- AdvancedDockingSystem/src/ContainerWidget.cpp | 15 +++++--- AdvancedDockingSystemDemo/src/mainwindow.cpp | 14 +++++--- AdvancedDockingSystemDemo/src/mainwindow.h | 4 +++ README.md | 4 ++- 5 files changed, 57 insertions(+), 15 deletions(-) diff --git a/AdvancedDockingSystem/src/API.cpp b/AdvancedDockingSystem/src/API.cpp index 0c8b66d..1cf8a78 100644 --- a/AdvancedDockingSystem/src/API.cpp +++ b/AdvancedDockingSystem/src/API.cpp @@ -3,21 +3,48 @@ #include #include #include +#include #include "ads/ContainerWidget.h" #include "ads/SectionWidget.h" ADS_NAMESPACE_BEGIN +static bool splitterContainsSectionWidget(QSplitter* splitter) +{ + for (int i = 0; i < splitter->count(); ++i) + { + QWidget* w = splitter->widget(i); + QSplitter* sp = qobject_cast(w); + SectionWidget* sw = NULL; + if (sp && splitterContainsSectionWidget(sp)) + return true; + else if ((sw = qobject_cast(w)) != NULL) + return true; + } + return false; +} + void deleteEmptySplitter(ContainerWidget* container) { - QList splitters = container->findChildren(); - for (int i = 0; i < splitters.count(); ++i) + bool doAgain = false; + do { - QSplitter* sp = splitters.at(i); - if (sp->count() == 0) + doAgain = false; + QList splitters = container->findChildren(); + for (int i = 0; i < splitters.count(); ++i) + { + QSplitter* sp = splitters.at(i); + if (!sp->property("ads-splitter").toBool()) + continue; + if (sp->count() > 0 && splitterContainsSectionWidget(sp)) + continue; delete splitters[i]; + doAgain = true; + break; + } } + while (doAgain); } ContainerWidget* findParentContainerWidget(QWidget* w) diff --git a/AdvancedDockingSystem/src/ContainerWidget.cpp b/AdvancedDockingSystem/src/ContainerWidget.cpp index 5eaa7db..310a228 100644 --- a/AdvancedDockingSystem/src/ContainerWidget.cpp +++ b/AdvancedDockingSystem/src/ContainerWidget.cpp @@ -22,6 +22,7 @@ ADS_NAMESPACE_BEGIN static QSplitter* newSplitter(Qt::Orientation orientation = Qt::Horizontal, QWidget* parent = 0) { QSplitter* s = new QSplitter(orientation, parent); + s->setProperty("ads-splitter", QVariant(true)); s->setChildrenCollapsible(false); s->setOpaqueResize(false); return s; @@ -348,9 +349,9 @@ QByteArray ContainerWidget::saveState() const { // Looks like the user has hidden all contents and no more sections // are available. We can simply write a list of all hidden contents. - out << 0; - out << _hiddenSectionContents.count(); + out << 0; // Mode + out << _hiddenSectionContents.count(); QHashIterator iter(_hiddenSectionContents); while (iter.hasNext()) { @@ -360,13 +361,15 @@ QByteArray ContainerWidget::saveState() const } else if (_mainLayout->count() == 1) { + out << 1; // Mode + // There should only be one! - out << 1; QLayoutItem* li = _mainLayout->itemAt(0); if (!li->widget()) qFatal("Not a widget in _mainLayout, this shouldn't happen."); - else - saveSectionWidgets(out, li->widget()); + + // Save sections beginning with the first QSplitter (li->widget()). + saveSectionWidgets(out, li->widget()); // Safe state of hidden contents, which doesn't have an section association // or the section association points to a no longer existing section. @@ -563,6 +566,8 @@ bool ContainerWidget::restoreState(const QByteArray& data) for (int i = 0; i < contentsToHide.count(); ++i) hideSectionContent(contentsToHide.at(i)); + deleteEmptySplitter(this); + qDebug() << "End of restore state" << success; return success; } diff --git a/AdvancedDockingSystemDemo/src/mainwindow.cpp b/AdvancedDockingSystemDemo/src/mainwindow.cpp index cd7b82e..e383fee 100644 --- a/AdvancedDockingSystemDemo/src/mainwindow.cpp +++ b/AdvancedDockingSystemDemo/src/mainwindow.cpp @@ -97,17 +97,21 @@ MainWindow::MainWindow(QWidget *parent) : #if QT_VERSION >= 0x050000 QObject::connect(_container, &ADS_NS::ContainerWidget::activeTabChanged, this, &MainWindow::onActiveTabChanged); #else - QObject::connect(_container, SIGNAL(activeTabChanged(SectionContent::RefPtr,bool)), this, SLOT(onActiveTabChanged(const::ads::SectionContent::RefPtr&,bool))); + QObject::connect(_container, SIGNAL(activeTabChanged(const SectionContent::RefPtr&, bool)), this, SLOT(onActiveTabChanged(const SectionContent::RefPtr&, bool))); #endif setCentralWidget(_container); // Test #1: Use high-level public API if (true) { - ADS_NS::SectionWidget* sw1 = _container->addSectionContent(createLongTextLabelSC(_container)); - _container->addSectionContent(createCalendarSC(_container), sw1, ADS_NS::BottomDropArea); - _container->addSectionContent(createFileSystemTreeSC(_container), NULL, ADS_NS::RightDropArea); - _container->addSectionContent(createCalendarSC(_container)); + ADS_NS::ContainerWidget* cw = _container; + ADS_NS::SectionWidget* sw = NULL; + + sw = _container->addSectionContent(createLongTextLabelSC(cw), sw, ADS_NS::CenterDropArea); + sw = _container->addSectionContent(createCalendarSC(cw), sw, ADS_NS::RightDropArea); + sw = _container->addSectionContent(createFileSystemTreeSC(cw), sw, ADS_NS::CenterDropArea); + +// _container->addSectionContent(createCalendarSC(_container)); // _container->addSectionContent(createLongTextLabelSC(_container)); // _container->addSectionContent(createLongTextLabelSC(_container)); // _container->addSectionContent(createLongTextLabelSC(_container)); diff --git a/AdvancedDockingSystemDemo/src/mainwindow.h b/AdvancedDockingSystemDemo/src/mainwindow.h index ee58cce..5a0a933 100644 --- a/AdvancedDockingSystemDemo/src/mainwindow.h +++ b/AdvancedDockingSystemDemo/src/mainwindow.h @@ -19,7 +19,11 @@ public: virtual ~MainWindow(); private slots: +#if QT_VERSION >= 0x050000 void onActiveTabChanged(const ADS_NS::SectionContent::RefPtr& sc, bool active); +#else + void onActiveTabChanged(const SectionContent::RefPtr& sc, bool active); +#endif void onActionAddSectionContentTriggered(); protected: diff --git a/README.md b/README.md index 60c88f4..fe80f37 100644 --- a/README.md +++ b/README.md @@ -40,13 +40,15 @@ Items sorted by priority ### Beta 0.2 - [ ] Use scrolling for SectionWidget tabs? - [ ] It would be easier when the SectionTitleWidget and SectionContentWidget are created inside the "SectionContent::newSectionContent(..)" method. - This would make sure, that those two objects always exists. + This would make sure, that those two objects always exists. - [ ] `ContainerWidget::showSectionContent` needs to insert the SC at the correct preferred position of SW +- [ ] It should be possible to drop a floating widget directly into the SW's tab-bar. - [ ] Empty splitters, if only 2 or 1 items are in container - [ ] Restore: Handle out-of-screen geometry for floating widgets - [ ] Better handling of sizes when dropping contents. Currently it's unpredictable. It might be good to use the same width/height as the parent content, if dropped on existing content. In case of outer-drop we might use the preferred size of the content. +- [ ] Floating widget should be a real window with all of its functionality (maximize and split by moving it to the edge of the screen) ### Beta 0.1 - [x] Improve FloatingWidget (Remove maximize button, only support close-button which hides the widget)