DataSourceItem.cpp
145 lines
| 4.0 KiB
| text/x-c
|
CppLexer
Alexandre Leroux
|
r35 | #include <DataSource/DataSourceItem.h> | ||
Alexandre Leroux
|
r135 | #include <DataSource/DataSourceItemAction.h> | ||
Alexandre Leroux
|
r35 | |||
#include <QVector> | ||||
Alexandre Leroux
|
r315 | const QString DataSourceItem::NAME_DATA_KEY = QStringLiteral("name"); | ||
Alexandre Leroux
|
r137 | |||
Alexandre Leroux
|
r35 | struct DataSourceItem::DataSourceItemPrivate { | ||
Alexandre Leroux
|
r374 | explicit DataSourceItemPrivate(DataSourceItemType type, QVariantHash data) | ||
Alexandre Leroux
|
r135 | : m_Parent{nullptr}, m_Children{}, m_Type{type}, m_Data{std::move(data)}, m_Actions{} | ||
Alexandre Leroux
|
r35 | { | ||
} | ||||
DataSourceItem *m_Parent; | ||||
std::vector<std::unique_ptr<DataSourceItem> > m_Children; | ||||
Alexandre Leroux
|
r78 | DataSourceItemType m_Type; | ||
Alexandre Leroux
|
r374 | QVariantHash m_Data; | ||
Alexandre Leroux
|
r135 | std::vector<std::unique_ptr<DataSourceItemAction> > m_Actions; | ||
Alexandre Leroux
|
r35 | }; | ||
Alexandre Leroux
|
r315 | DataSourceItem::DataSourceItem(DataSourceItemType type, const QString &name) | ||
Alexandre Leroux
|
r374 | : DataSourceItem{type, QVariantHash{{NAME_DATA_KEY, name}}} | ||
Alexandre Leroux
|
r315 | { | ||
} | ||||
Alexandre Leroux
|
r374 | DataSourceItem::DataSourceItem(DataSourceItemType type, QVariantHash data) | ||
Alexandre Leroux
|
r78 | : impl{spimpl::make_unique_impl<DataSourceItemPrivate>(type, std::move(data))} | ||
Alexandre Leroux
|
r35 | { | ||
} | ||||
Alexandre Leroux
|
r135 | QVector<DataSourceItemAction *> DataSourceItem::actions() const noexcept | ||
{ | ||||
Alexandre Leroux
|
r159 | auto result = QVector<DataSourceItemAction *>{}; | ||
Alexandre Leroux
|
r135 | |||
std::transform(std::cbegin(impl->m_Actions), std::cend(impl->m_Actions), | ||||
std::back_inserter(result), [](const auto &action) { return action.get(); }); | ||||
return result; | ||||
} | ||||
void DataSourceItem::addAction(std::unique_ptr<DataSourceItemAction> action) noexcept | ||||
{ | ||||
action->setDataSourceItem(this); | ||||
impl->m_Actions.push_back(std::move(action)); | ||||
} | ||||
Alexandre Leroux
|
r35 | void DataSourceItem::appendChild(std::unique_ptr<DataSourceItem> child) noexcept | ||
{ | ||||
child->impl->m_Parent = this; | ||||
impl->m_Children.push_back(std::move(child)); | ||||
} | ||||
DataSourceItem *DataSourceItem::child(int childIndex) const noexcept | ||||
{ | ||||
if (childIndex < 0 || childIndex >= childCount()) { | ||||
return nullptr; | ||||
} | ||||
else { | ||||
return impl->m_Children.at(childIndex).get(); | ||||
} | ||||
} | ||||
int DataSourceItem::childCount() const noexcept | ||||
{ | ||||
return impl->m_Children.size(); | ||||
} | ||||
Alexandre Leroux
|
r315 | QVariant DataSourceItem::data(const QString &key) const noexcept | ||
Alexandre Leroux
|
r35 | { | ||
Alexandre Leroux
|
r315 | return impl->m_Data.value(key); | ||
Alexandre Leroux
|
r35 | } | ||
Alexandre Leroux
|
r374 | QVariantHash DataSourceItem::data() const noexcept | ||
Alexandre Leroux
|
r319 | { | ||
return impl->m_Data; | ||||
} | ||||
Alexandre Leroux
|
r318 | bool DataSourceItem::isRoot() const noexcept | ||
{ | ||||
return impl->m_Parent == nullptr; | ||||
} | ||||
Alexandre Leroux
|
r137 | QString DataSourceItem::name() const noexcept | ||
{ | ||||
Alexandre Leroux
|
r315 | return data(NAME_DATA_KEY).toString(); | ||
Alexandre Leroux
|
r137 | } | ||
Alexandre Leroux
|
r35 | DataSourceItem *DataSourceItem::parentItem() const noexcept | ||
{ | ||||
return impl->m_Parent; | ||||
} | ||||
Alexandre Leroux
|
r78 | |||
Alexandre Leroux
|
r520 | const DataSourceItem &DataSourceItem::rootItem() const noexcept | ||
{ | ||||
return isRoot() ? *this : parentItem()->rootItem(); | ||||
} | ||||
Alexandre Leroux
|
r320 | void DataSourceItem::setData(const QString &key, const QVariant &value, bool append) noexcept | ||
{ | ||||
auto it = impl->m_Data.constFind(key); | ||||
if (append && it != impl->m_Data.constEnd()) { | ||||
// Case of an existing value to which we want to add to the new value | ||||
if (it->canConvert<QVariantList>()) { | ||||
auto variantList = it->value<QVariantList>(); | ||||
variantList.append(value); | ||||
impl->m_Data.insert(key, variantList); | ||||
} | ||||
else { | ||||
impl->m_Data.insert(key, QVariantList{*it, value}); | ||||
} | ||||
} | ||||
else { | ||||
// Other cases : | ||||
// - new value in map OR | ||||
// - replacement of an existing value (not appending) | ||||
impl->m_Data.insert(key, value); | ||||
} | ||||
} | ||||
Alexandre Leroux
|
r78 | DataSourceItemType DataSourceItem::type() const noexcept | ||
{ | ||||
return impl->m_Type; | ||||
} | ||||
Alexandre Leroux
|
r321 | |||
bool DataSourceItem::operator==(const DataSourceItem &other) | ||||
{ | ||||
// Compares items' attributes | ||||
if (std::tie(impl->m_Type, impl->m_Data) == std::tie(other.impl->m_Type, other.impl->m_Data)) { | ||||
// Compares contents of items' children | ||||
return std::equal(std::cbegin(impl->m_Children), std::cend(impl->m_Children), | ||||
std::cbegin(other.impl->m_Children), | ||||
[](const auto &itemChild, const auto &otherChild) { | ||||
return *itemChild == *otherChild; | ||||
}); | ||||
} | ||||
else { | ||||
return false; | ||||
} | ||||
} | ||||
bool DataSourceItem::operator!=(const DataSourceItem &other) | ||||
{ | ||||
return !(*this == other); | ||||
} | ||||