diff --git a/src/domain/task.h b/src/domain/task.h --- a/src/domain/task.h +++ b/src/domain/task.h @@ -33,15 +33,25 @@ class Task : public Artifact { Q_OBJECT + Q_ENUMS(Recurrence) Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged) 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(Recurrence recurrence READ recurrence WRITE setRecurrence NOTIFY recurrenceChanged) Q_PROPERTY(Domain::Task::Delegate delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) public: typedef QSharedPointer Ptr; typedef QList List; + enum Recurrence { + NoRecurrence = 0, + Daily, + Weekly, + MonthlyDay, // eg: 11th day of the month + MonthlyPos // eg: second monday of the month + }; + class Delegate { public: @@ -76,36 +86,44 @@ QDateTime dueDate() const; QDateTime doneDate() const; Delegate delegate() const; + Recurrence recurrence() const; public slots: void setRunning(bool running); void setDone(bool done); void setDoneDate(const QDateTime &doneDate); - void setStartDate(const QDateTime &startDate); + void setStartDate(const QDateTime &startDate, const Recurrence recurrence = NoRecurrence); void setDueDate(const QDateTime &dueDate); void setDelegate(const Domain::Task::Delegate &delegate); +private slots: + void setRecurrence(const Recurrence recurrence); + signals: void runningChanged(bool isRunning); void doneChanged(bool isDone); void doneDateChanged(const QDateTime &doneDate); void startDateChanged(const QDateTime &startDate); void dueDateChanged(const QDateTime &dueDate); void delegateChanged(const Domain::Task::Delegate &delegate); + void recurrenceChanged(const Domain::Task::Recurrence &recurrence); + void recurrentTaskDone(Domain::Task *task); private: bool m_running; bool m_done; QDateTime m_startDate; QDateTime m_dueDate; QDateTime m_doneDate; Delegate m_delegate; + Recurrence m_recurrence; }; } Q_DECLARE_METATYPE(Domain::Task::Ptr) Q_DECLARE_METATYPE(Domain::Task::List) Q_DECLARE_METATYPE(Domain::Task::Delegate) +Q_DECLARE_METATYPE(Domain::Task::Recurrence) #endif // DOMAIN_TASK_H diff --git a/src/domain/task.cpp b/src/domain/task.cpp --- a/src/domain/task.cpp +++ b/src/domain/task.cpp @@ -31,7 +31,8 @@ Task::Task(QObject *parent) : Artifact(parent), m_running(false), - m_done(false) + m_done(false), + m_recurrence(NoRecurrence) { } @@ -59,6 +60,9 @@ m_done = done; m_doneDate = doneDate; + if (m_recurrence != NoRecurrence) + emit recurrentTaskDone(this); + emit doneChanged(done); emit doneDateChanged(doneDate); } @@ -77,8 +81,10 @@ return m_startDate; } -void Task::setStartDate(const QDateTime &startDate) +void Task::setStartDate(const QDateTime &startDate, const Domain::Task::Recurrence recurrence) { + setRecurrence(recurrence); + if (m_startDate == startDate) return; @@ -109,6 +115,11 @@ emit runningChanged(running); } +Task::Recurrence Task::recurrence() const +{ + return m_recurrence; +} + void Task::setDueDate(const QDateTime &dueDate) { if (m_dueDate == dueDate) @@ -127,6 +138,14 @@ emit delegateChanged(delegate); } +void Task::setRecurrence(const Domain::Task::Recurrence recurrence) +{ + if (m_recurrence == recurrence) + return; + + m_recurrence = recurrence; + emit recurrenceChanged(m_recurrence); +} Task::Delegate::Delegate() { diff --git a/tests/units/domain/tasktest.cpp b/tests/units/domain/tasktest.cpp --- a/tests/units/domain/tasktest.cpp +++ b/tests/units/domain/tasktest.cpp @@ -49,6 +49,7 @@ QCOMPARE(t.startDate(), QDateTime()); QCOMPARE(t.dueDate(), QDateTime()); QCOMPARE(t.doneDate(), QDateTime()); + QCOMPARE(t.recurrence(), Domain::Task::NoRecurrence); QVERIFY(!t.delegate().isValid()); } @@ -189,6 +190,54 @@ QCOMPARE(spy.count(), 1); QCOMPARE(spy.takeFirst().at(0).toDateTime(), QDateTime()); } + + void shouldNotifyRecurrenceChanges_data() + { + QTest::addColumn("originalRecurrence"); + QTest::addColumn("newRecurrence"); + QTest::addColumn("originalStartDate"); + QTest::addColumn("newStartDate"); + QTest::addColumn("recurrenceChanged"); + QTest::addColumn("startDateChanged"); + + const auto today = Utils::DateTime::currentDateTime(); + const auto tomorrow = today.addDays(1); + + QTest::newRow("RecurrenceUnchangedStartDateUnchanged") << Domain::Task::NoRecurrence << Domain::Task::NoRecurrence << today << today << false << false; + QTest::newRow("RecurrenceUnchangedStartDateChanged") << Domain::Task::NoRecurrence << Domain::Task::NoRecurrence << today << tomorrow << false << true; + QTest::newRow("RecurrenceChangedStartDateUnchanged") << Domain::Task::Daily << Domain::Task::NoRecurrence << today << today << true << false; + QTest::newRow("RecurrenceChangedStartDateChanged") << Domain::Task::Daily << Domain::Task::NoRecurrence << today << tomorrow << true << true; + } + + void shouldNotifyRecurrenceChanges() + { + QFETCH(Domain::Task::Recurrence, originalRecurrence); + QFETCH(Domain::Task::Recurrence, newRecurrence); + QFETCH(QDateTime, originalStartDate); + QFETCH(QDateTime, newStartDate); + QFETCH(bool, recurrenceChanged); + QFETCH(bool, startDateChanged); + + // GIVEN + Task t; + t.setStartDate(originalStartDate, originalRecurrence); + + QSignalSpy spyRecurrence(&t, &Task::recurrenceChanged); + QSignalSpy spyStartDate(&t, &Task::startDateChanged); + + // WHEN + t.setStartDate(newStartDate, newRecurrence); + + // THEN + QCOMPARE(t.startDate(), newStartDate); + QCOMPARE(t.recurrence(), newRecurrence); + + if(startDateChanged) + QCOMPARE(spyStartDate.count(), 1); + + if (recurrenceChanged) + QCOMPARE(spyRecurrence.count(), 1); + } }; ZANSHIN_TEST_MAIN(TaskTest)