Implements storeGeometry() and restoreGeometry() for ContainerWidget. It

correctly aligns all widgets... wohooo.
This commit is contained in:
mfreiholz
2016-02-11 14:33:02 +01:00
parent 7123410bb1
commit 9050d1910c
7 changed files with 181 additions and 29 deletions

View File

@@ -50,6 +50,10 @@ public:
QMenu* createContextMenu() const;
private:
void saveGeometryWalk(QDataStream& out, QWidget* widget) const;
bool restoreGeometryWalk(QDataStream& in, QSplitter* currentSplitter = NULL);
signals:
void orientationChanged();
@@ -63,8 +67,8 @@ public:
// Layout stuff
QGridLayout* _mainLayout;
Qt::Orientation _orientation; ///< Default orientation of new sections.
QPointer<QSplitter> _splitter; ///< Default/main splitter.
Qt::Orientation _orientation;
QPointer<QSplitter> _splitter;
};
ADS_NAMESPACE_END

View File

@@ -5,6 +5,7 @@
#include <QWidget>
#include <QHash>
#include <QSharedPointer>
#include <QWeakPointer>
#include "ads/API.h"
@@ -12,28 +13,32 @@ ADS_NAMESPACE_BEGIN
class SectionContent
{
friend class ContainerWidget;
private:
SectionContent(QWidget* title, QWidget* content, const QString& uniqueName = QString()); ///< Do not use!
public:
typedef QSharedPointer<SectionContent> RefPtr;
typedef QWeakPointer<SectionContent> WeakPtr;
SectionContent(QWidget* title, QWidget* content, const QString& uniqueName = QString()); ///< Do not use!
virtual ~SectionContent();
int uid() const;
QString uniqueName() const;
QWidget* titleWidget() const;
QWidget* contentWidget() const;
static RefPtr newSectionContent(QWidget* title, QWidget* content);
static RefPtr newSectionContent(const QString& title, QWidget* content);
static RefPtr newSectionContent(QWidget* title, QWidget* content, const QString& uniqueName = QString());
public:
private:
const int _uid;
const QString _uniqueName;
QPointer<QWidget> _title;
QPointer<QWidget> _content;
static int NextUid;
static QHash<int, SectionContent*> LookupMap;
static QHash<int, SectionContent::WeakPtr> LookupMap;
static QHash<QString, SectionContent::WeakPtr> LookupMapByName;
};
ADS_NAMESPACE_END

View File

@@ -35,7 +35,7 @@ public:
QRect titleAreaGeometry() const;
QRect contentAreaGeometry() const;
QList<SectionContent::RefPtr> contents() const { return _contents; }
const QList<SectionContent::RefPtr>& contents() const { return _contents; }
void addContent(SectionContent::RefPtr c);
void addContent(const InternalContentData& data, bool autoActivate);
InternalContentData take(int uid, bool del = true);

View File

