diff --git a/src/presentation/artifacteditormodel.h b/src/presentation/artifacteditormodel.h --- a/src/presentation/artifacteditormodel.h +++ b/src/presentation/artifacteditormodel.h @@ -34,10 +34,13 @@ #include "presentation/errorhandlingmodelbase.h" +class QAbstractItemModel; class QTimer; namespace Presentation { +class AttachmentModel; + class ArtifactEditorModel : public QObject, public ErrorHandlingModelBase { Q_OBJECT @@ -47,6 +50,7 @@ Q_PROPERTY(bool done READ isDone WRITE setDone NOTIFY doneChanged) Q_PROPERTY(QDateTime startDate READ startDate WRITE setStartDate NOTIFY startDateChanged) Q_PROPERTY(QDateTime dueDate READ dueDate WRITE setDueDate NOTIFY dueDateChanged) + Q_PROPERTY(QAbstractItemModel* attachmentModel READ attachmentModel CONSTANT) Q_PROPERTY(QString delegateText READ delegateText NOTIFY delegateTextChanged) Q_PROPERTY(bool hasTaskProperties READ hasTaskProperties NOTIFY hasTaskPropertiesChanged) Q_PROPERTY(bool editingInProgress READ editingInProgress WRITE setEditingInProgress) @@ -74,6 +78,7 @@ bool isDone() const; QDateTime startDate() const; QDateTime dueDate() const; + QAbstractItemModel *attachmentModel() const; QString delegateText() const; static int autoSaveDelay(); @@ -128,6 +133,7 @@ bool m_done; QDateTime m_start; QDateTime m_due; + AttachmentModel *m_attachmentModel; QString m_delegateText; QTimer *m_saveTimer; diff --git a/src/presentation/artifacteditormodel.cpp b/src/presentation/artifacteditormodel.cpp --- a/src/presentation/artifacteditormodel.cpp +++ b/src/presentation/artifacteditormodel.cpp @@ -24,18 +24,86 @@ #include "artifacteditormodel.h" +#include +#include #include #include #include "domain/task.h" #include "errorhandler.h" +namespace Presentation { +class AttachmentModel : public QAbstractListModel +{ + Q_OBJECT +public: + explicit AttachmentModel(QObject *parent = nullptr) + : QAbstractListModel(parent) + { + } + + void setTask(const Domain::Task::Ptr &task) + { + if (m_task == task) + return; + + beginResetModel(); + if (m_task) { + disconnect(m_task.data(), &Domain::Task::attachmentsChanged, + this, &AttachmentModel::triggerReset); + } + m_task = task; + if (m_task) { + connect(m_task.data(), &Domain::Task::attachmentsChanged, + this, &AttachmentModel::triggerReset); + } + endResetModel(); + } + + int rowCount(const QModelIndex &parent) const override + { + if (parent.isValid()) + return 0; + + return m_task->attachments().size(); + } + + QVariant data(const QModelIndex &index, int role) const override + { + if (!index.isValid()) + return QVariant(); + + auto attachment = m_task->attachments().at(index.row()); + + switch (role) { + case Qt::DisplayRole: + return attachment.label(); + case Qt::DecorationRole: + return QVariant::fromValue(QIcon::fromTheme(attachment.iconName())); + default: + return QVariant(); + } + } + +private slots: + void triggerReset() + { + beginResetModel(); + endResetModel(); + } + +private: + Domain::Task::Ptr m_task; +}; +} + using namespace Presentation; ArtifactEditorModel::ArtifactEditorModel(QObject *parent) : QObject(parent), m_done(false), + m_attachmentModel(new AttachmentModel(this)), m_saveTimer(new QTimer(this)), m_saveNeeded(false), m_editingInProgress(false) @@ -66,6 +134,7 @@ m_done = false; m_start = QDateTime(); m_due = QDateTime(); + m_attachmentModel->setTask(Domain::Task::Ptr()); m_delegateText = QString(); if (m_artifact) @@ -85,6 +154,7 @@ m_done = task->isDone(); m_start = task->startDate(); m_due = task->dueDate(); + m_attachmentModel->setTask(task); m_delegateText = task->delegate().display(); connect(task.data(), &Domain::Task::doneChanged, this, &ArtifactEditorModel::onDoneChanged); @@ -153,6 +223,11 @@ return m_due; } +QAbstractItemModel *ArtifactEditorModel::attachmentModel() const +{ + return m_attachmentModel; +} + QString ArtifactEditorModel::delegateText() const { return m_delegateText; @@ -323,3 +398,5 @@ m_due = due; emit dueDateChanged(m_due); } + +#include "artifacteditormodel.moc" diff --git a/tests/units/presentation/artifacteditormodeltest.cpp b/tests/units/presentation/artifacteditormodeltest.cpp --- a/tests/units/presentation/artifacteditormodeltest.cpp +++ b/tests/units/presentation/artifacteditormodeltest.cpp @@ -68,6 +68,7 @@ QVERIFY(!model.isDone()); QVERIFY(model.startDate().isNull()); QVERIFY(model.dueDate().isNull()); + QVERIFY(model.attachmentModel() != nullptr); QVERIFY(model.delegateText().isNull()); QVERIFY(!model.hasSaveFunction()); QVERIFY(!model.hasDelegateFunction()); @@ -82,14 +83,32 @@ QSignalSpy doneSpy(&model, &Presentation::ArtifactEditorModel::doneChanged); QSignalSpy startSpy(&model, &Presentation::ArtifactEditorModel::startDateChanged); QSignalSpy dueSpy(&model, &Presentation::ArtifactEditorModel::dueDateChanged); + QSignalSpy attachmentSpy(model.attachmentModel(), &QAbstractItemModel::modelReset); QSignalSpy delegateSpy(&model, &Presentation::ArtifactEditorModel::delegateTextChanged); + Domain::Task::Attachments attachments; + + Domain::Task::Attachment dataAttachment; + dataAttachment.setData("foo"); + dataAttachment.setLabel("dataAttachment"); + dataAttachment.setMimeType("text/plain"); + dataAttachment.setIconName("text-plain"); + attachments.append(dataAttachment); + + Domain::Task::Attachment uriAttachment; + uriAttachment.setUri(QUrl("https://www.kde.org")); + uriAttachment.setLabel("uriAttachment"); + uriAttachment.setMimeType("text/html"); + uriAttachment.setIconName("text-html"); + attachments.append(uriAttachment); + auto task = Domain::Task::Ptr::create(); task->setText(QStringLiteral("description")); task->setTitle(QStringLiteral("title")); task->setDone(true); task->setStartDate(QDateTime::currentDateTime()); task->setDueDate(QDateTime::currentDateTime().addDays(2)); + task->setAttachments(attachments); task->setDelegate(Domain::Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("john@doe.com"))); // WHEN @@ -127,6 +146,14 @@ QCOMPARE(delegateSpy.size(), 1); QCOMPARE(delegateSpy.takeFirst().at(0).toString(), task->delegate().display()); QCOMPARE(model.property("delegateText").toString(), task->delegate().display()); + + QCOMPARE(attachmentSpy.size(), 1); + auto am = model.attachmentModel(); + QCOMPARE(am->rowCount(), 2); + QCOMPARE(am->data(am->index(0, 0), Qt::DisplayRole).toString(), QStringLiteral("dataAttachment")); + QCOMPARE(am->data(am->index(0, 0), Qt::DecorationRole).value(), QIcon::fromTheme("text-plain")); + QCOMPARE(am->data(am->index(1, 0), Qt::DisplayRole).toString(), QStringLiteral("uriAttachment")); + QCOMPARE(am->data(am->index(1, 0), Qt::DecorationRole).value(), QIcon::fromTheme("text-html")); } void shouldHaveNoteProperties()