315 lines
7.7 KiB
C++
Executable File
315 lines
7.7 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*
|
|
* Created by Philipp Last, NLSE, 05.01.2018
|
|
*/
|
|
|
|
#include "evl_edit_treemodel_schema.h"
|
|
#include <ngltools/ngltools_dtg.h>
|
|
|
|
#include <QJsonArray>
|
|
#include <QJsonObject>
|
|
|
|
namespace Evaluations
|
|
{
|
|
TreeModelSchema::TreeModelSchema(QObject *parent, NGL::INGLLogger &logger)
|
|
: TreeModelGeneral(parent, logger)
|
|
{
|
|
qRegisterMetaTypeStreamOperators<Evaluations::ElementData>();
|
|
}
|
|
|
|
|
|
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<Evaluations::ElementData>();
|
|
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>())
|
|
{
|
|
Evaluations::ElementData e = v.value<Evaluations::ElementData>();
|
|
return e.getText();
|
|
}
|
|
else if (v.canConvert<Evaluations::ItemComment>())
|
|
{
|
|
Evaluations::ItemComment c = v.value<Evaluations::ItemComment>();
|
|
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<Evaluations::ElementData>();
|
|
}
|
|
|
|
|
|
QVector<QString> TreeModelSchema::getSelectedIndexHierarchy(const QModelIndex &idx) const
|
|
{
|
|
if (!idx.isValid())
|
|
QString();
|
|
|
|
QVector<QString> 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<Evaluations::ElementData>();
|
|
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<int, QPersistentModelIndex> 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<Evaluations::ElementData>())
|
|
{
|
|
ElementData e = v.value<Evaluations::ElementData>();
|
|
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<Evaluations::ItemComment>();
|
|
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<Evaluations::ElementData>();
|
|
d.refreshIcon();
|
|
|
|
NGLTreeItem *item = privateData(idx);
|
|
item->setIcon(d.getIcon());
|
|
});
|
|
|
|
emit dataChanged(QModelIndex(), QModelIndex());
|
|
}
|
|
} // namespace Evaluations
|
|
|