@@ -5,6 +5,8 @@
#include <QContextMenuEvent>
#include <QMenu>
#include <QSplitter>
#include <QDataStream>
#include <QtGlobal>
ADS_NAMESPACE_BEGIN
@@ -25,7 +27,7 @@ static void dropContentOuterHelper(ContainerWidget* cw, QLayout* l, const Intern
QSplitter* oldsp = findImmediateSplitter(cw);
if (oldsp->orientation() == orientation
|| oldsp->count() == 1)
|| oldsp->count() == 1)
{
oldsp->setOrientation(orientation);
if (append)
@@ -276,8 +278,18 @@ QByteArray ContainerWidget::saveGeometry() const
QByteArray ba;
QDataStream out(&ba, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_5);
out << (int) 0x00001337;
out << _sections.size();
out << (quint32) 0x00001337; // Magic
out << (quint32) 1; // Version
// 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;
}
@@ -286,10 +298,28 @@ bool ContainerWidget::restoreGeometry(const QByteArray& data)
QDataStream in(data);
in.setVersion(QDataStream::Qt_4_5);
int magic = 0;
quint32 magic = 0;
in >> magic;
if (magic != 0x00001337)
return false;
return false;
quint32 version = 0;
in >> version;
if (version != 1)
return false;
QList<SectionWidget*> currentSections = _sections;
_sections.clear();
const bool success = restoreGeometryWalk(in, NULL);
if (success)
{
QLayoutItem* old = _mainLayout->takeAt(0);
_mainLayout->addWidget(_splitter);
delete old;
qDeleteAll(currentSections);
}
return success;
}
QMenu* ContainerWidget::createContextMenu() const
@@ -326,4 +356,91 @@ QMenu* ContainerWidget::createContextMenu() const
return m;
}
void ContainerWidget::saveGeometryWalk(QDataStream& out, QWidget* widget) const
{
QSplitter* sp = NULL;
SectionWidget* sw = NULL;
if (!widget)
{
out << 0;
}
else if ((sp = dynamic_cast<QSplitter*>(widget)) != NULL)
{
out << 1; // Type = QSplitter
out << ((sp->orientation() == Qt::Horizontal) ? (int) 1 : (int) 2);
out << sp->count();
for (int i = 0; i < sp->count(); ++i)
{
saveGeometryWalk(out, sp->widget(i));
}
}
else if ((sw = dynamic_cast<SectionWidget*>(widget)) != NULL)
{
out << 2; // Type = SectionWidget
out << sw->geometry();
out << sw->contents().count();
const QList<SectionContent::RefPtr>& contents = sw->contents();
for (int i = 0; i < contents.count(); ++i)
{
out << contents[i]->uniqueName();
}
}
}
bool ContainerWidget::restoreGeometryWalk(QDataStream& in, QSplitter* currentSplitter)
{
int type;
in >> type;
// Splitter
if (type == 1)
{
int orientation, count;
in >> orientation >> count;
QSplitter* sp = newSplitter((Qt::Orientation) orientation);
for (int i = 0; i < count; ++i)
{
if (!restoreGeometryWalk(in, sp))
return false;
}
if (!currentSplitter)
_splitter = sp;
else
currentSplitter->addWidget(sp);
}
// Section
else if (type == 2)
{
if (!currentSplitter)
{
qWarning() << "Missing splitter object for section";
return false;
}
QRect geom;
int count;
in >> geom >> count;
SectionWidget* sw = new SectionWidget(this);
sw->setGeometry(geom);
for (int i = 0; i < count; ++i)
{
QString name;
in >> name;
SectionContent::RefPtr sc = SectionContent::LookupMapByName.value(name).toStrongRef();
if (sc)
sw->addContent(sc);
}
currentSplitter->addWidget(sw);
}
// Unknown
else
{
qDebug() << QString("");
}
return true;
}
ADS_NAMESPACE_END

View File

@@ -5,20 +5,21 @@
ADS_NAMESPACE_BEGIN
int SectionContent::NextUid = 1;
QHash<int, SectionContent*> SectionContent::LookupMap;
QHash<int, SectionContent::WeakPtr> SectionContent::LookupMap;
QHash<QString, SectionContent::WeakPtr> SectionContent::LookupMapByName;
SectionContent::SectionContent(QWidget* title, QWidget* content, const QString& uniqueName) :
_uid(NextUid++),
_uniqueName(uniqueName)
_uniqueName(uniqueName),
_title(title),
_content(content)
{
_title = title;
_content = content;
LookupMap.insert(_uid, this);
}
SectionContent::~SectionContent()
{
LookupMap.remove(_uid);
LookupMapByName.remove(_uniqueName);
delete _title;
delete _content;
}
@@ -43,14 +44,13 @@ QWidget* SectionContent::contentWidget() const
return _content;
}
SectionContent::RefPtr SectionContent::newSectionContent(QWidget* title, QWidget* content)
SectionContent::RefPtr SectionContent::newSectionContent(QWidget* title, QWidget* content, const QString& uniqueName)
{
return QSharedPointer<SectionContent>(new SectionContent(title, content));
}
SectionContent::RefPtr SectionContent::newSectionContent(const QString& title, QWidget* content)
{
return QSharedPointer<SectionContent>(new SectionContent(new QLabel(title), content));
QSharedPointer<SectionContent> sc(new SectionContent(title, content, uniqueName));
LookupMap.insert(sc->uid(), sc);
if (!sc->uniqueName().isEmpty())
LookupMapByName.insert(sc->uniqueName(), sc);
return sc;
}
ADS_NAMESPACE_END