From 9b09ae2fa6b9e5c9598dab0210f1efd56c0ee532 Mon Sep 17 00:00:00 2001 From: mfreiholz Date: Mon, 15 Feb 2016 11:13:58 +0100 Subject: [PATCH] Do some refactoring for public api logic --- .../include/ads/ContainerWidget.h | 17 +- .../include/ads/FloatingWidget.h | 2 + .../include/ads/SectionContentWidget.h | 3 + .../include/ads/SectionTitleWidget.h | 3 +- .../include/ads/SectionWidget.h | 6 +- AdvancedDockingSystem/src/ContainerWidget.cpp | 274 +++++++++--------- .../src/SectionTitleWidget.cpp | 2 +- AdvancedDockingSystem/src/SectionWidget.cpp | 2 +- AdvancedDockingSystemDemo/src/mainwindow.cpp | 28 +- 9 files changed, 172 insertions(+), 165 deletions(-) diff --git a/AdvancedDockingSystem/include/ads/ContainerWidget.h b/AdvancedDockingSystem/include/ads/ContainerWidget.h index 929058a..447d93a 100644 --- a/AdvancedDockingSystem/include/ads/ContainerWidget.h +++ b/AdvancedDockingSystem/include/ads/ContainerWidget.h @@ -52,6 +52,18 @@ public: */ QMenu* createContextMenu() const; + /*! + * Serializes the current state of contents and returns it as a plain byte array. + * \see restoreState(const QByteArray&) + */ + QByteArray saveState() const; + + /*! + * Deserilizes the state of contents from data, which was written with saveState(). + * \see saveState() + */ + bool restoreState(const QByteArray& data); + // // Internal Stuff Begins Here // @@ -70,11 +82,8 @@ public: QRect outerBottomDropRect() const; QRect outerLeftDropRect() const; - // Geometry and state serialization - QByteArray saveState() const; - bool restoreState(const QByteArray& data); - private: + SectionWidget* dropContentOuterHelper(QLayout* l, const InternalContentData& data, Qt::Orientation orientation, bool append); void saveGeometryWalk(QDataStream& out, QWidget* widget) const; bool restoreGeometryWalk(QDataStream& in, QSplitter* currentSplitter = NULL); diff --git a/AdvancedDockingSystem/include/ads/FloatingWidget.h b/AdvancedDockingSystem/include/ads/FloatingWidget.h index 8a0bcc0..beb3e90 100644 --- a/AdvancedDockingSystem/include/ads/FloatingWidget.h +++ b/AdvancedDockingSystem/include/ads/FloatingWidget.h @@ -22,6 +22,8 @@ class FloatingWidget : public QWidget { Q_OBJECT + friend class ContainerWidget; + public: FloatingWidget(ContainerWidget* container, SectionContent::RefPtr sc, SectionTitleWidget* titleWidget, SectionContentWidget* contentWidget, QWidget* parent = NULL); virtual ~FloatingWidget(); diff --git a/AdvancedDockingSystem/include/ads/SectionContentWidget.h b/AdvancedDockingSystem/include/ads/SectionContentWidget.h index f418b9a..774e874 100644 --- a/AdvancedDockingSystem/include/ads/SectionContentWidget.h +++ b/AdvancedDockingSystem/include/ads/SectionContentWidget.h @@ -8,12 +8,15 @@ ADS_NAMESPACE_BEGIN +class ContainerWidget; class SectionWidget; class SectionContentWidget : public QFrame { Q_OBJECT + friend class ContainerWidget; + public: SectionContentWidget(SectionContent::RefPtr c, QWidget* parent = 0); diff --git a/AdvancedDockingSystem/include/ads/SectionTitleWidget.h b/AdvancedDockingSystem/include/ads/SectionTitleWidget.h index 77e03d9..492eb5a 100644 --- a/AdvancedDockingSystem/include/ads/SectionTitleWidget.h +++ b/AdvancedDockingSystem/include/ads/SectionTitleWidget.h @@ -8,7 +8,7 @@ #include "ads/SectionContent.h" ADS_NAMESPACE_BEGIN - +class ContainerWidget; class SectionWidget; class FloatingWidget; @@ -17,6 +17,7 @@ class SectionTitleWidget : public QFrame Q_OBJECT Q_PROPERTY(bool activeTab MEMBER _activeTab NOTIFY activeTabChanged) + friend class ContainerWidget; friend class SectionWidget; SectionContent::RefPtr _content; diff --git a/AdvancedDockingSystem/include/ads/SectionWidget.h b/AdvancedDockingSystem/include/ads/SectionWidget.h index 03ce30f..3491560 100644 --- a/AdvancedDockingSystem/include/ads/SectionWidget.h +++ b/AdvancedDockingSystem/include/ads/SectionWidget.h @@ -25,9 +25,11 @@ class InternalContentData; class SectionWidget : public QFrame { Q_OBJECT + friend class ContainerWidget; + + explicit SectionWidget(ContainerWidget* parent); public: - explicit SectionWidget(ContainerWidget* parent); virtual ~SectionWidget(); int uid() const; @@ -39,7 +41,7 @@ public: const QList& contents() const { return _contents; } void addContent(SectionContent::RefPtr c); void addContent(const InternalContentData& data, bool autoActivate); - bool take(int uid, InternalContentData& data); + bool takeContent(int uid, InternalContentData& data); int indexOfContent(SectionContent::RefPtr c) const; int indexOfContentByTitlePos(const QPoint& pos, QWidget* exclude = NULL) const; diff --git a/AdvancedDockingSystem/src/ContainerWidget.cpp b/AdvancedDockingSystem/src/ContainerWidget.cpp index ab1d2e9..7b16875 100644 --- a/AdvancedDockingSystem/src/ContainerWidget.cpp +++ b/AdvancedDockingSystem/src/ContainerWidget.cpp @@ -23,58 +23,6 @@ static QSplitter* newSplitter(Qt::Orientation orientation = Qt::Horizontal, QWid return s; } -static SectionWidget* dropContentOuterHelper(ContainerWidget* cw, QLayout* l, const InternalContentData& data, Qt::Orientation orientation, bool append) -{ - SectionWidget* sw = new SectionWidget(cw); - sw->addContent(data, true); - - QSplitter* oldsp = findImmediateSplitter(cw); - if (oldsp->orientation() == orientation - || oldsp->count() == 1) - { - oldsp->setOrientation(orientation); - if (append) - oldsp->addWidget(sw); - else - oldsp->insertWidget(0, sw); - } - else - { - QSplitter* sp = newSplitter(orientation); - if (append) - { -#if QT_VERSION >= 0x050000 - QLayoutItem* li = l->replaceWidget(oldsp, sp); - sp->addWidget(oldsp); - sp->addWidget(sw); - delete li; -#else - int index = l->indexOf(oldsp); - QLayoutItem* li = l->takeAt(index); - sp->addWidget(oldsp); - sp->addWidget(sw); - delete li; -#endif - } - else - { -#if QT_VERSION >= 0x050000 - sp->addWidget(sw); - QLayoutItem* li = l->replaceWidget(oldsp, sp); - sp->addWidget(oldsp); - delete li; -#else - sp->addWidget(sw); - int index = l->indexOf(oldsp); - QLayoutItem* li = l->takeAt(index); - sp->addWidget(oldsp); - delete li; -#endif - } - } - return sw; -} - /////////////////////////////////////////////////////////////////////// ContainerWidget::ContainerWidget(QWidget *parent) : @@ -174,6 +122,100 @@ QMenu* ContainerWidget::createContextMenu() const return m; } +QByteArray ContainerWidget::saveState() const +{ + QByteArray ba; + QDataStream out(&ba, QIODevice::WriteOnly); + out.setVersion(QDataStream::Qt_4_5); + out << (quint32) 0x00001337; // Magic + out << (quint32) 1; // Version + + // Save state of floating contents + out << _floatingWidgets.count(); + for (int i = 0; i < _floatingWidgets.count(); ++i) + { + FloatingWidget* fw = _floatingWidgets.at(i); + out << fw->content()->uniqueName(); + out << fw->saveGeometry(); + } + + // Walk through layout for splitters + // Well.. there actually shouldn't be more than one + for (int i = 0; i < _mainLayout->count(); ++i) + { + QLayoutItem* li = _mainLayout->itemAt(i); + if (!li->widget()) + continue; + saveGeometryWalk(out, li->widget()); + } + + return ba; +} + +bool ContainerWidget::restoreState(const QByteArray& data) +{ + QDataStream in(data); + in.setVersion(QDataStream::Qt_4_5); + + quint32 magic = 0; + in >> magic; + if (magic != 0x00001337) + return false; + + quint32 version = 0; + in >> version; + if (version != 1) + return false; + + QList oldFloatings = _floatingWidgets; + QList oldSections = _sections; + + // Restore floating widgets + int fwCount = 0; + in >> fwCount; + if (fwCount > 0) + { + for (int i = 0; i < fwCount; ++i) + { + QString uname; + in >> uname; + QByteArray geom; + in >> geom; + + SectionContent::RefPtr sc = SectionContent::LookupMapByName.value(uname).toStrongRef(); + if (!sc) + { + qWarning() << "Can not find floating widget section-content" << uname; + continue; + } + InternalContentData data; + if (!this->takeContent(sc, data)) + continue; + + FloatingWidget* fw = new FloatingWidget(this, sc, data.titleWidget, data.contentWidget, this); + fw->restoreGeometry(geom); + } + } + + _sections.clear(); + + // Restore splitters and section widgets + const bool success = restoreGeometryWalk(in, NULL); + if (success) + { + QLayoutItem* old = _mainLayout->takeAt(0); + _mainLayout->addWidget(_splitter); + delete old; + qDeleteAll(oldFloatings); + qDeleteAll(oldSections); + } + + // TODO Handle contents which are not mentioned by deserialized data + // ... + + return success; +} + /////////////////////////////////////////////////////////////////////// // PRIVATE API BEGINS HERE /////////////////////////////////////////////////////////////////////// @@ -207,16 +249,16 @@ SectionWidget* ContainerWidget::dropContent(const InternalContentData& data, Sec switch (area) { case TopDropArea: - ret = dropContentOuterHelper(this, _mainLayout, data, Qt::Vertical, false); + ret = dropContentOuterHelper(_mainLayout, data, Qt::Vertical, false); break; case RightDropArea: - ret = dropContentOuterHelper(this, _mainLayout, data, Qt::Horizontal, true); + ret = dropContentOuterHelper(_mainLayout, data, Qt::Horizontal, true); break; case BottomDropArea: - ret = dropContentOuterHelper(this, _mainLayout, data, Qt::Vertical, true); + ret = dropContentOuterHelper(_mainLayout, data, Qt::Vertical, true); break; case LeftDropArea: - ret = dropContentOuterHelper(this, _mainLayout, data, Qt::Horizontal, false); + ret = dropContentOuterHelper(_mainLayout, data, Qt::Horizontal, false); break; default: return NULL; @@ -379,86 +421,57 @@ QRect ContainerWidget::outerLeftDropRect() const return QRect(r.left(), r.top(), w, r.height()); } -QByteArray ContainerWidget::saveState() const +SectionWidget* ContainerWidget::dropContentOuterHelper(QLayout* l, const InternalContentData& data, Qt::Orientation orientation, bool append) { - QByteArray ba; - QDataStream out(&ba, QIODevice::WriteOnly); - out.setVersion(QDataStream::Qt_4_5); - out << (quint32) 0x00001337; // Magic - out << (quint32) 1; // Version + ContainerWidget* cw = this; + SectionWidget* sw = new SectionWidget(cw); + sw->addContent(data, true); - // Walk through layout for splitters - // Well.. there actually shouldn't be more than one - for (int i = 0; i < _mainLayout->count(); ++i) + QSplitter* oldsp = findImmediateSplitter(cw); + if (oldsp->orientation() == orientation + || oldsp->count() == 1) { - QLayoutItem* li = _mainLayout->itemAt(i); - if (!li->widget()) - continue; - saveGeometryWalk(out, li->widget()); + oldsp->setOrientation(orientation); + if (append) + oldsp->addWidget(sw); + else + oldsp->insertWidget(0, sw); } - - // Save state of FloatingWidgets - out << _floatingWidgets.count(); - for (int i = 0; i < _floatingWidgets.count(); ++i) + else { - FloatingWidget* fw = _floatingWidgets.at(i); - out << fw->content()->uniqueName(); - out << fw->isVisible(); - out << fw->saveGeometry(); - } - - return ba; -} - -bool ContainerWidget::restoreState(const QByteArray& data) -{ - QDataStream in(data); - in.setVersion(QDataStream::Qt_4_5); - - quint32 magic = 0; - in >> magic; - if (magic != 0x00001337) - return false; - - quint32 version = 0; - in >> version; - if (version != 1) - return false; - - QList currentSections = _sections; - _sections.clear(); - - // Restore splitters and section widgets - const bool success = restoreGeometryWalk(in, NULL); - if (success) - { - QLayoutItem* old = _mainLayout->takeAt(0); - _mainLayout->addWidget(_splitter); - delete old; - qDeleteAll(currentSections); - } - - // Restore floating widgets - int fwCount = 0; - in >> fwCount; - for (int i = 0; i < fwCount; ++i) - { - QString uname; - bool visible = false; - QRect geom; - in >> uname >> visible >> geom; - - SectionContent::RefPtr sc = SectionContent::LookupMapByName.value(uname).toStrongRef(); - if (!sc) + QSplitter* sp = newSplitter(orientation); + if (append) { - qWarning() << "Can not find floating widget section-content" << uname; - continue; +#if QT_VERSION >= 0x050000 + QLayoutItem* li = l->replaceWidget(oldsp, sp); + sp->addWidget(oldsp); + sp->addWidget(sw); + delete li; +#else + int index = l->indexOf(oldsp); + QLayoutItem* li = l->takeAt(index); + sp->addWidget(oldsp); + sp->addWidget(sw); + delete li; +#endif + } + else + { +#if QT_VERSION >= 0x050000 + sp->addWidget(sw); + QLayoutItem* li = l->replaceWidget(oldsp, sp); + sp->addWidget(oldsp); + delete li; +#else + sp->addWidget(sw); + int index = l->indexOf(oldsp); + QLayoutItem* li = l->takeAt(index); + sp->addWidget(oldsp); + delete li; +#endif } - -// FloatingWidget* fw = new FloatingWidget(this, sc,) } - - return success; + return sw; } void ContainerWidget::saveGeometryWalk(QDataStream& out, QWidget* widget) const @@ -532,7 +545,6 @@ bool ContainerWidget::restoreGeometryWalk(QDataStream& in, QSplitter* currentSpl in >> currentIndex >> count; SectionWidget* sw = new SectionWidget(this); - // sw->setGeometry(geom); for (int i = 0; i < count; ++i) { QString name; @@ -547,7 +559,7 @@ bool ContainerWidget::restoreGeometryWalk(QDataStream& in, QSplitter* currentSpl // Unknown else { - qDebug() << QString(""); + qDebug() << QString(); } return true; @@ -559,7 +571,7 @@ bool ContainerWidget::takeContent(const SectionContent::RefPtr& sc, InternalCont bool found = false; for (int i = 0; i < _sections.count() && !found; ++i) { - found = _sections.at(i)->take(sc->uid(), data); + found = _sections.at(i)->takeContent(sc->uid(), data); } // Search in floating widgets diff --git a/AdvancedDockingSystem/src/SectionTitleWidget.cpp b/AdvancedDockingSystem/src/SectionTitleWidget.cpp index ab2b5b3..03fef77 100644 --- a/AdvancedDockingSystem/src/SectionTitleWidget.cpp +++ b/AdvancedDockingSystem/src/SectionTitleWidget.cpp @@ -227,7 +227,7 @@ void SectionTitleWidget::mouseMoveEvent(QMouseEvent* ev) { // Create floating widget. InternalContentData data; - if (!section->take(_content->uid(), data)) + if (!section->takeContent(_content->uid(), data)) { qWarning() << "THIS SHOULD NOT HAPPEN!!" << _content->uid() << _content->uniqueName(); return; diff --git a/AdvancedDockingSystem/src/SectionWidget.cpp b/AdvancedDockingSystem/src/SectionWidget.cpp index de6dbe1..acda50f 100644 --- a/AdvancedDockingSystem/src/SectionWidget.cpp +++ b/AdvancedDockingSystem/src/SectionWidget.cpp @@ -145,7 +145,7 @@ void SectionWidget::addContent(const InternalContentData& data, bool autoActivat // take removes a widget from the SectionWidget but does not delete // the used SectionTitle- and SectionContent-Widget. Instead it returns // these objects. -bool SectionWidget::take(int uid, InternalContentData& data) +bool SectionWidget::takeContent(int uid, InternalContentData& data) { // Find SectionContent. SectionContent::RefPtr sc; diff --git a/AdvancedDockingSystemDemo/src/mainwindow.cpp b/AdvancedDockingSystemDemo/src/mainwindow.cpp index 03ae029..2e9f0b5 100644 --- a/AdvancedDockingSystemDemo/src/mainwindow.cpp +++ b/AdvancedDockingSystemDemo/src/mainwindow.cpp @@ -95,29 +95,7 @@ MainWindow::MainWindow(QWidget *parent) : _container->setOrientation(Qt::Vertical); setCentralWidget(_container); - // Test #1: Use low-level API - // if (true) - // { - // ADS_NS::SectionWidget* section = NULL; - - // section = new ADS_NS::SectionWidget(_container); - // section->addContent(createLongTextLabelSC()); - // _container->addSection(section); - - // section = new ADS_NS::SectionWidget(_container); - // section->addContent(createCalendarSC()); - // _container->addSection(section); - - // section = new ADS_NS::SectionWidget(_container); - // section->addContent(createFileSystemTreeSC()); - // _container->addSection(section); - - // section = new ADS_NS::SectionWidget(_container); - // section->addContent(createCalendarSC()); - // _container->addSection(section); - // } - - // Test #2: Use high-level public API + // Test #1: Use high-level public API if (true) { ADS_NS::SectionWidget* sw1 = _container->addSectionContent(createLongTextLabelSC()); @@ -130,8 +108,8 @@ MainWindow::MainWindow(QWidget *parent) : resize(800, 600); // Restore window geometry and ContainerWidget state from last session - // restoreGeometry(loadDataHelper("MainWindow")); - // _container->restoreState(loadDataHelper("ContainerWidget")); + restoreGeometry(loadDataHelper("MainWindow")); + _container->restoreState(loadDataHelper("ContainerWidget")); } MainWindow::~MainWindow()