diff --git a/src/widgets/editorview.h b/src/widgets/editorview.h --- a/src/widgets/editorview.h +++ b/src/widgets/editorview.h @@ -29,6 +29,8 @@ #include +#include "domain/task.h" + class QAbstractButton; class QLabel; class QPlainTextEdit; @@ -63,6 +65,7 @@ void startDateChanged(const QDateTime &start); void dueDateChanged(const QDateTime &due); void doneChanged(bool done); + void recurrenceChanged(Domain::Task::Recurrence recurrence); protected: bool eventFilter(QObject *watched, QEvent *event) Q_DECL_OVERRIDE; @@ -74,13 +77,15 @@ void onStartDateChanged(); void onDueDateChanged(); void onDoneChanged(); + void onRecurrenceChanged(); void onDelegateTextChanged(); void onTextEditChanged(); void onStartEditEntered(const QDate &start); void onDueEditEntered(const QDate &due); void onDoneButtonChanged(bool checked); void onStartTodayClicked(); + void onRecurrenceComboChanged(int index); void onDelegateEntered(); void onAttachmentDoubleClicked(const QModelIndex &index); diff --git a/src/widgets/editorview.cpp b/src/widgets/editorview.cpp --- a/src/widgets/editorview.cpp +++ b/src/widgets/editorview.cpp @@ -64,6 +64,11 @@ ui->startDateEdit->setMinimumContentsLength(10); ui->dueDateEdit->setMinimumContentsLength(10); + ui->recurrenceCombo->addItem(i18n("Never"), QVariant::fromValue(Domain::Task::NoRecurrence)); + ui->recurrenceCombo->addItem(i18n("Daily"), QVariant::fromValue(Domain::Task::RecursDaily)); + ui->recurrenceCombo->addItem(i18n("Weekly"), QVariant::fromValue(Domain::Task::RecursWeekly)); + ui->recurrenceCombo->addItem(i18n("Monthly"), QVariant::fromValue(Domain::Task::RecursMonthly)); + // Make sure our minimum width is always the one with // the task group visible ui->layout->activate(); @@ -76,13 +81,16 @@ ui->startDateEdit->installEventFilter(this); ui->dueDateEdit->installEventFilter(this); ui->doneButton->installEventFilter(this); + ui->recurrenceCombo->installEventFilter(this); m_delegateEdit->installEventFilter(this); connect(ui->textEdit, &QPlainTextEdit::textChanged, this, &EditorView::onTextEditChanged); connect(ui->startDateEdit, &KPIM::KDateEdit::dateEntered, this, &EditorView::onStartEditEntered); connect(ui->dueDateEdit, &KPIM::KDateEdit::dateEntered, this, &EditorView::onDueEditEntered); connect(ui->doneButton, &QAbstractButton::toggled, this, &EditorView::onDoneButtonChanged); connect(ui->startTodayButton, &QAbstractButton::clicked, this, &EditorView::onStartTodayClicked); + connect(ui->recurrenceCombo, static_cast(&QComboBox::currentIndexChanged), + this, &EditorView::onRecurrenceComboChanged); connect(ui->attachmentList, &QAbstractItemView::doubleClicked, this, &EditorView::onAttachmentDoubleClicked); connect(m_delegateEdit, &KLineEdit::returnPressed, this, &EditorView::onDelegateEntered); @@ -129,6 +137,7 @@ onStartDateChanged(); onDueDateChanged(); onDoneChanged(); + onRecurrenceChanged(); onDelegateTextChanged(); connect(m_model, SIGNAL(artifactChanged(Domain::Artifact::Ptr)), @@ -140,13 +149,15 @@ connect(m_model, SIGNAL(startDateChanged(QDateTime)), this, SLOT(onStartDateChanged())); connect(m_model, SIGNAL(dueDateChanged(QDateTime)), this, SLOT(onDueDateChanged())); connect(m_model, SIGNAL(doneChanged(bool)), this, SLOT(onDoneChanged())); + connect(m_model, SIGNAL(recurrenceChanged(Domain::Task::Recurrence)), this, SLOT(onRecurrenceChanged())); connect(m_model, SIGNAL(delegateTextChanged(QString)), this, SLOT(onDelegateTextChanged())); connect(this, SIGNAL(titleChanged(QString)), m_model, SLOT(setTitle(QString))); connect(this, SIGNAL(textChanged(QString)), m_model, SLOT(setText(QString))); connect(this, SIGNAL(startDateChanged(QDateTime)), m_model, SLOT(setStartDate(QDateTime))); connect(this, SIGNAL(dueDateChanged(QDateTime)), m_model, SLOT(setDueDate(QDateTime))); connect(this, SIGNAL(doneChanged(bool)), m_model, SLOT(setDone(bool))); + connect(this, SIGNAL(recurrenceChanged(Domain::Task::Recurrence)), m_model, SLOT(setRecurrence(Domain::Task::Recurrence))); } bool EditorView::eventFilter(QObject *watched, QEvent *event) @@ -206,6 +217,17 @@ ui->doneButton->setChecked(m_model->property("done").toBool()); } +void EditorView::onRecurrenceChanged() +{ + const auto recurrence = m_model->property("recurrence").value(); + for (int index = 0; index < ui->recurrenceCombo->count(); index++) { + if (recurrence == ui->recurrenceCombo->itemData(index).value()) { + ui->recurrenceCombo->setCurrentIndex(index); + return; + } + } +} + void EditorView::onDelegateTextChanged() { const auto delegateText = m_model->property("delegateText").toString(); @@ -253,6 +275,12 @@ emit startDateChanged(QDateTime(today, QTime(), Qt::UTC)); } +void EditorView::onRecurrenceComboChanged(int index) +{ + const auto recurrence = ui->recurrenceCombo->itemData(index).value(); + emit recurrenceChanged(recurrence); +} + void EditorView::onDelegateEntered() { const auto input = m_delegateEdit->text(); diff --git a/src/widgets/editorview.ui b/src/widgets/editorview.ui --- a/src/widgets/editorview.ui +++ b/src/widgets/editorview.ui @@ -108,6 +108,22 @@ + + + &Recurrence + + + 4 + + + recurrenceCombo + + + + + + + De&legate to @@ -117,7 +133,7 @@ - + @@ -135,7 +151,7 @@ - + 3 diff --git a/tests/units/widgets/editorviewtest.cpp b/tests/units/widgets/editorviewtest.cpp --- a/tests/units/widgets/editorviewtest.cpp +++ b/tests/units/widgets/editorviewtest.cpp @@ -69,6 +69,8 @@ emit startDateChanged(value.toDateTime()); else if (name == "dueDate") emit dueDateChanged(value.toDateTime()); + else if (name == "recurrence") + emit recurrenceChanged(value.value()); else if (name == "delegateText") emit delegateTextChanged(value.toString()); else if (name == "hasTaskProperties") @@ -84,6 +86,7 @@ void setDone(bool done) { setPropertyAndSignal("done", done); } void setStartDate(const QDateTime &start) { setPropertyAndSignal("startDate", start); } void setDueDate(const QDateTime &due) { setPropertyAndSignal("dueDate", due); } + void setRecurrence(Domain::Task::Recurrence recurrence) { setPropertyAndSignal("recurrence", QVariant::fromValue(recurrence)); } void setDelegateText(const QString &text) { setPropertyAndSignal("delegateText", text); } void makeTaskAvailable() { setArtifact(Domain::Artifact::Ptr(new Domain::Task)); } @@ -101,6 +104,7 @@ void doneChanged(bool done); void startDateChanged(const QDateTime &date); void dueDateChanged(const QDateTime &due); + void recurrenceChanged(Domain::Task::Recurrence recurrence); void delegateTextChanged(const QString &delegateText); public: @@ -138,6 +142,10 @@ QVERIFY(dueDateEdit); QVERIFY(!dueDateEdit->isVisibleTo(&editor)); + auto recurrenceCombo = editor.findChild(QStringLiteral("recurrenceCombo")); + QVERIFY(recurrenceCombo); + QVERIFY(!recurrenceCombo->isVisibleTo(&editor)); + auto doneButton = editor.findChild(QStringLiteral("doneButton")); QVERIFY(doneButton); QVERIFY(!doneButton->isVisibleTo(&editor)); @@ -174,6 +182,9 @@ auto dueDateEdit = editor.findChild(QStringLiteral("dueDateEdit")); QVERIFY(dueDateEdit); + auto recurrenceCombo = editor.findChild(QStringLiteral("recurrenceCombo")); + QVERIFY(recurrenceCombo); + auto doneButton = editor.findChild(QStringLiteral("doneButton")); QVERIFY(doneButton); @@ -195,6 +206,7 @@ QVERIFY(textEdit->toPlainText().isEmpty()); QVERIFY(!startDateEdit->isVisibleTo(&editor)); QVERIFY(!dueDateEdit->isVisibleTo(&editor)); + QVERIFY(!recurrenceCombo->isVisibleTo(&editor)); QVERIFY(!doneButton->isVisibleTo(&editor)); QVERIFY(!attachmentList->isVisibleTo(&editor)); QVERIFY(attachmentList->model() == nullptr); @@ -215,6 +227,9 @@ auto dueDateEdit = editor.findChild(QStringLiteral("dueDateEdit")); QVERIFY(!dueDateEdit->isVisibleTo(&editor)); + auto recurrenceCombo = editor.findChild(QStringLiteral("recurrenceCombo")); + QVERIFY(recurrenceCombo); + auto doneButton = editor.findChild(QStringLiteral("doneButton")); QVERIFY(!doneButton->isVisibleTo(&editor)); @@ -233,6 +248,7 @@ // THEN QVERIFY(startDateEdit->isVisibleTo(&editor)); QVERIFY(dueDateEdit->isVisibleTo(&editor)); + QVERIFY(recurrenceCombo->isVisibleTo(&editor)); QVERIFY(doneButton->isVisibleTo(&editor)); QVERIFY(attachmentList->isVisibleTo(&editor)); QVERIFY(!delegateLabel->isVisibleTo(&editor)); @@ -335,11 +351,13 @@ model.setProperty("text", "\nMy text"); model.setProperty("startDate", QDateTime::currentDateTime()); model.setProperty("dueDate", QDateTime::currentDateTime().addDays(2)); + model.setProperty("recurrence", QVariant::fromValue(Domain::Task::RecursWeekly)); model.setProperty("done", true); auto textEdit = editor.findChild(QStringLiteral("textEdit")); auto startDateEdit = editor.findChild(QStringLiteral("startDateEdit")); auto dueDateEdit = editor.findChild(QStringLiteral("dueDateEdit")); + auto recurrenceCombo = editor.findChild(QStringLiteral("recurrenceCombo")); auto doneButton = editor.findChild(QStringLiteral("doneButton")); // WHEN @@ -351,6 +369,7 @@ + model.property("text").toString())); QCOMPARE(startDateEdit->date(), model.property("startDate").toDateTime().date()); QCOMPARE(dueDateEdit->date(), model.property("dueDate").toDateTime().date()); + QCOMPARE(recurrenceCombo->currentData().value(), model.property("recurrence").value()); QCOMPARE(doneButton->isChecked(), model.property("done").toBool()); } @@ -364,12 +383,14 @@ model.setProperty("text", "\nMy text"); model.setProperty("startDate", QDateTime::currentDateTime()); model.setProperty("dueDate", QDateTime::currentDateTime().addDays(2)); + model.setProperty("recurrence", QVariant::fromValue(Domain::Task::RecursWeekly)); model.setProperty("done", true); editor.setModel(&model); auto textEdit = editor.findChild(QStringLiteral("textEdit")); auto startDateEdit = editor.findChild(QStringLiteral("startDateEdit")); auto dueDateEdit = editor.findChild(QStringLiteral("dueDateEdit")); + auto recurrenceCombo = editor.findChild(QStringLiteral("recurrenceCombo")); auto doneButton = editor.findChild(QStringLiteral("doneButton")); auto delegateLabel = editor.findChild(QStringLiteral("delegateLabel")); auto delegateEdit = editor.findChild(QStringLiteral("delegateEdit")); @@ -387,6 +408,8 @@ model.setStartDate(QDateTime::currentDateTime().addDays(1)); dueDateEdit->setFocus(); model.setDueDate(QDateTime::currentDateTime().addDays(3)); + recurrenceCombo->setFocus(); + model.setRecurrence(Domain::Task::RecursDaily); doneButton->setFocus(); model.setDone(false); delegateEdit->setFocus(); @@ -396,6 +419,7 @@ QCOMPARE(textEdit->toPlainText(), QStringLiteral("My title\n\nMy text")); QCOMPARE(startDateEdit->date(), QDate::currentDate()); QCOMPARE(dueDateEdit->date(), QDate::currentDate().addDays(2)); + QCOMPARE(recurrenceCombo->currentData().value(), Domain::Task::RecursWeekly); QVERIFY(doneButton->isChecked()); auto expectedText = i18n("Delegated to: %1", QStringLiteral("John Doe")); QCOMPARE(delegateLabel->text(), expectedText); @@ -627,6 +651,46 @@ QCOMPARE(model.property("startDate").toDateTime().date(), today); } + void shouldReactToRecurrenceChanges() + { + // GIVEN + Widgets::EditorView editor; + EditorModelStub model; + model.makeTaskAvailable(); + model.setProperty("title", "My title"); + model.setProperty("text", "\nMy text"); + model.setProperty("startDate", QDateTime::currentDateTime()); + model.setProperty("dueDate", QDateTime::currentDateTime().addDays(2)); + model.setProperty("recurrence", QVariant::fromValue(Domain::Task::RecursWeekly)); + model.setProperty("done", false); + editor.setModel(&model); + + auto recurrenceCombo = editor.findChild(QStringLiteral("recurrenceCombo")); + + // WHEN + model.setPropertyAndSignal("recurrence", Domain::Task::RecursMonthly); + + // THEN + QCOMPARE(recurrenceCombo->currentData().value(), model.property("recurrence").value()); + } + + void shouldApplyRecurrenceComboChanges() + { + // GIVEN + Widgets::EditorView editor; + EditorModelStub model; + model.makeTaskAvailable(); + editor.setModel(&model); + + auto recurrenceCombo = editor.findChild(QStringLiteral("recurrenceCombo")); + + // WHEN + recurrenceCombo->setCurrentIndex(2); // Weekly + + // THEN + QCOMPARE(model.property("recurrence").value(), Domain::Task::RecursWeekly); + } + void shouldReactToDelegateTextChanges() { // GIVEN