33 #include "alarmtimewidget.moc"
35 #include <kalarmcal/datetime.h>
37 #include <kdatecombobox.h>
42 #include <QGridLayout>
52 return i18nc(
"@info/plain",
"Enter the length of time (in hours and minutes) after "
53 "the current time to schedule the alarm.");
62 mMinDateTimeIsNow(false),
66 init(mode, groupBoxTitle);
74 mMinDateTimeIsNow(false),
81 void AlarmTimeWidget::init(Mode mode,
const QString& title)
83 static const QString
recurText = i18nc(
"@info/plain",
84 "If a recurrence is configured, the start date/time will be adjusted "
85 "to the first recurrence on or after the entered date/time.");
86 static const QString tzText = i18nc(
"@info/plain",
87 "This uses KAlarm's default time zone, set in the Configuration dialog.");
94 QBoxLayout* layout =
new QVBoxLayout(
this);
96 layout->setSpacing(0);
98 layout->addWidget(topWidget);
102 connect(mButtonGroup, SIGNAL(buttonSet(QAbstractButton*)), SLOT(slotButtonSet(QAbstractButton*)));
103 QVBoxLayout* topLayout =
new QVBoxLayout(topWidget);
104 topLayout->setSpacing(KDialog::spacingHint());
105 topLayout->setMargin(title.isEmpty() ? 0 : KDialog::marginHint());
108 mAtTimeRadio =
new RadioButton((mDeferring ? i18nc(
"@option:radio",
"Defer to date/time:") : i18nc(
"@option:radio",
"At date/time:")), topWidget);
109 mAtTimeRadio->setFixedSize(mAtTimeRadio->sizeHint());
110 mAtTimeRadio->setWhatsThis(mDeferring ? i18nc(
"@info:whatsthis",
"Reschedule the alarm to the specified date and time.")
111 : i18nc(
"@info:whatsthis",
"Specify the date, or date and time, to schedule the alarm."));
115 mDateEdit =
new KDateComboBox(topWidget);
116 mDateEdit->setOptions(KDateComboBox::EditDate | KDateComboBox::SelectDate | KDateComboBox::DatePicker);
117 connect(mDateEdit, SIGNAL(dateEntered(QDate)), SLOT(dateTimeChanged()));
118 mDateEdit->setWhatsThis(i18nc(
"@info:whatsthis",
119 "<para>Enter the date to schedule the alarm.</para>"
120 "<para>%1</para>", (mDeferring ? tzText : recurText)));
125 timeBox->setSpacing(2*KDialog::spacingHint());
127 mTimeEdit->setFixedSize(mTimeEdit->sizeHint());
128 connect(mTimeEdit, SIGNAL(valueChanged(
int)), SLOT(dateTimeChanged()));
129 mTimeEdit->setWhatsThis(i18nc(
"@info:whatsthis",
130 "<para>Enter the time to schedule the alarm.</para>"
135 if (mode == DEFER_TIME)
137 mAnyTimeAllowed =
false;
138 mAnyTimeCheckBox = 0;
142 mAnyTimeAllowed =
true;
143 mAnyTimeCheckBox =
new CheckBox(i18nc(
"@option:check",
"Any time"), timeBox);
144 mAnyTimeCheckBox->setFixedSize(mAnyTimeCheckBox->sizeHint());
145 connect(mAnyTimeCheckBox, SIGNAL(toggled(
bool)), SLOT(slotAnyTimeToggled(
bool)));
146 mAnyTimeCheckBox->setWhatsThis(i18nc(
"@info:whatsthis",
147 "Check to specify only a date (without a time) for the alarm. The alarm will trigger at the first opportunity on the selected date."));
151 mAfterTimeRadio =
new RadioButton((mDeferring ? i18nc(
"@option:radio",
"Defer for time interval:") : i18nc(
"@option:radio",
"Time from now:")), topWidget);
152 mAfterTimeRadio->setFixedSize(mAfterTimeRadio->sizeHint());
153 mAfterTimeRadio->setWhatsThis(mDeferring ? i18nc(
"@info:whatsthis",
"Reschedule the alarm for the specified time interval after now.")
154 : i18nc(
"@info:whatsthis",
"Schedule the alarm after the specified time interval from now."));
155 mButtonGroup->
addButton(mAfterTimeRadio);
160 mDelayTimeEdit->setFixedSize(mDelayTimeEdit->
sizeHint());
161 connect(mDelayTimeEdit, SIGNAL(valueChanged(
int)), SLOT(delayTimeChanged(
int)));
167 QGridLayout* grid =
new QGridLayout();
169 topLayout->addLayout(grid);
172 grid->addWidget(mAtTimeRadio, 0, 0);
173 grid->addWidget(mDateEdit, 0, 1, Qt::AlignLeft);
174 grid->addWidget(timeBox, 1, 1, Qt::AlignLeft);
175 grid->setColumnStretch(2, 1);
176 topLayout->addStretch();
177 QHBoxLayout* layout =
new QHBoxLayout();
178 topLayout->addLayout(layout);
179 layout->addWidget(mAfterTimeRadio);
180 layout->addWidget(mDelayTimeEdit);
181 layout->addStretch();
185 grid->addWidget(mAtTimeRadio, 0, 0, Qt::AlignLeft);
186 grid->addWidget(mDateEdit, 0, 1, Qt::AlignLeft);
187 grid->addWidget(timeBox, 0, 2, Qt::AlignLeft);
188 grid->setRowStretch(1, 1);
189 grid->addWidget(mAfterTimeRadio, 2, 0, Qt::AlignLeft);
190 grid->addWidget(mDelayTimeEdit, 2, 1, Qt::AlignLeft);
193 mTimeZoneButton =
new PushButton(i18nc(
"@action:button",
"Time Zone..."), topWidget);
194 connect(mTimeZoneButton, SIGNAL(clicked()), SLOT(showTimeZoneSelector()));
195 mTimeZoneButton->setWhatsThis(i18nc(
"@info:whatsthis",
196 "Choose a time zone for this alarm which is different from the default time zone set in KAlarm's configuration dialog."));
197 grid->addWidget(mTimeZoneButton, 2, 2, 1, 2, Qt::AlignRight);
199 grid->setColumnStretch(2, 1);
200 topLayout->addStretch();
202 QHBoxLayout* layout =
new QHBoxLayout();
203 topLayout->addLayout(layout);
204 layout->setSpacing(2*KDialog::spacingHint());
207 mTimeZoneBox =
new KHBox(topWidget);
208 mTimeZoneBox->setMargin(0);
209 mTimeZoneBox->setSpacing(KDialog::spacingHint());
210 QLabel* label =
new QLabel(i18nc(
"@label:listbox",
"Time zone:"), mTimeZoneBox);
212 mTimeZone->setMaxVisibleItems(15);
213 connect(mTimeZone, SIGNAL(activated(
int)), SLOT(slotTimeZoneChanged()));
214 mTimeZoneBox->setWhatsThis(i18nc(
"@info:whatsthis",
"Select the time zone to use for this alarm."));
215 label->setBuddy(mTimeZone);
216 layout->addWidget(mTimeZoneBox);
219 mNoTimeZone =
new CheckBox(i18nc(
"@option:check",
"Ignore time zone"), topWidget);
220 connect(mNoTimeZone, SIGNAL(toggled(
bool)), SLOT(slotTimeZoneToggled(
bool)));
221 mNoTimeZone->setWhatsThis(i18nc(
"@info:whatsthis",
222 "<para>Check to use the local computer time, ignoring time zones.</para>"
223 "<para>You are recommended not to use this option if the alarm has a "
224 "recurrence specified in hours/minutes. If you do, the alarm may "
225 "occur at unexpected times after daylight saving time shifts.</para>"));
226 layout->addWidget(mNoTimeZone);
227 layout->addStretch();
230 mTimeZoneBox->hide();
235 mAtTimeRadio->setChecked(
true);
236 slotButtonSet(mAtTimeRadio);
248 mDateEdit->setOptions(ro ? KDateComboBox::Options(0) : KDateComboBox::EditDate | KDateComboBox::SelectDate | KDateComboBox::DatePicker);
250 if (mAnyTimeCheckBox)
266 mAfterTimeRadio->setChecked(
true);
286 KDateTime now = KDateTime::currentUtcDateTime();
287 now.setTime(QTime(now.time().hour(), now.time().minute(), 0));
288 if (!mAtTimeRadio->isChecked())
290 if (!mDelayTimeEdit->
isValid())
292 if (showErrorMessage)
295 *errorWidget = mDelayTimeEdit;
298 int delayMins = mDelayTimeEdit->
value();
300 *minsFromNow = delayMins;
301 return now.addSecs(delayMins * 60).toTimeSpec(mTimeSpec);
305 bool dateOnly = mAnyTimeAllowed && mAnyTimeCheckBox && mAnyTimeCheckBox->isChecked();
306 if (!mDateEdit->date().isValid() || !mTimeEdit->
isValid())
309 if (!mDateEdit->date().isValid())
311 if (showErrorMessage)
314 *errorWidget = mDateEdit;
318 if (showErrorMessage)
321 *errorWidget = mTimeEdit;
329 result = KDateTime(mDateEdit->date(), mTimeSpec);
330 if (checkExpired && result.date() < now.date())
332 if (showErrorMessage)
333 KAMessageBox::sorry(const_cast<AlarmTimeWidget*>(
this), i18nc(
"@info",
"Alarm date has already expired"));
335 *errorWidget = mDateEdit;
341 result = KDateTime(mDateEdit->date(), mTimeEdit->
time(), mTimeSpec);
342 if (checkExpired && result <= now.addSecs(1))
344 if (showErrorMessage)
345 KAMessageBox::sorry(const_cast<AlarmTimeWidget*>(
this), i18nc(
"@info",
"Alarm time has already expired"));
347 *errorWidget = mTimeEdit;
362 mTimeSpec = dt.timeSpec().isValid() ? dt.timeSpec() : KDateTime::LocalZone;
365 KTimeZone tz = dt.timeZone();
366 mNoTimeZone->setChecked(!tz.isValid());
368 slotTimeZoneChanged();
371 if (dt.date().isValid())
373 mTimeEdit->
setValue(dt.effectiveTime());
374 mDateEdit->setDate(dt.date());
380 mDateEdit->setDate(QDate());
383 if (mAnyTimeCheckBox)
385 bool dateOnly = dt.isDateOnly();
387 mAnyTimeAllowed =
true;
388 mAnyTimeCheckBox->setChecked(dateOnly);
398 mMinDateTimeIsNow =
true;
399 mMinDateTime = KDateTime();
400 KDateTime now = KDateTime::currentDateTime(mTimeSpec);
401 mDateEdit->setMinimumDate(now.date());
402 setMaxMinTimeIf(now);
411 mMinDateTimeIsNow =
false;
412 mMinDateTime = dt.toTimeSpec(mTimeSpec);
413 mDateEdit->setMinimumDate(mMinDateTime.date());
414 setMaxMinTimeIf(KDateTime::currentDateTime(mTimeSpec));
424 if (dt.isValid() && dt.isDateOnly())
425 mMaxDateTime = dt.effectiveKDateTime().addSecs(24*3600 - 60).toTimeSpec(mTimeSpec);
427 mMaxDateTime = dt.kDateTime().toTimeSpec(mTimeSpec);
428 mDateEdit->setMaximumDate(mMaxDateTime.date());
429 KDateTime now = KDateTime::currentDateTime(mTimeSpec);
430 setMaxMinTimeIf(now);
431 setMaxDelayTime(now);
438 void AlarmTimeWidget::setMaxMinTimeIf(
const KDateTime& now)
442 mMinMaxTimeSet =
false;
443 if (mMaxDateTime.isValid())
447 if (mMinDateTimeIsNow)
448 minDT = now.addSecs(60);
449 else if (mMinDateTime.isValid())
450 minDT = mMinDateTime;
453 if (set && mMaxDateTime.date() == minDT.date())
457 mint = minDT.time().hour()*60 + minDT.time().minute();
458 maxt = mMaxDateTime.time();
459 mMinMaxTimeSet =
true;
471 void AlarmTimeWidget::setMaxDelayTime(
const KDateTime& now)
474 if (mMaxDateTime.isValid())
476 if (now.date().daysTo(mMaxDateTime.date()) < 100)
479 dt.setTime(QTime(now.time().hour(), now.time().minute(), 0));
480 maxVal = dt.secsTo(mMaxDateTime) / 60;
491 void AlarmTimeWidget::setAnyTime()
494 mAnyTime = (mAtTimeRadio->isChecked() && mAnyTimeAllowed && mAnyTimeCheckBox && mAnyTimeCheckBox->isChecked()) ? 1 : 0;
504 if (mAnyTimeCheckBox)
506 mAnyTimeAllowed = enable;
507 bool at = mAtTimeRadio->isChecked();
508 mAnyTimeCheckBox->setEnabled(enable && at);
510 mTimeEdit->setEnabled(!enable || !mAnyTimeCheckBox->isChecked());
519 void AlarmTimeWidget::updateTimes()
522 if (mMinDateTimeIsNow)
525 now = KDateTime::currentDateTime(mTimeSpec);
526 mDateEdit->setMinimumDate(now.date());
528 if (mMaxDateTime.isValid())
531 now = KDateTime::currentDateTime(mTimeSpec);
535 if (now.date() >= mMaxDateTime.date())
538 if (now.date() > mMaxDateTime.date()
539 || (!mAnyTime && now.time() > mTimeEdit->
maxTime()))
544 else if (mMinDateTimeIsNow && !mMinMaxTimeSet)
548 setMaxMinTimeIf(now);
552 setMaxDelayTime(now);
555 if (mAtTimeRadio->isChecked())
558 delayTimeChanged(mDelayTimeEdit->
value());
566 void AlarmTimeWidget::slotButtonSet(QAbstractButton*)
568 bool at = mAtTimeRadio->isChecked();
569 mDateEdit->setEnabled(at);
570 mTimeEdit->setEnabled(at && (!mAnyTimeAllowed || !mAnyTimeCheckBox || !mAnyTimeCheckBox->isChecked()));
571 if (mAnyTimeCheckBox)
572 mAnyTimeCheckBox->setEnabled(at && mAnyTimeAllowed);
574 KDateTime att(mDateEdit->date(), mTimeEdit->
time(), mTimeSpec);
575 int minutes = (KDateTime::currentUtcDateTime().secsTo(att) + 59) / 60;
585 void AlarmTimeWidget::slotAnyTimeToggled(
bool on)
587 on = (on && mAnyTimeAllowed);
588 mTimeEdit->setEnabled(!on && mAtTimeRadio->isChecked());
591 emit
changed(KDateTime(mDateEdit->date(), mTimeSpec));
593 emit
changed(KDateTime(mDateEdit->date(), mTimeEdit->
time(), mTimeSpec));
600 void AlarmTimeWidget::slotTimeZoneChanged()
602 if (mNoTimeZone->isChecked())
603 mTimeSpec = KDateTime::ClockTime;
606 KTimeZone tz = mTimeZone->
timeZone();
607 mTimeSpec = tz.isValid() ? KDateTime::Spec(tz) : KDateTime::LocalZone;
613 showTimeZoneSelector();
615 mMinDateTime = mMinDateTime.toTimeSpec(mTimeSpec);
616 mMaxDateTime = mMaxDateTime.toTimeSpec(mTimeSpec);
623 void AlarmTimeWidget::slotTimeZoneToggled(
bool on)
625 mTimeZone->setEnabled(!on);
626 slotTimeZoneChanged();
633 void AlarmTimeWidget::showTimeZoneSelector()
635 mTimeZoneButton->hide();
636 mTimeZoneBox->show();
647 if (!mTimeZoneBox->isVisible())
648 mTimeZoneButton->show();
651 mTimeZoneButton->hide();
658 void AlarmTimeWidget::dateTimeChanged()
660 KDateTime dt(mDateEdit->date(), mTimeEdit->
time(), mTimeSpec);
661 int minutes = (KDateTime::currentUtcDateTime().secsTo(dt) + 59) / 60;
662 bool blocked = mDelayTimeEdit->signalsBlocked();
663 mDelayTimeEdit->blockSignals(
true);
664 if (minutes <= 0 || minutes > mDelayTimeEdit->
maximum())
668 mDelayTimeEdit->blockSignals(blocked);
669 if (mAnyTimeAllowed && mAnyTimeCheckBox && mAnyTimeCheckBox->isChecked())
670 emit
changed(KDateTime(dt.date(), mTimeSpec));
679 void AlarmTimeWidget::delayTimeChanged(
int minutes)
683 QDateTime dt = KDateTime::currentUtcDateTime().addSecs(minutes * 60).toTimeSpec(mTimeSpec).dateTime();
684 bool blockedT = mTimeEdit->signalsBlocked();
685 bool blockedD = mDateEdit->signalsBlocked();
686 mTimeEdit->blockSignals(
true);
687 mDateEdit->blockSignals(
true);
689 mDateEdit->setDate(dt.date());
690 mTimeEdit->blockSignals(blockedT);
691 mDateEdit->blockSignals(blockedD);
692 emit
changed(KDateTime(dt.date(), dt.time(), mTimeSpec));
virtual void setReadOnly(bool readOnly)
virtual void setEnabled(bool enabled)
virtual void setReadOnly(bool readOnly)
KTimeZone timeZone() const
void setMinimum(int minutes)
virtual QSize sizeHint() const
static KTimeZone timeZone(bool reload=false)
virtual void setReadOnly(bool readOnly)
static void connect(QObject *receiver, const char *member)
virtual void setReadOnly(bool readOnly)
void setWrapping(bool on)
virtual void setValue(int minutes)
void set(quint32, const QString &, const QString &, const QString &, const QString &, time_t)
void setTimeZone(const KTimeZone &tz)
static void sorry(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Options(Notify|WindowModal))
virtual void setValue(int minutes)
void setValid(bool valid)
static QString shiftWhatsThis()
virtual void setMaximum(int minutes)
void setMaximum(int minutes)
QString recurText(const KAEvent &event)