|
|
|
@ -18,8 +18,12 @@
|
|
|
|
|
#include "ads/DropOverlay.h"
|
|
|
|
|
#include "ads/Serialization.h"
|
|
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
|
|
ADS_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Static Helper //////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
static QSplitter* newSplitter(Qt::Orientation orientation = Qt::Horizontal, QWidget* parent = 0)
|
|
|
|
@ -35,15 +39,13 @@ static QSplitter* newSplitter(Qt::Orientation orientation = Qt::Horizontal, QWid
|
|
|
|
|
|
|
|
|
|
ContainerWidget::ContainerWidget(QWidget *parent) :
|
|
|
|
|
QFrame(parent),
|
|
|
|
|
_mainLayout(NULL),
|
|
|
|
|
_orientation(Qt::Horizontal),
|
|
|
|
|
_splitter(NULL),
|
|
|
|
|
_dropOverlay(new DropOverlay(this))
|
|
|
|
|
d(new ContainerWidgetPrivate())
|
|
|
|
|
{
|
|
|
|
|
_mainLayout = new QGridLayout();
|
|
|
|
|
_mainLayout->setContentsMargins(9, 9, 9, 9);
|
|
|
|
|
_mainLayout->setSpacing(0);
|
|
|
|
|
setLayout(_mainLayout);
|
|
|
|
|
d->dropOverlay = new DropOverlay(this);
|
|
|
|
|
d->mainLayout = new QGridLayout();
|
|
|
|
|
d->mainLayout->setContentsMargins(4, 4, 4, 4);
|
|
|
|
|
d->mainLayout->setSpacing(0);
|
|
|
|
|
setLayout(d->mainLayout);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ContainerWidget::~ContainerWidget()
|
|
|
|
@ -52,21 +54,23 @@ ContainerWidget::~ContainerWidget()
|
|
|
|
|
// Remove from list, and then delete.
|
|
|
|
|
// Because the destrcutor of objects wants to modfiy the current
|
|
|
|
|
// iterating list as well... :-/
|
|
|
|
|
while (!_sections.isEmpty())
|
|
|
|
|
while (!d->sections.isEmpty())
|
|
|
|
|
{
|
|
|
|
|
SectionWidget* sw = _sections.takeLast();
|
|
|
|
|
SectionWidget* sw = d->sections.takeLast();
|
|
|
|
|
delete sw;
|
|
|
|
|
}
|
|
|
|
|
while (!_floatings.isEmpty())
|
|
|
|
|
while (!d->floatings.isEmpty())
|
|
|
|
|
{
|
|
|
|
|
FloatingWidget* fw = _floatings.takeLast();
|
|
|
|
|
FloatingWidget* fw = d->floatings.takeLast();
|
|
|
|
|
delete fw;
|
|
|
|
|
}
|
|
|
|
|
_scLookupMapById.clear();
|
|
|
|
|
_scLookupMapByName.clear();
|
|
|
|
|
_swLookupMapById.clear();
|
|
|
|
|
d->scLookupMapById.clear();
|
|
|
|
|
d->scLookupMapByName.clear();
|
|
|
|
|
d->swLookupMapById.clear();
|
|
|
|
|
delete d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SectionWidget* ContainerWidget::addSectionContent(const SectionContent::RefPtr& sc, SectionWidget* sw, DropArea area)
|
|
|
|
|
{
|
|
|
|
|
ADS_Expects(!sc.isNull());
|
|
|
|
@ -77,12 +81,7 @@ SectionWidget* ContainerWidget::addSectionContent(const SectionContent::RefPtr&
|
|
|
|
|
data.titleWidget = new SectionTitleWidget(sc, NULL);
|
|
|
|
|
data.contentWidget = new SectionContentWidget(sc, NULL);
|
|
|
|
|
|
|
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
|
|
|
|
QObject::connect(data.titleWidget, &SectionTitleWidget::activeTabChanged, this, &ContainerWidget::onActiveTabChanged);
|
|
|
|
|
#else
|
|
|
|
|
QObject::connect(data.titleWidget, SIGNAL(activeTabChanged()), this, SLOT(onActiveTabChanged()));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
connect(data.titleWidget, SIGNAL(activeTabChanged()), this, SLOT(onActiveTabChanged()));
|
|
|
|
|
return dropContent(data, sw, area, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -100,13 +99,13 @@ bool ContainerWidget::removeSectionContent(const SectionContent::RefPtr& sc)
|
|
|
|
|
// but only cares about SectionWidgets right now. So we need to check whether it was a FloatingWidget
|
|
|
|
|
// and delete it.
|
|
|
|
|
bool found = false;
|
|
|
|
|
for (int i = 0; i < _floatings.count(); ++i)
|
|
|
|
|
for (int i = 0; i < d->floatings.count(); ++i)
|
|
|
|
|
{
|
|
|
|
|
FloatingWidget* fw = _floatings.at(i);
|
|
|
|
|
FloatingWidget* fw = d->floatings.at(i);
|
|
|
|
|
InternalContentData data;
|
|
|
|
|
if (!(found = fw->takeContent(data)))
|
|
|
|
|
continue;
|
|
|
|
|
_floatings.removeAll(fw);
|
|
|
|
|
d->floatings.removeAll(fw);
|
|
|
|
|
delete fw;
|
|
|
|
|
delete data.titleWidget;
|
|
|
|
|
delete data.contentWidget;
|
|
|
|
@ -114,14 +113,14 @@ bool ContainerWidget::removeSectionContent(const SectionContent::RefPtr& sc)
|
|
|
|
|
} // End of ugly work arround.
|
|
|
|
|
|
|
|
|
|
// Get from hidden contents and delete associated internal stuff.
|
|
|
|
|
if (!_hiddenSectionContents.contains(sc->uid()))
|
|
|
|
|
if (!d->hiddenSectionContents.contains(sc->uid()))
|
|
|
|
|
{
|
|
|
|
|
qFatal("Something went wrong... The content should have been there :-/");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Delete internal objects.
|
|
|
|
|
HiddenSectionItem hsi = _hiddenSectionContents.take(sc->uid());
|
|
|
|
|
HiddenSectionItem hsi = d->hiddenSectionContents.take(sc->uid());
|
|
|
|
|
delete hsi.data.titleWidget;
|
|
|
|
|
delete hsi.data.contentWidget;
|
|
|
|
|
|
|
|
|
@ -136,9 +135,9 @@ bool ContainerWidget::showSectionContent(const SectionContent::RefPtr& sc)
|
|
|
|
|
ADS_Expects(!sc.isNull());
|
|
|
|
|
|
|
|
|
|
// Search SC in floatings
|
|
|
|
|
for (int i = 0; i < _floatings.count(); ++i)
|
|
|
|
|
for (int i = 0; i < d->floatings.count(); ++i)
|
|
|
|
|
{
|
|
|
|
|
FloatingWidget* fw = _floatings.at(i);
|
|
|
|
|
FloatingWidget* fw = d->floatings.at(i);
|
|
|
|
|
const bool found = fw->content()->uid() == sc->uid();
|
|
|
|
|
if (!found)
|
|
|
|
|
continue;
|
|
|
|
@ -152,19 +151,19 @@ bool ContainerWidget::showSectionContent(const SectionContent::RefPtr& sc)
|
|
|
|
|
// Search SC in hidden sections
|
|
|
|
|
// Try to show them in the last position, otherwise simply append
|
|
|
|
|
// it to the first section (or create a new section?)
|
|
|
|
|
if (_hiddenSectionContents.contains(sc->uid()))
|
|
|
|
|
if (d->hiddenSectionContents.contains(sc->uid()))
|
|
|
|
|
{
|
|
|
|
|
const HiddenSectionItem hsi = _hiddenSectionContents.take(sc->uid());
|
|
|
|
|
const HiddenSectionItem hsi = d->hiddenSectionContents.take(sc->uid());
|
|
|
|
|
hsi.data.titleWidget->setVisible(true);
|
|
|
|
|
hsi.data.contentWidget->setVisible(true);
|
|
|
|
|
SectionWidget* sw = NULL;
|
|
|
|
|
if (hsi.preferredSectionId > 0 && (sw = SWLookupMapById(this).value(hsi.preferredSectionId)) != NULL)
|
|
|
|
|
SectionWidget* sw = nullptr;
|
|
|
|
|
if (hsi.preferredSectionId > 0 && (sw = d->swLookupMapById.value(hsi.preferredSectionId)) != nullptr)
|
|
|
|
|
{
|
|
|
|
|
sw->addContent(hsi.data, true);
|
|
|
|
|
emit sectionContentVisibilityChanged(sc, true);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else if (_sections.size() > 0 && (sw = _sections.first()) != NULL)
|
|
|
|
|
else if (d->sections.size() > 0 && (sw = d->sections.first()) != NULL)
|
|
|
|
|
{
|
|
|
|
|
sw->addContent(hsi.data, true);
|
|
|
|
|
emit sectionContentVisibilityChanged(sc, true);
|
|
|
|
@ -192,12 +191,12 @@ bool ContainerWidget::hideSectionContent(const SectionContent::RefPtr& sc)
|
|
|
|
|
|
|
|
|
|
// Search SC in floatings
|
|
|
|
|
// We can simply hide floatings, nothing else required.
|
|
|
|
|
for (int i = 0; i < _floatings.count(); ++i)
|
|
|
|
|
for (int i = 0; i < d->floatings.count(); ++i)
|
|
|
|
|
{
|
|
|
|
|
const bool found = _floatings.at(i)->content()->uid() == sc->uid();
|
|
|
|
|
const bool found = d->floatings.at(i)->content()->uid() == sc->uid();
|
|
|
|
|
if (!found)
|
|
|
|
|
continue;
|
|
|
|
|
_floatings.at(i)->setVisible(false);
|
|
|
|
|
d->floatings.at(i)->setVisible(false);
|
|
|
|
|
emit sectionContentVisibilityChanged(sc, false);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@ -206,9 +205,9 @@ bool ContainerWidget::hideSectionContent(const SectionContent::RefPtr& sc)
|
|
|
|
|
// It's required to remove the SC from SW completely and hold it in a
|
|
|
|
|
// separate list as long as a "showSectionContent" gets called for the SC again.
|
|
|
|
|
// In case that the SW does not have any other SCs, we need to delete it.
|
|
|
|
|
for (int i = 0; i < _sections.count(); ++i)
|
|
|
|
|
for (int i = 0; i < d->sections.count(); ++i)
|
|
|
|
|
{
|
|
|
|
|
SectionWidget* sw = _sections.at(i);
|
|
|
|
|
SectionWidget* sw = d->sections.at(i);
|
|
|
|
|
const bool found = sw->indexOfContent(sc) >= 0;
|
|
|
|
|
if (!found)
|
|
|
|
|
continue;
|
|
|
|
@ -221,7 +220,7 @@ bool ContainerWidget::hideSectionContent(const SectionContent::RefPtr& sc)
|
|
|
|
|
|
|
|
|
|
hsi.data.titleWidget->setVisible(false);
|
|
|
|
|
hsi.data.contentWidget->setVisible(false);
|
|
|
|
|
_hiddenSectionContents.insert(sc->uid(), hsi);
|
|
|
|
|
d->hiddenSectionContents.insert(sc->uid(), hsi);
|
|
|
|
|
|
|
|
|
|
if (sw->contents().isEmpty())
|
|
|
|
|
{
|
|
|
|
@ -235,7 +234,7 @@ bool ContainerWidget::hideSectionContent(const SectionContent::RefPtr& sc)
|
|
|
|
|
|
|
|
|
|
// Search SC in hidden elements
|
|
|
|
|
// The content may already be hidden
|
|
|
|
|
if (_hiddenSectionContents.contains(sc->uid()))
|
|
|
|
|
if (d->hiddenSectionContents.contains(sc->uid()))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
qFatal("Unable to hide SectionContent, don't know this one 8-/");
|
|
|
|
@ -247,9 +246,9 @@ bool ContainerWidget::raiseSectionContent(const SectionContent::RefPtr& sc)
|
|
|
|
|
ADS_Expects(!sc.isNull());
|
|
|
|
|
|
|
|
|
|
// Search SC in sections
|
|
|
|
|
for (int i = 0; i < _sections.count(); ++i)
|
|
|
|
|
for (int i = 0; i < d->sections.count(); ++i)
|
|
|
|
|
{
|
|
|
|
|
SectionWidget* sw = _sections.at(i);
|
|
|
|
|
SectionWidget* sw = d->sections.at(i);
|
|
|
|
|
int index = sw->indexOfContent(sc);
|
|
|
|
|
if (index < 0)
|
|
|
|
|
continue;
|
|
|
|
@ -258,9 +257,9 @@ bool ContainerWidget::raiseSectionContent(const SectionContent::RefPtr& sc)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Search SC in floatings
|
|
|
|
|
for (int i = 0; i < _floatings.size(); ++i)
|
|
|
|
|
for (int i = 0; i < d->floatings.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
FloatingWidget* fw = _floatings.at(i);
|
|
|
|
|
FloatingWidget* fw = d->floatings.at(i);
|
|
|
|
|
if (fw->content()->uid() != sc->uid())
|
|
|
|
|
continue;
|
|
|
|
|
fw->setVisible(true);
|
|
|
|
@ -269,7 +268,7 @@ bool ContainerWidget::raiseSectionContent(const SectionContent::RefPtr& sc)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Search SC in hidden
|
|
|
|
|
if (_hiddenSectionContents.contains(sc->uid()))
|
|
|
|
|
if (d->hiddenSectionContents.contains(sc->uid()))
|
|
|
|
|
return showSectionContent(sc);
|
|
|
|
|
|
|
|
|
|
qFatal("Unable to hide SectionContent, don't know this one 8-/");
|
|
|
|
@ -281,18 +280,18 @@ bool ContainerWidget::isSectionContentVisible(const SectionContent::RefPtr& sc)
|
|
|
|
|
ADS_Expects(!sc.isNull());
|
|
|
|
|
|
|
|
|
|
// Search SC in floatings
|
|
|
|
|
for (int i = 0; i < _floatings.count(); ++i)
|
|
|
|
|
for (int i = 0; i < d->floatings.count(); ++i)
|
|
|
|
|
{
|
|
|
|
|
const bool found = _floatings.at(i)->content()->uid() == sc->uid();
|
|
|
|
|
const bool found = d->floatings.at(i)->content()->uid() == sc->uid();
|
|
|
|
|
if (!found)
|
|
|
|
|
continue;
|
|
|
|
|
return _floatings.at(i)->isVisible();
|
|
|
|
|
return d->floatings.at(i)->isVisible();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Search SC in sections
|
|
|
|
|
for (int i = 0; i < _sections.count(); ++i)
|
|
|
|
|
for (int i = 0; i < d->sections.count(); ++i)
|
|
|
|
|
{
|
|
|
|
|
SectionWidget* sw = _sections.at(i);
|
|
|
|
|
SectionWidget* sw = d->sections.at(i);
|
|
|
|
|
const int index = sw->indexOfContent(sc);
|
|
|
|
|
if (index < 0)
|
|
|
|
|
continue;
|
|
|
|
@ -300,7 +299,7 @@ bool ContainerWidget::isSectionContentVisible(const SectionContent::RefPtr& sc)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Search SC in hidden
|
|
|
|
|
if (_hiddenSectionContents.contains(sc->uid()))
|
|
|
|
|
if (d->hiddenSectionContents.contains(sc->uid()))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
qWarning() << "SectionContent is not a part of this ContainerWidget:" << sc->uniqueName();
|
|
|
|
@ -313,9 +312,9 @@ QMenu* ContainerWidget::createContextMenu() const
|
|
|
|
|
QMap<QString, QAction*> actions;
|
|
|
|
|
|
|
|
|
|
// Visible contents of sections
|
|
|
|
|
for (int i = 0; i < _sections.size(); ++i)
|
|
|
|
|
for (int i = 0; i < d->sections.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
const SectionWidget* sw = _sections.at(i);
|
|
|
|
|
const SectionWidget* sw = d->sections.at(i);
|
|
|
|
|
const QList<SectionContent::RefPtr>& contents = sw->contents();
|
|
|
|
|
foreach (const SectionContent::RefPtr& sc, contents)
|
|
|
|
|
{
|
|
|
|
@ -326,17 +325,13 @@ QMenu* ContainerWidget::createContextMenu() const
|
|
|
|
|
a->setCheckable(true);
|
|
|
|
|
a->setChecked(true);
|
|
|
|
|
a->setEnabled(sc->flags().testFlag(SectionContent::Closeable));
|
|
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
|
|
|
|
QObject::connect(a, &QAction::toggled, this, &ContainerWidget::onActionToggleSectionContentVisibility);
|
|
|
|
|
#else
|
|
|
|
|
QObject::connect(a, SIGNAL(toggled(bool)), this, SLOT(onActionToggleSectionContentVisibility(bool)));
|
|
|
|
|
#endif
|
|
|
|
|
connect(a, SIGNAL(toggled(bool)), this, SLOT(onActionToggleSectionContentVisibility(bool)));
|
|
|
|
|
actions.insert(a->text(), a);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Hidden contents of sections
|
|
|
|
|
QHashIterator<int, HiddenSectionItem> hiddenIter(_hiddenSectionContents);
|
|
|
|
|
QHashIterator<int, HiddenSectionItem> hiddenIter(d->hiddenSectionContents);
|
|
|
|
|
while (hiddenIter.hasNext())
|
|
|
|
|
{
|
|
|
|
|
hiddenIter.next();
|
|
|
|
@ -348,18 +343,14 @@ QMenu* ContainerWidget::createContextMenu() const
|
|
|
|
|
a->setProperty("type", "section");
|
|
|
|
|
a->setCheckable(true);
|
|
|
|
|
a->setChecked(false);
|
|
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
|
|
|
|
QObject::connect(a, &QAction::toggled, this, &ContainerWidget::onActionToggleSectionContentVisibility);
|
|
|
|
|
#else
|
|
|
|
|
QObject::connect(a, SIGNAL(toggled(bool)), this, SLOT(onActionToggleSectionContentVisibility(bool)));
|
|
|
|
|
#endif
|
|
|
|
|
connect(a, SIGNAL(toggled(bool)), this, SLOT(onActionToggleSectionContentVisibility(bool)));
|
|
|
|
|
actions.insert(a->text(), a);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Floating contents
|
|
|
|
|
for (int i = 0; i < _floatings.size(); ++i)
|
|
|
|
|
for (int i = 0; i < d->floatings.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
const FloatingWidget* fw = _floatings.at(i);
|
|
|
|
|
const FloatingWidget* fw = d->floatings.at(i);
|
|
|
|
|
const SectionContent::RefPtr sc = fw->content();
|
|
|
|
|
|
|
|
|
|
QAction* a = new QAction(QIcon(), sc->visibleTitle(), NULL);
|
|
|
|
@ -368,11 +359,7 @@ QMenu* ContainerWidget::createContextMenu() const
|
|
|
|
|
a->setProperty("type", "floating");
|
|
|
|
|
a->setCheckable(true);
|
|
|
|
|
a->setChecked(fw->isVisible());
|
|
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
|
|
|
|
QObject::connect(a, &QAction::toggled, this, &ContainerWidget::onActionToggleSectionContentVisibility);
|
|
|
|
|
#else
|
|
|
|
|
QObject::connect(a, SIGNAL(toggled(bool)), this, SLOT(onActionToggleSectionContentVisibility(bool)));
|
|
|
|
|
#endif
|
|
|
|
|
connect(a, SIGNAL(toggled(bool)), this, SLOT(onActionToggleSectionContentVisibility(bool)));
|
|
|
|
|
actions.insert(a->text(), a);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -453,7 +440,7 @@ QRect ContainerWidget::outerLeftDropRect() const
|
|
|
|
|
|
|
|
|
|
QList<SectionContent::RefPtr> ContainerWidget::contents() const
|
|
|
|
|
{
|
|
|
|
|
QList<SectionContent::WeakPtr> wl = _scLookupMapById.values();
|
|
|
|
|
QList<SectionContent::WeakPtr> wl = d->scLookupMapById.values();
|
|
|
|
|
QList<SectionContent::RefPtr> sl;
|
|
|
|
|
for (int i = 0; i < wl.count(); ++i)
|
|
|
|
|
{
|
|
|
|
@ -466,7 +453,7 @@ QList<SectionContent::RefPtr> ContainerWidget::contents() const
|
|
|
|
|
|
|
|
|
|
QPointer<DropOverlay> ContainerWidget::dropOverlay() const
|
|
|
|
|
{
|
|
|
|
|
return _dropOverlay;
|
|
|
|
|
return d->dropOverlay;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
@ -476,7 +463,7 @@ QPointer<DropOverlay> ContainerWidget::dropOverlay() const
|
|
|
|
|
SectionWidget* ContainerWidget::newSectionWidget()
|
|
|
|
|
{
|
|
|
|
|
SectionWidget* sw = new SectionWidget(this);
|
|
|
|
|
_sections.append(sw);
|
|
|
|
|
d->sections.append(sw);
|
|
|
|
|
return sw;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -487,7 +474,7 @@ SectionWidget* ContainerWidget::dropContent(const InternalContentData& data, Sec
|
|
|
|
|
SectionWidget* ret = NULL;
|
|
|
|
|
|
|
|
|
|
// If no sections exists yet, create a default one and always drop into it.
|
|
|
|
|
if (_sections.count() <= 0)
|
|
|
|
|
if (d->sections.count() <= 0)
|
|
|
|
|
{
|
|
|
|
|
targetSection = newSectionWidget();
|
|
|
|
|
addSection(targetSection);
|
|
|
|
@ -500,17 +487,17 @@ SectionWidget* ContainerWidget::dropContent(const InternalContentData& data, Sec
|
|
|
|
|
switch (area)
|
|
|
|
|
{
|
|
|
|
|
case TopDropArea:
|
|
|
|
|
ret = dropContentOuterHelper(_mainLayout, data, Qt::Vertical, false);
|
|
|
|
|
ret = dropContentOuterHelper(d->mainLayout, data, Qt::Vertical, false);
|
|
|
|
|
break;
|
|
|
|
|
case RightDropArea:
|
|
|
|
|
ret = dropContentOuterHelper(_mainLayout, data, Qt::Horizontal, true);
|
|
|
|
|
ret = dropContentOuterHelper(d->mainLayout, data, Qt::Horizontal, true);
|
|
|
|
|
break;
|
|
|
|
|
case CenterDropArea:
|
|
|
|
|
case BottomDropArea:
|
|
|
|
|
ret = dropContentOuterHelper(_mainLayout, data, Qt::Vertical, true);
|
|
|
|
|
ret = dropContentOuterHelper(d->mainLayout, data, Qt::Vertical, true);
|
|
|
|
|
break;
|
|
|
|
|
case LeftDropArea:
|
|
|
|
|
ret = dropContentOuterHelper(_mainLayout, data, Qt::Horizontal, false);
|
|
|
|
|
ret = dropContentOuterHelper(d->mainLayout, data, Qt::Horizontal, false);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return NULL;
|
|
|
|
@ -620,25 +607,25 @@ void ContainerWidget::addSection(SectionWidget* section)
|
|
|
|
|
ADS_Expects(section != NULL);
|
|
|
|
|
|
|
|
|
|
// Create default splitter.
|
|
|
|
|
if (!_splitter)
|
|
|
|
|
if (!d->splitter)
|
|
|
|
|
{
|
|
|
|
|
_splitter = newSplitter(_orientation);
|
|
|
|
|
_mainLayout->addWidget(_splitter, 0, 0);
|
|
|
|
|
d->splitter = newSplitter(d->orientation);
|
|
|
|
|
d->mainLayout->addWidget(d->splitter, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
if (_splitter->indexOf(section) != -1)
|
|
|
|
|
if (d->splitter->indexOf(section) != -1)
|
|
|
|
|
{
|
|
|
|
|
qWarning() << Q_FUNC_INFO << QString("Section has already been added");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
_splitter->addWidget(section);
|
|
|
|
|
d->splitter->addWidget(section);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SectionWidget* ContainerWidget::sectionAt(const QPoint& pos) const
|
|
|
|
|
{
|
|
|
|
|
const QPoint gpos = mapToGlobal(pos);
|
|
|
|
|
for (int i = 0; i < _sections.size(); ++i)
|
|
|
|
|
for (int i = 0; i < d->sections.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
SectionWidget* sw = _sections[i];
|
|
|
|
|
SectionWidget* sw = d->sections[i];
|
|
|
|
|
if (sw->rect().contains(sw->mapFromGlobal(gpos)))
|
|
|
|
|
{
|
|
|
|
|
return sw;
|
|
|
|
@ -748,40 +735,40 @@ QByteArray ContainerWidget::saveHierarchy() const
|
|
|
|
|
saveFloatingWidgets(out);
|
|
|
|
|
|
|
|
|
|
// Save state of sections and contents
|
|
|
|
|
if (_mainLayout->count() <= 0 || _sections.isEmpty())
|
|
|
|
|
if (d->mainLayout->count() <= 0 || d->sections.isEmpty())
|
|
|
|
|
{
|
|
|
|
|
// Looks like the user has hidden all contents and no more sections
|
|
|
|
|
// are available. We can simply write a list of all hidden contents.
|
|
|
|
|
out << 0; // Mode
|
|
|
|
|
|
|
|
|
|
out << _hiddenSectionContents.count();
|
|
|
|
|
QHashIterator<int, HiddenSectionItem> iter(_hiddenSectionContents);
|
|
|
|
|
out << d->hiddenSectionContents.count();
|
|
|
|
|
QHashIterator<int, HiddenSectionItem> iter(d->hiddenSectionContents);
|
|
|
|
|
while (iter.hasNext())
|
|
|
|
|
{
|
|
|
|
|
iter.next();
|
|
|
|
|
out << iter.value().data.content->uniqueName();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (_mainLayout->count() == 1)
|
|
|
|
|
else if (d->mainLayout->count() == 1)
|
|
|
|
|
{
|
|
|
|
|
out << 1; // Mode
|
|
|
|
|
|
|
|
|
|
// There should only be one!
|
|
|
|
|
QLayoutItem* li = _mainLayout->itemAt(0);
|
|
|
|
|
QLayoutItem* li = d->mainLayout->itemAt(0);
|
|
|
|
|
if (!li->widget())
|
|
|
|
|
qFatal("Not a widget in _mainLayout, this shouldn't happen.");
|
|
|
|
|
qFatal("Not a widget in d->mainLayout, this shouldn't happen.");
|
|
|
|
|
|
|
|
|
|
// Save sections beginning with the first QSplitter (li->widget()).
|
|
|
|
|
saveSectionWidgets(out, li->widget());
|
|
|
|
|
|
|
|
|
|
// Safe state of hidden contents, which doesn't have an section association
|
|
|
|
|
// or the section association points to a no longer existing section.
|
|
|
|
|
QHashIterator<int, HiddenSectionItem> iter(_hiddenSectionContents);
|
|
|
|
|
QHashIterator<int, HiddenSectionItem> iter(d->hiddenSectionContents);
|
|
|
|
|
int cnt = 0;
|
|
|
|
|
while (iter.hasNext())
|
|
|
|
|
{
|
|
|
|
|
iter.next();
|
|
|
|
|
if (iter.value().preferredSectionId <= 0 || !SWLookupMapById(this).contains(iter.value().preferredSectionId))
|
|
|
|
|
if (iter.value().preferredSectionId <= 0 || !d->swLookupMapById.contains(iter.value().preferredSectionId))
|
|
|
|
|
cnt++;
|
|
|
|
|
}
|
|
|
|
|
out << cnt;
|
|
|
|
@ -789,7 +776,7 @@ QByteArray ContainerWidget::saveHierarchy() const
|
|
|
|
|
while (iter.hasNext())
|
|
|
|
|
{
|
|
|
|
|
iter.next();
|
|
|
|
|
if (iter.value().preferredSectionId <= 0 || !SWLookupMapById(this).contains(iter.value().preferredSectionId))
|
|
|
|
|
if (iter.value().preferredSectionId <= 0 || !d->swLookupMapById.contains(iter.value().preferredSectionId))
|
|
|
|
|
out << iter.value().data.content->uniqueName();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -797,17 +784,17 @@ QByteArray ContainerWidget::saveHierarchy() const
|
|
|
|
|
{
|
|
|
|
|
// More? Oh oh.. something is wrong :-/
|
|
|
|
|
out << -1;
|
|
|
|
|
qWarning() << "Oh noooz.. Something went wrong. There are too many items in _mainLayout.";
|
|
|
|
|
qWarning() << "Oh noooz.. Something went wrong. There are too many items in d->mainLayout.";
|
|
|
|
|
}
|
|
|
|
|
return ba;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ContainerWidget::saveFloatingWidgets(QDataStream& out) const
|
|
|
|
|
{
|
|
|
|
|
out << _floatings.count();
|
|
|
|
|
for (int i = 0; i < _floatings.count(); ++i)
|
|
|
|
|
out << d->floatings.count();
|
|
|
|
|
for (int i = 0; i < d->floatings.count(); ++i)
|
|
|
|
|
{
|
|
|
|
|
FloatingWidget* fw = _floatings.at(i);
|
|
|
|
|
FloatingWidget* fw = d->floatings.at(i);
|
|
|
|
|
out << fw->content()->uniqueName();
|
|
|
|
|
out << fw->saveGeometry();
|
|
|
|
|
out << fw->isVisible();
|
|
|
|
@ -848,7 +835,7 @@ void ContainerWidget::saveSectionWidgets(QDataStream& out, QWidget* widget) cons
|
|
|
|
|
const QList<SectionContent::RefPtr>& contents = sw->contents();
|
|
|
|
|
QList<HiddenSectionItem> hiddenContents;
|
|
|
|
|
|
|
|
|
|
QHashIterator<int, HiddenSectionItem> iter(_hiddenSectionContents);
|
|
|
|
|
QHashIterator<int, HiddenSectionItem> iter(d->hiddenSectionContents);
|
|
|
|
|
while (iter.hasNext())
|
|
|
|
|
{
|
|
|
|
|
iter.next();
|
|
|
|
@ -879,25 +866,25 @@ void ContainerWidget::saveSectionWidgets(QDataStream& out, QWidget* widget) cons
|
|
|
|
|
|
|
|
|
|
bool ContainerWidget::saveSectionIndex(ADS_NS_SER::SectionIndexData& sid) const
|
|
|
|
|
{
|
|
|
|
|
if (_sections.count() <= 0)
|
|
|
|
|
if (d->sections.count() <= 0)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
sid.sectionsCount = _sections.count();
|
|
|
|
|
sid.sectionsCount = d->sections.count();
|
|
|
|
|
for (int i = 0; i < sid.sectionsCount; ++i)
|
|
|
|
|
{
|
|
|
|
|
ADS_NS_SER::SectionEntity se;
|
|
|
|
|
se.x = mapFromGlobal(_sections[i]->parentWidget()->mapToGlobal(_sections[i]->pos())).x();
|
|
|
|
|
se.y = mapFromGlobal(_sections[i]->parentWidget()->mapToGlobal(_sections[i]->pos())).y();
|
|
|
|
|
se.width = _sections[i]->geometry().width();
|
|
|
|
|
se.height = _sections[i]->geometry().height();
|
|
|
|
|
se.currentIndex = _sections[i]->currentIndex();
|
|
|
|
|
se.sectionContentsCount = _sections[i]->contents().count();
|
|
|
|
|
foreach (const SectionContent::RefPtr& sc, _sections[i]->contents())
|
|
|
|
|
se.x = mapFromGlobal(d->sections[i]->parentWidget()->mapToGlobal(d->sections[i]->pos())).x();
|
|
|
|
|
se.y = mapFromGlobal(d->sections[i]->parentWidget()->mapToGlobal(d->sections[i]->pos())).y();
|
|
|
|
|
se.width = d->sections[i]->geometry().width();
|
|
|
|
|
se.height = d->sections[i]->geometry().height();
|
|
|
|
|
se.currentIndex = d->sections[i]->currentIndex();
|
|
|
|
|
se.sectionContentsCount = d->sections[i]->contents().count();
|
|
|
|
|
foreach (const SectionContent::RefPtr& sc, d->sections[i]->contents())
|
|
|
|
|
{
|
|
|
|
|
ADS_NS_SER::SectionContentEntity sce;
|
|
|
|
|
sce.uniqueName = sc->uniqueName();
|
|
|
|
|
sce.visible = true;
|
|
|
|
|
sce.preferredIndex = _sections[i]->indexOfContent(sc);
|
|
|
|
|
sce.preferredIndex = d->sections[i]->indexOfContent(sc);
|
|
|
|
|
se.sectionContents.append(sce); // std::move()?
|
|
|
|
|
}
|
|
|
|
|
sid.sections.append(se); // std::move()?
|
|
|
|
@ -920,8 +907,8 @@ bool ContainerWidget::restoreHierarchy(const QByteArray& data)
|
|
|
|
|
if (version != 1)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
QList<FloatingWidget*> oldFloatings = _floatings;
|
|
|
|
|
QList<SectionWidget*> oldSections = _sections;
|
|
|
|
|
QList<FloatingWidget*> oldFloatings = d->floatings;
|
|
|
|
|
QList<SectionWidget*> oldSections = d->sections;
|
|
|
|
|
|
|
|
|
|
// Restore floating widgets
|
|
|
|
|
QList<FloatingWidget*> floatings;
|
|
|
|
@ -954,7 +941,7 @@ bool ContainerWidget::restoreHierarchy(const QByteArray& data)
|
|
|
|
|
QString uname;
|
|
|
|
|
in >> uname;
|
|
|
|
|
|
|
|
|
|
const SectionContent::RefPtr sc = SCLookupMapByName(this).value(uname);
|
|
|
|
|
const SectionContent::RefPtr sc = d->scLookupMapByName.value(uname);
|
|
|
|
|
if (!sc)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
@ -980,7 +967,7 @@ bool ContainerWidget::restoreHierarchy(const QByteArray& data)
|
|
|
|
|
{
|
|
|
|
|
QString uname;
|
|
|
|
|
in >> uname;
|
|
|
|
|
const SectionContent::RefPtr sc = SCLookupMapByName(this).value(uname);
|
|
|
|
|
const SectionContent::RefPtr sc = d->scLookupMapByName.value(uname);
|
|
|
|
|
if (!sc)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
@ -1019,7 +1006,7 @@ bool ContainerWidget::restoreHierarchy(const QByteArray& data)
|
|
|
|
|
contents.append(contentsToHide.at(i));
|
|
|
|
|
|
|
|
|
|
// Compare restored contents with available contents
|
|
|
|
|
const QList<SectionContent::WeakPtr> allContents = SCLookupMapById(this).values();
|
|
|
|
|
const QList<SectionContent::WeakPtr> allContents = d->scLookupMapById.values();
|
|
|
|
|
for (int i = 0; i < allContents.count(); ++i)
|
|
|
|
|
{
|
|
|
|
|
const SectionContent::RefPtr sc = allContents.at(i).toStrongRef();
|
|
|
|
@ -1055,12 +1042,12 @@ bool ContainerWidget::restoreHierarchy(const QByteArray& data)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_floatings = floatings;
|
|
|
|
|
_sections = sections;
|
|
|
|
|
d->floatings = floatings;
|
|
|
|
|
d->sections = sections;
|
|
|
|
|
|
|
|
|
|
// Delete old objects
|
|
|
|
|
QLayoutItem* old = _mainLayout->takeAt(0);
|
|
|
|
|
_mainLayout->addWidget(_splitter);
|
|
|
|
|
QLayoutItem* old = d->mainLayout->takeAt(0);
|
|
|
|
|
d->mainLayout->addWidget(d->splitter);
|
|
|
|
|
delete old;
|
|
|
|
|
qDeleteAll(oldFloatings);
|
|
|
|
|
qDeleteAll(oldSections);
|
|
|
|
@ -1091,7 +1078,7 @@ bool ContainerWidget::restoreFloatingWidgets(QDataStream& in, int version, QList
|
|
|
|
|
bool visible = false;
|
|
|
|
|
in >> visible;
|
|
|
|
|
|
|
|
|
|
const SectionContent::RefPtr sc = SCLookupMapByName(this).value(uname).toStrongRef();
|
|
|
|
|
const SectionContent::RefPtr sc = d->scLookupMapByName.value(uname).toStrongRef();
|
|
|
|
|
if (!sc)
|
|
|
|
|
{
|
|
|
|
|
qWarning() << "Can not find SectionContent:" << uname;
|
|
|
|
@ -1147,7 +1134,7 @@ bool ContainerWidget::restoreSectionWidgets(QDataStream& in, int version, QSplit
|
|
|
|
|
sp->setSizes(sizes);
|
|
|
|
|
|
|
|
|
|
if (!currentSplitter)
|
|
|
|
|
_splitter = sp;
|
|
|
|
|
d->splitter = sp;
|
|
|
|
|
else
|
|
|
|
|
currentSplitter->addWidget(sp);
|
|
|
|
|
}
|
|
|
|
@ -1174,7 +1161,7 @@ bool ContainerWidget::restoreSectionWidgets(QDataStream& in, int version, QSplit
|
|
|
|
|
int preferredIndex = -1;
|
|
|
|
|
in >> preferredIndex;
|
|
|
|
|
|
|
|
|
|
const SectionContent::RefPtr sc = SCLookupMapByName(this).value(uname).toStrongRef();
|
|
|
|
|
const SectionContent::RefPtr sc = d->scLookupMapByName.value(uname).toStrongRef();
|
|
|
|
|
if (!sc)
|
|
|
|
|
{
|
|
|
|
|
qWarning() << "Can not find SectionContent:" << uname;
|
|
|
|
@ -1220,23 +1207,23 @@ bool ContainerWidget::takeContent(const SectionContent::RefPtr& sc, InternalCont
|
|
|
|
|
|
|
|
|
|
// Search in sections
|
|
|
|
|
bool found = false;
|
|
|
|
|
for (int i = 0; i < _sections.count() && !found; ++i)
|
|
|
|
|
for (int i = 0; i < d->sections.count() && !found; ++i)
|
|
|
|
|
{
|
|
|
|
|
found = _sections.at(i)->takeContent(sc->uid(), data);
|
|
|
|
|
found = d->sections.at(i)->takeContent(sc->uid(), data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Search in floating widgets
|
|
|
|
|
for (int i = 0; i < _floatings.count() && !found; ++i)
|
|
|
|
|
for (int i = 0; i < d->floatings.count() && !found; ++i)
|
|
|
|
|
{
|
|
|
|
|
found = _floatings.at(i)->content()->uid() == sc->uid();
|
|
|
|
|
found = d->floatings.at(i)->content()->uid() == sc->uid();
|
|
|
|
|
if (found)
|
|
|
|
|
_floatings.at(i)->takeContent(data);
|
|
|
|
|
d->floatings.at(i)->takeContent(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Search in hidden items
|
|
|
|
|
if (!found && _hiddenSectionContents.contains(sc->uid()))
|
|
|
|
|
if (!found && d->hiddenSectionContents.contains(sc->uid()))
|
|
|
|
|
{
|
|
|
|
|
const HiddenSectionItem hsi = _hiddenSectionContents.take(sc->uid());
|
|
|
|
|
const HiddenSectionItem hsi = d->hiddenSectionContents.take(sc->uid());
|
|
|
|
|
data = hsi.data;
|
|
|
|
|
found = true;
|
|
|
|
|
}
|
|
|
|
@ -1259,7 +1246,7 @@ void ContainerWidget::onActionToggleSectionContentVisibility(bool visible)
|
|
|
|
|
if (!a)
|
|
|
|
|
return;
|
|
|
|
|
const int uid = a->property("uid").toInt();
|
|
|
|
|
const SectionContent::RefPtr sc = SCLookupMapById(this).value(uid).toStrongRef();
|
|
|
|
|
const SectionContent::RefPtr sc = d->scLookupMapById.value(uid).toStrongRef();
|
|
|
|
|
if (sc.isNull())
|
|
|
|
|
{
|
|
|
|
|
qCritical() << "Can not find content by ID" << uid;
|
|
|
|
@ -1276,37 +1263,21 @@ void ContainerWidget::moveFloatingWidget(const QPoint& TargetPos)
|
|
|
|
|
{
|
|
|
|
|
// Mouse is over a SectionWidget
|
|
|
|
|
SectionWidget* sectionwidget = sectionAt(mapFromGlobal(QCursor::pos()));
|
|
|
|
|
if (rect().contains(mapFromGlobal(QCursor::pos())))
|
|
|
|
|
{
|
|
|
|
|
std::cout << "over Container" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sectionwidget)
|
|
|
|
|
{
|
|
|
|
|
qInfo() << "over sectionWidget";
|
|
|
|
|
_dropOverlay->setAllowedAreas(ADS_NS::AllAreas);
|
|
|
|
|
_dropOverlay->showDropOverlay(sectionwidget);
|
|
|
|
|
}
|
|
|
|
|
// Mouse is at the edge of the ContainerWidget
|
|
|
|
|
// Top, Right, Bottom, Left
|
|
|
|
|
else if (outerTopDropRect().contains(mapFromGlobal(QCursor::pos())))
|
|
|
|
|
{
|
|
|
|
|
_dropOverlay->setAllowedAreas(ADS_NS::TopDropArea);
|
|
|
|
|
_dropOverlay->showDropOverlay(this, outerTopDropRect());
|
|
|
|
|
}
|
|
|
|
|
else if (outerRightDropRect().contains(mapFromGlobal(QCursor::pos())))
|
|
|
|
|
{
|
|
|
|
|
_dropOverlay->setAllowedAreas(ADS_NS::RightDropArea);
|
|
|
|
|
_dropOverlay->showDropOverlay(this, outerRightDropRect());
|
|
|
|
|
}
|
|
|
|
|
else if (outerBottomDropRect().contains(mapFromGlobal(QCursor::pos())))
|
|
|
|
|
{
|
|
|
|
|
_dropOverlay->setAllowedAreas(ADS_NS::BottomDropArea);
|
|
|
|
|
_dropOverlay->showDropOverlay(this, outerBottomDropRect());
|
|
|
|
|
}
|
|
|
|
|
else if (outerLeftDropRect().contains(mapFromGlobal(QCursor::pos())))
|
|
|
|
|
{
|
|
|
|
|
_dropOverlay->setAllowedAreas(ADS_NS::LeftDropArea);
|
|
|
|
|
_dropOverlay->showDropOverlay(this, outerLeftDropRect());
|
|
|
|
|
d->dropOverlay->setAllowedAreas(ADS_NS::AllAreas);
|
|
|
|
|
d->dropOverlay->showDropOverlay(sectionwidget);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_dropOverlay->hideDropOverlay();
|
|
|
|
|
d->dropOverlay->hideDropOverlay();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1323,7 +1294,7 @@ FloatingWidget* ContainerWidget::startFloating(SectionWidget* sectionwidget, int
|
|
|
|
|
|
|
|
|
|
FloatingWidget* fw = new FloatingWidget(this, data.content, data.titleWidget, data.contentWidget, this);
|
|
|
|
|
fw->resize(sectionwidget->size());
|
|
|
|
|
_floatings.append(fw);
|
|
|
|
|
d->floatings.append(fw);
|
|
|
|
|
fw->move(TargetPos);
|
|
|
|
|
fw->show();
|
|
|
|
|
|
|
|
|
|