#include "gtl_selection_data_model.h" #include "core/gtl_data_model.h" namespace gtl { selection_data_model::selection_data_model(QObject *source, int count) : QIdentityProxyModel{source} , _count(count) { // setSourceModel(source); _selection = new selection_list(this); } void selection_data_model::save(QDomElement &root_element) { for(auto it = _selection->begin(); it != _selection->end(); it++) { QDomElement item_element = root_element.ownerDocument().createElement("item"); root_element.appendChild(item_element); item_element.setAttribute("path", (*it)->path()); } root_element.setAttribute("count", _count); } void gtl::selection_data_model::add_selection(gtl::data_model_node* node) { if(std::find(_selection->begin(), _selection->end(), node) != _selection->end()) return; _selection->add(node); connect(node, >l::data_model_node::deleting, this, &selection_data_model::deleting_node); emit selected(static_cast(node)); while(_selection->size() > _count && _count > 0) deselect(_selection->front()); } void selection_data_model::load(const QDomElement &root_element) { clear(); gtl::data_model* model = static_cast(sourceModel()); _count = root_element.attribute("count", "0").toInt(); QDomElement item_element = root_element.firstChildElement(/*"item"*/); while(!item_element.isNull()) { gtl::data_model_node* node = model->node(item_element.attribute("path", "")); if(node) { add_selection(node); QModelIndex index = createIndex(node->index_of(), 0, node); emit dataChanged(index, index, QList() << Qt::CheckStateRole); } item_element = item_element.nextSiblingElement("item"); } } void selection_data_model::clear() { for(auto it = _selection->begin(); it != _selection->end(); it++) emit deselected(static_cast(*it)); _selection->remove_all(); } QAbstractListModel *selection_data_model::selection() { return _selection; } Qt::ItemFlags selection_data_model::flags(const QModelIndex &index) const { return QIdentityProxyModel::flags(index) | Qt::ItemIsUserCheckable; } QVariant selection_data_model::data(const QModelIndex &index, int role) const { if(role == Qt::CheckStateRole) { if(parent(index).isValid()) { data_model_node* node = static_cast(index.internalPointer()); if(std::find(_selection->begin(), _selection->end(), node) == _selection->end()) return Qt::Unchecked; else return Qt::Checked; } } return QIdentityProxyModel::data(index, role); } bool selection_data_model::setData(const QModelIndex &index, const QVariant &value, int role) { if(role == Qt::CheckStateRole) { data_model_node* node = static_cast(index.internalPointer()); if(node->is_checkable()) { if(value.toBool()) { add_selection(node); } else { if(_selection->size() > _count) { _selection->remove(node); emit deselected(static_cast(node)); } } } return true; } return QIdentityProxyModel::setData(index, value, role); } void selection_data_model::get_selections(std::back_insert_iterator > ad) { std::copy(_selection->begin(), _selection->end(), ad); } void selection_data_model::select(analog_data *node) { QModelIndex index = mapFromSource(static_cast(sourceModel())->index(node)); setData(index, true, Qt::CheckStateRole); emit dataChanged(index, index, {Qt::CheckStateRole}); } void selection_data_model::deselect(analog_data *node) { QModelIndex index = mapFromSource(static_cast(sourceModel())->index(node)); setData(index, false, Qt::CheckStateRole); emit dataChanged(index, index, {Qt::CheckStateRole}); } void selection_data_model::deleting_node() { auto iter_node = std::find(_selection->begin(), _selection->end(), sender()); if(iter_node != _selection->end()) _selection->remove(*iter_node); } selection_list::selection_list(QObject *parent) : QAbstractListModel(parent) { } int selection_list::rowCount(const QModelIndex&) const { return (int)size(); } QVariant selection_list::data(const QModelIndex &index, int role) const { if(role == Qt::DisplayRole) return at(index.row())->name(); return QVariant(); } void selection_list::add(data_model_node *node) { beginInsertRows(QModelIndex(), (int)size(), (int)size()); push_back(static_cast(node)); endInsertRows(); } void selection_list::remove(data_model_node *node) { auto it = std::find(begin(), end(), node); if(it == end()) return; int idx = std::distance(begin(), it); beginRemoveRows(QModelIndex(), idx, idx); erase(it); endRemoveRows(); } void selection_list::remove_all() { beginResetModel(); clear(); endResetModel(); } }