00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kalarm.h"
00022
00023 #include <qlayout.h>
00024 #include <qgroupbox.h>
00025 #include <qhbox.h>
00026 #include <qpushbutton.h>
00027 #include <qwhatsthis.h>
00028
00029 #include <kdialog.h>
00030 #include <kmessagebox.h>
00031 #include <klocale.h>
00032
00033 #include "checkbox.h"
00034 #include "dateedit.h"
00035 #include "datetime.h"
00036 #include "radiobutton.h"
00037 #include "synchtimer.h"
00038 #include "timeedit.h"
00039 #include "timespinbox.h"
00040 #include "alarmtimewidget.moc"
00041
00042 static const QTime time_23_59(23, 59);
00043
00044
00045 const int AlarmTimeWidget::maxDelayTime = 99*60 + 59;
00046
00047 QString AlarmTimeWidget::i18n_w_TimeFromNow() { return i18n("Time from no&w:"); }
00048 QString AlarmTimeWidget::i18n_TimeAfterPeriod()
00049 {
00050 return i18n("Enter the length of time (in hours and minutes) after "
00051 "the current time to schedule the alarm.");
00052 }
00053
00054
00055
00056
00057
00058 AlarmTimeWidget::AlarmTimeWidget(const QString& groupBoxTitle, int mode, QWidget* parent, const char* name)
00059 : ButtonGroup(groupBoxTitle, parent, name),
00060 mMinDateTimeIsNow(false),
00061 mPastMax(false),
00062 mMinMaxTimeSet(false)
00063 {
00064 init(mode);
00065 }
00066
00067
00068
00069
00070 AlarmTimeWidget::AlarmTimeWidget(int mode, QWidget* parent, const char* name)
00071 : ButtonGroup(parent, name),
00072 mMinDateTimeIsNow(false),
00073 mPastMax(false),
00074 mMinMaxTimeSet(false)
00075 {
00076 setFrameStyle(QFrame::NoFrame);
00077 init(mode);
00078 }
00079
00080 void AlarmTimeWidget::init(int mode)
00081 {
00082 static const QString recurText = i18n("For a simple repetition, enter the date/time of the first occurrence.\n"
00083 "If a recurrence is configured, the start date/time will be adjusted "
00084 "to the first recurrence on or after the entered date/time.");
00085
00086 connect(this, SIGNAL(buttonSet(int)), SLOT(slotButtonSet(int)));
00087 QBoxLayout* topLayout = new QVBoxLayout(this, 0, KDialog::spacingHint());
00088 if (!title().isEmpty())
00089 {
00090 topLayout->setMargin(KDialog::marginHint());
00091 topLayout->addSpacing(fontMetrics().lineSpacing()/2);
00092 }
00093
00094
00095 mAtTimeRadio = new RadioButton(((mode & DEFER_TIME) ? i18n("&Defer to date/time:") : i18n("At &date/time:")), this, "atTimeRadio");
00096 mAtTimeRadio->setFixedSize(mAtTimeRadio->sizeHint());
00097 QWhatsThis::add(mAtTimeRadio,
00098 ((mode & DEFER_TIME) ? i18n("Reschedule the alarm to the specified date and time.")
00099 : i18n("Schedule the alarm at the specified date and time.")));
00100
00101
00102 mDateEdit = new DateEdit(this);
00103 mDateEdit->setFixedSize(mDateEdit->sizeHint());
00104 connect(mDateEdit, SIGNAL(dateChanged(const QDate&)), SLOT(dateTimeChanged()));
00105 static const QString enterDateText = i18n("Enter the date to schedule the alarm.");
00106 QWhatsThis::add(mDateEdit, ((mode & DEFER_TIME) ? enterDateText
00107 : QString("%1\n%2").arg(enterDateText).arg(recurText)));
00108 mAtTimeRadio->setFocusWidget(mDateEdit);
00109
00110
00111 QHBox* timeBox = new QHBox(this);
00112 timeBox->setSpacing(2*KDialog::spacingHint());
00113 mTimeEdit = new TimeEdit(timeBox);
00114 mTimeEdit->setFixedSize(mTimeEdit->sizeHint());
00115 connect(mTimeEdit, SIGNAL(valueChanged(int)), SLOT(dateTimeChanged()));
00116 static const QString enterTimeText = i18n("Enter the time to schedule the alarm.");
00117 QWhatsThis::add(mTimeEdit,
00118 ((mode & DEFER_TIME) ? QString("%1\n\n%2").arg(enterTimeText).arg(TimeSpinBox::shiftWhatsThis())
00119 : QString("%1\n%2\n\n%3").arg(enterTimeText).arg(recurText).arg(TimeSpinBox::shiftWhatsThis())));
00120
00121 mAnyTime = -1;
00122 if (mode & DEFER_TIME)
00123 {
00124 mAnyTimeAllowed = false;
00125 mAnyTimeCheckBox = 0;
00126 }
00127 else
00128 {
00129 mAnyTimeAllowed = true;
00130 mAnyTimeCheckBox = new CheckBox(i18n("An&y time"), timeBox);
00131 mAnyTimeCheckBox->setFixedSize(mAnyTimeCheckBox->sizeHint());
00132 connect(mAnyTimeCheckBox, SIGNAL(toggled(bool)), SLOT(slotAnyTimeToggled(bool)));
00133 QWhatsThis::add(mAnyTimeCheckBox, i18n("Schedule the alarm for any time during the day"));
00134 }
00135
00136
00137 mAfterTimeRadio = new RadioButton(((mode & DEFER_TIME) ? i18n("Defer for time &interval:") : i18n_w_TimeFromNow()),
00138 this, "afterTimeRadio");
00139 mAfterTimeRadio->setFixedSize(mAfterTimeRadio->sizeHint());
00140 QWhatsThis::add(mAfterTimeRadio,
00141 ((mode & DEFER_TIME) ? i18n("Reschedule the alarm for the specified time interval after now.")
00142 : i18n("Schedule the alarm after the specified time interval from now.")));
00143
00144
00145 mDelayTimeEdit = new TimeSpinBox(1, maxDelayTime, this);
00146 mDelayTimeEdit->setValue(1439);
00147 mDelayTimeEdit->setFixedSize(mDelayTimeEdit->sizeHint());
00148 connect(mDelayTimeEdit, SIGNAL(valueChanged(int)), SLOT(delayTimeChanged(int)));
00149 QWhatsThis::add(mDelayTimeEdit,
00150 ((mode & DEFER_TIME) ? QString("%1\n\n%2").arg(i18n_TimeAfterPeriod()).arg(TimeSpinBox::shiftWhatsThis())
00151 : QString("%1\n%2\n\n%3").arg(i18n_TimeAfterPeriod()).arg(recurText).arg(TimeSpinBox::shiftWhatsThis())));
00152 mAfterTimeRadio->setFocusWidget(mDelayTimeEdit);
00153
00154
00155 if (mode & NARROW)
00156 {
00157 QGridLayout* grid = new QGridLayout(topLayout, 2, 2, KDialog::spacingHint());
00158 grid->addWidget(mAtTimeRadio, 0, 0);
00159 grid->addWidget(mDateEdit, 0, 1, Qt::AlignAuto);
00160 grid->addWidget(timeBox, 1, 1, Qt::AlignAuto);
00161 grid->setColStretch(2, 1);
00162 topLayout->addStretch();
00163 QBoxLayout* layout = new QHBoxLayout(topLayout, KDialog::spacingHint());
00164 layout->addWidget(mAfterTimeRadio);
00165 layout->addWidget(mDelayTimeEdit);
00166 layout->addStretch();
00167 }
00168 else
00169 {
00170 QGridLayout* grid = new QGridLayout(topLayout, 2, 3, KDialog::spacingHint());
00171 grid->addWidget(mAtTimeRadio, 0, 0, Qt::AlignAuto);
00172 grid->addWidget(mDateEdit, 0, 1, Qt::AlignAuto);
00173 grid->addWidget(timeBox, 0, 2, Qt::AlignAuto);
00174 grid->setRowStretch(0, 1);
00175 grid->addWidget(mAfterTimeRadio, 1, 0, Qt::AlignAuto);
00176 grid->addWidget(mDelayTimeEdit, 1, 1, Qt::AlignAuto);
00177 grid->setColStretch(3, 1);
00178 topLayout->addStretch();
00179 }
00180
00181
00182 setButton(id(mAtTimeRadio));
00183
00184
00185 MinuteTimer::connect(this, SLOT(slotTimer()));
00186 }
00187
00188
00189
00190
00191 void AlarmTimeWidget::setReadOnly(bool ro)
00192 {
00193 mAtTimeRadio->setReadOnly(ro);
00194 mDateEdit->setReadOnly(ro);
00195 mTimeEdit->setReadOnly(ro);
00196 if (mAnyTimeCheckBox)
00197 mAnyTimeCheckBox->setReadOnly(ro);
00198 mAfterTimeRadio->setReadOnly(ro);
00199 mDelayTimeEdit->setReadOnly(ro);
00200 }
00201
00202
00203
00204
00205 void AlarmTimeWidget::selectTimeFromNow(int minutes)
00206 {
00207 mAfterTimeRadio->setChecked(true);
00208 slotButtonSet(1);
00209 if (minutes > 0)
00210 mDelayTimeEdit->setValue(minutes);
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 DateTime AlarmTimeWidget::getDateTime(int* minsFromNow, bool checkExpired, bool showErrorMessage, QWidget** errorWidget) const
00223 {
00224 if (minsFromNow)
00225 *minsFromNow = 0;
00226 if (errorWidget)
00227 *errorWidget = 0;
00228 QTime nowt = QTime::currentTime();
00229 QDateTime now(QDate::currentDate(), QTime(nowt.hour(), nowt.minute()));
00230 if (mAtTimeRadio->isOn())
00231 {
00232 bool anyTime = mAnyTimeAllowed && mAnyTimeCheckBox && mAnyTimeCheckBox->isChecked();
00233 if (!mDateEdit->isValid() || !mTimeEdit->isValid())
00234 {
00235
00236 if (!mDateEdit->isValid())
00237 {
00238 if (showErrorMessage)
00239 KMessageBox::sorry(const_cast<AlarmTimeWidget*>(this), i18n("Invalid date"));
00240 if (errorWidget)
00241 *errorWidget = mDateEdit;
00242 }
00243 else
00244 {
00245 if (showErrorMessage)
00246 KMessageBox::sorry(const_cast<AlarmTimeWidget*>(this), i18n("Invalid time"));
00247 if (errorWidget)
00248 *errorWidget = mTimeEdit;
00249 }
00250 return DateTime();
00251 }
00252
00253 DateTime result;
00254 if (anyTime)
00255 {
00256 result = mDateEdit->date();
00257 if (checkExpired && result.date() < now.date())
00258 {
00259 if (showErrorMessage)
00260 KMessageBox::sorry(const_cast<AlarmTimeWidget*>(this), i18n("Alarm date has already expired"));
00261 if (errorWidget)
00262 *errorWidget = mDateEdit;
00263 return DateTime();
00264 }
00265 }
00266 else
00267 {
00268 result.set(mDateEdit->date(), mTimeEdit->time());
00269 if (checkExpired && result <= now.addSecs(1))
00270 {
00271 if (showErrorMessage)
00272 KMessageBox::sorry(const_cast<AlarmTimeWidget*>(this), i18n("Alarm time has already expired"));
00273 if (errorWidget)
00274 *errorWidget = mTimeEdit;
00275 return DateTime();
00276 }
00277 }
00278 return result;
00279 }
00280 else
00281 {
00282 if (!mDelayTimeEdit->isValid())
00283 {
00284 if (showErrorMessage)
00285 KMessageBox::sorry(const_cast<AlarmTimeWidget*>(this), i18n("Invalid time"));
00286 if (errorWidget)
00287 *errorWidget = mDelayTimeEdit;
00288 return DateTime();
00289 }
00290 int delayMins = mDelayTimeEdit->value();
00291 if (minsFromNow)
00292 *minsFromNow = delayMins;
00293 return now.addSecs(delayMins * 60);
00294 }
00295 }
00296
00297
00298
00299
00300 void AlarmTimeWidget::setDateTime(const DateTime& dt)
00301 {
00302 if (dt.date().isValid())
00303 {
00304 mTimeEdit->setValue(dt.time());
00305 mDateEdit->setDate(dt.date());
00306 dateTimeChanged();
00307 }
00308 else
00309 {
00310 mTimeEdit->setValid(false);
00311 mDateEdit->setInvalid();
00312 mDelayTimeEdit->setValid(false);
00313 }
00314 if (mAnyTimeCheckBox)
00315 {
00316 bool anyTime = dt.isDateOnly();
00317 if (anyTime)
00318 mAnyTimeAllowed = true;
00319 mAnyTimeCheckBox->setChecked(anyTime);
00320 setAnyTime();
00321 }
00322 }
00323
00324
00325
00326
00327 void AlarmTimeWidget::setMinDateTimeIsCurrent()
00328 {
00329 mMinDateTimeIsNow = true;
00330 mMinDateTime = QDateTime();
00331 QDateTime now = QDateTime::currentDateTime();
00332 mDateEdit->setMinDate(now.date());
00333 setMaxMinTimeIf(now);
00334 }
00335
00336
00337
00338
00339
00340 void AlarmTimeWidget::setMinDateTime(const QDateTime& dt)
00341 {
00342 mMinDateTimeIsNow = false;
00343 mMinDateTime = dt;
00344 mDateEdit->setMinDate(dt.date());
00345 setMaxMinTimeIf(QDateTime::currentDateTime());
00346 }
00347
00348
00349
00350
00351
00352 void AlarmTimeWidget::setMaxDateTime(const DateTime& dt)
00353 {
00354 mPastMax = false;
00355 if (dt.isValid() && dt.isDateOnly())
00356 mMaxDateTime = dt.dateTime().addSecs(24*3600 - 60);
00357 else
00358 mMaxDateTime = dt.dateTime();
00359 mDateEdit->setMaxDate(mMaxDateTime.date());
00360 QDateTime now = QDateTime::currentDateTime();
00361 setMaxMinTimeIf(now);
00362 setMaxDelayTime(now);
00363 }
00364
00365
00366
00367
00368
00369 void AlarmTimeWidget::setMaxMinTimeIf(const QDateTime& now)
00370 {
00371 int mint = 0;
00372 QTime maxt = time_23_59;
00373 mMinMaxTimeSet = false;
00374 if (mMaxDateTime.isValid())
00375 {
00376 bool set = true;
00377 QDateTime minDT;
00378 if (mMinDateTimeIsNow)
00379 minDT = now.addSecs(60);
00380 else if (mMinDateTime.isValid())
00381 minDT = mMinDateTime;
00382 else
00383 set = false;
00384 if (set && mMaxDateTime.date() == minDT.date())
00385 {
00386
00387
00388 mint = minDT.time().hour()*60 + minDT.time().minute();
00389 maxt = mMaxDateTime.time();
00390 mMinMaxTimeSet = true;
00391 }
00392 }
00393 mTimeEdit->setMinValue(mint);
00394 mTimeEdit->setMaxValue(maxt);
00395 mTimeEdit->setWrapping(!mint && maxt == time_23_59);
00396 }
00397
00398
00399
00400
00401
00402 void AlarmTimeWidget::setMaxDelayTime(const QDateTime& now)
00403 {
00404 int maxVal = maxDelayTime;
00405 if (mMaxDateTime.isValid())
00406 {
00407 if (now.date().daysTo(mMaxDateTime.date()) < 100)
00408 {
00409 QDateTime dt(now.date(), QTime(now.time().hour(), now.time().minute(), 0));
00410 maxVal = dt.secsTo(mMaxDateTime) / 60;
00411 if (maxVal > maxDelayTime)
00412 maxVal = maxDelayTime;
00413 }
00414 }
00415 mDelayTimeEdit->setMaxValue(maxVal);
00416 }
00417
00418
00419
00420
00421 void AlarmTimeWidget::setAnyTime()
00422 {
00423 int old = mAnyTime;
00424 mAnyTime = (mAtTimeRadio->isOn() && mAnyTimeAllowed && mAnyTimeCheckBox && mAnyTimeCheckBox->isChecked()) ? 1 : 0;
00425 if (mAnyTime != old)
00426 emit anyTimeToggled(mAnyTime);
00427 }
00428
00429
00430
00431
00432 void AlarmTimeWidget::enableAnyTime(bool enable)
00433 {
00434 if (mAnyTimeCheckBox)
00435 {
00436 mAnyTimeAllowed = enable;
00437 bool at = mAtTimeRadio->isOn();
00438 mAnyTimeCheckBox->setEnabled(enable && at);
00439 if (at)
00440 mTimeEdit->setEnabled(!enable || !mAnyTimeCheckBox->isChecked());
00441 setAnyTime();
00442 }
00443 }
00444
00445
00446
00447
00448
00449 void AlarmTimeWidget::slotTimer()
00450 {
00451 QDateTime now;
00452 if (mMinDateTimeIsNow)
00453 {
00454
00455 now = QDateTime::currentDateTime();
00456 mDateEdit->setMinDate(now.date());
00457 }
00458 if (mMaxDateTime.isValid())
00459 {
00460 if (!now.isValid())
00461 now = QDateTime::currentDateTime();
00462 if (!mPastMax)
00463 {
00464
00465 if (now.date() >= mMaxDateTime.date())
00466 {
00467
00468 if (now.date() > mMaxDateTime.date()
00469 || !mAnyTime && now.time() > mTimeEdit->maxTime())
00470 {
00471 mPastMax = true;
00472 emit pastMax();
00473 }
00474 else if (mMinDateTimeIsNow && !mMinMaxTimeSet)
00475 {
00476
00477
00478 setMaxMinTimeIf(now);
00479 }
00480 }
00481 }
00482 setMaxDelayTime(now);
00483 }
00484
00485 if (mAtTimeRadio->isOn())
00486 dateTimeChanged();
00487 else
00488 delayTimeChanged(mDelayTimeEdit->value());
00489 }
00490
00491
00492
00493
00494
00495
00496 void AlarmTimeWidget::slotButtonSet(int)
00497 {
00498 bool at = mAtTimeRadio->isOn();
00499 mDateEdit->setEnabled(at);
00500 mTimeEdit->setEnabled(at && (!mAnyTimeAllowed || !mAnyTimeCheckBox || !mAnyTimeCheckBox->isChecked()));
00501 if (mAnyTimeCheckBox)
00502 mAnyTimeCheckBox->setEnabled(at && mAnyTimeAllowed);
00503
00504 QDateTime dt(mDateEdit->date(), mTimeEdit->time());
00505 int minutes = (QDateTime::currentDateTime().secsTo(dt) + 59) / 60;
00506 if (minutes <= 0)
00507 mDelayTimeEdit->setValid(true);
00508 mDelayTimeEdit->setEnabled(!at);
00509 setAnyTime();
00510 }
00511
00512
00513
00514
00515 void AlarmTimeWidget::slotAnyTimeToggled(bool on)
00516 {
00517 mTimeEdit->setEnabled((!mAnyTimeAllowed || !on) && mAtTimeRadio->isOn());
00518 setAnyTime();
00519 }
00520
00521
00522
00523
00524
00525 void AlarmTimeWidget::dateTimeChanged()
00526 {
00527 QDateTime dt(mDateEdit->date(), mTimeEdit->time());
00528 int minutes = (QDateTime::currentDateTime().secsTo(dt) + 59) / 60;
00529 bool blocked = mDelayTimeEdit->signalsBlocked();
00530 mDelayTimeEdit->blockSignals(true);
00531 if (minutes <= 0 || minutes > mDelayTimeEdit->maxValue())
00532 mDelayTimeEdit->setValid(false);
00533 else
00534 mDelayTimeEdit->setValue(minutes);
00535 mDelayTimeEdit->blockSignals(blocked);
00536 }
00537
00538
00539
00540
00541
00542 void AlarmTimeWidget::delayTimeChanged(int minutes)
00543 {
00544 if (mDelayTimeEdit->isValid())
00545 {
00546 QDateTime dt = QDateTime::currentDateTime().addSecs(minutes * 60);
00547 bool blockedT = mTimeEdit->signalsBlocked();
00548 bool blockedD = mDateEdit->signalsBlocked();
00549 mTimeEdit->blockSignals(true);
00550 mDateEdit->blockSignals(true);
00551 mTimeEdit->setValue(dt.time());
00552 mDateEdit->setDate(dt.date());
00553 mTimeEdit->blockSignals(blockedT);
00554 mDateEdit->blockSignals(blockedD);
00555 }
00556 }