mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-11-15 13:15:43 +08:00
Do some refactoring for public api logic
This commit is contained in:
parent
77d05431c6
commit
9b09ae2fa6
@ -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 <em>data</em>, which was written with <em>saveState()</em>.
|
||||
* \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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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<SectionContent::RefPtr>& 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;
|
||||
|
||||
|
@ -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<FloatingWidget*> oldFloatings = _floatingWidgets;
|
||||
QList<SectionWidget*> 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<SectionWidget*> 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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user