Optimizes includes and forward declarations.

Fixes a bug where SectionWidget removes itself from _sections list during a qDeleteAll call on _sections.. that was stupid..
This commit is contained in:
mfreiholz 2016-02-26 12:43:14 +01:00
parent 74f6ba333f
commit 06304b9818
15 changed files with 125 additions and 80 deletions

View File

@ -1,10 +1,8 @@
#ifndef ADS_API_H
#define ADS_API_H
#include <QByteArray>
#include <QDataStream>
#include <QIODevice>
#include <QSharedPointer>
#include <QFlags>
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

View File

@ -1,21 +1,21 @@
#ifndef ADS_CONTAINERWIDGET_H
#define ADS_CONTAINERWIDGET_H
#include <QList>
#include <QPointer>
#include <QFrame>
#include <QGridLayout>
#include <QPoint>
#include <QList>
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<SectionWidget*> _sections;
QList<FloatingWidget*> _floatings;
QHash<int, HiddenSectionItem> _hiddenSectionContents;
// Helper lookup maps, restricted to this container.
QHash<int, SectionContent::WeakPtr> _scLookupMapById;
QHash<QString, SectionContent::WeakPtr> _scLookupMapByName;
QHash<int, SectionWidget*> _swLookupMapById;
//QHash<ContainerWidget*, QHash<int, SectionWidget*> > _swLookupMapByContainer; // TODO Do we really need it?
// Layout stuff
QGridLayout* _mainLayout;
Qt::Orientation _orientation;

View File

@ -1,12 +1,13 @@
#ifndef DROP_OVERLAY_H
#define DROP_OVERLAY_H
#include <QFrame>
#include <QRect>
#include <QFrame>
#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;
};

View File

@ -2,7 +2,6 @@
#define FLOATINGWIDGET_H
#include <QWidget>
#include <QFrame>
class QBoxLayout;
#include "ads/API.h"

View File

@ -5,7 +5,10 @@
#include <QWeakPointer>
#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<SectionContent> content;
SectionTitleWidget* titleWidget;
SectionContentWidget* contentWidget;
};

View File

@ -1,11 +1,10 @@
#ifndef SECTIONCONTENT_H
#define SECTIONCONTENT_H
#include <QPointer>
#include <QWidget>
#include <QHash>
#include <QSharedPointer>
#include <QWeakPointer>
#include <QPointer>
class QWidget;
#include "ads/API.h"
@ -51,7 +50,7 @@ private:
const int _uid;
QString _uniqueName;
ContainerWidget* _containerWidget;
QPointer<ContainerWidget> _containerWidget;
QPointer<QWidget> _titleWidget;
QPointer<QWidget> _contentWidget;
@ -59,8 +58,6 @@ private:
QString _title;
static int GetNextUid();
static QHash<int, SectionContent::WeakPtr>& GetLookupMap();
static QHash<QString, SectionContent::WeakPtr>& GetLookupMapByName();
};
ADS_NAMESPACE_END

View File

@ -1,8 +1,9 @@
#ifndef SECTION_TITLE_WIDGET_H
#define SECTION_TITLE_WIDGET_H
#include <QFrame>
#include <QPointer>
#include <QPoint>
#include <QFrame>
#include "ads/API.h"
#include "ads/SectionContent.h"

View File

@ -2,8 +2,8 @@
#define SECTION_WIDGET_H
#include <QDebug>
#include <QPointer>
#include <QList>
#include <QHash>
#include <QFrame>
class QBoxLayout;
class QStackedLayout;
@ -56,7 +56,7 @@ private slots:
private:
const int _uid;
ContainerWidget* _container;
QPointer<ContainerWidget> _container;
QList<SectionContent::RefPtr> _contents;
QList<SectionTitleWidget*> _sectionTitles;
QList<SectionContentWidget*> _sectionContents;
@ -69,12 +69,6 @@ private:
SectionTitleWidget* _mousePressTitleWidget;
static int GetNextUid();
static QHash<int, SectionWidget*>& GetLookupMap();
static QHash<ContainerWidget*, QHash<int, SectionWidget*> >& GetLookupMapByContainer();
// static int NextUid;
// static QHash<int, SectionWidget*> LookupMap;
// static QHash<ContainerWidget*, QHash<int, SectionWidget*> > LookupMapByContainer;
};
ADS_NAMESPACE_END

View File

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

View File

@ -2,8 +2,10 @@
#include <QWidget>
#include <QSplitter>
#include <QLayout>
#include "ads/ContainerWidget.h"
#include "ads/SectionWidget.h"
ADS_NAMESPACE_BEGIN

View File

@ -1,7 +1,4 @@
#include "ads/ContainerWidget.h"
#include "ads/Internal.h"
#include "ads/SectionTitleWidget.h"
#include "ads/SectionContentWidget.h"
#include <QPaintEvent>
#include <QPainter>
@ -10,6 +7,13 @@
#include <QSplitter>
#include <QDataStream>
#include <QtGlobal>
#include <QGridLayout>
#include <QPoint>
#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<SectionContent::WeakPtr> allContents = SectionContent::GetLookupMap().values();
const QList<SectionContent::WeakPtr> 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;

View File

@ -1,8 +1,12 @@
#include "ads/SectionContent.h"
#include <QDebug>
#include <QWidget>
#include <QLabel>
#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<int, SectionContent::WeakPtr>& SectionContent::GetLookupMap()
{
static QHash<int, SectionContent::WeakPtr> LookupMap;
return LookupMap;
}
QHash<QString, SectionContent::WeakPtr>& SectionContent::GetLookupMapByName()
{
static QHash<QString, SectionContent::WeakPtr> LookupMapByName;
return LookupMapByName;
}
ADS_NAMESPACE_END

View File

@ -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<int, SectionWidget*>& SectionWidget::GetLookupMap()
{
static QHash<int, SectionWidget*> LookupMap;
return LookupMap;
//QHash<int, SectionWidget*>& SectionWidget::GetLookupMap()
//{
// static QHash<int, SectionWidget*> LookupMap;
// return LookupMap;
}
//}
QHash<ContainerWidget*, QHash<int, SectionWidget*> >& SectionWidget::GetLookupMapByContainer()
{
static QHash<ContainerWidget*, QHash<int, SectionWidget*> > LookupMapByContainer;
return LookupMapByContainer;
}
//QHash<ContainerWidget*, QHash<int, SectionWidget*> >& SectionWidget::GetLookupMapByContainer()
//{
// static QHash<ContainerWidget*, QHash<int, SectionWidget*> > LookupMapByContainer;
// return LookupMapByContainer;
//}
ADS_NAMESPACE_END

View File

@ -8,6 +8,7 @@
#include <QFrame>
#include <QTreeView>
#include <QFileSystemModel>
#include <QBoxLayout>
#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<IconTitleWidget*>(sc->titleWidget());
if (itw)
{

View File

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