diff --git a/AdvancedDockingSystem/include/ads/API.h b/AdvancedDockingSystem/include/ads/API.h index 9714863..6c721db 100644 --- a/AdvancedDockingSystem/include/ads/API.h +++ b/AdvancedDockingSystem/include/ads/API.h @@ -1,10 +1,8 @@ #ifndef ADS_API_H #define ADS_API_H -#include -#include -#include -#include +#include +class QWidget; class QSplitter; // DLL Export API @@ -38,6 +36,8 @@ class QSplitter; //#define ADS_ANIMATION_DURATION 150 ADS_NAMESPACE_BEGIN +class ContainerWidget; +class SectionWidget; enum DropArea { @@ -52,11 +52,11 @@ enum DropArea }; Q_DECLARE_FLAGS(DropAreas, DropArea) -void deleteEmptySplitter(class ContainerWidget* container); -class ContainerWidget* findParentContainerWidget(class QWidget* w); -class SectionWidget* findParentSectionWidget(class QWidget* w); -QSplitter* findParentSplitter(class QWidget* w); -QSplitter* findImmediateSplitter(class QWidget* w); +void deleteEmptySplitter(ContainerWidget* container); +ContainerWidget* findParentContainerWidget(QWidget* w); +SectionWidget* findParentSectionWidget(QWidget* w); +QSplitter* findParentSplitter(QWidget* w); +QSplitter* findImmediateSplitter(QWidget* w); ADS_NAMESPACE_END #endif diff --git a/AdvancedDockingSystem/include/ads/ContainerWidget.h b/AdvancedDockingSystem/include/ads/ContainerWidget.h index 36261f8..f596f32 100644 --- a/AdvancedDockingSystem/include/ads/ContainerWidget.h +++ b/AdvancedDockingSystem/include/ads/ContainerWidget.h @@ -1,21 +1,21 @@ #ifndef ADS_CONTAINERWIDGET_H #define ADS_CONTAINERWIDGET_H +#include #include #include -#include -#include -#include +class QPoint; class QSplitter; class QMenu; +class QGridLayout; #include "ads/API.h" #include "ads/Internal.h" #include "ads/SectionContent.h" -#include "ads/SectionWidget.h" #include "ads/FloatingWidget.h" ADS_NAMESPACE_BEGIN +class SectionWidget; class InternalContentData; @@ -28,6 +28,7 @@ class ADS_EXPORT_API ContainerWidget : public QFrame Q_OBJECT Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged) + friend class SectionContent; friend class SectionWidget; friend class FloatingWidget; friend class SectionTitleWidget; @@ -35,6 +36,7 @@ class ADS_EXPORT_API ContainerWidget : public QFrame public: explicit ContainerWidget(QWidget *parent = NULL); + virtual ~ContainerWidget(); // // Public API @@ -132,12 +134,20 @@ signals: void activeTabChanged(const SectionContent::RefPtr& sc, bool active); private: + // Elements inside container. QList _sections; QList _floatings; - QHash _hiddenSectionContents; + // Helper lookup maps, restricted to this container. + QHash _scLookupMapById; + QHash _scLookupMapByName; + + QHash _swLookupMapById; + //QHash > _swLookupMapByContainer; // TODO Do we really need it? + + // Layout stuff QGridLayout* _mainLayout; Qt::Orientation _orientation; diff --git a/AdvancedDockingSystem/include/ads/DropOverlay.h b/AdvancedDockingSystem/include/ads/DropOverlay.h index 2a1fea5..a89d096 100644 --- a/AdvancedDockingSystem/include/ads/DropOverlay.h +++ b/AdvancedDockingSystem/include/ads/DropOverlay.h @@ -1,12 +1,13 @@ #ifndef DROP_OVERLAY_H #define DROP_OVERLAY_H -#include #include +#include #include "ads/API.h" ADS_NAMESPACE_BEGIN +class DropSplitAreas; // DropOverlay paints a translucent rectangle over another widget. // It can also show different types of drop area indicators. @@ -26,7 +27,7 @@ protected: virtual void moveEvent(QMoveEvent* e); private: - class DropSplitAreas* _splitAreas; + DropSplitAreas* _splitAreas; bool _fullAreaDrop; }; diff --git a/AdvancedDockingSystem/include/ads/FloatingWidget.h b/AdvancedDockingSystem/include/ads/FloatingWidget.h index 0438f22..7dce5c0 100644 --- a/AdvancedDockingSystem/include/ads/FloatingWidget.h +++ b/AdvancedDockingSystem/include/ads/FloatingWidget.h @@ -2,7 +2,6 @@ #define FLOATINGWIDGET_H #include -#include class QBoxLayout; #include "ads/API.h" diff --git a/AdvancedDockingSystem/include/ads/Internal.h b/AdvancedDockingSystem/include/ads/Internal.h index 062b833..ccd996a 100644 --- a/AdvancedDockingSystem/include/ads/Internal.h +++ b/AdvancedDockingSystem/include/ads/Internal.h @@ -5,7 +5,10 @@ #include #include "ads/API.h" -#include "ads/SectionContent.h" + +#define SCLookupMapById(X) X->_scLookupMapById +#define SCLookupMapByName(X) X->_scLookupMapByName +#define SWLookupMapById(X) X->_swLookupMapById ADS_NAMESPACE_BEGIN class SectionContent; @@ -22,7 +25,7 @@ public: InternalContentData(); ~InternalContentData(); - SectionContent::RefPtr content; + QSharedPointer content; SectionTitleWidget* titleWidget; SectionContentWidget* contentWidget; }; diff --git a/AdvancedDockingSystem/include/ads/SectionContent.h b/AdvancedDockingSystem/include/ads/SectionContent.h index d5d8a75..f101f71 100644 --- a/AdvancedDockingSystem/include/ads/SectionContent.h +++ b/AdvancedDockingSystem/include/ads/SectionContent.h @@ -1,11 +1,10 @@ #ifndef SECTIONCONTENT_H #define SECTIONCONTENT_H -#include -#include -#include #include #include +#include +class QWidget; #include "ads/API.h" @@ -51,7 +50,7 @@ private: const int _uid; QString _uniqueName; - ContainerWidget* _containerWidget; + QPointer _containerWidget; QPointer _titleWidget; QPointer _contentWidget; @@ -59,8 +58,6 @@ private: QString _title; static int GetNextUid(); - static QHash& GetLookupMap(); - static QHash& GetLookupMapByName(); }; ADS_NAMESPACE_END diff --git a/AdvancedDockingSystem/include/ads/SectionTitleWidget.h b/AdvancedDockingSystem/include/ads/SectionTitleWidget.h index faa7ce5..31d98f8 100644 --- a/AdvancedDockingSystem/include/ads/SectionTitleWidget.h +++ b/AdvancedDockingSystem/include/ads/SectionTitleWidget.h @@ -1,8 +1,9 @@ #ifndef SECTION_TITLE_WIDGET_H #define SECTION_TITLE_WIDGET_H -#include +#include #include +#include #include "ads/API.h" #include "ads/SectionContent.h" diff --git a/AdvancedDockingSystem/include/ads/SectionWidget.h b/AdvancedDockingSystem/include/ads/SectionWidget.h index 9e00255..9a58487 100644 --- a/AdvancedDockingSystem/include/ads/SectionWidget.h +++ b/AdvancedDockingSystem/include/ads/SectionWidget.h @@ -2,8 +2,8 @@ #define SECTION_WIDGET_H #include +#include #include -#include #include class QBoxLayout; class QStackedLayout; @@ -56,7 +56,7 @@ private slots: private: const int _uid; - ContainerWidget* _container; + QPointer _container; QList _contents; QList _sectionTitles; QList _sectionContents; @@ -69,12 +69,6 @@ private: SectionTitleWidget* _mousePressTitleWidget; static int GetNextUid(); - static QHash& GetLookupMap(); - static QHash >& GetLookupMapByContainer(); - -// static int NextUid; -// static QHash LookupMap; -// static QHash > LookupMapByContainer; }; ADS_NAMESPACE_END diff --git a/AdvancedDockingSystem/res/stylesheets/vendor-partsolutions.css b/AdvancedDockingSystem/res/stylesheets/vendor-partsolutions.css index 0d6262a..ee7ed2a 100644 --- a/AdvancedDockingSystem/res/stylesheets/vendor-partsolutions.css +++ b/AdvancedDockingSystem/res/stylesheets/vendor-partsolutions.css @@ -34,6 +34,12 @@ ads--SectionTitleWidget[activeTab="true"], SectionTitleWidget[activeTab="true"] border: 1px solid #E7F3F8; } +ads--SectionWidget QPushButton#closeButton, SectionWidget QPushButton#closeButton, +ads--FloatingWidget QPushButton#closeButton, FloatingWidget QPushButton#closeButton { + background: #ff0000; + border: 1px solid red; +} + ads--SectionContentWidget, SectionContentWidget { background: #ffffff; border: 0px solid #E7F3F8; diff --git a/AdvancedDockingSystem/src/API.cpp b/AdvancedDockingSystem/src/API.cpp index fbe8dc9..0c8b66d 100644 --- a/AdvancedDockingSystem/src/API.cpp +++ b/AdvancedDockingSystem/src/API.cpp @@ -2,8 +2,10 @@ #include #include +#include #include "ads/ContainerWidget.h" +#include "ads/SectionWidget.h" ADS_NAMESPACE_BEGIN diff --git a/AdvancedDockingSystem/src/ContainerWidget.cpp b/AdvancedDockingSystem/src/ContainerWidget.cpp index 43fe103..12469c3 100644 --- a/AdvancedDockingSystem/src/ContainerWidget.cpp +++ b/AdvancedDockingSystem/src/ContainerWidget.cpp @@ -1,7 +1,4 @@ #include "ads/ContainerWidget.h" -#include "ads/Internal.h" -#include "ads/SectionTitleWidget.h" -#include "ads/SectionContentWidget.h" #include #include @@ -10,6 +7,13 @@ #include #include #include +#include +#include + +#include "ads/Internal.h" +#include "ads/SectionWidget.h" +#include "ads/SectionTitleWidget.h" +#include "ads/SectionContentWidget.h" ADS_NAMESPACE_BEGIN @@ -37,6 +41,27 @@ ContainerWidget::ContainerWidget(QWidget *parent) : setLayout(_mainLayout); } +ContainerWidget::~ContainerWidget() +{ + // Note: It's required to delete in 2 steps + // Remove from list, and then delete. + // Because the destrcutor of objects wants to modfiy the current + // iterating list as well... :-/ + while (!_sections.isEmpty()) + { + SectionWidget* sw = _sections.takeLast(); + delete sw; + } + while (!_floatings.isEmpty()) + { + FloatingWidget* fw = _floatings.takeLast(); + delete fw; + } + _scLookupMapById.clear(); + _scLookupMapByName.clear(); + _swLookupMapById.clear(); +} + Qt::Orientation ContainerWidget::orientation() const { return _orientation; @@ -70,7 +95,12 @@ SectionWidget* ContainerWidget::addSectionContent(const SectionContent::RefPtr& data.content = sc; data.titleWidget = new SectionTitleWidget(sc, NULL); data.contentWidget = new SectionContentWidget(sc, NULL); + +#if QT_VERSION >= 0x050000 QObject::connect(data.titleWidget, &SectionTitleWidget::activeTabChanged, this, &ContainerWidget::onActiveTabChanged); +#else + QObject::connect(data.titleWidget, SIGNAL(activeTabChanged()), this, SLOT(onActiveTabChanged())); +#endif return dropContent(data, sw, area, false); } @@ -96,7 +126,7 @@ bool ContainerWidget::showSectionContent(const SectionContent::RefPtr& sc) hsi.data.titleWidget->setVisible(true); hsi.data.contentWidget->setVisible(true); SectionWidget* sw = NULL; - if (hsi.preferredSectionId > 0 && (sw = SectionWidget::GetLookupMap().value(hsi.preferredSectionId)) != NULL) + if (hsi.preferredSectionId > 0 && (sw = SWLookupMapById(this).value(hsi.preferredSectionId)) != NULL) { sw->addContent(hsi.data, true); return true; @@ -343,7 +373,7 @@ QByteArray ContainerWidget::saveState() const while (iter.hasNext()) { iter.next(); - if (iter.value().preferredSectionId <= 0 || !SectionWidget::GetLookupMap().contains(iter.value().preferredSectionId)) + if (iter.value().preferredSectionId <= 0 || !SWLookupMapById(this).contains(iter.value().preferredSectionId)) cnt++; } out << cnt; @@ -351,7 +381,7 @@ QByteArray ContainerWidget::saveState() const while (iter.hasNext()) { iter.next(); - if (iter.value().preferredSectionId <= 0 || !SectionWidget::GetLookupMap().contains(iter.value().preferredSectionId)) + if (iter.value().preferredSectionId <= 0 || !SWLookupMapById(this).contains(iter.value().preferredSectionId)) out << iter.value().data.content->uniqueName(); } } @@ -417,7 +447,7 @@ bool ContainerWidget::restoreState(const QByteArray& data) QString uname; in >> uname; - const SectionContent::RefPtr sc = SectionContent::GetLookupMapByName().value(uname); + const SectionContent::RefPtr sc = SCLookupMapByName(this).value(uname); if (!sc) continue; @@ -442,7 +472,7 @@ bool ContainerWidget::restoreState(const QByteArray& data) { QString uname; in >> uname; - const SectionContent::RefPtr sc = SectionContent::GetLookupMapByName().value(uname); + const SectionContent::RefPtr sc = SCLookupMapByName(this).value(uname); if (!sc) continue; @@ -478,7 +508,7 @@ bool ContainerWidget::restoreState(const QByteArray& data) contents.append(contentsToHide.at(i)); // Compare restored contents with available contents - const QList allContents = SectionContent::GetLookupMap().values(); + const QList allContents = SCLookupMapById(this).values(); for (int i = 0; i < allContents.count(); ++i) { const SectionContent::RefPtr sc = allContents.at(i).toStrongRef(); @@ -885,7 +915,7 @@ bool ContainerWidget::restoreFloatingWidgets(QDataStream& in, int version, QList in >> visible; qDebug() << "Restore FloatingWidget" << uname << geom << visible; - const SectionContent::RefPtr sc = SectionContent::GetLookupMapByName().value(uname).toStrongRef(); + const SectionContent::RefPtr sc = SCLookupMapByName(this).value(uname).toStrongRef(); if (!sc) { qWarning() << "Can not find SectionContent:" << uname; @@ -963,7 +993,7 @@ bool ContainerWidget::restoreSectionWidgets(QDataStream& in, int version, QSplit int preferredIndex = -1; in >> preferredIndex; - const SectionContent::RefPtr sc = SectionContent::GetLookupMapByName().value(uname).toStrongRef(); + const SectionContent::RefPtr sc = SCLookupMapByName(this).value(uname).toStrongRef(); if (!sc) { qWarning() << "Can not find SectionContent:" << uname; @@ -1039,7 +1069,7 @@ void ContainerWidget::onActionToggleSectionContentVisibility(bool visible) if (!a) return; const int uid = a->property("uid").toInt(); - const SectionContent::RefPtr sc = SectionContent::GetLookupMap().value(uid).toStrongRef(); + const SectionContent::RefPtr sc = SCLookupMapById(this).value(uid).toStrongRef(); if (sc.isNull()) { qCritical() << "Can not find content by ID" << uid; diff --git a/AdvancedDockingSystem/src/SectionContent.cpp b/AdvancedDockingSystem/src/SectionContent.cpp index 254e1c4..13a750b 100644 --- a/AdvancedDockingSystem/src/SectionContent.cpp +++ b/AdvancedDockingSystem/src/SectionContent.cpp @@ -1,8 +1,12 @@ #include "ads/SectionContent.h" #include +#include #include +#include "ads/Internal.h" +#include "ads/ContainerWidget.h" + ADS_NAMESPACE_BEGIN SectionContent::SectionContent() : @@ -17,7 +21,7 @@ SectionContent::RefPtr SectionContent::newSectionContent(const QString& uniqueNa qFatal("Can not create SectionContent with empty uniqueName"); return RefPtr(); } - else if (GetLookupMapByName().contains(uniqueName)) + else if (SCLookupMapByName(container).contains(uniqueName)) { qFatal("Can not create SectionContent with already used uniqueName"); return RefPtr(); @@ -34,17 +38,18 @@ SectionContent::RefPtr SectionContent::newSectionContent(const QString& uniqueNa sc->_titleWidget = title; sc->_contentWidget = content; - GetLookupMap().insert(sc->uid(), sc); - if (!sc->uniqueName().isEmpty()) - GetLookupMapByName().insert(sc->uniqueName(), sc); - + SCLookupMapById(container).insert(sc->uid(), sc); + SCLookupMapByName(container).insert(sc->uniqueName(), sc); return sc; } SectionContent::~SectionContent() { - GetLookupMap().remove(_uid); - GetLookupMapByName().remove(_uniqueName); + if (_containerWidget) + { + SCLookupMapById(_containerWidget).remove(_uid); + SCLookupMapByName(_containerWidget).remove(_uniqueName); + } delete _titleWidget; delete _contentWidget; } @@ -97,16 +102,4 @@ int SectionContent::GetNextUid() return ++NextUid; } -QHash& SectionContent::GetLookupMap() -{ - static QHash LookupMap; - return LookupMap; -} - -QHash& SectionContent::GetLookupMapByName() -{ - static QHash LookupMapByName; - return LookupMapByName; -} - ADS_NAMESPACE_END diff --git a/AdvancedDockingSystem/src/SectionWidget.cpp b/AdvancedDockingSystem/src/SectionWidget.cpp index d038afe..7cd1c34 100644 --- a/AdvancedDockingSystem/src/SectionWidget.cpp +++ b/AdvancedDockingSystem/src/SectionWidget.cpp @@ -73,16 +73,17 @@ SectionWidget::SectionWidget(ContainerWidget* parent) : setGraphicsEffect(shadow); #endif - GetLookupMap().insert(_uid, this); - GetLookupMapByContainer()[_container].insert(_uid, this); + SWLookupMapById(_container).insert(_uid, this); } SectionWidget::~SectionWidget() { qDebug() << Q_FUNC_INFO; - GetLookupMap().remove(_uid); - GetLookupMapByContainer()[_container].remove(_uid); - _container->_sections.removeAll(this); // Note: I don't like this here, but we have to remove it from list... + if (_container) + { + SWLookupMapById(_container).remove(_uid); + _container->_sections.removeAll(this); // Note: I don't like this here, but we have to remove it from list... + } // Delete empty QSplitter. QSplitter* splitter = findParentSplitter(this); @@ -324,17 +325,17 @@ int SectionWidget::GetNextUid() return ++NextUid; } -QHash& SectionWidget::GetLookupMap() -{ - static QHash LookupMap; - return LookupMap; +//QHash& SectionWidget::GetLookupMap() +//{ +// static QHash LookupMap; +// return LookupMap; -} +//} -QHash >& SectionWidget::GetLookupMapByContainer() -{ - static QHash > LookupMapByContainer; - return LookupMapByContainer; -} +//QHash >& SectionWidget::GetLookupMapByContainer() +//{ +// static QHash > LookupMapByContainer; +// return LookupMapByContainer; +//} ADS_NAMESPACE_END diff --git a/AdvancedDockingSystemDemo/src/mainwindow.cpp b/AdvancedDockingSystemDemo/src/mainwindow.cpp index 9174d14..cd7b82e 100644 --- a/AdvancedDockingSystemDemo/src/mainwindow.cpp +++ b/AdvancedDockingSystemDemo/src/mainwindow.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "ads/SectionWidget.h" @@ -93,7 +94,11 @@ MainWindow::MainWindow(QWidget *parent) : _container = new ADS_NS::ContainerWidget(); _container->setOrientation(Qt::Vertical); +#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))); +#endif setCentralWidget(_container); // Test #1: Use high-level public API @@ -123,6 +128,7 @@ MainWindow::~MainWindow() void MainWindow::onActiveTabChanged(const ADS_NS::SectionContent::RefPtr& sc, bool active) { + Q_UNUSED(active); IconTitleWidget* itw = dynamic_cast(sc->titleWidget()); if (itw) { diff --git a/README.md b/README.md index bf3304e..832d9b4 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,8 @@ Items sorted by priority - [x] Add "title" to SectionContent object, which will be used in visible areas to display contents name. - [x] It should be possible to catch the "activeTabChanged" signal for EXTERN_API users - [x] Add API function to set an SC as active-tab +- [ ] Move all lookup maps into ContainterWidget as non-static members, otherwise we can not have the same SC name inside another ContainerWidget instance. + The uniqueness of a SectionContainer needs to be restricted to its parent ContainerWidget, not global! - [ ] Use scrolling for SectionWidget tabs? ### Some day...