Refactorings of namespace filter

Moved details from header to cpp
Refactored use of dynamic_cast into virtual calls on the *Node objects.
This commit is contained in:
eelke 2017-12-29 10:10:06 +01:00
parent 590a02599d
commit 206d734ff5
2 changed files with 148 additions and 150 deletions

View file

@ -3,6 +3,140 @@
#include "PgNamespaceContainer.h"
#include "ScopeGuard.h"
namespace NamespaceItemModel_impl {
class Node {
public:
virtual ~Node() {}
virtual int getRowCount() const = 0;
virtual Qt::CheckState getCheckState() const = 0;
virtual void setChecked(NamespaceItemModel *model, const QModelIndex &index, bool checked) = 0;
virtual QVariant data(const QModelIndex &index, int role) const = 0;
};
class GroupNode;
class LeafNode: public Node {
public:
std::weak_ptr<GroupNode> parent;
bool checked = false;
PgNamespace ns;
LeafNode(std::weak_ptr<GroupNode> p, const PgNamespace &nspace)
: parent(p)
, ns(nspace)
{}
virtual int getRowCount() const override
{
return 0;
}
virtual Qt::CheckState getCheckState() const override
{
return checked ? Qt::Checked : Qt::Unchecked;
}
virtual void setChecked(NamespaceItemModel *model, const QModelIndex &index, bool chk) override
{
checked = chk;
emit model->dataChanged(index, index);
emit model->dataChanged(index.parent(), index.parent());
}
virtual QVariant data(const QModelIndex &/*index*/, int role) const override
{
QVariant v;
if (role == Qt::DisplayRole) {
v = ns.name;
}
else if (role == Qt::CheckStateRole) {
v = getCheckState();
}
return v;
}
bool operator < (const LeafNode &rhs) const
{
return ns.name < rhs.ns.name;
}
};
class GroupNode: public Node {
public:
using LeafVec = std::vector<std::shared_ptr<LeafNode>>;
QString name;
LeafVec leaves;
GroupNode(QString n)
: name(n)
{}
virtual int getRowCount() const override
{
return leaves.size();
}
void sortLeaves()
{
std::sort(leaves.begin(), leaves.end(),
[] (auto l, auto r) -> bool { return *l < *r; });
}
virtual Qt::CheckState getCheckState() const override
{
bool some_checked = false;
bool some_unchecked = false;
for (auto l : leaves) {
if (l->checked)
some_checked = true;
else
some_unchecked = true;
}
Qt::CheckState result;
if (some_checked && some_unchecked)
result = Qt::PartiallyChecked;
else if (some_checked)
result = Qt::Checked;
else
result = Qt::Unchecked;
return result;
}
virtual void setChecked(NamespaceItemModel *model, const QModelIndex &index, bool chk) override
{
if (chk)
for (auto l : leaves)
l->checked = true;
if (!chk)
for (auto l : leaves)
l->checked = false;
emit model->dataChanged(index, index);
emit model->dataChanged(model->index(0, 0, index), model->index(leaves.size(), 0, index));
}
virtual QVariant data(const QModelIndex &/*index*/, int role) const override
{
QVariant v;
if (role == Qt::DisplayRole) {
v = name;
}
else if(role == Qt::CheckStateRole) {
v = getCheckState();
}
return v;
}
};
} // end of NamespaceItemModel_impl
using namespace NamespaceItemModel_impl;
NamespaceItemModel::NamespaceItemModel(QObject *parent)
: QAbstractItemModel(parent)
{
@ -56,7 +190,7 @@ QModelIndex NamespaceItemModel::parent(const QModelIndex &index) const
if (index.isValid()) {
auto *n = static_cast<Node*>(index.internalPointer());
LeafNode *ln = dynamic_cast<LeafNode*>(n);
if (ln) { // leftnode
if (ln) { // leafnode
auto grp = ln->parent.lock(); // Get the parent group
auto fr = std::find(groups.begin(), groups.end(), grp); // find it in the list
int row = fr - groups.begin(); // calculate index ie row
@ -80,7 +214,7 @@ int NamespaceItemModel::rowCount(const QModelIndex &parent) const
return count;
}
int NamespaceItemModel::columnCount(const QModelIndex &parent) const
int NamespaceItemModel::columnCount(const QModelIndex &/*index*/) const
{
return 1;
}
@ -89,24 +223,7 @@ QVariant NamespaceItemModel::data(const QModelIndex &index, int role) const
{
QVariant v;
auto *n = static_cast<Node*>(index.internalPointer());
LeafNode *leaf = dynamic_cast<LeafNode*>(n);
if (role == Qt::DisplayRole) {
if (leaf) {
v = leaf->ns.name;
}
else {
GroupNode *grp = dynamic_cast<GroupNode*>(n);
if (grp) {
v = grp->name;
}
}
}
else if(role == Qt::CheckStateRole) {
//return checkedItems.contains(index) ?
// Qt::Checked : Qt::Unchecked;
if (n)
v = n->getCheckState();
}
v = n->data(index, role);
return v;
}
@ -117,30 +234,7 @@ bool NamespaceItemModel::setData(const QModelIndex &index,
return false;
auto *n = static_cast<Node*>(index.internalPointer());
LeafNode *leaf = dynamic_cast<LeafNode*>(n);
if (leaf) {
leaf->checked = value == Qt::Checked;
emit dataChanged(index, index);
emit dataChanged(index.parent(), index.parent());
}
else {
GroupNode *gn = dynamic_cast<GroupNode*>(n);
if (gn) {
if (value == Qt::Checked)
for (auto l : gn->leaves)
l->checked = true;
if (value == Qt::Unchecked)
for (auto l : gn->leaves)
l->checked = false;
emit dataChanged(index, index);
emit dataChanged(this->index(0, 0, index), this->index(gn->leaves.size(), 0, index));
}
}
// if(value == Qt::Checked)
// checkedItems.insert(index);
// else
// checkedItems.remove(index);
n->setChecked(this, index, value == Qt::Checked);
return true;
}
@ -148,24 +242,7 @@ bool NamespaceItemModel::setData(const QModelIndex &index,
Qt::ItemFlags NamespaceItemModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
auto *n = static_cast<Node*>(index.internalPointer());
// LeafNode *leaf = dynamic_cast<LeafNode*>(n);
// if (leaf) {
flags.setFlag(Qt::ItemIsUserCheckable);
// }
// else {
// flags.setFlag(Qt::ItemIsAutoTristate);
// }
flags.setFlag(Qt::ItemIsUserCheckable);
return flags;
}
//std::set<Oid> NamespaceItemModel::getCheckedNamespaces() const
//{
// std::set<Oid> result;
// for (auto g : groups)
// for (auto l : g->leaves)
// if (l->checked)
// result.insert(l->ns.oid);
// return result;
//}