From 74a91e13153f0696bb62baa78dac119f3a2e9fca Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Thu, 6 Aug 2015 08:48:29 +0900 Subject: [PATCH] Fixed KAlarm event date/time selection for recurrent events. This relates to bug 304. Signed-off-by: Michele Calgaro --- kalarm/editdlg.cpp | 16 ++++--- kalarm/recurrenceedit.cpp | 93 +++++++++++++++++++++++++++++++++++++++ kalarm/recurrenceedit.h | 1 + 3 files changed, 105 insertions(+), 5 deletions(-) diff --git a/kalarm/editdlg.cpp b/kalarm/editdlg.cpp index f6e1f0b0..8e0cbde3 100644 --- a/kalarm/editdlg.cpp +++ b/kalarm/editdlg.cpp @@ -1374,13 +1374,20 @@ void EditAlarmDlg::slotOk() return; } } - if (!checkCommandData() - || !checkEmailData()) + if (!checkCommandData() || !checkEmailData()) return; if (!mTemplate) { if (timedRecurrence) { + // For daily, weekly, monthly and yearly recurrences, check that the + // specified date matches the allowed days of the week + if (!mRecurrenceEdit->validateDate(mAlarmDateTime)) + { + KMessageBox::sorry(this, i18n("The date/time in the Alarm tab does not " + "match the recurrence settings specified in the Recurrence tab.")); + return; + } TQDateTime now = TQDateTime::currentDateTime(); if (mAlarmDateTime.date() < now.date() || mAlarmDateTime.date() == now.date() @@ -1415,7 +1422,7 @@ void EditAlarmDlg::slotOk() KAEvent recurEvent; int longestRecurInterval = -1; int reminder = mReminder->minutes(); - if (reminder && !mReminder->isOnceOnly()) + if (reminder && !mReminder->isOnceOnly()) { mRecurrenceEdit->updateEvent(recurEvent, false); longestRecurInterval = recurEvent.longestRecurrenceInterval(); @@ -1423,8 +1430,7 @@ void EditAlarmDlg::slotOk() { mTabs->setCurrentPage(mMainPageIndex); mReminder->setFocusOnCount(); - KMessageBox::sorry(this, i18n("Reminder period must be less than the recurrence interval, unless '%1' is checked." - ).arg(Reminder::i18n_first_recurrence_only())); + KMessageBox::sorry(this, i18n("Reminder period must be less than the recurrence interval, unless '%1' is checked.").arg(Reminder::i18n_first_recurrence_only())); return; } } diff --git a/kalarm/recurrenceedit.cpp b/kalarm/recurrenceedit.cpp index 4a39022e..1389f54e 100644 --- a/kalarm/recurrenceedit.cpp +++ b/kalarm/recurrenceedit.cpp @@ -530,6 +530,99 @@ void RecurrenceEdit::activateSubRepetition() mSubRepetition->activate(); } +/****************************************************************************** +* For weekly, monthly and yearly recurrence, checks that the specified date +* matches the days allowed. For the other recurrence simply return true. +*/ +bool RecurrenceEdit::validateDate(const DateTime &date) const +{ + if (mRuleButtonType == RecurrenceEdit::DAILY) + { + TQBitArray selectedDays = mDailyRule->days(); + if (!selectedDays[date.date().dayOfWeek()-1]) + return false; + } + else if (mRuleButtonType == RecurrenceEdit::WEEKLY) + { + TQBitArray selectedDays = mWeeklyRule->days(); + if (!selectedDays[date.date().dayOfWeek()-1]) + return false; + } + else if (mRuleButtonType == RecurrenceEdit::MONTHLY) + { + if (mMonthlyRule->type() == MonthYearRule::DATE) + { + // on the nth day of the month + int comboDate = mMonthlyRule->date(); + if ((comboDate > 0 && date.date().day() != comboDate) || + (comboDate <=0 && date.date().day() != date.date().daysInMonth())) + return false; + } + else + { + // on the nth weekday (i.e. Monday) of the month + if (date.date().dayOfWeek() != mMonthlyRule->dayOfWeek()) + return false; + + int monthDay = date.date().day(); + int weekNum = mMonthlyRule->week(); + int minDay = 0, maxDay = 0; + if (weekNum > 0 ) + { + minDay = (weekNum-1) * 7; + maxDay = weekNum * 7; + } + else if (weekNum < 0) + { + int dim = date.date().daysInMonth(); + minDay = dim + weekNum * 7; + maxDay = dim + (weekNum+1) * 7; + } + if (monthDay <= minDay || monthDay > maxDay) + return false; + } + } + else if (mRuleButtonType == RecurrenceEdit::ANNUAL) + { + TQValueList months = mYearlyRule->months(); + if (!months.contains(date.date().month())) + return false; + + if (mYearlyRule->type() == MonthYearRule::DATE) + { + // on the nth day of the month + int comboDate = mYearlyRule->date(); + if ((comboDate > 0 && date.date().day() != comboDate) || + (comboDate <=0 && date.date().day() != date.date().daysInMonth())) + return false; + } + else + { + // on the nth weekday (i.e. Monday) of the month + if (date.date().dayOfWeek() != mYearlyRule->dayOfWeek()) + return false; + + int monthDay = date.date().day(); + int weekNum = mYearlyRule->week(); + int minDay = 0, maxDay = 0; + if (weekNum > 0 ) + { + minDay = (weekNum-1) * 7; + maxDay = weekNum * 7; + } + else if (weekNum < 0) + { + int dim = date.date().daysInMonth(); + minDay = dim + weekNum * 7; + maxDay = dim + (weekNum+1) * 7; + } + if (monthDay <= minDay || monthDay > maxDay) + return false; + } + } + return true; +} + /****************************************************************************** * Called when the value of the repeat count field changes, to reset the * minimum value to 1 if the value was 0. diff --git a/kalarm/recurrenceedit.h b/kalarm/recurrenceedit.h index 82ab954c..cc460afd 100644 --- a/kalarm/recurrenceedit.h +++ b/kalarm/recurrenceedit.h @@ -81,6 +81,7 @@ class RecurrenceEdit : public TQFrame DateTime endDateTime() const; bool stateChanged() const; void activateSubRepetition(); + bool validateDate(const DateTime &date) const; static TQString i18n_Norecur(); // text of 'No recurrence' selection, lower case static TQString i18n_NoRecur(); // text of 'No Recurrence' selection, initial capitals