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:
parent
590a02599d
commit
206d734ff5
2 changed files with 148 additions and 150 deletions
|
|
@ -3,6 +3,140 @@
|
||||||
#include "PgNamespaceContainer.h"
|
#include "PgNamespaceContainer.h"
|
||||||
#include "ScopeGuard.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)
|
NamespaceItemModel::NamespaceItemModel(QObject *parent)
|
||||||
: QAbstractItemModel(parent)
|
: QAbstractItemModel(parent)
|
||||||
{
|
{
|
||||||
|
|
@ -56,7 +190,7 @@ QModelIndex NamespaceItemModel::parent(const QModelIndex &index) const
|
||||||
if (index.isValid()) {
|
if (index.isValid()) {
|
||||||
auto *n = static_cast<Node*>(index.internalPointer());
|
auto *n = static_cast<Node*>(index.internalPointer());
|
||||||
LeafNode *ln = dynamic_cast<LeafNode*>(n);
|
LeafNode *ln = dynamic_cast<LeafNode*>(n);
|
||||||
if (ln) { // leftnode
|
if (ln) { // leafnode
|
||||||
auto grp = ln->parent.lock(); // Get the parent group
|
auto grp = ln->parent.lock(); // Get the parent group
|
||||||
auto fr = std::find(groups.begin(), groups.end(), grp); // find it in the list
|
auto fr = std::find(groups.begin(), groups.end(), grp); // find it in the list
|
||||||
int row = fr - groups.begin(); // calculate index ie row
|
int row = fr - groups.begin(); // calculate index ie row
|
||||||
|
|
@ -80,7 +214,7 @@ int NamespaceItemModel::rowCount(const QModelIndex &parent) const
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NamespaceItemModel::columnCount(const QModelIndex &parent) const
|
int NamespaceItemModel::columnCount(const QModelIndex &/*index*/) const
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -89,24 +223,7 @@ QVariant NamespaceItemModel::data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
QVariant v;
|
QVariant v;
|
||||||
auto *n = static_cast<Node*>(index.internalPointer());
|
auto *n = static_cast<Node*>(index.internalPointer());
|
||||||
LeafNode *leaf = dynamic_cast<LeafNode*>(n);
|
v = n->data(index, role);
|
||||||
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();
|
|
||||||
}
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,30 +234,7 @@ bool NamespaceItemModel::setData(const QModelIndex &index,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto *n = static_cast<Node*>(index.internalPointer());
|
auto *n = static_cast<Node*>(index.internalPointer());
|
||||||
LeafNode *leaf = dynamic_cast<LeafNode*>(n);
|
n->setChecked(this, index, value == Qt::Checked);
|
||||||
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);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -148,24 +242,7 @@ bool NamespaceItemModel::setData(const QModelIndex &index,
|
||||||
Qt::ItemFlags NamespaceItemModel::flags(const QModelIndex &index) const
|
Qt::ItemFlags NamespaceItemModel::flags(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
|
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
|
||||||
auto *n = static_cast<Node*>(index.internalPointer());
|
flags.setFlag(Qt::ItemIsUserCheckable);
|
||||||
// LeafNode *leaf = dynamic_cast<LeafNode*>(n);
|
|
||||||
// if (leaf) {
|
|
||||||
flags.setFlag(Qt::ItemIsUserCheckable);
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// flags.setFlag(Qt::ItemIsAutoTristate);
|
|
||||||
// }
|
|
||||||
return flags;
|
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;
|
|
||||||
//}
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,14 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace NamespaceItemModel_impl {
|
||||||
|
|
||||||
|
class Node;
|
||||||
|
class LeafNode;
|
||||||
|
class GroupNode;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
class PgNamespaceContainer;
|
class PgNamespaceContainer;
|
||||||
|
|
||||||
class NamespaceItemModel: public QAbstractItemModel {
|
class NamespaceItemModel: public QAbstractItemModel {
|
||||||
|
|
@ -24,97 +32,10 @@ public:
|
||||||
virtual bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
virtual bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
|
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||||
|
|
||||||
template <typename I>
|
|
||||||
void getCheckedNamespaces(I inserter) const
|
|
||||||
{
|
|
||||||
for (auto g : groups)
|
|
||||||
for (auto l : g->leaves)
|
|
||||||
if (l->checked)
|
|
||||||
inserter = l->ns.oid;
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
class Node {
|
using GroupVec = std::vector<std::shared_ptr<NamespaceItemModel_impl::GroupNode>>;
|
||||||
public:
|
|
||||||
|
|
||||||
virtual ~Node() {}
|
|
||||||
virtual int getRowCount() const = 0;
|
|
||||||
virtual Qt::CheckState getCheckState() 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
using GroupVec = std::vector<std::shared_ptr<GroupNode>>;
|
|
||||||
|
|
||||||
GroupVec groups;
|
GroupVec groups;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NAMESPACEITEMMODEL_H
|
#endif // NAMESPACEITEMMODEL_H
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue