mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-11-15 13:15:43 +08:00
Implements storeGeometry() and restoreGeometry() for ContainerWidget. It
correctly aligns all widgets... wohooo.
This commit is contained in:
parent
7123410bb1
commit
9050d1910c
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <QContextMenuEvent>
|
||||
#include <QMenu>
|
||||
#include <QSplitter>
|
||||
#include <QDataStream>
|
||||
#include <QtGlobal>
|
||||
|
||||
ADS_NAMESPACE_BEGIN
|
||||
|
||||
@ -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;
|
||||
|
||||
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
|
||||
|
@ -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
|
@ -31,13 +31,16 @@ static ads::SectionContent::RefPtr createLongTextLabelSC()
|
||||
l->setText(QString("Lorem Ipsum ist ein einfacher Demo-Text für die Print- und Schriftindustrie. Lorem Ipsum ist in der Industrie bereits der Standard Demo-Text seit 1500, als ein unbekannter Schriftsteller eine Hand voll Wörter nahm und diese durcheinander warf um ein Musterbuch zu erstellen. Es hat nicht nur 5 Jahrhunderte überlebt, sondern auch in Spruch in die elektronische Schriftbearbeitung geschafft (bemerke, nahezu unverändert). Bekannt wurde es 1960, mit dem erscheinen von Letrase, welches Passagen von Lorem Ipsum enhielt, so wie Desktop Software wie Aldus PageMaker - ebenfalls mit Lorem Ipsum."));
|
||||
bl->addWidget(l);
|
||||
|
||||
return ads::SectionContent::newSectionContent(new IconTitleWidget(QIcon(), QString("Label %1").arg(++CONTENT_COUNT)), w);
|
||||
const int index = ++CONTENT_COUNT;
|
||||
return ads::SectionContent::newSectionContent(new IconTitleWidget(QIcon(), QString("Label %1").arg(index)), w, QString("uname-%1").arg(index));
|
||||
}
|
||||
|
||||
static ads::SectionContent::RefPtr createCalendarSC()
|
||||
{
|
||||
QCalendarWidget* w = new QCalendarWidget();
|
||||
return ads::SectionContent::newSectionContent(new IconTitleWidget(QIcon(), QString("Calendar %1").arg(++CONTENT_COUNT)), w);
|
||||
|
||||
const int index = ++CONTENT_COUNT;
|
||||
return ads::SectionContent::newSectionContent(new IconTitleWidget(QIcon(), QString("Calendar %1").arg(index)), w, QString("uname-%1").arg(index));
|
||||
}
|
||||
|
||||
static ads::SectionContent::RefPtr createFileSystemTreeSC()
|
||||
@ -46,7 +49,9 @@ static ads::SectionContent::RefPtr createFileSystemTreeSC()
|
||||
// QFileSystemModel* m = new QFileSystemModel(w);
|
||||
// m->setRootPath(QDir::currentPath());
|
||||
// w->setModel(m);
|
||||
return ads::SectionContent::newSectionContent(new IconTitleWidget(QIcon(), QString("Filesystem %1").arg(++CONTENT_COUNT)), w);
|
||||
|
||||
const int index = ++CONTENT_COUNT;
|
||||
return ads::SectionContent::newSectionContent(new IconTitleWidget(QIcon(), QString("Filesystem %1").arg(index)), w, QString("uname-%1").arg(index));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
@ -82,6 +87,15 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
section = new ads::SectionWidget(_container);
|
||||
section->addContent(createCalendarSC());
|
||||
_container->addSection(section);
|
||||
|
||||
QByteArray ba;
|
||||
QFile f("test.dat");
|
||||
if (f.open(QFile::ReadOnly))
|
||||
{
|
||||
ba = f.readAll();
|
||||
f.close();
|
||||
}
|
||||
_container->restoreGeometry(ba);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
@ -108,3 +122,14 @@ void MainWindow::contextMenuEvent(QContextMenuEvent* e)
|
||||
m->exec(QCursor::pos());
|
||||
delete m;
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent* e)
|
||||
{
|
||||
QByteArray ba = _container->saveGeometry();
|
||||
QFile f("test.dat");
|
||||
if (f.open(QFile::WriteOnly))
|
||||
{
|
||||
f.write(ba);
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ private slots:
|
||||
|
||||
protected:
|
||||
virtual void contextMenuEvent(QContextMenuEvent* e);
|
||||
virtual void closeEvent(QCloseEvent* e);
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
|
Loading…
Reference in New Issue
Block a user