00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "kalarm.h"
00025
00026 #include <tqtooltip.h>
00027 #include <tqlayout.h>
00028 #include <tqvbox.h>
00029 #include <tqwidgetstack.h>
00030 #include <tqlistbox.h>
00031 #include <tqframe.h>
00032 #include <tqlabel.h>
00033 #include <tqpushbutton.h>
00034 #include <tqlineedit.h>
00035 #include <tqwhatsthis.h>
00036
00037 #include <tdeglobal.h>
00038 #include <tdelocale.h>
00039 #include <kcalendarsystem.h>
00040 #include <kiconloader.h>
00041 #include <kdialog.h>
00042 #include <tdemessagebox.h>
00043 #include <kdebug.h>
00044
00045 #include <libkcal/event.h>
00046
00047 #include "alarmevent.h"
00048 #include "alarmtimewidget.h"
00049 #include "checkbox.h"
00050 #include "combobox.h"
00051 #include "dateedit.h"
00052 #include "functions.h"
00053 #include "kalarmapp.h"
00054 #include "karecurrence.h"
00055 #include "preferences.h"
00056 #include "radiobutton.h"
00057 #include "repetition.h"
00058 #include "spinbox.h"
00059 #include "timeedit.h"
00060 #include "timespinbox.h"
00061 #include "buttongroup.h"
00062 using namespace KCal;
00063
00064 #include "recurrenceedit.moc"
00065 #include "recurrenceeditprivate.moc"
00066
00067
00068
00069 TQString RecurrenceEdit::i18n_Norecur() { return i18n("No recurrence"); }
00070 TQString RecurrenceEdit::i18n_NoRecur() { return i18n("No Recurrence"); }
00071 TQString RecurrenceEdit::i18n_AtLogin() { return i18n("At Login"); }
00072 TQString RecurrenceEdit::i18n_l_Atlogin() { return i18n("At &login"); }
00073 TQString RecurrenceEdit::i18n_HourlyMinutely() { return i18n("Hourly/Minutely"); }
00074 TQString RecurrenceEdit::i18n_u_HourlyMinutely() { return i18n("Ho&urly/Minutely"); }
00075 TQString RecurrenceEdit::i18n_Daily() { return i18n("Daily"); }
00076 TQString RecurrenceEdit::i18n_d_Daily() { return i18n("&Daily"); }
00077 TQString RecurrenceEdit::i18n_Weekly() { return i18n("Weekly"); }
00078 TQString RecurrenceEdit::i18n_w_Weekly() { return i18n("&Weekly"); }
00079 TQString RecurrenceEdit::i18n_Monthly() { return i18n("Monthly"); }
00080 TQString RecurrenceEdit::i18n_m_Monthly() { return i18n("&Monthly"); }
00081 TQString RecurrenceEdit::i18n_Yearly() { return i18n("Yearly"); }
00082 TQString RecurrenceEdit::i18n_y_Yearly() { return i18n("&Yearly"); }
00083
00084
00085 RecurrenceEdit::RecurrenceEdit(bool readOnly, TQWidget* parent, const char* name)
00086 : TQFrame(parent, name),
00087 mRule(0),
00088 mRuleButtonType(INVALID_RECUR),
00089 mDailyShown(false),
00090 mWeeklyShown(false),
00091 mMonthlyShown(false),
00092 mYearlyShown(false),
00093 mNoEmitTypeChanged(true),
00094 mReadOnly(readOnly)
00095 {
00096 TQBoxLayout* layout;
00097 TQVBoxLayout* topLayout = new TQVBoxLayout(this, 0, KDialog::spacingHint());
00098
00099
00100
00101
00102
00103
00104
00105
00106 TQGroupBox* recurGroup = new TQGroupBox(1, Qt::Vertical, i18n("Recurrence Rule"), this, "recurGroup");
00107 topLayout->addWidget(recurGroup);
00108 TQFrame* ruleFrame = new TQFrame(recurGroup, "ruleFrame");
00109 layout = new TQVBoxLayout(ruleFrame, 0);
00110 layout->addSpacing(KDialog::spacingHint()/2);
00111
00112 layout = new TQHBoxLayout(layout, 0);
00113 TQBoxLayout* lay = new TQVBoxLayout(layout, 0);
00114 mRuleButtonGroup = new ButtonGroup(1, Qt::Horizontal, ruleFrame);
00115 mRuleButtonGroup->setInsideMargin(0);
00116 mRuleButtonGroup->setFrameStyle(TQFrame::NoFrame);
00117 lay->addWidget(mRuleButtonGroup);
00118 lay->addStretch();
00119 connect(mRuleButtonGroup, TQT_SIGNAL(buttonSet(int)), TQT_SLOT(periodClicked(int)));
00120
00121 mNoneButton = new RadioButton(i18n_Norecur(), mRuleButtonGroup);
00122 mNoneButton->setFixedSize(mNoneButton->sizeHint());
00123 mNoneButton->setReadOnly(mReadOnly);
00124 TQWhatsThis::add(mNoneButton, i18n("Do not repeat the alarm"));
00125
00126 mAtLoginButton = new RadioButton(i18n_l_Atlogin(), mRuleButtonGroup);
00127 mAtLoginButton->setFixedSize(mAtLoginButton->sizeHint());
00128 mAtLoginButton->setReadOnly(mReadOnly);
00129 TQWhatsThis::add(mAtLoginButton,
00130 i18n("Trigger the alarm at the specified date/time and at every login until then.\n"
00131 "Note that it will also be triggered any time the alarm daemon is restarted."));
00132
00133 mSubDailyButton = new RadioButton(i18n_u_HourlyMinutely(), mRuleButtonGroup);
00134 mSubDailyButton->setFixedSize(mSubDailyButton->sizeHint());
00135 mSubDailyButton->setReadOnly(mReadOnly);
00136 TQWhatsThis::add(mSubDailyButton,
00137 i18n("Repeat the alarm at hourly/minutely intervals"));
00138
00139 mDailyButton = new RadioButton(i18n_d_Daily(), mRuleButtonGroup);
00140 mDailyButton->setFixedSize(mDailyButton->sizeHint());
00141 mDailyButton->setReadOnly(mReadOnly);
00142 TQWhatsThis::add(mDailyButton,
00143 i18n("Repeat the alarm at daily intervals"));
00144
00145 mWeeklyButton = new RadioButton(i18n_w_Weekly(), mRuleButtonGroup);
00146 mWeeklyButton->setFixedSize(mWeeklyButton->sizeHint());
00147 mWeeklyButton->setReadOnly(mReadOnly);
00148 TQWhatsThis::add(mWeeklyButton,
00149 i18n("Repeat the alarm at weekly intervals"));
00150
00151 mMonthlyButton = new RadioButton(i18n_m_Monthly(), mRuleButtonGroup);
00152 mMonthlyButton->setFixedSize(mMonthlyButton->sizeHint());
00153 mMonthlyButton->setReadOnly(mReadOnly);
00154 TQWhatsThis::add(mMonthlyButton,
00155 i18n("Repeat the alarm at monthly intervals"));
00156
00157 mYearlyButton = new RadioButton(i18n_y_Yearly(), mRuleButtonGroup);
00158 mYearlyButton->setFixedSize(mYearlyButton->sizeHint());
00159 mYearlyButton->setReadOnly(mReadOnly);
00160 TQWhatsThis::add(mYearlyButton,
00161 i18n("Repeat the alarm at annual intervals"));
00162
00163 mNoneButtonId = mRuleButtonGroup->id(mNoneButton);
00164 mAtLoginButtonId = mRuleButtonGroup->id(mAtLoginButton);
00165 mSubDailyButtonId = mRuleButtonGroup->id(mSubDailyButton);
00166 mDailyButtonId = mRuleButtonGroup->id(mDailyButton);
00167 mWeeklyButtonId = mRuleButtonGroup->id(mWeeklyButton);
00168 mMonthlyButtonId = mRuleButtonGroup->id(mMonthlyButton);
00169 mYearlyButtonId = mRuleButtonGroup->id(mYearlyButton);
00170
00171
00172 mSubRepetition = new RepetitionButton(i18n("Sub-Repetition"), true, ruleFrame);
00173 mSubRepetition->setFixedSize(mSubRepetition->sizeHint());
00174 mSubRepetition->setReadOnly(mReadOnly);
00175 connect(mSubRepetition, TQT_SIGNAL(needsInitialisation()), TQT_SIGNAL(repeatNeedsInitialisation()));
00176 connect(mSubRepetition, TQT_SIGNAL(changed()), TQT_SIGNAL(frequencyChanged()));
00177 TQWhatsThis::add(mSubRepetition, i18n("Set up a repetition within the recurrence, to trigger the alarm multiple times each time the recurrence is due."));
00178 lay->addSpacing(KDialog::spacingHint());
00179 lay->addWidget(mSubRepetition);
00180
00181 lay = new TQVBoxLayout(layout);
00182
00183 lay->addStretch();
00184 layout = new TQHBoxLayout(lay);
00185
00186 layout->addSpacing(KDialog::marginHint());
00187 TQFrame* divider = new TQFrame(ruleFrame);
00188 divider->setFrameStyle(TQFrame::VLine | TQFrame::Sunken);
00189 layout->addWidget(divider);
00190 layout->addSpacing(KDialog::marginHint());
00191
00192 mNoRule = new NoRule(ruleFrame, "noFrame");
00193 mSubDailyRule = new SubDailyRule(mReadOnly, ruleFrame, "subdayFrame");
00194 mDailyRule = new DailyRule(mReadOnly, ruleFrame, "dayFrame");
00195 mWeeklyRule = new WeeklyRule(mReadOnly, ruleFrame, "weekFrame");
00196 mMonthlyRule = new MonthlyRule(mReadOnly, ruleFrame, "monthFrame");
00197 mYearlyRule = new YearlyRule(mReadOnly, ruleFrame, "yearFrame");
00198
00199 connect(mSubDailyRule, TQT_SIGNAL(frequencyChanged()), this, TQT_SIGNAL(frequencyChanged()));
00200 connect(mDailyRule, TQT_SIGNAL(frequencyChanged()), this, TQT_SIGNAL(frequencyChanged()));
00201 connect(mWeeklyRule, TQT_SIGNAL(frequencyChanged()), this, TQT_SIGNAL(frequencyChanged()));
00202 connect(mMonthlyRule, TQT_SIGNAL(frequencyChanged()), this, TQT_SIGNAL(frequencyChanged()));
00203 connect(mYearlyRule, TQT_SIGNAL(frequencyChanged()), this, TQT_SIGNAL(frequencyChanged()));
00204
00205 mRuleStack = new TQWidgetStack(ruleFrame);
00206 layout->addWidget(mRuleStack);
00207 layout->addStretch(1);
00208 mRuleStack->addWidget(mNoRule, 0);
00209 mRuleStack->addWidget(mSubDailyRule, 1);
00210 mRuleStack->addWidget(mDailyRule, 2);
00211 mRuleStack->addWidget(mWeeklyRule, 3);
00212 mRuleStack->addWidget(mMonthlyRule, 4);
00213 mRuleStack->addWidget(mYearlyRule, 5);
00214 layout->addSpacing(KDialog::marginHint());
00215
00216
00217
00218
00219 mRangeButtonGroup = new ButtonGroup(i18n("Recurrence End"), this, "mRangeButtonGroup");
00220 connect(mRangeButtonGroup, TQT_SIGNAL(buttonSet(int)), TQT_SLOT(rangeTypeClicked()));
00221 topLayout->addWidget(mRangeButtonGroup);
00222
00223 TQVBoxLayout* vlayout = new TQVBoxLayout(mRangeButtonGroup, KDialog::marginHint(), KDialog::spacingHint());
00224 vlayout->addSpacing(fontMetrics().lineSpacing()/2);
00225 mNoEndDateButton = new RadioButton(i18n("No &end"), mRangeButtonGroup);
00226 mNoEndDateButton->setFixedSize(mNoEndDateButton->sizeHint());
00227 mNoEndDateButton->setReadOnly(mReadOnly);
00228 TQWhatsThis::add(mNoEndDateButton, i18n("Repeat the alarm indefinitely"));
00229 vlayout->addWidget(mNoEndDateButton, 1, TQt::AlignAuto);
00230 TQSize size = mNoEndDateButton->size();
00231
00232 layout = new TQHBoxLayout(vlayout, KDialog::spacingHint());
00233 mRepeatCountButton = new RadioButton(i18n("End a&fter:"), mRangeButtonGroup);
00234 mRepeatCountButton->setReadOnly(mReadOnly);
00235 TQWhatsThis::add(mRepeatCountButton,
00236 i18n("Repeat the alarm for the number of times specified"));
00237 mRepeatCountEntry = new SpinBox(1, 9999, 1, mRangeButtonGroup);
00238 mRepeatCountEntry->setFixedSize(mRepeatCountEntry->sizeHint());
00239 mRepeatCountEntry->setLineShiftStep(10);
00240 mRepeatCountEntry->setSelectOnStep(false);
00241 mRepeatCountEntry->setReadOnly(mReadOnly);
00242 connect(mRepeatCountEntry, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(repeatCountChanged(int)));
00243 TQWhatsThis::add(mRepeatCountEntry,
00244 i18n("Enter the total number of times to trigger the alarm"));
00245 mRepeatCountButton->setFocusWidget(mRepeatCountEntry);
00246 mRepeatCountLabel = new TQLabel(i18n("occurrence(s)"), mRangeButtonGroup);
00247 mRepeatCountLabel->setFixedSize(mRepeatCountLabel->sizeHint());
00248 layout->addWidget(mRepeatCountButton);
00249 layout->addSpacing(KDialog::spacingHint());
00250 layout->addWidget(mRepeatCountEntry);
00251 layout->addWidget(mRepeatCountLabel);
00252 layout->addStretch();
00253 size = size.expandedTo(mRepeatCountButton->sizeHint());
00254
00255 layout = new TQHBoxLayout(vlayout, KDialog::spacingHint());
00256 mEndDateButton = new RadioButton(i18n("End &by:"), mRangeButtonGroup);
00257 mEndDateButton->setReadOnly(mReadOnly);
00258 TQWhatsThis::add(mEndDateButton,
00259 i18n("Repeat the alarm until the date/time specified.\n\n"
00260 "Note: This applies to the main recurrence only. It does not limit any sub-repetition which will occur regardless after the last main recurrence."));
00261 mEndDateEdit = new DateEdit(mRangeButtonGroup);
00262 mEndDateEdit->setFixedSize(mEndDateEdit->sizeHint());
00263 mEndDateEdit->setReadOnly(mReadOnly);
00264 TQWhatsThis::add(mEndDateEdit,
00265 i18n("Enter the last date to repeat the alarm"));
00266 mEndDateButton->setFocusWidget(mEndDateEdit);
00267 mEndTimeEdit = new TimeEdit(mRangeButtonGroup);
00268 mEndTimeEdit->setFixedSize(mEndTimeEdit->sizeHint());
00269 mEndTimeEdit->setReadOnly(mReadOnly);
00270 static const TQString lastTimeText = i18n("Enter the last time to repeat the alarm.");
00271 TQWhatsThis::add(mEndTimeEdit, TQString("%1\n\n%2").arg(lastTimeText).arg(TimeSpinBox::shiftWhatsThis()));
00272 mEndAnyTimeCheckBox = new CheckBox(i18n("Any time"), mRangeButtonGroup);
00273 mEndAnyTimeCheckBox->setFixedSize(mEndAnyTimeCheckBox->sizeHint());
00274 mEndAnyTimeCheckBox->setReadOnly(mReadOnly);
00275 connect(mEndAnyTimeCheckBox, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotAnyTimeToggled(bool)));
00276 TQWhatsThis::add(mEndAnyTimeCheckBox,
00277 i18n("Stop repeating the alarm after your first login on or after the specified end date"));
00278 layout->addWidget(mEndDateButton);
00279 layout->addSpacing(KDialog::spacingHint());
00280 layout->addWidget(mEndDateEdit);
00281 layout->addWidget(mEndTimeEdit);
00282 layout->addWidget(mEndAnyTimeCheckBox);
00283 layout->addStretch();
00284 size = size.expandedTo(mEndDateButton->sizeHint());
00285
00286
00287 mRepeatCountButton->setFixedSize(size);
00288 mEndDateButton->setFixedSize(size);
00289
00290
00291
00292
00293 mExceptionGroup = new TQGroupBox(i18n("E&xceptions"), this, "mExceptionGroup");
00294 topLayout->addWidget(mExceptionGroup);
00295 topLayout->setStretchFactor(mExceptionGroup, 2);
00296 vlayout = new TQVBoxLayout(mExceptionGroup, KDialog::marginHint(), KDialog::spacingHint());
00297 vlayout->addSpacing(fontMetrics().lineSpacing()/2);
00298 layout = new TQHBoxLayout(vlayout, KDialog::spacingHint());
00299 vlayout = new TQVBoxLayout(layout);
00300
00301 mExceptionDateList = new TQListBox(mExceptionGroup);
00302 mExceptionDateList->setSizePolicy(TQSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Expanding));
00303 connect(mExceptionDateList, TQT_SIGNAL(selectionChanged()), TQT_SLOT(enableExceptionButtons()));
00304 TQWhatsThis::add(mExceptionDateList,
00305 i18n("The list of exceptions, i.e. dates/times excluded from the recurrence"));
00306 vlayout->addWidget(mExceptionDateList);
00307
00308 if (mReadOnly)
00309 {
00310 mExceptionDateEdit = 0;
00311 mChangeExceptionButton = 0;
00312 mDeleteExceptionButton = 0;
00313 }
00314 else
00315 {
00316 vlayout = new TQVBoxLayout(layout);
00317 mExceptionDateEdit = new DateEdit(mExceptionGroup);
00318 mExceptionDateEdit->setFixedSize(mExceptionDateEdit->sizeHint());
00319 mExceptionDateEdit->setDate(TQDate::currentDate());
00320 TQWhatsThis::add(mExceptionDateEdit,
00321 i18n("Enter a date to insert in the exceptions list. "
00322 "Use in conjunction with the Add or Change button below."));
00323 vlayout->addWidget(mExceptionDateEdit);
00324
00325 layout = new TQHBoxLayout(vlayout, KDialog::spacingHint());
00326 TQPushButton* button = new TQPushButton(i18n("Add"), mExceptionGroup);
00327 button->setFixedSize(button->sizeHint());
00328 connect(button, TQT_SIGNAL(clicked()), TQT_SLOT(addException()));
00329 TQWhatsThis::add(button,
00330 i18n("Add the date entered above to the exceptions list"));
00331 layout->addWidget(button);
00332
00333 mChangeExceptionButton = new TQPushButton(i18n("Change"), mExceptionGroup);
00334 mChangeExceptionButton->setFixedSize(mChangeExceptionButton->sizeHint());
00335 connect(mChangeExceptionButton, TQT_SIGNAL(clicked()), TQT_SLOT(changeException()));
00336 TQWhatsThis::add(mChangeExceptionButton,
00337 i18n("Replace the currently highlighted item in the exceptions list with the date entered above"));
00338 layout->addWidget(mChangeExceptionButton);
00339
00340 mDeleteExceptionButton = new TQPushButton(i18n("Delete"), mExceptionGroup);
00341 mDeleteExceptionButton->setFixedSize(mDeleteExceptionButton->sizeHint());
00342 connect(mDeleteExceptionButton, TQT_SIGNAL(clicked()), TQT_SLOT(deleteException()));
00343 TQWhatsThis::add(mDeleteExceptionButton,
00344 i18n("Remove the currently highlighted item from the exceptions list"));
00345 layout->addWidget(mDeleteExceptionButton);
00346 }
00347
00348 mNoEmitTypeChanged = false;
00349 }
00350
00351
00352
00353
00354
00355 TQWidget* RecurrenceEdit::checkData(const TQDateTime& startDateTime, TQString& errorMessage) const
00356 {
00357 if (mAtLoginButton->isOn())
00358 return 0;
00359 const_cast<RecurrenceEdit*>(this)->mCurrStartDateTime = startDateTime;
00360 if (mEndDateButton->isChecked())
00361 {
00362 TQWidget* errWidget = 0;
00363 bool noTime = !mEndTimeEdit->isEnabled();
00364 TQDate endDate = mEndDateEdit->date();
00365 if (endDate < startDateTime.date())
00366 errWidget = mEndDateEdit;
00367 else if (!noTime && TQDateTime(endDate, mEndTimeEdit->time()) < startDateTime)
00368 errWidget = mEndTimeEdit;
00369 if (errWidget)
00370 {
00371 errorMessage = noTime
00372 ? i18n("End date is earlier than start date")
00373 : i18n("End date/time is earlier than start date/time");
00374 return errWidget;
00375 }
00376 }
00377 if (!mRule)
00378 return 0;
00379 return mRule->validate(errorMessage);
00380 }
00381
00382
00383
00384
00385 void RecurrenceEdit::periodClicked(int id)
00386 {
00387 RepeatType oldType = mRuleButtonType;
00388 bool none = (id == mNoneButtonId);
00389 bool atLogin = (id == mAtLoginButtonId);
00390 bool subdaily = (id == mSubDailyButtonId);
00391 if (none)
00392 {
00393 mRule = 0;
00394 mRuleButtonType = NO_RECUR;
00395 }
00396 else if (atLogin)
00397 {
00398 mRule = 0;
00399 mRuleButtonType = AT_LOGIN;
00400 mRangeButtonGroup->setButton(mRangeButtonGroup->id(mEndDateButton));
00401 }
00402 else if (subdaily)
00403 {
00404 mRule = mSubDailyRule;
00405 mRuleButtonType = SUBDAILY;
00406 }
00407 else if (id == mDailyButtonId)
00408 {
00409 mRule = mDailyRule;
00410 mRuleButtonType = DAILY;
00411 mDailyShown = true;
00412 }
00413 else if (id == mWeeklyButtonId)
00414 {
00415 mRule = mWeeklyRule;
00416 mRuleButtonType = WEEKLY;
00417 mWeeklyShown = true;
00418 }
00419 else if (id == mMonthlyButtonId)
00420 {
00421 mRule = mMonthlyRule;
00422 mRuleButtonType = MONTHLY;
00423 mMonthlyShown = true;
00424 }
00425 else if (id == mYearlyButtonId)
00426 {
00427 mRule = mYearlyRule;
00428 mRuleButtonType = ANNUAL;
00429 mYearlyShown = true;
00430 }
00431 else
00432 return;
00433
00434 if (mRuleButtonType != oldType)
00435 {
00436 mRuleStack->raiseWidget(mRule ? mRule : mNoRule);
00437 if (oldType == NO_RECUR || none)
00438 mRangeButtonGroup->setEnabled(!none);
00439 mExceptionGroup->setEnabled(!(none || atLogin));
00440 mEndAnyTimeCheckBox->setEnabled(atLogin);
00441 if (!none)
00442 {
00443 mNoEndDateButton->setEnabled(!atLogin);
00444 mRepeatCountButton->setEnabled(!atLogin);
00445 }
00446 rangeTypeClicked();
00447 mSubRepetition->setEnabled(!(none || atLogin));
00448 if (!mNoEmitTypeChanged)
00449 emit typeChanged(mRuleButtonType);
00450 }
00451 }
00452
00453 void RecurrenceEdit::slotAnyTimeToggled(bool on)
00454 {
00455 TQButton* button = mRuleButtonGroup->selected();
00456 mEndTimeEdit->setEnabled((button == mAtLoginButton && !on)
00457 || (button == mSubDailyButton && mEndDateButton->isChecked()));
00458 }
00459
00460
00461
00462
00463 void RecurrenceEdit::rangeTypeClicked()
00464 {
00465 bool endDate = mEndDateButton->isOn();
00466 mEndDateEdit->setEnabled(endDate);
00467 mEndTimeEdit->setEnabled(endDate
00468 && ((mAtLoginButton->isOn() && !mEndAnyTimeCheckBox->isChecked())
00469 || mSubDailyButton->isOn()));
00470 bool repeatCount = mRepeatCountButton->isOn();
00471 mRepeatCountEntry->setEnabled(repeatCount);
00472 mRepeatCountLabel->setEnabled(repeatCount);
00473 }
00474
00475 void RecurrenceEdit::showEvent(TQShowEvent*)
00476 {
00477 if (mRule)
00478 mRule->setFrequencyFocus();
00479 else
00480 mRuleButtonGroup->selected()->setFocus();
00481 emit shown();
00482 }
00483
00484
00485
00486
00487
00488 int RecurrenceEdit::subRepeatCount(int* subRepeatInterval) const
00489 {
00490 int count = (mRuleButtonType >= SUBDAILY) ? mSubRepetition->count() : 0;
00491 if (subRepeatInterval)
00492 *subRepeatInterval = count ? mSubRepetition->interval() : 0;
00493 return count;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 void RecurrenceEdit::setSubRepetition(int reminderMinutes, bool dateOnly)
00505 {
00506 int maxDuration;
00507 switch (mRuleButtonType)
00508 {
00509 case RecurrenceEdit::NO_RECUR:
00510 case RecurrenceEdit::AT_LOGIN:
00511 maxDuration = 0;
00512 break;
00513 default:
00514 {
00515 KAEvent event;
00516 updateEvent(event, false);
00517 maxDuration = event.longestRecurrenceInterval() - reminderMinutes - 1;
00518 break;
00519 }
00520 }
00521 mSubRepetition->initialise(mSubRepetition->interval(), mSubRepetition->count(), dateOnly, maxDuration);
00522 mSubRepetition->setEnabled(mRuleButtonType >= SUBDAILY && maxDuration);
00523 }
00524
00525
00526
00527
00528 void RecurrenceEdit::activateSubRepetition()
00529 {
00530 mSubRepetition->activate();
00531 }
00532
00533
00534
00535
00536
00537 bool RecurrenceEdit::validateDate(const DateTime &date) const
00538 {
00539 if (mRuleButtonType == RecurrenceEdit::DAILY)
00540 {
00541 TQBitArray selectedDays = mDailyRule->days();
00542 if (!selectedDays[date.date().dayOfWeek()-1])
00543 return false;
00544 }
00545 else if (mRuleButtonType == RecurrenceEdit::WEEKLY)
00546 {
00547 TQBitArray selectedDays = mWeeklyRule->days();
00548 if (!selectedDays[date.date().dayOfWeek()-1])
00549 return false;
00550 }
00551 else if (mRuleButtonType == RecurrenceEdit::MONTHLY)
00552 {
00553 if (mMonthlyRule->type() == MonthYearRule::DATE)
00554 {
00555
00556 int comboDate = mMonthlyRule->date();
00557 if ((comboDate > 0 && date.date().day() != comboDate) ||
00558 (comboDate <=0 && date.date().day() != date.date().daysInMonth()))
00559 return false;
00560 }
00561 else
00562 {
00563
00564 if (date.date().dayOfWeek() != mMonthlyRule->dayOfWeek())
00565 return false;
00566
00567 int monthDay = date.date().day();
00568 int weekNum = mMonthlyRule->week();
00569 int minDay = 0, maxDay = 0;
00570 if (weekNum > 0 )
00571 {
00572 minDay = (weekNum-1) * 7;
00573 maxDay = weekNum * 7;
00574 }
00575 else if (weekNum < 0)
00576 {
00577 int dim = date.date().daysInMonth();
00578 minDay = dim + weekNum * 7;
00579 maxDay = dim + (weekNum+1) * 7;
00580 }
00581 if (monthDay <= minDay || monthDay > maxDay)
00582 return false;
00583 }
00584 }
00585 else if (mRuleButtonType == RecurrenceEdit::ANNUAL)
00586 {
00587 TQValueList<int> months = mYearlyRule->months();
00588 if (!months.contains(date.date().month()))
00589 return false;
00590
00591 if (mYearlyRule->type() == MonthYearRule::DATE)
00592 {
00593
00594 int comboDate = mYearlyRule->date();
00595 if ((comboDate > 0 && date.date().day() != comboDate) ||
00596 (comboDate <=0 && date.date().day() != date.date().daysInMonth()))
00597 return false;
00598 }
00599 else
00600 {
00601
00602 if (date.date().dayOfWeek() != mYearlyRule->dayOfWeek())
00603 return false;
00604
00605 int monthDay = date.date().day();
00606 int weekNum = mYearlyRule->week();
00607 int minDay = 0, maxDay = 0;
00608 if (weekNum > 0 )
00609 {
00610 minDay = (weekNum-1) * 7;
00611 maxDay = weekNum * 7;
00612 }
00613 else if (weekNum < 0)
00614 {
00615 int dim = date.date().daysInMonth();
00616 minDay = dim + weekNum * 7;
00617 maxDay = dim + (weekNum+1) * 7;
00618 }
00619 if (monthDay <= minDay || monthDay > maxDay)
00620 return false;
00621 }
00622 }
00623 return true;
00624 }
00625
00626
00627
00628
00629
00630 void RecurrenceEdit::repeatCountChanged(int value)
00631 {
00632 if (value > 0 && mRepeatCountEntry->minValue() == 0)
00633 mRepeatCountEntry->setMinValue(1);
00634 }
00635
00636
00637
00638
00639
00640 void RecurrenceEdit::addException()
00641 {
00642 if (!mExceptionDateEdit || !mExceptionDateEdit->isValid())
00643 return;
00644 TQDate date = mExceptionDateEdit->date();
00645 TQValueList<TQDate>::Iterator it;
00646 int index = 0;
00647 bool insert = true;
00648 for (it = mExceptionDates.begin(); it != mExceptionDates.end(); ++index, ++it)
00649 {
00650 if (date <= *it)
00651 {
00652 insert = (date != *it);
00653 break;
00654 }
00655 }
00656 if (insert)
00657 {
00658 mExceptionDates.insert(it, date);
00659 mExceptionDateList->insertItem(TDEGlobal::locale()->formatDate(date), index);
00660 }
00661 mExceptionDateList->setCurrentItem(index);
00662 enableExceptionButtons();
00663 }
00664
00665
00666
00667
00668
00669 void RecurrenceEdit::changeException()
00670 {
00671 if (!mExceptionDateEdit || !mExceptionDateEdit->isValid())
00672 return;
00673 int index = mExceptionDateList->currentItem();
00674 if (index >= 0 && mExceptionDateList->isSelected(index))
00675 {
00676 TQDate olddate = mExceptionDates[index];
00677 TQDate newdate = mExceptionDateEdit->date();
00678 if (newdate != olddate)
00679 {
00680 mExceptionDates.remove(mExceptionDates.at(index));
00681 mExceptionDateList->removeItem(index);
00682 addException();
00683 }
00684 }
00685 }
00686
00687
00688
00689
00690 void RecurrenceEdit::deleteException()
00691 {
00692 int index = mExceptionDateList->currentItem();
00693 if (index >= 0 && mExceptionDateList->isSelected(index))
00694 {
00695 mExceptionDates.remove(mExceptionDates.at(index));
00696 mExceptionDateList->removeItem(index);
00697 enableExceptionButtons();
00698 }
00699 }
00700
00701
00702
00703
00704
00705 void RecurrenceEdit::enableExceptionButtons()
00706 {
00707 int index = mExceptionDateList->currentItem();
00708 bool enable = (index >= 0 && mExceptionDateList->isSelected(index));
00709 if (mDeleteExceptionButton)
00710 mDeleteExceptionButton->setEnabled(enable);
00711 if (mChangeExceptionButton)
00712 mChangeExceptionButton->setEnabled(enable);
00713
00714
00715 mExceptionDateList->setFocusPolicy(mExceptionDateList->count() ? TQ_WheelFocus : TQ_NoFocus);
00716 }
00717
00718
00719
00720
00721 void RecurrenceEdit::setStartDate(const TQDate& start, const TQDate& today)
00722 {
00723 if (!mReadOnly)
00724 {
00725 setRuleDefaults(start);
00726 if (start < today)
00727 {
00728 mEndDateEdit->setMinDate(today);
00729 if (mExceptionDateEdit)
00730 mExceptionDateEdit->setMinDate(today);
00731 }
00732 else
00733 {
00734 const TQString startString = i18n("Date cannot be earlier than start date", "start date");
00735 mEndDateEdit->setMinDate(start, startString);
00736 if (mExceptionDateEdit)
00737 mExceptionDateEdit->setMinDate(start, startString);
00738 }
00739 }
00740 }
00741
00742
00743
00744
00745 void RecurrenceEdit::setDefaultEndDate(const TQDate& end)
00746 {
00747 if (!mEndDateButton->isOn())
00748 mEndDateEdit->setDate(end);
00749 }
00750
00751 void RecurrenceEdit::setEndDateTime(const DateTime& end)
00752 {
00753 mEndDateEdit->setDate(end.date());
00754 mEndTimeEdit->setValue(end.time());
00755 mEndTimeEdit->setEnabled(!end.isDateOnly());
00756 mEndAnyTimeCheckBox->setChecked(end.isDateOnly());
00757 }
00758
00759 DateTime RecurrenceEdit::endDateTime() const
00760 {
00761 if (mRuleButtonGroup->selected() == mAtLoginButton && mEndAnyTimeCheckBox->isChecked())
00762 return DateTime(mEndDateEdit->date());
00763 return DateTime(mEndDateEdit->date(), mEndTimeEdit->time());
00764 }
00765
00766
00767
00768
00769 void RecurrenceEdit::setDefaults(const TQDateTime& from)
00770 {
00771 mCurrStartDateTime = from;
00772 TQDate fromDate = from.date();
00773 mNoEndDateButton->setChecked(true);
00774
00775 mSubDailyRule->setFrequency(1);
00776 mDailyRule->setFrequency(1);
00777 mWeeklyRule->setFrequency(1);
00778 mMonthlyRule->setFrequency(1);
00779 mYearlyRule->setFrequency(1);
00780
00781 setRuleDefaults(fromDate);
00782 mMonthlyRule->setType(MonthYearRule::DATE);
00783 mYearlyRule->setType(MonthYearRule::DATE);
00784
00785 mEndDateEdit->setDate(fromDate);
00786
00787 mNoEmitTypeChanged = true;
00788 int button;
00789 switch (Preferences::defaultRecurPeriod())
00790 {
00791 case AT_LOGIN: button = mAtLoginButtonId; break;
00792 case ANNUAL: button = mYearlyButtonId; break;
00793 case MONTHLY: button = mMonthlyButtonId; break;
00794 case WEEKLY: button = mWeeklyButtonId; break;
00795 case DAILY: button = mDailyButtonId; break;
00796 case SUBDAILY: button = mSubDailyButtonId; break;
00797 case NO_RECUR:
00798 default: button = mNoneButtonId; break;
00799 }
00800 mRuleButtonGroup->setButton(button);
00801 mNoEmitTypeChanged = false;
00802 rangeTypeClicked();
00803 enableExceptionButtons();
00804
00805 saveState();
00806 }
00807
00808
00809
00810
00811
00812 void RecurrenceEdit::setRuleDefaults(const TQDate& fromDate)
00813 {
00814 int day = fromDate.day();
00815 int dayOfWeek = fromDate.dayOfWeek();
00816 int month = fromDate.month();
00817 if (!mDailyShown)
00818 mDailyRule->setDays(true);
00819 if (!mWeeklyShown)
00820 mWeeklyRule->setDay(dayOfWeek);
00821 if (!mMonthlyShown)
00822 mMonthlyRule->setDefaultValues(day, dayOfWeek);
00823 if (!mYearlyShown)
00824 mYearlyRule->setDefaultValues(day, dayOfWeek, month);
00825 }
00826
00827
00828
00829
00830
00831
00832 void RecurrenceEdit::set(const KAEvent& event, bool keepDuration)
00833 {
00834 setDefaults(event.mainDateTime().dateTime());
00835 if (event.repeatAtLogin())
00836 {
00837 mRuleButtonGroup->setButton(mAtLoginButtonId);
00838 mEndDateButton->setChecked(true);
00839 return;
00840 }
00841 mRuleButtonGroup->setButton(mNoneButtonId);
00842 KARecurrence* recurrence = event.recurrence();
00843 if (!recurrence)
00844 return;
00845 KARecurrence::Type rtype = recurrence->type();
00846 switch (rtype)
00847 {
00848 case KARecurrence::MINUTELY:
00849 mRuleButtonGroup->setButton(mSubDailyButtonId);
00850 break;
00851
00852 case KARecurrence::DAILY:
00853 {
00854 mRuleButtonGroup->setButton(mDailyButtonId);
00855 TQBitArray rDays = recurrence->days();
00856 bool set = false;
00857 for (int i = 0; i < 7 && !set; ++i)
00858 set = rDays.testBit(i);
00859 if (set)
00860 mDailyRule->setDays(rDays);
00861 else
00862 mDailyRule->setDays(true);
00863 break;
00864 }
00865 case KARecurrence::WEEKLY:
00866 {
00867 mRuleButtonGroup->setButton(mWeeklyButtonId);
00868 TQBitArray rDays = recurrence->days();
00869 mWeeklyRule->setDays(rDays);
00870 break;
00871 }
00872 case KARecurrence::MONTHLY_POS:
00873 {
00874 TQValueList<RecurrenceRule::WDayPos> posns = recurrence->monthPositions();
00875 int i = posns.first().pos();
00876 if (!i)
00877 {
00878
00879
00880 mRuleButtonGroup->setButton(mWeeklyButtonId);
00881 mWeeklyRule->setFrequency(recurrence->frequency());
00882 TQBitArray rDays(7);
00883 for (TQValueList<RecurrenceRule::WDayPos>::ConstIterator it = posns.begin(); it != posns.end(); ++it)
00884 {
00885 if (!(*it).pos())
00886 rDays.setBit((*it).day() - 1, 1);
00887 }
00888 mWeeklyRule->setDays(rDays);
00889 break;
00890 }
00891 mRuleButtonGroup->setButton(mMonthlyButtonId);
00892 mMonthlyRule->setPosition(i, posns.first().day());
00893 break;
00894 }
00895 case KARecurrence::MONTHLY_DAY:
00896 {
00897 mRuleButtonGroup->setButton(mMonthlyButtonId);
00898 TQValueList<int> rmd = recurrence->monthDays();
00899 int day = (rmd.isEmpty()) ? event.mainDate().day() : rmd.first();
00900 mMonthlyRule->setDate(day);
00901 break;
00902 }
00903 case KARecurrence::ANNUAL_DATE:
00904 case KARecurrence::ANNUAL_POS:
00905 {
00906 if (rtype == KARecurrence::ANNUAL_DATE)
00907 {
00908 mRuleButtonGroup->setButton(mYearlyButtonId);
00909 const TQValueList<int> rmd = recurrence->monthDays();
00910 int day = (rmd.isEmpty()) ? event.mainDate().day() : rmd.first();
00911 mYearlyRule->setDate(day);
00912 mYearlyRule->setFeb29Type(recurrence->feb29Type());
00913 }
00914 else if (rtype == KARecurrence::ANNUAL_POS)
00915 {
00916 mRuleButtonGroup->setButton(mYearlyButtonId);
00917 TQValueList<RecurrenceRule::WDayPos> posns = recurrence->yearPositions();
00918 mYearlyRule->setPosition(posns.first().pos(), posns.first().day());
00919 }
00920 mYearlyRule->setMonths(recurrence->yearMonths());
00921 break;
00922 }
00923 default:
00924 return;
00925 }
00926
00927 mRule->setFrequency(recurrence->frequency());
00928
00929
00930 TQDateTime endtime = mCurrStartDateTime;
00931 int duration = recurrence->duration();
00932 if (duration == -1)
00933 mNoEndDateButton->setChecked(true);
00934 else if (duration)
00935 {
00936 mRepeatCountButton->setChecked(true);
00937 mRepeatCountEntry->setValue(duration);
00938 }
00939 else
00940 {
00941 mEndDateButton->setChecked(true);
00942 endtime = recurrence->endDateTime();
00943 mEndTimeEdit->setValue(endtime.time());
00944 }
00945 mEndDateEdit->setDate(endtime.date());
00946
00947
00948 mExceptionDates = event.recurrence()->exDates();
00949 qHeapSort(mExceptionDates);
00950 mExceptionDateList->clear();
00951 for (DateList::ConstIterator it = mExceptionDates.begin(); it != mExceptionDates.end(); ++it)
00952 mExceptionDateList->insertItem(TDEGlobal::locale()->formatDate(*it));
00953 enableExceptionButtons();
00954
00955
00956 mSubRepetition->set(event.repeatInterval(), event.repeatCount());
00957
00958 rangeTypeClicked();
00959
00960 saveState();
00961 }
00962
00963
00964
00965
00966
00967
00968 void RecurrenceEdit::updateEvent(KAEvent& event, bool adjustStart)
00969 {
00970
00971 TQDate endDate;
00972 TQTime endTime;
00973 int repeatCount;
00974 if (mNoEndDateButton->isChecked())
00975 repeatCount = -1;
00976 else if (mRepeatCountButton->isChecked())
00977 repeatCount = mRepeatCountEntry->value();
00978 else
00979 {
00980 repeatCount = 0;
00981 endDate = mEndDateEdit->date();
00982 endTime = mEndTimeEdit->time();
00983 }
00984
00985
00986 TQButton* button = mRuleButtonGroup->selected();
00987 event.setRepeatAtLogin(button == mAtLoginButton);
00988 int frequency = mRule ? mRule->frequency() : 0;
00989 if (button == mSubDailyButton)
00990 {
00991 TQDateTime endDateTime(endDate, endTime);
00992 event.setRecurMinutely(frequency, repeatCount, endDateTime);
00993 }
00994 else if (button == mDailyButton)
00995 {
00996 event.setRecurDaily(frequency, mDailyRule->days(), repeatCount, endDate);
00997 }
00998 else if (button == mWeeklyButton)
00999 {
01000 event.setRecurWeekly(frequency, mWeeklyRule->days(), repeatCount, endDate);
01001 }
01002 else if (button == mMonthlyButton)
01003 {
01004 if (mMonthlyRule->type() == MonthlyRule::POS)
01005 {
01006
01007 KAEvent::MonthPos pos;
01008 pos.days.fill(false);
01009 pos.days.setBit(mMonthlyRule->dayOfWeek() - 1);
01010 pos.weeknum = mMonthlyRule->week();
01011 TQValueList<KAEvent::MonthPos> poses;
01012 poses.append(pos);
01013 event.setRecurMonthlyByPos(frequency, poses, repeatCount, endDate);
01014 }
01015 else
01016 {
01017
01018 int daynum = mMonthlyRule->date();
01019 TQValueList<int> daynums;
01020 daynums.append(daynum);
01021 event.setRecurMonthlyByDate(frequency, daynums, repeatCount, endDate);
01022 }
01023 }
01024 else if (button == mYearlyButton)
01025 {
01026 TQValueList<int> months = mYearlyRule->months();
01027 if (mYearlyRule->type() == YearlyRule::POS)
01028 {
01029
01030 KAEvent::MonthPos pos;
01031 pos.days.fill(false);
01032 pos.days.setBit(mYearlyRule->dayOfWeek() - 1);
01033 pos.weeknum = mYearlyRule->week();
01034 TQValueList<KAEvent::MonthPos> poses;
01035 poses.append(pos);
01036 event.setRecurAnnualByPos(frequency, poses, months, repeatCount, endDate);
01037 }
01038 else
01039 {
01040
01041 event.setRecurAnnualByDate(frequency, months, mYearlyRule->date(),
01042 mYearlyRule->feb29Type(), repeatCount, endDate);
01043 }
01044 }
01045 else
01046 {
01047 event.setNoRecur();
01048 return;
01049 }
01050 if (!event.recurs())
01051 return;
01052 if (adjustStart)
01053 event.setFirstRecurrence();
01054
01055
01056
01057 int count = mSubRepetition->count();
01058 if (mRuleButtonType < SUBDAILY)
01059 count = 0;
01060 event.setRepetition(mSubRepetition->interval(), count);
01061
01062
01063 event.recurrence()->setExDates(mExceptionDates);
01064
01065 event.setUpdated();
01066 }
01067
01068
01069
01070
01071 void RecurrenceEdit::saveState()
01072 {
01073 mSavedRuleButton = mRuleButtonGroup->selected();
01074 if (mRule)
01075 mRule->saveState();
01076 mSavedRangeButton = mRangeButtonGroup->selected();
01077 if (mSavedRangeButton == mRepeatCountButton)
01078 mSavedRecurCount = mRepeatCountEntry->value();
01079 else if (mSavedRangeButton == mEndDateButton)
01080 mSavedEndDateTime.set(TQDateTime(mEndDateEdit->date(), mEndTimeEdit->time()), mEndAnyTimeCheckBox->isChecked());
01081 mSavedExceptionDates = mExceptionDates;
01082 mSavedRepeatInterval = mSubRepetition->interval();
01083 mSavedRepeatCount = mSubRepetition->count();
01084 }
01085
01086
01087
01088
01089 bool RecurrenceEdit::stateChanged() const
01090 {
01091 if (mSavedRuleButton != mRuleButtonGroup->selected()
01092 || mSavedRangeButton != mRangeButtonGroup->selected()
01093 || (mRule && mRule->stateChanged()))
01094 return true;
01095 if (mSavedRangeButton == mRepeatCountButton
01096 && mSavedRecurCount != mRepeatCountEntry->value())
01097 return true;
01098 if (mSavedRangeButton == mEndDateButton
01099 && mSavedEndDateTime != DateTime(TQDateTime(mEndDateEdit->date(), mEndTimeEdit->time()), mEndAnyTimeCheckBox->isChecked()))
01100 return true;
01101 if (mSavedExceptionDates != mExceptionDates
01102 || mSavedRepeatInterval != mSubRepetition->interval()
01103 || mSavedRepeatCount != mSubRepetition->count())
01104 return true;
01105 return false;
01106 }
01107
01108
01109
01110
01111
01112
01113
01114
01115 Rule::Rule(const TQString& freqText, const TQString& freqWhatsThis, bool time, bool readOnly, TQWidget* parent, const char* name)
01116 : NoRule(parent, name)
01117 {
01118 mLayout = new TQVBoxLayout(this, 0, KDialog::spacingHint());
01119 TQHBox* freqBox = new TQHBox(this);
01120 mLayout->addWidget(freqBox);
01121 TQHBox* box = new TQHBox(freqBox);
01122 box->setSpacing(KDialog::spacingHint());
01123
01124 TQLabel* label = new TQLabel(i18n("Recur e&very"), box);
01125 label->setFixedSize(label->sizeHint());
01126 if (time)
01127 {
01128 mIntSpinBox = 0;
01129 mSpinBox = mTimeSpinBox = new TimeSpinBox(1, 5999, box);
01130 mTimeSpinBox->setFixedSize(mTimeSpinBox->sizeHint());
01131 mTimeSpinBox->setReadOnly(readOnly);
01132 }
01133 else
01134 {
01135 mTimeSpinBox = 0;
01136 mSpinBox = mIntSpinBox = new SpinBox(1, 999, 1, box);
01137 mIntSpinBox->setFixedSize(mIntSpinBox->sizeHint());
01138 mIntSpinBox->setReadOnly(readOnly);
01139 }
01140 connect(mSpinBox, TQT_SIGNAL(valueChanged(int)), TQT_SIGNAL(frequencyChanged()));
01141 label->setBuddy(mSpinBox);
01142 label = new TQLabel(freqText, box);
01143 label->setFixedSize(label->sizeHint());
01144 box->setFixedSize(sizeHint());
01145 TQWhatsThis::add(box, freqWhatsThis);
01146
01147 new TQWidget(freqBox);
01148 freqBox->setFixedHeight(freqBox->sizeHint().height());
01149 freqBox->setFocusProxy(mSpinBox);
01150 }
01151
01152 int Rule::frequency() const
01153 {
01154 if (mIntSpinBox)
01155 return mIntSpinBox->value();
01156 if (mTimeSpinBox)
01157 return mTimeSpinBox->value();
01158 return 0;
01159 }
01160
01161 void Rule::setFrequency(int n)
01162 {
01163 if (mIntSpinBox)
01164 mIntSpinBox->setValue(n);
01165 if (mTimeSpinBox)
01166 mTimeSpinBox->setValue(n);
01167 }
01168
01169
01170
01171
01172 void Rule::saveState()
01173 {
01174 mSavedFrequency = frequency();
01175 }
01176
01177
01178
01179
01180 bool Rule::stateChanged() const
01181 {
01182 return (mSavedFrequency != frequency());
01183 }
01184
01185
01186
01187
01188
01189
01190
01191 SubDailyRule::SubDailyRule(bool readOnly, TQWidget* parent, const char* name)
01192 : Rule(i18n("hours:minutes"),
01193 i18n("Enter the number of hours and minutes between repetitions of the alarm"),
01194 true, readOnly, parent, name)
01195 { }
01196
01197
01198
01199
01200
01201
01202
01203 DayWeekRule::DayWeekRule(const TQString& freqText, const TQString& freqWhatsThis, const TQString& daysWhatsThis,
01204 bool readOnly, TQWidget* parent, const char* name)
01205 : Rule(freqText, freqWhatsThis, false, readOnly, parent, name),
01206 mSavedDays(7)
01207 {
01208 TQGridLayout* grid = new TQGridLayout(layout(), 1, 4, KDialog::spacingHint());
01209 grid->setRowStretch(0, 1);
01210
01211 TQLabel* label = new TQLabel(i18n("On: Tuesday", "O&n:"), this);
01212 label->setFixedSize(label->sizeHint());
01213 grid->addWidget(label, 0, 0, TQt::AlignRight | TQt::AlignTop);
01214 grid->addColSpacing(1, KDialog::spacingHint());
01215
01216
01217
01218 TQWidget* box = new TQWidget(this);
01219 TQGridLayout* dgrid = new TQGridLayout(box, 4, 2, 0, KDialog::spacingHint());
01220 const KCalendarSystem* calendar = TDEGlobal::locale()->calendar();
01221 for (int i = 0; i < 7; ++i)
01222 {
01223 int day = KAlarm::localeDayInWeek_to_weekDay(i);
01224 mDayBox[i] = new CheckBox(calendar->weekDayName(day), box);
01225 mDayBox[i]->setFixedSize(mDayBox[i]->sizeHint());
01226 mDayBox[i]->setReadOnly(readOnly);
01227 dgrid->addWidget(mDayBox[i], i%4, i/4, TQt::AlignAuto);
01228 }
01229 box->setFixedSize(box->sizeHint());
01230 TQWhatsThis::add(box, daysWhatsThis);
01231 grid->addWidget(box, 0, 2, TQt::AlignAuto);
01232 label->setBuddy(mDayBox[0]);
01233 grid->setColStretch(3, 1);
01234 }
01235
01236
01237
01238
01239 TQBitArray DayWeekRule::days() const
01240 {
01241 TQBitArray ds(7);
01242 ds.fill(false);
01243 for (int i = 0; i < 7; ++i)
01244 if (mDayBox[i]->isChecked())
01245 ds.setBit(KAlarm::localeDayInWeek_to_weekDay(i) - 1, 1);
01246 return ds;
01247 }
01248
01249
01250
01251
01252 void DayWeekRule::setDays(bool tick)
01253 {
01254 for (int i = 0; i < 7; ++i)
01255 mDayBox[i]->setChecked(tick);
01256 }
01257
01258
01259
01260
01261 void DayWeekRule::setDays(const TQBitArray& days)
01262 {
01263 for (int i = 0; i < 7; ++i)
01264 {
01265 bool x = days.testBit(KAlarm::localeDayInWeek_to_weekDay(i) - 1);
01266 mDayBox[i]->setChecked(x);
01267 }
01268 }
01269
01270
01271
01272
01273 void DayWeekRule::setDay(int dayOfWeek)
01274 {
01275 for (int i = 0; i < 7; ++i)
01276 mDayBox[i]->setChecked(false);
01277 if (dayOfWeek > 0 && dayOfWeek <= 7)
01278 mDayBox[KAlarm::weekDay_to_localeDayInWeek(dayOfWeek)]->setChecked(true);
01279 }
01280
01281
01282
01283
01284 TQWidget* DayWeekRule::validate(TQString& errorMessage)
01285 {
01286 for (int i = 0; i < 7; ++i)
01287 if (mDayBox[i]->isChecked())
01288 return 0;
01289 errorMessage = i18n("No day selected");
01290 return mDayBox[0];
01291 }
01292
01293
01294
01295
01296 void DayWeekRule::saveState()
01297 {
01298 Rule::saveState();
01299 mSavedDays = days();
01300 }
01301
01302
01303
01304
01305 bool DayWeekRule::stateChanged() const
01306 {
01307 return (Rule::stateChanged()
01308 || mSavedDays != days());
01309 }
01310
01311
01312
01313
01314
01315
01316
01317 DailyRule::DailyRule(bool readOnly, TQWidget* parent, const char* name)
01318 : DayWeekRule(i18n("day(s)"),
01319 i18n("Enter the number of days between repetitions of the alarm"),
01320 i18n("Select the days of the week on which the alarm is allowed to occur"),
01321 readOnly, parent, name)
01322 { }
01323
01324
01325
01326
01327
01328
01329
01330 WeeklyRule::WeeklyRule(bool readOnly, TQWidget* parent, const char* name)
01331 : DayWeekRule(i18n("week(s)"),
01332 i18n("Enter the number of weeks between repetitions of the alarm"),
01333 i18n("Select the days of the week on which to repeat the alarm"),
01334 readOnly, parent, name)
01335 { }
01336
01337
01338
01339
01340
01341
01342
01343 MonthYearRule::MonthYearRule(const TQString& freqText, const TQString& freqWhatsThis, bool allowEveryWeek,
01344 bool readOnly, TQWidget* parent, const char* name)
01345 : Rule(freqText, freqWhatsThis, false, readOnly, parent, name),
01346 mEveryWeek(allowEveryWeek)
01347 {
01348 mButtonGroup = new ButtonGroup(this);
01349 mButtonGroup->hide();
01350
01351
01352 TQHBox* box = new TQHBox(this);
01353 box->setSpacing(KDialog::spacingHint());
01354 layout()->addWidget(box);
01355
01356 mDayButton = new RadioButton(i18n("On day number in the month", "O&n day"), box);
01357 mDayButton->setFixedSize(mDayButton->sizeHint());
01358 mDayButton->setReadOnly(readOnly);
01359 mDayButtonId = mButtonGroup->insert(mDayButton);
01360 TQWhatsThis::add(mDayButton, i18n("Repeat the alarm on the selected day of the month"));
01361
01362 mDayCombo = new ComboBox(false, box);
01363 mDayCombo->setSizeLimit(11);
01364 for (int i = 0; i < 31; ++i)
01365 mDayCombo->insertItem(TQString::number(i + 1));
01366 mDayCombo->insertItem(i18n("Last day of month", "Last"));
01367 mDayCombo->setFixedSize(mDayCombo->sizeHint());
01368 mDayCombo->setReadOnly(readOnly);
01369 TQWhatsThis::add(mDayCombo, i18n("Select the day of the month on which to repeat the alarm"));
01370 mDayButton->setFocusWidget(mDayCombo);
01371 connect(mDayCombo, TQT_SIGNAL(activated(int)), TQT_SLOT(slotDaySelected(int)));
01372
01373 box->setStretchFactor(new TQWidget(box), 1);
01374 box->setFixedHeight(box->sizeHint().height());
01375
01376
01377 box = new TQHBox(this);
01378 box->setSpacing(KDialog::spacingHint());
01379 layout()->addWidget(box);
01380
01381 mPosButton = new RadioButton(i18n("On the 1st Tuesday", "On t&he"), box);
01382 mPosButton->setFixedSize(mPosButton->sizeHint());
01383 mPosButton->setReadOnly(readOnly);
01384 mPosButtonId = mButtonGroup->insert(mPosButton);
01385 TQWhatsThis::add(mPosButton,
01386 i18n("Repeat the alarm on one day of the week, in the selected week of the month"));
01387
01388 mWeekCombo = new ComboBox(false, box);
01389 mWeekCombo->insertItem(i18n("1st"));
01390 mWeekCombo->insertItem(i18n("2nd"));
01391 mWeekCombo->insertItem(i18n("3rd"));
01392 mWeekCombo->insertItem(i18n("4th"));
01393 mWeekCombo->insertItem(i18n("5th"));
01394 mWeekCombo->insertItem(i18n("Last Monday in March", "Last"));
01395 mWeekCombo->insertItem(i18n("2nd Last"));
01396 mWeekCombo->insertItem(i18n("3rd Last"));
01397 mWeekCombo->insertItem(i18n("4th Last"));
01398 mWeekCombo->insertItem(i18n("5th Last"));
01399 if (mEveryWeek)
01400 {
01401 mWeekCombo->insertItem(i18n("Every (Monday...) in month", "Every"));
01402 mWeekCombo->setSizeLimit(11);
01403 }
01404 TQWhatsThis::add(mWeekCombo, i18n("Select the week of the month in which to repeat the alarm"));
01405 mWeekCombo->setFixedSize(mWeekCombo->sizeHint());
01406 mWeekCombo->setReadOnly(readOnly);
01407 mPosButton->setFocusWidget(mWeekCombo);
01408
01409 mDayOfWeekCombo = new ComboBox(false, box);
01410 const KCalendarSystem* calendar = TDEGlobal::locale()->calendar();
01411 for (int i = 0; i < 7; ++i)
01412 {
01413 int day = KAlarm::localeDayInWeek_to_weekDay(i);
01414 mDayOfWeekCombo->insertItem(calendar->weekDayName(day));
01415 }
01416 mDayOfWeekCombo->setReadOnly(readOnly);
01417 TQWhatsThis::add(mDayOfWeekCombo, i18n("Select the day of the week on which to repeat the alarm"));
01418
01419 box->setStretchFactor(new TQWidget(box), 1);
01420 box->setFixedHeight(box->sizeHint().height());
01421 connect(mButtonGroup, TQT_SIGNAL(buttonSet(int)), TQT_SLOT(clicked(int)));
01422 }
01423
01424 MonthYearRule::DayPosType MonthYearRule::type() const
01425 {
01426 return (mButtonGroup->selectedId() == mDayButtonId) ? DATE : POS;
01427 }
01428
01429 void MonthYearRule::setType(MonthYearRule::DayPosType type)
01430 {
01431 mButtonGroup->setButton(type == DATE ? mDayButtonId : mPosButtonId);
01432 }
01433
01434 void MonthYearRule::setDefaultValues(int dayOfMonth, int dayOfWeek)
01435 {
01436 --dayOfMonth;
01437 mDayCombo->setCurrentItem(dayOfMonth);
01438 mWeekCombo->setCurrentItem(dayOfMonth / 7);
01439 mDayOfWeekCombo->setCurrentItem(KAlarm::weekDay_to_localeDayInWeek(dayOfWeek));
01440 }
01441
01442 int MonthYearRule::date() const
01443 {
01444 int daynum = mDayCombo->currentItem() + 1;
01445 return (daynum <= 31) ? daynum : 31 - daynum;
01446 }
01447
01448 int MonthYearRule::week() const
01449 {
01450 int weeknum = mWeekCombo->currentItem() + 1;
01451 return (weeknum <= 5) ? weeknum : (weeknum == 11) ? 0 : 5 - weeknum;
01452 }
01453
01454 int MonthYearRule::dayOfWeek() const
01455 {
01456 return KAlarm::localeDayInWeek_to_weekDay(mDayOfWeekCombo->currentItem());
01457 }
01458
01459 void MonthYearRule::setDate(int dayOfMonth)
01460 {
01461 mButtonGroup->setButton(mDayButtonId);
01462 mDayCombo->setCurrentItem(dayOfMonth > 0 ? dayOfMonth - 1 : dayOfMonth < 0 ? 30 - dayOfMonth : 0);
01463 }
01464
01465 void MonthYearRule::setPosition(int week, int dayOfWeek)
01466 {
01467 mButtonGroup->setButton(mPosButtonId);
01468 mWeekCombo->setCurrentItem((week > 0) ? week - 1 : (week < 0) ? 4 - week : mEveryWeek ? 10 : 0);
01469 mDayOfWeekCombo->setCurrentItem(KAlarm::weekDay_to_localeDayInWeek(dayOfWeek));
01470 }
01471
01472 void MonthYearRule::enableSelection(DayPosType type)
01473 {
01474 bool date = (type == DATE);
01475 mDayCombo->setEnabled(date);
01476 mWeekCombo->setEnabled(!date);
01477 mDayOfWeekCombo->setEnabled(!date);
01478 }
01479
01480 void MonthYearRule::clicked(int id)
01481 {
01482 enableSelection(id == mDayButtonId ? DATE : POS);
01483 }
01484
01485 void MonthYearRule::slotDaySelected(int index)
01486 {
01487 daySelected(index <= 30 ? index + 1 : 30 - index);
01488 }
01489
01490
01491
01492
01493 void MonthYearRule::saveState()
01494 {
01495 Rule::saveState();
01496 mSavedType = type();
01497 if (mSavedType == DATE)
01498 mSavedDay = date();
01499 else
01500 {
01501 mSavedWeek = week();
01502 mSavedWeekDay = dayOfWeek();
01503 }
01504 }
01505
01506
01507
01508
01509 bool MonthYearRule::stateChanged() const
01510 {
01511 if (Rule::stateChanged()
01512 || mSavedType != type())
01513 return true;
01514 if (mSavedType == DATE)
01515 {
01516 if (mSavedDay != date())
01517 return true;
01518 }
01519 else
01520 {
01521 if (mSavedWeek != week()
01522 || mSavedWeekDay != dayOfWeek())
01523 return true;
01524 }
01525 return false;
01526 }
01527
01528
01529
01530
01531
01532
01533
01534 MonthlyRule::MonthlyRule(bool readOnly, TQWidget* parent, const char* name)
01535 : MonthYearRule(i18n("month(s)"),
01536 i18n("Enter the number of months between repetitions of the alarm"),
01537 false, readOnly, parent, name)
01538 { }
01539
01540
01541
01542
01543
01544
01545
01546 YearlyRule::YearlyRule(bool readOnly, TQWidget* parent, const char* name)
01547 : MonthYearRule(i18n("year(s)"),
01548 i18n("Enter the number of years between repetitions of the alarm"),
01549 true, readOnly, parent, name)
01550 {
01551
01552 TQBoxLayout* hlayout = new TQHBoxLayout(layout(), KDialog::spacingHint());
01553 TQLabel* label = new TQLabel(i18n("List of months to select", "Months:"), this);
01554 label->setFixedSize(label->sizeHint());
01555 hlayout->addWidget(label, 0, TQt::AlignAuto | TQt::AlignTop);
01556
01557
01558 TQWidget* w = new TQWidget(this);
01559 hlayout->addWidget(w, 1, TQt::AlignAuto);
01560 TQGridLayout* grid = new TQGridLayout(w, 4, 3, 0, KDialog::spacingHint());
01561 const KCalendarSystem* calendar = TDEGlobal::locale()->calendar();
01562 int year = TQDate::currentDate().year();
01563 for (int i = 0; i < 12; ++i)
01564 {
01565 mMonthBox[i] = new CheckBox(calendar->monthName(i + 1, year, true), w);
01566 mMonthBox[i]->setFixedSize(mMonthBox[i]->sizeHint());
01567 mMonthBox[i]->setReadOnly(readOnly);
01568 grid->addWidget(mMonthBox[i], i%3, i/3, TQt::AlignAuto);
01569 }
01570 connect(mMonthBox[1], TQT_SIGNAL(toggled(bool)), TQT_SLOT(enableFeb29()));
01571 w->setFixedHeight(w->sizeHint().height());
01572 TQWhatsThis::add(w, i18n("Select the months of the year in which to repeat the alarm"));
01573
01574
01575 TQHBox* f29box = new TQHBox(this);
01576 layout()->addWidget(f29box);
01577 TQHBox* box = new TQHBox(f29box);
01578 box->setSpacing(KDialog::spacingHint());
01579 mFeb29Label = new TQLabel(i18n("February 2&9th alarm in non-leap years:"), box);
01580 mFeb29Label->setFixedSize(mFeb29Label->sizeHint());
01581 mFeb29Combo = new ComboBox(false, box);
01582 mFeb29Combo->insertItem(i18n("No date", "None"));
01583 mFeb29Combo->insertItem(i18n("1st March (short form)", "1 Mar"));
01584 mFeb29Combo->insertItem(i18n("28th February (short form)", "28 Feb"));
01585 mFeb29Combo->setFixedSize(mFeb29Combo->sizeHint());
01586 mFeb29Combo->setReadOnly(readOnly);
01587 mFeb29Label->setBuddy(mFeb29Combo);
01588 box->setFixedSize(box->sizeHint());
01589 TQWhatsThis::add(box,
01590 i18n("Select which date, if any, the February 29th alarm should trigger in non-leap years"));
01591 new TQWidget(f29box);
01592 f29box->setFixedHeight(f29box->sizeHint().height());
01593 }
01594
01595 void YearlyRule::setDefaultValues(int dayOfMonth, int dayOfWeek, int month)
01596 {
01597 MonthYearRule::setDefaultValues(dayOfMonth, dayOfWeek);
01598 --month;
01599 for (int i = 0; i < 12; ++i)
01600 mMonthBox[i]->setChecked(i == month);
01601 setFeb29Type(Preferences::defaultFeb29Type());
01602 daySelected(dayOfMonth);
01603 }
01604
01605
01606
01607
01608
01609 TQValueList<int> YearlyRule::months() const
01610 {
01611 TQValueList<int> mnths;
01612 for (int i = 0; i < 12; ++i)
01613 if (mMonthBox[i]->isChecked() && mMonthBox[i]->isEnabled())
01614 mnths.append(i + 1);
01615 return mnths;
01616 }
01617
01618
01619
01620
01621 void YearlyRule::setMonths(const TQValueList<int>& mnths)
01622 {
01623 bool checked[12];
01624 for (int i = 0; i < 12; ++i)
01625 checked[i] = false;
01626 for (TQValueListConstIterator<int> it = mnths.begin(); it != mnths.end(); ++it)
01627 checked[(*it) - 1] = true;
01628 for (int i = 0; i < 12; ++i)
01629 mMonthBox[i]->setChecked(checked[i]);
01630 enableFeb29();
01631 }
01632
01633
01634
01635
01636 KARecurrence::Feb29Type YearlyRule::feb29Type() const
01637 {
01638 if (mFeb29Combo->isEnabled())
01639 {
01640 switch (mFeb29Combo->currentItem())
01641 {
01642 case 1: return KARecurrence::FEB29_MAR1;
01643 case 2: return KARecurrence::FEB29_FEB28;
01644 default: break;
01645 }
01646 }
01647 return KARecurrence::FEB29_FEB29;
01648 }
01649
01650
01651
01652
01653 void YearlyRule::setFeb29Type(KARecurrence::Feb29Type type)
01654 {
01655 int index;
01656 switch (type)
01657 {
01658 default:
01659 case KARecurrence::FEB29_FEB29: index = 0; break;
01660 case KARecurrence::FEB29_MAR1: index = 1; break;
01661 case KARecurrence::FEB29_FEB28: index = 2; break;
01662 }
01663 mFeb29Combo->setCurrentItem(index);
01664 }
01665
01666
01667
01668
01669 TQWidget* YearlyRule::validate(TQString& errorMessage)
01670 {
01671 for (int i = 0; i < 12; ++i)
01672 if (mMonthBox[i]->isChecked() && mMonthBox[i]->isEnabled())
01673 return 0;
01674 errorMessage = i18n("No month selected");
01675 return mMonthBox[0];
01676 }
01677
01678
01679
01680
01681
01682 void YearlyRule::clicked(int id)
01683 {
01684 MonthYearRule::clicked(id);
01685 daySelected(buttonType(id) == DATE ? date() : 1);
01686 }
01687
01688
01689
01690
01691
01692 void YearlyRule::daySelected(int day)
01693 {
01694 mMonthBox[1]->setEnabled(day <= 29);
01695 bool enable = (day != 31);
01696 mMonthBox[3]->setEnabled(enable);
01697 mMonthBox[5]->setEnabled(enable);
01698 mMonthBox[8]->setEnabled(enable);
01699 mMonthBox[10]->setEnabled(enable);
01700 enableFeb29();
01701 }
01702
01703
01704
01705
01706
01707 void YearlyRule::enableFeb29()
01708 {
01709 bool enable = (type() == DATE && date() == 29 && mMonthBox[1]->isChecked() && mMonthBox[1]->isEnabled());
01710 mFeb29Label->setEnabled(enable);
01711 mFeb29Combo->setEnabled(enable);
01712 }
01713
01714
01715
01716
01717 void YearlyRule::saveState()
01718 {
01719 MonthYearRule::saveState();
01720 mSavedMonths = months();
01721 mSavedFeb29Type = feb29Type();
01722 }
01723
01724
01725
01726
01727 bool YearlyRule::stateChanged() const
01728 {
01729 return (MonthYearRule::stateChanged()
01730 || mSavedMonths != months()
01731 || mSavedFeb29Type != feb29Type());
01732 }