kalarm Library API Documentation

recurrenceedit.cpp

00001 /*
00002  *  recurrenceedit.cpp  -  widget to edit the event's recurrence definition
00003  *  Program:  kalarm
00004  *  (C) 2002 by David Jarvie  software@astrojar.org.uk
00005  *
00006  *  Based on KOrganizer module koeditorrecurrence.cpp,
00007     Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
00008 
00009     This program is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     This program is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00017     GNU General Public License for more details.
00018 
00019     You should have received a copy of the GNU General Public License
00020     along with this program; if not, write to the Free Software
00021     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00022 
00023     As a special exception, permission is given to link this program
00024     with any edition of Qt, and distribute the resulting executable,
00025     without including the source code for Qt in the source distribution.
00026  */
00027 #include "kalarm.h"
00028 
00029 #include <qtooltip.h>
00030 #include <qlayout.h>
00031 #include <qvbox.h>
00032 #include <qradiobutton.h>
00033 #include <qwidgetstack.h>
00034 #include <qframe.h>
00035 #include <qlabel.h>
00036 #include <qcheckbox.h>
00037 #include <qpushbutton.h>
00038 #include <qlineedit.h>
00039 #include <qcombobox.h>
00040 #include <qwhatsthis.h>
00041 
00042 #include <kglobal.h>
00043 #include <klocale.h>
00044 #include <kiconloader.h>
00045 #include <kdialog.h>
00046 #include <kmessagebox.h>
00047 #include <kdebug.h>
00048 
00049 #include <libkcal/event.h>
00050 
00051 #include "kalarmapp.h"
00052 #include "prefsettings.h"
00053 #include "datetime.h"
00054 #include "dateedit.h"
00055 #include "msgevent.h"
00056 #include "buttongroup.h"
00057 
00058 #include "recurrenceedit.moc"
00059 
00060 static const char* const ordinal[] = {
00061         I18N_NOOP("1st"),  I18N_NOOP("2nd"),  I18N_NOOP("3rd"),  I18N_NOOP("4th"),  I18N_NOOP("5th"),
00062         I18N_NOOP("6th"),  I18N_NOOP("7th"),  I18N_NOOP("8th"),  I18N_NOOP("9th"),  I18N_NOOP("10th"),
00063         I18N_NOOP("11th"), I18N_NOOP("12th"), I18N_NOOP("13th"), I18N_NOOP("14th"), I18N_NOOP("15th"),
00064         I18N_NOOP("16th"), I18N_NOOP("17th"), I18N_NOOP("18th"), I18N_NOOP("19th"), I18N_NOOP("20th"),
00065         I18N_NOOP("21st"), I18N_NOOP("22nd"), I18N_NOOP("23rd"), I18N_NOOP("24th"), I18N_NOOP("25th"),
00066         I18N_NOOP("26th"), I18N_NOOP("27th"), I18N_NOOP("28th"), I18N_NOOP("29th"), I18N_NOOP("30th"),
00067         I18N_NOOP("31st")
00068 };
00069 
00070 using namespace KCal;
00071 RecurrenceEdit::RecurrenceEdit(QWidget* parent, const char* name)
00072         : QFrame(parent, name),
00073           noEmitTypeChanged(true)
00074 {
00075         QBoxLayout* layout;
00076         QVBoxLayout* topLayout = new QVBoxLayout(this, marginKDE2, KDialog::spacingHint());
00077 
00078         // Create the recurrence rule Group box which holds the recurrence period
00079         // selection buttons, and the weekly, monthly and yearly recurrence rule
00080         // frames which specify options individual to each of these distinct
00081         // sections of the recurrence rule. Each frame is made visible by the
00082         // selection of its corresponding radio button.
00083 
00084 #if KDE_VERSION >= 290
00085         recurGroup = new QGroupBox(1, Qt::Vertical, i18n("Recurrence Rule"), this, "recurGroup");
00086 #else
00087         recurGroup = new QGroupBox(i18n("Recurrence Rule"), this, "recurGroup");
00088         layout = new QVBoxLayout(recurGroup, KDialog::marginHint(), KDialog::spacingHint());
00089         layout->addSpacing(fontMetrics().lineSpacing()/2);
00090         QBoxLayout* boxLayout = new QHBoxLayout(layout);
00091 #endif
00092         topLayout->addWidget(recurGroup);
00093         ruleFrame = new QFrame(recurGroup, "ruleFrame");
00094 #if KDE_VERSION < 290
00095         boxLayout->addWidget(ruleFrame);
00096 #endif
00097         layout = new QVBoxLayout(ruleFrame, 0);
00098         layout->addSpacing(KDialog::spacingHint()/2);
00099 
00100         layout = new QHBoxLayout(layout, 0);
00101         ruleButtonGroup = new ButtonGroup(1, Qt::Horizontal, ruleFrame);
00102         ruleButtonGroup->setInsideMargin(0);
00103         ruleButtonGroup->setFrameStyle(QFrame::NoFrame);
00104         layout->addWidget(ruleButtonGroup);
00105         connect(ruleButtonGroup, SIGNAL(buttonSet(int)), SLOT(periodClicked(int)));
00106 
00107         recurEveryLabel = new QLabel(i18n("Recur e&very:"), ruleButtonGroup);
00108         recurEveryLabel->setFixedSize(recurEveryLabel->sizeHint());
00109         recurFrequencyStack = new QWidgetStack(ruleButtonGroup);
00110         recurFrequency = new QSpinBox(1, 999, 1, ruleButtonGroup);
00111         recurFrequencyStack->addWidget(recurFrequency, 0);
00112         recurHourMinFrequency = new TimeSpinBox(1, 99*60+59, ruleButtonGroup);
00113         QWhatsThis::add(recurHourMinFrequency,
00114               i18n("Enter the time (in hours and minutes) between repetitions of the alarm."));
00115         recurFrequencyStack->addWidget(recurHourMinFrequency, 1);
00116         QSize size = recurFrequency->sizeHint().expandedTo(recurHourMinFrequency->sizeHint());
00117         recurFrequency->setFixedSize(size);
00118         recurHourMinFrequency->setFixedSize(size);
00119         recurFrequencyStack->setFixedSize(size);
00120 
00121         subdailyButton = new QRadioButton(i18n("Ho&urs/Minutes"), ruleButtonGroup);
00122         subdailyButton->setFixedSize(subdailyButton->sizeHint());
00123         QWhatsThis::add(subdailyButton,
00124               i18n("Set the alarm repetition interval to the number of hours and minutes entered"));
00125 
00126         dailyButton = new QRadioButton(i18n("&Days"), ruleButtonGroup);
00127         dailyButton->setFixedSize(dailyButton->sizeHint());
00128         QWhatsThis::add(dailyButton,
00129               i18n("Set the alarm repetition interval to the number of days entered"));
00130 
00131         weeklyButton = new QRadioButton(i18n("&Weeks"), ruleButtonGroup);
00132         weeklyButton->setFixedSize(weeklyButton->sizeHint());
00133         QWhatsThis::add(weeklyButton,
00134               i18n("Set the alarm repetition interval to the number of weeks entered"));
00135 
00136         monthlyButton = new QRadioButton(i18n("&Months"), ruleButtonGroup);
00137         monthlyButton->setFixedSize(monthlyButton->sizeHint());
00138         QWhatsThis::add(monthlyButton,
00139               i18n("Set the alarm repetition interval to the number of months entered"));
00140 
00141         yearlyButton = new QRadioButton(i18n("&Years"), ruleButtonGroup);
00142         yearlyButton->setFixedSize(yearlyButton->sizeHint());
00143         QWhatsThis::add(yearlyButton,
00144               i18n("Set the alarm repetition interval to the number of years entered"));
00145 
00146         subdailyButtonId = ruleButtonGroup->id(subdailyButton);
00147         dailyButtonId    = ruleButtonGroup->id(dailyButton);
00148         weeklyButtonId   = ruleButtonGroup->id(weeklyButton);
00149         monthlyButtonId  = ruleButtonGroup->id(monthlyButton);
00150         yearlyButtonId   = ruleButtonGroup->id(yearlyButton);
00151 
00152         QBoxLayout* lay = new QVBoxLayout(layout);
00153 
00154         lay->addStretch();
00155         layout = new QHBoxLayout(lay);
00156 
00157         layout->addSpacing(KDialog::marginHint());
00158         QFrame* divider = new QFrame(ruleFrame);
00159         divider->setFrameStyle(QFrame::VLine | QFrame::Sunken);
00160         layout->addWidget(divider);
00161 
00162         initNone();
00163         initWeekly();
00164         initMonthly();
00165         initYearly();
00166 
00167         ruleStack = new QWidgetStack(ruleFrame);
00168         layout->addWidget(ruleStack);
00169         layout->addStretch(1);
00170         ruleStack->addWidget(noneFrame, 0);
00171         ruleStack->addWidget(weeklyFrame, 1);
00172         ruleStack->addWidget(monthlyFrame, 2);
00173         ruleStack->addWidget(yearlyFrame, 3);
00174 
00175         // Create the recurrence range group which contains the controls
00176         // which specify how long the recurrence is to last.
00177 
00178         rangeButtonGroup = new QButtonGroup(i18n("Recurrence End"), this, "rangeButtonGroup");
00179         topLayout->addWidget(rangeButtonGroup);
00180 
00181         QVBoxLayout* vlayout = new QVBoxLayout(rangeButtonGroup, marginKDE2 + KDialog::marginHint(), KDialog::spacingHint());
00182         vlayout->addSpacing(fontMetrics().lineSpacing()/2);
00183         noEndDateButton = new QRadioButton(i18n("No &end"), rangeButtonGroup);
00184         noEndDateButton->setFixedSize(noEndDateButton->sizeHint());
00185         connect(noEndDateButton, SIGNAL(toggled(bool)), SLOT(disableRange(bool)));
00186         QWhatsThis::add(noEndDateButton, i18n("Repeat the alarm indefinitely"));
00187         vlayout->addWidget(noEndDateButton, 1, Qt::AlignLeft);
00188         size = noEndDateButton->size();
00189 
00190         layout = new QHBoxLayout(vlayout, KDialog::spacingHint());
00191         repeatCountButton = new QRadioButton(i18n("End a&fter:"), rangeButtonGroup);
00192         connect(repeatCountButton, SIGNAL(toggled(bool)), SLOT(enableDurationRange(bool)));
00193         QWhatsThis::add(repeatCountButton,
00194               i18n("Repeat the alarm for the number of times specified"));
00195         repeatCountEntry = new QSpinBox(1, 9999, 1, rangeButtonGroup);
00196         repeatCountEntry->setFixedSize(repeatCountEntry->sizeHint());
00197         QWhatsThis::add(repeatCountEntry,
00198               i18n("Enter the total number of times to trigger the alarm"));
00199         repeatCountLabel = new QLabel(i18n("occurrence(s)"), rangeButtonGroup);
00200         repeatCountLabel->setFixedSize(repeatCountLabel->sizeHint());
00201         layout->addWidget(repeatCountButton);
00202         layout->addSpacing(KDialog::spacingHint());
00203         layout->addWidget(repeatCountEntry);
00204         layout->addWidget(repeatCountLabel);
00205         layout->addStretch();
00206         size = size.expandedTo(repeatCountButton->sizeHint());
00207 
00208         layout = new QHBoxLayout(vlayout, KDialog::spacingHint());
00209         endDateButton = new QRadioButton(i18n("End &by:"), rangeButtonGroup);
00210         connect(endDateButton, SIGNAL(toggled(bool)), SLOT(enableDateRange(bool)));
00211         QWhatsThis::add(endDateButton,
00212               i18n("Repeat the alarm until the date/time specified"));
00213         endDateEdit = new DateEdit(rangeButtonGroup);
00214         endDateEdit->setFixedSize(endDateEdit->sizeHint());
00215         QWhatsThis::add(endDateEdit,
00216               i18n("Enter the last date to repeat the alarm"));
00217         endTimeEdit = new TimeSpinBox(rangeButtonGroup);
00218         endTimeEdit->setFixedSize(endTimeEdit->sizeHint());
00219         QWhatsThis::add(endTimeEdit,
00220               i18n("Enter the last time to repeat the alarm"));
00221         layout->addWidget(endDateButton);
00222         layout->addSpacing(KDialog::spacingHint());
00223         layout->addWidget(endDateEdit);
00224         layout->addWidget(endTimeEdit);
00225         layout->addStretch();
00226         size = size.expandedTo(endDateButton->sizeHint());
00227 
00228         // Line up the widgets to the right of the radio buttons
00229         repeatCountButton->setFixedSize(size);
00230         endDateButton->setFixedSize(size);
00231 
00232         topLayout->addStretch();
00233         noEmitTypeChanged = false;
00234 }
00235 
00236 void RecurrenceEdit::initNone()
00237 {
00238         noneFrame = new QFrame(ruleFrame);
00239         noneFrame->setFrameStyle(QFrame::NoFrame);
00240 }
00241 
00242 /******************************************************************************
00243  * Set up the weekly recurrence dialog controls.
00244  */
00245 void RecurrenceEdit::initWeekly()
00246 {
00247         weeklyFrame = new QFrame(ruleFrame);
00248         weeklyFrame->setFrameStyle(QFrame::NoFrame);
00249         QBoxLayout* topLayout = new QVBoxLayout(weeklyFrame);
00250         topLayout->addStretch();
00251         QGridLayout* layout = new QGridLayout(topLayout, 7, 5, KDialog::spacingHint());
00252         layout->setRowStretch(0, 1);
00253         layout->setColStretch(0, 1);
00254 
00255         QLabel* label = new QLabel(i18n("On: Tuesday", "O&n:"), weeklyFrame);
00256         label->setFixedSize(label->sizeHint());
00257         layout->addWidget(label, 0, 1, Qt::AlignRight);
00258         layout->addColSpacing(2, 2*KDialog::spacingHint());
00259         for (int i = 0;  i < 7;  ++i)
00260         {
00261                 dayBox[i] = new QCheckBox(KGlobal::locale()->weekDayName(i + 1), weeklyFrame);    // starts Monday
00262                 dayBox[i]->setFixedSize(dayBox[i]->sizeHint());
00263                 QWhatsThis::add(dayBox[i],
00264                       i18n("Select the day(s) of the week on which to repeat the alarm"));
00265                 layout->addWidget(dayBox[i], i, 3, Qt::AlignLeft);
00266         }
00267         label->setBuddy(dayBox[0]);
00268         layout->setColStretch(4, 1);
00269 }
00270 
00271 /******************************************************************************
00272  * Set up the monthly recurrence dialog controls.
00273  */
00274 void RecurrenceEdit::initMonthly()
00275 {
00276         int i;
00277 
00278         monthlyFrame = new QVBox(ruleFrame);
00279         monthlyFrame->setFrameStyle(QFrame::NoFrame);
00280 
00281         monthlyButtonGroup = new ButtonGroup(monthlyFrame);
00282         monthlyButtonGroup->setFrameStyle(QFrame::NoFrame);
00283         QBoxLayout* topLayout = new QVBoxLayout(monthlyButtonGroup, KDialog::marginHint());
00284 
00285         QBoxLayout* layout = new QHBoxLayout(topLayout, KDialog::spacingHint());
00286         onNthDayButton = new QRadioButton(i18n("On the 7th day", "O&n the"), monthlyButtonGroup);
00287         onNthDayButton->setFixedSize(onNthDayButton->sizeHint());
00288         QWhatsThis::add(onNthDayButton,
00289               i18n("Repeat the alarm on the selected day of the month"));
00290         layout->addWidget(onNthDayButton);
00291         nthDayEntry = new QComboBox(false, monthlyButtonGroup);
00292         nthDayEntry->setSizeLimit(11);
00293         for (i = 0;  i < 31;  ++i)
00294                 nthDayEntry->insertItem(i18n(ordinal[i]));
00295         nthDayEntry->setFixedSize(nthDayEntry->sizeHint());
00296         QWhatsThis::add(nthDayEntry,
00297               i18n("Select the day of the month on which to repeat the alarm"));
00298         layout->addWidget(nthDayEntry);
00299         QLabel* label = new QLabel(i18n("day"), monthlyButtonGroup);
00300         label->setFixedSize(label->sizeHint());
00301         layout->addWidget(label);
00302         layout->addStretch();
00303 
00304         layout = new QHBoxLayout(topLayout, KDialog::spacingHint());
00305         onNthTypeOfDayButton = new QRadioButton(i18n("On the 1st Tuesday", "On t&he"), monthlyButtonGroup);
00306         onNthTypeOfDayButton->setFixedSize(onNthTypeOfDayButton->sizeHint());
00307         QWhatsThis::add(onNthTypeOfDayButton,
00308               i18n("Repeat the alarm on one day of the week, in the selected week of the month"));
00309         layout->addWidget(onNthTypeOfDayButton);
00310         nthNumberEntry = new QComboBox(false, monthlyButtonGroup);
00311         for (i = 0;  i < 5;  ++i)
00312                 nthNumberEntry->insertItem(i18n(ordinal[i]));
00313         nthNumberEntry->insertItem(i18n("Last"));
00314         nthNumberEntry->setFixedSize(nthNumberEntry->sizeHint());
00315         QWhatsThis::add(nthNumberEntry,
00316               i18n("Select the week of the month in which to repeat the alarm"));
00317         layout->addWidget(nthNumberEntry);
00318         nthTypeOfDayEntry = new QComboBox(false, monthlyButtonGroup);
00319         for (i = 1;  i <= 7;  ++i)
00320                 nthTypeOfDayEntry->insertItem(KGlobal::locale()->weekDayName(i));    // starts Monday
00321         QWhatsThis::add(nthTypeOfDayEntry,
00322               i18n("Select the day of the week on which to repeat the alarm"));
00323         layout->addWidget(nthTypeOfDayEntry);
00324         layout->addStretch();
00325 
00326         onNthDayButtonId       = monthlyButtonGroup->id(onNthDayButton);
00327         onNthTypeOfDayButtonId = monthlyButtonGroup->id(onNthTypeOfDayButton);
00328 
00329         connect(monthlyButtonGroup, SIGNAL(buttonSet(int)), SLOT(monthlyClicked(int)));
00330 }
00331 
00332 /******************************************************************************
00333  * Set up the yearly recurrence dialog controls.
00334  */
00335 void RecurrenceEdit::initYearly()
00336 {
00337         int i;
00338 
00339         yearlyFrame = new QVBox(ruleFrame);
00340         yearlyFrame->setFrameStyle(QFrame::NoFrame);
00341 
00342         yearlyButtonGroup = new ButtonGroup(yearlyFrame);
00343         yearlyButtonGroup->setFrameStyle(QFrame::NoFrame);
00344         QBoxLayout* topLayout = new QVBoxLayout(yearlyButtonGroup, KDialog::marginHint());
00345 
00346         // Set up the February 29th selection widget
00347         mYearRuleFeb29Button = new QRadioButton(i18n("On &29th February"), yearlyButtonGroup);
00348         mYearRuleFeb29Button->setFixedSize(mYearRuleFeb29Button->sizeHint());
00349         yearlyButtonGroup->insert(mYearRuleFeb29Button);
00350         QWhatsThis::add(mYearRuleFeb29Button,
00351               i18n("Repeat the alarm on 29th February in leap years, and on 1st March in non-leap years."));
00352         topLayout->addWidget(mYearRuleFeb29Button);
00353 
00354         // Set up the yearly date widget
00355         yearMonthButton = new QRadioButton(i18n("On 7th January", "O&n %1 %2"), yearlyButtonGroup);
00356         yearMonthButton->setFixedSize(yearMonthButton->sizeHint());
00357         yearlyButtonGroup->insert(yearMonthButton);
00358         QWhatsThis::add(yearMonthButton,
00359               i18n("Repeat the alarm on the selected date in the year"));
00360         topLayout->addWidget(yearMonthButton);
00361 
00362         // Set up the yearly position widgets
00363         QBoxLayout* vlayout = new QVBoxLayout(topLayout, KDialog::spacingHint());
00364         QBoxLayout* layout = new QHBoxLayout(vlayout, KDialog::spacingHint());
00365         yearlyOnNthTypeOfDayButton = new QRadioButton(i18n("On the 1st Tuesday", "On t&he"), yearlyButtonGroup);
00366         yearlyOnNthTypeOfDayButton->setFixedSize(yearlyOnNthTypeOfDayButton->sizeHint());
00367         QWhatsThis::add(yearlyOnNthTypeOfDayButton,
00368               i18n("Repeat the alarm on one day of the week, in the selected week of a month"));
00369         layout->addWidget(yearlyOnNthTypeOfDayButton);
00370 
00371         yearlyNthNumberEntry = new QComboBox(false, yearlyButtonGroup);
00372         for (i = 0;  i < 5;  ++i)
00373                 yearlyNthNumberEntry->insertItem(i18n(ordinal[i]));
00374         yearlyNthNumberEntry->insertItem(i18n("Last"));
00375         yearlyNthNumberEntry->setFixedSize(yearlyNthNumberEntry->sizeHint());
00376         QWhatsThis::add(yearlyNthNumberEntry,
00377               i18n("Select the week of the month in which to repeat the alarm"));
00378         layout->addWidget(yearlyNthNumberEntry);
00379 
00380         yearlyNthTypeOfDayEntry = new QComboBox(false, yearlyButtonGroup);
00381         for (i = 1;  i <= 7;  ++i)
00382                 yearlyNthTypeOfDayEntry->insertItem(KGlobal::locale()->weekDayName(i));    // starts Monday
00383         QWhatsThis::add(yearlyNthTypeOfDayEntry,
00384               i18n("Select the day of the week on which to repeat the alarm"));
00385         layout->addWidget(yearlyNthTypeOfDayEntry);
00386 
00387         layout = new QHBoxLayout(vlayout, KDialog::spacingHint());
00388         QLabel* label = new QLabel(i18n("first week of January", "of"), yearlyButtonGroup);
00389         label->setFixedSize(label->sizeHint());
00390         int spac = yearlyOnNthTypeOfDayButton->width() - label->width();
00391         if (spac > 0)
00392                 layout->addSpacing(spac);
00393         layout->addWidget(label);
00394 
00395         yeardayMonthComboBox = new QComboBox(yearlyButtonGroup);
00396         for (i = 1;  i <= 12;  ++i)
00397                 yeardayMonthComboBox->insertItem(KGlobal::locale()->monthName(i));
00398         yeardayMonthComboBox->setSizeLimit(12);
00399         QWhatsThis::add(yeardayMonthComboBox,
00400               i18n("Select the month of the year in which to repeat the alarm"));
00401         layout->addWidget(yeardayMonthComboBox);
00402         layout->addStretch();
00403 
00404 /*      layout = new QHBoxLayout(topLayout, KDialog::spacingHint());
00405         yearDayButton = new QRadioButton(i18n("Recur on day"), yearlyButtonGroup);
00406         yearDayButton->setFixedSize(yearDayButton->sizeHint());
00407         QWhatsThis::add(yearDayButton,
00408               i18n("Repeat the alarm on the selected day number in the year"));
00409         layout->addWidget(yearDayButton);
00410         yearDayEntry = new QSpinBox(1, 366, 1, yearlyButtonGroup);
00411         yearDayEntry->setFixedSize(yearDayEntry->sizeHint());
00412         QWhatsThis::add(yearDayEntry,
00413               i18n("Select the day number in the year on which to repeat the alarm"));
00414         layout->addWidget(yearDayEntry);
00415         layout->addStretch();*/
00416 
00417         mYearRuleFeb29ButtonId = yearlyButtonGroup->id(mYearRuleFeb29Button);
00418         yearMonthButtonId = yearlyButtonGroup->id(yearMonthButton);
00419 //      yearDayButtonId   = yearlyButtonGroup->id(yearDayButton);
00420         yearlyOnNthTypeOfDayButtonId = yearlyButtonGroup->id(yearlyOnNthTypeOfDayButton);
00421 
00422         connect(yearlyButtonGroup, SIGNAL(buttonSet(int)), SLOT(yearlyClicked(int)));
00423 }
00424 
00425 /******************************************************************************
00426  * Verify the consistency of the entered data.
00427  */
00428 QWidget* RecurrenceEdit::checkData(const QDateTime& startDateTime, bool& noTime) const
00429 {
00430         const_cast<RecurrenceEdit*>(this)->currStartDateTime = startDateTime;
00431         if (endDateButton->isChecked())
00432         {
00433                 noTime = !endTimeEdit->isEnabled();
00434                 QDate endDate = endDateEdit->date();
00435                 if (endDate < startDateTime.date())
00436                         return endDateEdit;
00437                 if (!noTime  &&  QDateTime(endDate, endTimeEdit->time()) < startDateTime)
00438                         return endTimeEdit;
00439         }
00440         return 0;
00441 }
00442 
00443 /******************************************************************************
00444  * Called when a recurrence period radio button is clicked.
00445  */
00446 void RecurrenceEdit::periodClicked(int id)
00447 {
00448         QFrame* frame;
00449         QString whatsThis;
00450         bool subdaily = (id == subdailyButtonId);
00451         if (subdaily)
00452         {
00453                 frame = noneFrame;
00454                 ruleButtonType = SUBDAILY;
00455         }
00456         else if (id == dailyButtonId)
00457         {
00458                 frame = noneFrame;
00459                 whatsThis = i18n("Enter the number of days between repetitions of the alarm");
00460                 ruleButtonType = DAILY;
00461         }
00462         else if (id == weeklyButtonId)
00463         {
00464                 frame = weeklyFrame;
00465                 whatsThis = i18n("Enter the number of weeks between repetitions of the alarm");
00466                 ruleButtonType = WEEKLY;
00467         }
00468         else if (id == monthlyButtonId)
00469         {
00470                 frame = monthlyFrame;
00471                 whatsThis = i18n("Enter the number of months between repetitions of the alarm");
00472                 ruleButtonType = MONTHLY;
00473         }
00474         else if (id == yearlyButtonId)
00475         {
00476                 frame = yearlyFrame;
00477                 whatsThis = i18n("Enter the number of years between repetitions of the alarm");
00478                 ruleButtonType = ANNUAL;
00479         }
00480         else
00481                 return;
00482 
00483         ruleStack->raiseWidget(frame);
00484         if (subdaily)
00485         {
00486                 recurFrequencyStack->raiseWidget(recurHourMinFrequency);
00487                 recurEveryLabel->setBuddy(recurHourMinFrequency);
00488         }
00489         else
00490         {
00491                 recurFrequencyStack->raiseWidget(recurFrequency);
00492                 recurEveryLabel->setBuddy(recurFrequency);
00493         }
00494         endTimeEdit->setEnabled(subdaily && endDateButton->isChecked());
00495         if (!subdaily)
00496                 QWhatsThis::add(recurFrequency, whatsThis);
00497         if (!noEmitTypeChanged)
00498                 emit typeChanged(ruleButtonType);
00499 }
00500 
00501 void RecurrenceEdit::disableRange(bool on)
00502 {
00503         if (on)
00504         {
00505                 endDateEdit->setEnabled(false);
00506                 endTimeEdit->setEnabled(false);
00507                 repeatCountEntry->setEnabled(false);
00508                 repeatCountLabel->setEnabled(false);
00509         }
00510 }
00511 
00512 void RecurrenceEdit::enableDurationRange(bool on)
00513 {
00514         if (on)
00515         {
00516                 endDateEdit->setEnabled(false);
00517                 endTimeEdit->setEnabled(false);
00518                 repeatCountEntry->setEnabled(true);
00519                 repeatCountLabel->setEnabled(true);
00520         }
00521 }
00522 
00523 void RecurrenceEdit::enableDateRange(bool on)
00524 {
00525         if (on)
00526         {
00527                 endDateEdit->setEnabled(true);
00528                 endTimeEdit->setEnabled(subdailyButton->isOn());
00529                 repeatCountEntry->setEnabled(false);
00530                 repeatCountLabel->setEnabled(false);
00531         }
00532 }
00533 
00534 /******************************************************************************
00535  * Called when a monthly recurrence type radio button is clicked.
00536  */
00537 void RecurrenceEdit::monthlyClicked(int id)
00538 {
00539         bool nthDay;
00540         if (id == onNthDayButtonId)
00541                 nthDay = true;
00542         else if (id == onNthTypeOfDayButtonId)
00543                 nthDay = false;
00544         else
00545                 return;
00546 
00547         nthDayEntry->setEnabled(nthDay);
00548         nthNumberEntry->setEnabled(!nthDay);
00549         nthTypeOfDayEntry->setEnabled(!nthDay);
00550 }
00551 
00552 /******************************************************************************
00553  * Called when a yearly recurrence type radio button is clicked.
00554  */
00555 void RecurrenceEdit::yearlyClicked(int id)
00556 {
00557         bool date;
00558         if (id == yearMonthButtonId
00559         ||  id == mYearRuleFeb29ButtonId)
00560                 date = true;
00561 //      else if (id == yearDayButtonId)
00562         else if (id == yearlyOnNthTypeOfDayButtonId)
00563                 date = false;
00564         else
00565                 return;
00566 
00567 //      yearDayEntry->setEnabled(!date);
00568         yearlyNthNumberEntry->setEnabled(!date);
00569         yearlyNthTypeOfDayEntry->setEnabled(!date);
00570         yeardayMonthComboBox->setEnabled(!date);
00571 }
00572 
00573 void RecurrenceEdit::showEvent(QShowEvent*)
00574 {
00575         recurEveryLabel->buddy()->setFocus();
00576         emit shown();
00577 }
00578 
00579 void RecurrenceEdit::unsetAllCheckboxes()
00580 {
00581         onNthDayButton->setChecked(false);
00582         onNthTypeOfDayButton->setChecked(false);
00583         mYearRuleFeb29Button->setChecked(false);
00584         yearMonthButton->setChecked(false);
00585 //      yearDayButton->setChecked(false);
00586         yearlyOnNthTypeOfDayButton->setChecked(false);
00587 
00588         for (int i = 0;  i < 7;  ++i)
00589                 dayBox[i]->setChecked(false);
00590 
00591         endDateButton->setChecked(false);
00592         noEndDateButton->setChecked(false);
00593         repeatCountButton->setChecked(false);
00594 }
00595 
00596 void RecurrenceEdit::setDefaults(const QDateTime& from)
00597 {
00598         // unset everything
00599         unsetAllCheckboxes();
00600 
00601         currStartDateTime = from;
00602         QDate fromDate = from.date();
00603 
00604         noEmitTypeChanged = true;
00605         int button;
00606         switch (theApp()->settings()->defaultRecurPeriod())
00607         {
00608                 case ANNUAL:  button = yearlyButtonId;   break;
00609                 case MONTHLY: button = monthlyButtonId;  break;
00610                 case WEEKLY:  button = weeklyButtonId;   break;
00611                 case DAILY:   button = dailyButtonId;    break;
00612                 case SUBDAILY:
00613                 default:      button = subdailyButtonId; break;
00614         }
00615         ruleButtonGroup->setButton(button);
00616         noEmitTypeChanged = false;
00617         noEndDateButton->setChecked(true);
00618 
00619         recurHourMinFrequency->setValue(1);
00620         recurFrequency->setValue(1);
00621 
00622         checkDay(fromDate.dayOfWeek());
00623         monthlyButtonGroup->setButton(onNthDayButtonId);    // date in month
00624         int day = fromDate.day() - 1;
00625         int dayOfWeek = fromDate.dayOfWeek() - 1;
00626         int month = fromDate.month() - 1;
00627         nthDayEntry->setCurrentItem(day);
00628         nthNumberEntry->setCurrentItem(day / 7);
00629         nthTypeOfDayEntry->setCurrentItem(dayOfWeek);
00630         yearlyButtonGroup->setButton(yearMonthButtonId);     // date in year
00631         setStartDate(fromDate);
00632 //      yearDayEntry->setValue(fromDate.dayOfYear());
00633         yearlyNthNumberEntry->setCurrentItem(day / 7);
00634         yearlyNthTypeOfDayEntry->setCurrentItem(dayOfWeek);
00635         yeardayMonthComboBox->setCurrentItem(month);
00636 
00637         endDateEdit->setDate(fromDate);
00638 }
00639 
00640 void RecurrenceEdit::setStartDate(const QDate& start)
00641 {
00642         int day = start.day();
00643         int month = start.month();
00644         if (month == 3  &&  day == 1  &&  !QDate::leapYear(start.year()))
00645         {
00646                 // For a start date of March 1st in a non-leap year, a recurrence on
00647                 // either February 29th or March 1st is permissible
00648                 mYearRuleFeb29Button->show();
00649         }
00650         else
00651                 mYearRuleFeb29Button->hide();
00652         yearMonthButton->setText(i18n("On 7th January", "O&n %1 %2")
00653                                          .arg(i18n(ordinal[day - 1]))
00654                                          .arg(KGlobal::locale()->monthName(month)));
00655         yearMonthButton->setMinimumSize(yearMonthButton->sizeHint());
00656 }
00657 
00658 void RecurrenceEdit::setEndDate(const QDate& start)
00659 {
00660         endDateEdit->setDate(start);
00661 }
00662 
00663 
00664 void RecurrenceEdit::checkDay(int day)
00665 {
00666         if (day >= 1  &&  day <= 7)
00667                 dayBox[day - 1]->setChecked(true);
00668 }
00669 
00670 void RecurrenceEdit::getCheckedDays(QBitArray& rDays)
00671 {
00672         rDays.fill(false);
00673         for (int i = 0;  i < 7;  ++i)
00674                 if (dayBox[i]->isChecked())
00675                         rDays.setBit(i, 1);
00676 }
00677 
00678 void RecurrenceEdit::setCheckedDays(QBitArray& rDays)
00679 {
00680         for (int i = 0;  i < 7;  ++i)
00681                 if (rDays.testBit(i))
00682                         dayBox[i]->setChecked(true);
00683 }
00684 
00685 /******************************************************************************
00686  * Set the state of all controls to reflect the data in the specified event.
00687  */
00688 void RecurrenceEdit::set(const KAlarmEvent& event)
00689 {
00690         setDefaults(event.mainDateTime());
00691         int repeatDuration;
00692         Recurrence* recurrence = event.recurrence();
00693         if (!recurrence)
00694                 return;
00695         switch (recurrence->doesRecur())
00696         {
00697                 case Recurrence::rMinutely:
00698                         ruleButtonGroup->setButton(subdailyButtonId);
00699                         recurHourMinFrequency->setValue(recurrence->frequency());
00700                         break;
00701 
00702                 case Recurrence::rDaily:
00703                         ruleButtonGroup->setButton(dailyButtonId);
00704                         break;
00705 
00706                 case Recurrence::rWeekly:
00707                 {
00708                         ruleButtonGroup->setButton(weeklyButtonId);
00709                         QBitArray rDays = recurrence->days();
00710                         setCheckedDays(rDays);
00711                         break;
00712                 }
00713                 case Recurrence::rMonthlyPos:    // on nth (Tuesday) of the month
00714                 {
00715                         // we only handle one possibility in the list right now,
00716                         // so I have hardcoded calls with first().  If we make the GUI
00717                         // more extended, this can be changed.
00718                         ruleButtonGroup->setButton(monthlyButtonId);
00719                         monthlyButtonGroup->setButton(onNthTypeOfDayButtonId);
00720                         QPtrList<Recurrence::rMonthPos> rmp = recurrence->monthPositions();
00721                         int i = rmp.first()->rPos - 1;
00722                         if (rmp.first()->negative)
00723                                 i = 5;
00724                         nthNumberEntry->setCurrentItem(i);
00725                         for (i = 0;  !rmp.first()->rDays.testBit(i);  ++i) ;
00726                         nthTypeOfDayEntry->setCurrentItem(i);
00727                         break;
00728                 }
00729                 case Recurrence::rMonthlyDay:     // on nth day of the month
00730                 {
00731                         ruleButtonGroup->setButton(monthlyButtonId);
00732                         monthlyButtonGroup->setButton(onNthDayButtonId);
00733                         QPtrList<int> rmd = recurrence->monthDays();
00734                         int i = *rmd.first() - 1;
00735                         nthDayEntry->setCurrentItem(i);
00736                         break;
00737                 }
00738                 case Recurrence::rYearlyMonth:   // in the nth month of the year
00739                 {
00740                         ruleButtonGroup->setButton(yearlyButtonId);
00741                         bool feb29 = (event.recursFeb29()  &&  !mYearRuleFeb29Button->isHidden());
00742                         yearlyButtonGroup->setButton(feb29 ? mYearRuleFeb29ButtonId : yearMonthButtonId);
00743                         break;
00744                 }
00745 /*                      case Recurrence::rYearlyDay:     // on the nth day of the year
00746                 {
00747                         ruleButtonGroup->setButton(yearlyButtonId);
00748                         yearlyButtonGroup->setButton(yearDayButtonId);
00749                         break;
00750                 }*/
00751                 case Recurrence::rYearlyPos:     // on the nth (Tuesday) of a month in the year
00752                 {
00753                         ruleButtonGroup->setButton(yearlyButtonId);
00754                         yearlyButtonGroup->setButton(yearlyOnNthTypeOfDayButtonId);
00755                         QPtrList<Recurrence::rMonthPos> rmp = recurrence->yearMonthPositions();
00756                         int i = rmp.first()->rPos - 1;
00757                         if (rmp.first()->negative)
00758                                 i = 5;
00759                         yearlyNthNumberEntry->setCurrentItem(i);
00760                         for (i = 0;  !rmp.first()->rDays.testBit(i);  ++i) ;
00761                                 yearlyNthTypeOfDayEntry->setCurrentItem(i);
00762                         QPtrList<int> rmd = recurrence->yearNums();
00763                         yeardayMonthComboBox->setCurrentItem(*rmd.first() - 1);
00764                         break;
00765                 }
00766                 case Recurrence::rNone:
00767                 default:
00768                         return;
00769         }
00770 
00771         recurFrequency->setValue(recurrence->frequency());
00772         repeatDuration = event.repeatCount();
00773 
00774         // get range information
00775         QDateTime endtime = currStartDateTime;
00776         if (repeatDuration == -1)
00777                 noEndDateButton->setChecked(true);
00778         else if (repeatDuration)
00779         {
00780                 repeatCountButton->setChecked(true);
00781                 repeatCountEntry->setValue(repeatDuration);
00782         }
00783         else
00784         {
00785                 endDateButton->setChecked(true);
00786                 endtime = recurrence->endDateTime();
00787                 endTimeEdit->setValue(endtime.time().hour()*60 + endtime.time().minute());
00788         }
00789         endDateEdit->setDate(endtime.date());
00790 }
00791 
00792 /******************************************************************************
00793  * Update the specified KAlarmEvent with the entered recurrence data.
00794  */
00795 void RecurrenceEdit::updateEvent(KAlarmEvent& event)
00796 {
00797         // Get end date and repeat count, common to all types of recurring events
00798         QDate  endDate;
00799         QTime  endTime;
00800         int    repeatCount;
00801         if (noEndDateButton->isChecked())
00802                 repeatCount = -1;
00803         else if (repeatCountButton->isChecked())
00804                 repeatCount = repeatCountEntry->value();
00805         else
00806         {
00807                 repeatCount = 0;
00808                 endDate = endDateEdit->date();
00809                 endTime = endTimeEdit->time();
00810         }
00811 
00812         // Set up the recurrence according to the type selected
00813         QButton* button = ruleButtonGroup->selected();
00814         if (button == subdailyButton)
00815         {
00816                 QDateTime endDateTime(endDate, endTime);
00817                 int frequency = recurHourMinFrequency->value();
00818                 event.setRecurMinutely(frequency, repeatCount, endDateTime);
00819         }
00820         else if (button == dailyButton)
00821         {
00822                 int frequency = recurFrequency->value();
00823                 event.setRecurDaily(frequency, repeatCount, endDate);
00824         }
00825         else if (button == weeklyButton)
00826         {
00827                 int frequency = recurFrequency->value();
00828                 QBitArray rDays(7);
00829                 getCheckedDays(rDays);
00830                 event.setRecurWeekly(frequency, rDays, repeatCount, endDate);
00831         }
00832         else if (button == monthlyButton)
00833         {
00834                 int frequency = recurFrequency->value();
00835                 if (onNthTypeOfDayButton->isChecked())
00836                 {
00837                         // it's by position
00838                         KAlarmEvent::MonthPos pos;
00839                         pos.days.fill(false);
00840                         pos.days.setBit(nthTypeOfDayEntry->currentItem());
00841                         int i = nthNumberEntry->currentItem() + 1;
00842                         pos.weeknum = (i <= 5) ? i : 5 - i;
00843                         QValueList<KAlarmEvent::MonthPos> poses;
00844                         poses.append(pos);
00845                         event.setRecurMonthlyByPos(frequency, poses, repeatCount, endDate);
00846                         event.setFirstRecurrence();
00847                 }
00848                 else
00849                 {
00850                         // it's by day
00851                         short daynum  = nthDayEntry->currentItem() + 1;
00852                         QValueList<int> daynums;
00853                         daynums.append(daynum);
00854                         event.setRecurMonthlyByDate(frequency, daynums, repeatCount, endDate);
00855                 }
00856         }
00857         else if (button == yearlyButton)
00858         {
00859                 int frequency = recurFrequency->value();
00860                 if (yearlyOnNthTypeOfDayButton->isChecked())
00861                 {
00862                         // it's by position
00863                         KAlarmEvent::MonthPos pos;
00864                         pos.days.fill(false);
00865                         pos.days.setBit(yearlyNthTypeOfDayEntry->currentItem());
00866                         int i = yearlyNthNumberEntry->currentItem() + 1;
00867                         pos.weeknum = (i <= 5) ? i : 5 - i;
00868                         QValueList<KAlarmEvent::MonthPos> poses;
00869                         poses.append(pos);
00870                         int month = yeardayMonthComboBox->currentItem() + 1;
00871                         QValueList<int> months;
00872                         months.append(month);
00873                         event.setRecurAnnualByPos(frequency, poses, months, repeatCount, endDate);
00874                         event.setFirstRecurrence();
00875                 }
00876 /*              else if (yearDayButton->isChecked())
00877                 {
00878                         // it's by day
00879                         int daynum = event.mainDate().dayOfYear();
00880                         QValueList<int> daynums;
00881                         daynums.append(daynum);
00882                         event.setRecurAnnualByDay(frequency, daynums, repeatCount, endDate);
00883                 }*/
00884                 else
00885                 {
00886                         bool feb29 = mYearRuleFeb29Button->isChecked();
00887                         QValueList<int> months;
00888                         months.append(feb29 ? 2 : event.mainDate().month());
00889                         event.setRecurAnnualByDate(frequency, months, feb29, repeatCount, endDate);
00890                 }
00891         }
00892 }
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sat Oct 18 02:47:27 2003 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001