mirror of
https://github.com/status-im/QtModelsToolkit.git
synced 2026-08-31 01:51:08 +00:00
181 lines
4.2 KiB
C++
181 lines
4.2 KiB
C++
#include "qtmodelstoolkit/rolesrenamingmodel.h"
|
||||
|
|
|
|||
|
|
#include <QDebug>
|
|||
|
|
|
|||
|
|
namespace qtmt {
|
|||
|
|
|
|||
|
|
/*!
|
|||
|
|
\qmltype RolesRenamingModel
|
|||
|
|
\inherits QIdentityProxyModel
|
|||
|
|
\inqmlmodule QtModelsToolkit
|
|||
|
|
\ingroup ProxyModels
|
|||
|
|
\brief Simple proxy allowing to rename roles according to a provided mapping.
|
|||
|
|
|
|||
|
|
In the following example original roles \c key and \c title are renamed
|
|||
|
|
to \c id and \c name, respectively.
|
|||
|
|
|
|||
|
|
\qml
|
|||
|
|
RolesRenamingModel {
|
|||
|
|
id: renamedModel
|
|||
|
|
|
|||
|
|
sourceModel: sourceModel
|
|||
|
|
|
|||
|
|
mapping: [
|
|||
|
|
RoleRename {
|
|||
|
|
from: "key"
|
|||
|
|
to: "id"
|
|||
|
|
},
|
|||
|
|
RoleRename {
|
|||
|
|
from: "title"
|
|||
|
|
to: "name"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
\endqml
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/*!
|
|||
|
|
\qmltype RoleRename
|
|||
|
|
\inherits QtObject
|
|||
|
|
\inqmlmodule QtModelsToolkit
|
|||
|
|
\ingroup ProxyModelsAssociated
|
|||
|
|
\brief Defines name mapping for a single role within \l {RolesRenamingModel}.
|
|||
|
|
|
|||
|
|
This helper component allows specify name of existing role (old name) and
|
|||
|
|
the new name which will be exposed from \l {RolesRenamingModel}.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
RoleRename::RoleRename(QObject* parent)
|
|||
|
|
: QObject{parent}
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void RoleRename::setFrom(const QString& from)
|
|||
|
|
{
|
|||
|
|
if (m_from == from)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
if (!m_from.isEmpty()) {
|
|||
|
|
qWarning() << "RoleRename: property \"from\" is intended to be "
|
|||
|
|
"initialized once and not changed!";
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_from = from;
|
|||
|
|
emit fromChanged();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*!
|
|||
|
|
\qmlproperty string RoleRename::from
|
|||
|
|
|
|||
|
|
This property specifies the role name exising in the source model that is
|
|||
|
|
intended to be renamed.
|
|||
|
|
*/
|
|||
|
|
const QString& RoleRename::from() const
|
|||
|
|
{
|
|||
|
|
return m_from;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void RoleRename::setTo(const QString& to)
|
|||
|
|
{
|
|||
|
|
if (m_to == to)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
if (!m_to.isEmpty()) {
|
|||
|
|
qWarning() << "RoleRename: property \"to\" is intended to be "
|
|||
|
|
"initialized once and not changed!";
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_to = to;
|
|||
|
|
emit toChanged();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*!
|
|||
|
|
\qmlproperty string RoleRename::to
|
|||
|
|
|
|||
|
|
This property specifies the new name for the role.
|
|||
|
|
*/
|
|||
|
|
const QString& RoleRename::to() const
|
|||
|
|
{
|
|||
|
|
return m_to;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
RolesRenamingModel::RolesRenamingModel(QObject* parent)
|
|||
|
|
: QIdentityProxyModel{parent}
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*!
|
|||
|
|
\qmlproperty list<RoleName> RolesRenamingModel::mapping
|
|||
|
|
|
|||
|
|
This property holds the mapping as a list of \l RoleRename objects.
|
|||
|
|
*/
|
|||
|
|
QQmlListProperty<RoleRename> RolesRenamingModel::mapping()
|
|||
|
|
{
|
|||
|
|
QQmlListProperty<RoleRename> list(this, &m_mapping);
|
|||
|
|
|
|||
|
|
list.replace = nullptr;
|
|||
|
|
list.clear = nullptr;
|
|||
|
|
list.removeLast = nullptr;
|
|||
|
|
|
|||
|
|
list.append = [](auto listProperty, auto element) {
|
|||
|
|
RolesRenamingModel* model = qobject_cast<RolesRenamingModel*>(
|
|||
|
|
listProperty->object);
|
|||
|
|
|
|||
|
|
if (model->m_rolesFetched) {
|
|||
|
|
qWarning() << "RolesRenamingModel: role names mapping cannot be "
|
|||
|
|
"modified after fetching role names!";
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
model->m_mapping.append(element);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return list;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QHash<int, QByteArray> RolesRenamingModel::roleNames() const
|
|||
|
|
{
|
|||
|
|
const auto roles = sourceModel() ? sourceModel()->roleNames() : QHash<int, QByteArray>{};
|
|||
|
|
|
|||
|
|
if (roles.isEmpty())
|
|||
|
|
return roles;
|
|||
|
|
|
|||
|
|
QHash<QString, RoleRename*> renameMap;
|
|||
|
|
|
|||
|
|
for (const auto rename : m_mapping)
|
|||
|
|
renameMap.insert(rename->from(), rename);
|
|||
|
|
|
|||
|
|
QHash<int, QByteArray> remapped;
|
|||
|
|
remapped.reserve(roles.size());
|
|||
|
|
|
|||
|
|
QSet<QByteArray> roleNamesSet;
|
|||
|
|
roleNamesSet.reserve(roles.size());
|
|||
|
|
|
|||
|
|
for (auto i = roles.cbegin(), end = roles.cend(); i != end; ++i) {
|
|||
|
|
RoleRename* rename = renameMap.take(i.value());
|
|||
|
|
QByteArray roleName = rename ? rename->to().toUtf8() : i.value();
|
|||
|
|
|
|||
|
|
remapped.insert(i.key(), roleName);
|
|||
|
|
roleNamesSet.insert(roleName);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (roles.size() != roleNamesSet.size()) {
|
|||
|
|
qWarning() << "RolesRenamingModel: model cannot contain duplicated "
|
|||
|
|
"role names!";
|
|||
|
|
return {};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!renameMap.isEmpty()) {
|
|||
|
|
qWarning().nospace()
|
|||
|
|
<< "RolesRenamingModel: specified source roles not found: "
|
|||
|
|
<< renameMap.keys().join(" ") << "!";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_rolesFetched = true;
|
|||
|
|
return remapped;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} // namespace qtmt
|