/** * @RDE_HEADER@ * $Id$ * $HeadURL$ * $Author$ * * Created by Philipp Last, NLSE, 05.01.2018 */ #include "evl_edit_treemodel_schema.h" #include #include #include namespace Evaluations { TreeModelSchema::TreeModelSchema(QObject *parent, NGL::INGLLogger &logger) : TreeModelGeneral(parent, logger) { qRegisterMetaTypeStreamOperators(); } void TreeModelSchema::resetModel() { TreeModelGeneral::resetModel(); m_elementId = 1; m_cntComments = 0; m_cntSentComments = 0; } bool TreeModelSchema::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { /* * Prevent dropping/appending elements to other elements! * Only dropping to folders is allowed! */ ElementData p = getSelectedIndexDataAsElement(parent); if (!p.isFolder()) { emit signalTriedToDropFolderToElement(); return false; } bool success = TreeModelGeneral::dropMimeData(data, action, row, column, parent); if (success) { /* * User may have moved a folder with some elements into another folder. * Hence, we have to update the parent ids. */ int parentId = getSelectedIndexDataAsElement(parent).m_id; iterateModel(parent, [this, parentId](const QModelIndex & idx, const QVariant & v) { Evaluations::ElementData e = v.value(); e.m_parentId = parentId; updateElementData(idx, e); }, false); refreshAllIcons(); emit signalSuccessfulDropPerformed(parent); } return success; } QVariant TreeModelSchema::data(const QModelIndex &index, int role) const { QVariant v = TreeModelGeneral::data(index, role); if (v.isNull()) return v; if (v.canConvert()) { Evaluations::ElementData e = v.value(); return e.getText(); } else if (v.canConvert()) { Evaluations::ItemComment c = v.value(); QString str(DTG::toStringMSec(c.getTimeStamp().toMSecsSinceEpoch())); str += QLatin1Char(' '); str += c.getText(); return str; } return v; } ElementData TreeModelSchema::getSelectedIndexDataAsElement(const QModelIndex &idx) const { if (!idx.isValid()) ElementData(); QVariant v = TreeModelGeneral::dataAsVariant(idx); return v.value(); } QVector TreeModelSchema::getSelectedIndexHierarchy(const QModelIndex &idx) const { if (!idx.isValid()) QString(); QVector vecHierarchy; QModelIndex iterIdx = idx; while (iterIdx.parent() != QModelIndex()) { Evaluations::ElementData e = getSelectedIndexDataAsElement(iterIdx); vecHierarchy.push_front(e.getText()); iterIdx = iterIdx.parent(); } Evaluations::ElementData e = getSelectedIndexDataAsElement(iterIdx); vecHierarchy.push_front(e.getText()); return vecHierarchy; } QJsonDocument TreeModelSchema::toJsonDocument() const { QJsonArray arr; QModelIndex root; iterateModel(root, [this, &arr](const QModelIndex & idx, const QVariant & v) { Q_UNUSED(idx); Evaluations::ElementData e = v.value(); INFO_LOG(m_logger) << "toJsonDocument: Name: " << e.getText() << ", elementId: " << e.m_id << ", parent id: " << e.m_parentId; QJsonObject obj; obj[QStringLiteral("id")] = e.m_id; obj[QStringLiteral("parentId")] = e.m_parentId; obj[QStringLiteral("text")] = e.getText(); obj[QStringLiteral("state")] = int(e.getState()); arr.append(obj); }); QJsonDocument doc(arr); return doc; } bool TreeModelSchema::fromQJsonDocument(const QJsonDocument &doc) { resetModel(); const QJsonArray arr(doc.array()); if (!arr.size()) return false; QHash mapId2Index; for (const QJsonValue &val : arr) { const QJsonObject obj = val.toObject(); ElementData d(obj[QStringLiteral("text")].toString()); d.m_id = obj[QStringLiteral("id")].toInt(); d.m_parentId = obj[QStringLiteral("parentId")].toInt(); d.switchState((ElementData::State)obj[QStringLiteral("state")].toInt()); QPersistentModelIndex parent = (d.m_parentId == 0) ? QPersistentModelIndex() : mapId2Index[d.m_parentId]; QModelIndex newIdx = TreeModelGeneral::insertRow(parent, QVariant::fromValue(d), d.getIcon()); mapId2Index[d.m_id] = newIdx; /* * Get current max element id. This is required since * the user will most likely add new elements to the loaded treeview / element list */ m_elementId = std::max(m_elementId, d.m_id); INFO_LOG(m_logger) << "fromQJsonDocument: " << d.getText() << ", own id = " << d.m_id << ", parent id = " << d.m_parentId; } ++m_elementId; return true; } QModelIndex TreeModelSchema::insertComment(const QModelIndex &parent, const ItemComment &data) { QModelIndex idx = TreeModelGeneral::insertRow(parent, QVariant::fromValue(data), data.getIcon()); if (idx.isValid()) { ++m_cntComments; if (data.isSent()) ++m_cntSentComments; refreshElementDataIconState(parent); } return idx; } void TreeModelSchema::insertComment(const ItemComment &data) { QModelIndex root = QModelIndex(); iterateModel(root, [&data, this](const QModelIndex & idx, const QVariant & v) { if (v.canConvert()) { ElementData e = v.value(); if (e.m_id == data.elementId()) TreeModelSchema::insertComment(idx, data); } }); } bool TreeModelSchema::updateComment(const QModelIndex &index, const ItemComment &data) { bool success = TreeModelGeneral::updateRow(index, QVariant::fromValue(data), data.getIcon()); if (success) { if (data.isSent()) ++m_cntSentComments; refreshElementDataIconState(index.parent()); } return success; } void TreeModelSchema::removeComment(const QModelIndex &idx) { if (!idx.isValid()) return; --m_cntComments; QModelIndex idxParentElement = idx.parent(); removeRow(idx); refreshElementDataIconState(idxParentElement); } QModelIndex TreeModelSchema::insertElementData(const QModelIndex &parent, const ElementData &data) { ElementData d(data); d.m_id = m_elementId++; d.m_parentId = !parent.isValid() ? 0 : getSelectedIndexDataAsElement(parent).m_id; return TreeModelGeneral::insertRow(parent, QVariant::fromValue(d), d.getIcon()); } bool TreeModelSchema::updateElementData(const QModelIndex &index, const ElementData &data) { return TreeModelGeneral::updateRow(index, QVariant::fromValue(data), data.getIcon()); } void TreeModelSchema::refreshElementDataIconState(const QModelIndex &idx) { ElementData e = getSelectedIndexDataAsElement(idx); if (e.isFolder()) return; if (!rowCount(idx)) e.switchState(ElementData::State::ElementWithoutComments); else { bool hasUnsentComments = false; iterateModel(idx, [&hasUnsentComments](const QModelIndex & idx, const QVariant & v) { Q_UNUSED(idx); const Evaluations::ItemComment d = v.value(); if (!d.isSent()) hasUnsentComments = true; }); e.switchState(hasUnsentComments ? ElementData::State::ElementWithUnsentComments : ElementData::State::ElementAllCommentsSent); } TreeModelGeneral::updateRow(idx, QVariant::fromValue(e), e.getIcon()); } void TreeModelSchema::refreshAllIcons() { QModelIndex root; iterateModel(root, [this](const QModelIndex & idx, const QVariant & v) { Evaluations::ElementData d = v.value(); d.refreshIcon(); NGLTreeItem *item = privateData(idx); item->setIcon(d.getIcon()); }); emit dataChanged(QModelIndex(), QModelIndex()); } } // namespace Evaluations