2 * alarmtimewidget.cpp - alarm date/time entry widget
4 * Copyright © 2001-2011 by David Jarvie <djarvie@kde.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include "buttongroup.h"
25 #include "messagebox.h"
26 #include "preferences.h"
27 #include "pushbutton.h"
28 #include "radiobutton.h"
29 #include "synchtimer.h"
31 #include "timespinbox.h"
32 #include "timezonecombo.h"
33 #include "alarmtimewidget.h"
35 #include <kalarmcal/datetime.h>
37 #include <kdatecombobox.h>
38 #include <KLocalizedString>
41 #include <QGridLayout>
43 #include <QHBoxLayout>
45 static const QTime
time_23_59(23, 59);
48 const int AlarmTimeWidget::maxDelayTime
= 999*60 + 59; // < 1000 hours
50 QString
AlarmTimeWidget::i18n_TimeAfterPeriod()
52 return i18nc("@info", "Enter the length of time (in hours and minutes) after "
53 "the current time to schedule the alarm.");
57 /******************************************************************************
58 * Construct a widget with a group box and title.
60 AlarmTimeWidget::AlarmTimeWidget(const QString
& groupBoxTitle
, Mode mode
, QWidget
* parent
)
62 mMinDateTimeIsNow(false),
66 init(mode
, groupBoxTitle
);
69 /******************************************************************************
70 * Construct a widget without a group box or title.
72 AlarmTimeWidget::AlarmTimeWidget(Mode mode
, QWidget
* parent
)
74 mMinDateTimeIsNow(false),
81 void AlarmTimeWidget::init(Mode mode
, const QString
& title
)
83 static const QString recurText
= i18nc("@info",
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",
87 "This uses KAlarm's default time zone, set in the Configuration dialog.");
94 QBoxLayout
* layout
= new QVBoxLayout(this);
96 layout
->setSpacing(0);
97 topWidget
= new QGroupBox(title
, this);
98 layout
->addWidget(topWidget
);
100 mDeferring
= mode
& DEFER_TIME
;
101 mButtonGroup
= new ButtonGroup(this);
102 connect(mButtonGroup
, &ButtonGroup::buttonSet
, this, &AlarmTimeWidget::slotButtonSet
);
103 QVBoxLayout
* topLayout
= new QVBoxLayout(topWidget
);
104 topLayout
->setSpacing(style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing
));
105 topLayout
->setMargin(title
.isEmpty() ? 0 : style()->pixelMetric(QStyle::PM_DefaultChildMargin
));
107 // At time radio button/label
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."));
112 mButtonGroup
->addButton(mAtTimeRadio
);
115 mDateEdit
= new KDateComboBox(topWidget
);
116 mDateEdit
->setOptions(KDateComboBox::EditDate
| KDateComboBox::SelectDate
| KDateComboBox::DatePicker
);
117 connect(mDateEdit
, &KDateComboBox::dateEntered
, this, &AlarmTimeWidget::dateTimeChanged
);
118 mDateEdit
->setWhatsThis(xi18nc("@info:whatsthis",
119 "<para>Enter the date to schedule the alarm.</para>"
120 "<para>%1</para>", (mDeferring
? tzText
: recurText
)));
121 mAtTimeRadio
->setFocusWidget(mDateEdit
);
123 // Time edit box and Any time checkbox
124 QWidget
* timeBox
= new QWidget(topWidget
);
125 QHBoxLayout
* timeBoxHLayout
= new QHBoxLayout(timeBox
);
126 timeBoxHLayout
->setMargin(0);
127 timeBoxHLayout
->setSpacing(2 * style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing
));
128 mTimeEdit
= new TimeEdit(timeBox
);
129 timeBoxHLayout
->addWidget(mTimeEdit
);
130 mTimeEdit
->setFixedSize(mTimeEdit
->sizeHint());
131 connect(mTimeEdit
, &TimeEdit::valueChanged
, this, &AlarmTimeWidget::dateTimeChanged
);
132 mTimeEdit
->setWhatsThis(xi18nc("@info:whatsthis",
133 "<para>Enter the time to schedule the alarm.</para>"
135 "<para>%2</para>", (mDeferring
? tzText
: recurText
), TimeSpinBox::shiftWhatsThis()));
137 mAnyTime
= -1; // current status is uninitialised
138 if (mode
== DEFER_TIME
)
140 mAnyTimeAllowed
= false;
141 mAnyTimeCheckBox
= Q_NULLPTR
;
145 mAnyTimeAllowed
= true;
146 mAnyTimeCheckBox
= new CheckBox(i18nc("@option:check", "Any time"), timeBox
);
147 timeBoxHLayout
->addWidget(mAnyTimeCheckBox
);
148 mAnyTimeCheckBox
->setFixedSize(mAnyTimeCheckBox
->sizeHint());
149 connect(mAnyTimeCheckBox
, &CheckBox::toggled
, this, &AlarmTimeWidget::slotAnyTimeToggled
);
150 mAnyTimeCheckBox
->setWhatsThis(i18nc("@info:whatsthis",
151 "Check to specify only a date (without a time) for the alarm. The alarm will trigger at the first opportunity on the selected date."));
154 // 'Time from now' radio button/label
155 mAfterTimeRadio
= new RadioButton((mDeferring
? i18nc("@option:radio", "Defer for time interval:") : i18nc("@option:radio", "Time from now:")), topWidget
);
156 mAfterTimeRadio
->setFixedSize(mAfterTimeRadio
->sizeHint());
157 mAfterTimeRadio
->setWhatsThis(mDeferring
? i18nc("@info:whatsthis", "Reschedule the alarm for the specified time interval after now.")
158 : i18nc("@info:whatsthis", "Schedule the alarm after the specified time interval from now."));
159 mButtonGroup
->addButton(mAfterTimeRadio
);
161 // Delay time spin box
162 mDelayTimeEdit
= new TimeSpinBox(1, maxDelayTime
, topWidget
);
163 mDelayTimeEdit
->setValue(1439);
164 mDelayTimeEdit
->setFixedSize(mDelayTimeEdit
->sizeHint());
165 connect(mDelayTimeEdit
, static_cast<void (TimeSpinBox::*)(int)>(&TimeSpinBox::valueChanged
), this, &AlarmTimeWidget::delayTimeChanged
);
166 mDelayTimeEdit
->setWhatsThis(mDeferring
? xi18nc("@info:whatsthis", "<para>%1</para><para>%2</para>", i18n_TimeAfterPeriod(), TimeSpinBox::shiftWhatsThis())
167 : xi18nc("@info:whatsthis", "<para>%1</para><para>%2</para><para>%3</para>", i18n_TimeAfterPeriod(), recurText
, TimeSpinBox::shiftWhatsThis()));
168 mAfterTimeRadio
->setFocusWidget(mDelayTimeEdit
);
170 // Set up the layout, either narrow or wide
171 QGridLayout
* grid
= new QGridLayout();
173 topLayout
->addLayout(grid
);
176 grid
->addWidget(mAtTimeRadio
, 0, 0);
177 grid
->addWidget(mDateEdit
, 0, 1, Qt::AlignLeft
);
178 grid
->addWidget(timeBox
, 1, 1, Qt::AlignLeft
);
179 grid
->setColumnStretch(2, 1);
180 topLayout
->addStretch();
181 QHBoxLayout
* layout
= new QHBoxLayout();
182 topLayout
->addLayout(layout
);
183 layout
->addWidget(mAfterTimeRadio
);
184 layout
->addWidget(mDelayTimeEdit
);
185 layout
->addStretch();
189 grid
->addWidget(mAtTimeRadio
, 0, 0, Qt::AlignLeft
);
190 grid
->addWidget(mDateEdit
, 0, 1, Qt::AlignLeft
);
191 grid
->addWidget(timeBox
, 0, 2, Qt::AlignLeft
);
192 grid
->setRowStretch(1, 1);
193 grid
->addWidget(mAfterTimeRadio
, 2, 0, Qt::AlignLeft
);
194 grid
->addWidget(mDelayTimeEdit
, 2, 1, Qt::AlignLeft
);
196 // Time zone selection push button
197 mTimeZoneButton
= new PushButton(i18nc("@action:button", "Time Zone..."), topWidget
);
198 connect(mTimeZoneButton
, &PushButton::clicked
, this, &AlarmTimeWidget::showTimeZoneSelector
);
199 mTimeZoneButton
->setWhatsThis(i18nc("@info:whatsthis",
200 "Choose a time zone for this alarm which is different from the default time zone set in KAlarm's configuration dialog."));
201 grid
->addWidget(mTimeZoneButton
, 2, 2, 1, 2, Qt::AlignRight
);
203 grid
->setColumnStretch(2, 1);
204 topLayout
->addStretch();
206 QHBoxLayout
* layout
= new QHBoxLayout();
207 topLayout
->addLayout(layout
);
208 layout
->setSpacing(2 * style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing
));
210 // Time zone selector
211 mTimeZoneBox
= new QWidget(topWidget
); // this is to control the QWhatsThis text display area
212 QHBoxLayout
* hlayout
= new QHBoxLayout(mTimeZoneBox
);
213 hlayout
->setMargin(0);
214 QLabel
* label
= new QLabel(i18nc("@label:listbox", "Time zone:"), mTimeZoneBox
);
215 hlayout
->addWidget(label
);
216 mTimeZone
= new TimeZoneCombo(mTimeZoneBox
);
217 hlayout
->addWidget(mTimeZone
);
218 mTimeZone
->setMaxVisibleItems(15);
219 connect(mTimeZone
, static_cast<void (TimeZoneCombo::*)(int)>(&TimeZoneCombo::activated
), this, &AlarmTimeWidget::slotTimeZoneChanged
);
220 mTimeZoneBox
->setWhatsThis(i18nc("@info:whatsthis", "Select the time zone to use for this alarm."));
221 label
->setBuddy(mTimeZone
);
222 layout
->addWidget(mTimeZoneBox
);
224 // Time zone checkbox
225 mNoTimeZone
= new CheckBox(i18nc("@option:check", "Ignore time zone"), topWidget
);
226 connect(mNoTimeZone
, &CheckBox::toggled
, this, &AlarmTimeWidget::slotTimeZoneToggled
);
227 mNoTimeZone
->setWhatsThis(xi18nc("@info:whatsthis",
228 "<para>Check to use the local computer time, ignoring time zones.</para>"
229 "<para>You are recommended not to use this option if the alarm has a "
230 "recurrence specified in hours/minutes. If you do, the alarm may "
231 "occur at unexpected times after daylight saving time shifts.</para>"));
232 layout
->addWidget(mNoTimeZone
);
233 layout
->addStretch();
235 // Initially show only the time zone button, not time zone selector
236 mTimeZoneBox
->hide();
240 // Initialise the radio button statuses
241 mAtTimeRadio
->setChecked(true);
242 slotButtonSet(mAtTimeRadio
);
244 // Timeout every minute to update alarm time fields.
245 MinuteTimer::connect(this, SLOT(updateTimes()));
248 /******************************************************************************
249 * Set or clear read-only status for the controls
251 void AlarmTimeWidget::setReadOnly(bool ro
)
253 mAtTimeRadio
->setReadOnly(ro
);
254 mDateEdit
->setOptions(ro
? KDateComboBox::Options(0) : KDateComboBox::EditDate
| KDateComboBox::SelectDate
| KDateComboBox::DatePicker
);
255 mTimeEdit
->setReadOnly(ro
);
256 if (mAnyTimeCheckBox
)
257 mAnyTimeCheckBox
->setReadOnly(ro
);
258 mAfterTimeRadio
->setReadOnly(ro
);
261 mTimeZone
->setReadOnly(ro
);
262 mNoTimeZone
->setReadOnly(ro
);
264 mDelayTimeEdit
->setReadOnly(ro
);
267 /******************************************************************************
268 * Select the "Time from now" radio button.
270 void AlarmTimeWidget::selectTimeFromNow(int minutes
)
272 mAfterTimeRadio
->setChecked(true);
274 mDelayTimeEdit
->setValue(minutes
);
277 /******************************************************************************
278 * Fetch the entered date/time.
279 * If 'checkExpired' is true and the entered value <= current time, an error occurs.
280 * If 'minsFromNow' is non-null, it is set to the number of minutes' delay selected,
281 * or to zero if a date/time was entered.
282 * In this case, if 'showErrorMessage' is true, output an error message.
283 * 'errorWidget' if non-null, is set to point to the widget containing the error.
284 * Reply = invalid date/time if error.
286 KDateTime
AlarmTimeWidget::getDateTime(int* minsFromNow
, bool checkExpired
, bool showErrorMessage
, QWidget
** errorWidget
) const
291 *errorWidget
= Q_NULLPTR
;
292 KDateTime now
= KDateTime::currentUtcDateTime();
293 now
.setTime(QTime(now
.time().hour(), now
.time().minute(), 0));
294 if (!mAtTimeRadio
->isChecked())
296 if (!mDelayTimeEdit
->isValid())
298 if (showErrorMessage
)
299 KAMessageBox::sorry(const_cast<AlarmTimeWidget
*>(this), i18nc("@info", "Invalid time"));
301 *errorWidget
= mDelayTimeEdit
;
304 int delayMins
= mDelayTimeEdit
->value();
306 *minsFromNow
= delayMins
;
307 return now
.addSecs(delayMins
* 60).toTimeSpec(mTimeSpec
);
311 bool dateOnly
= mAnyTimeAllowed
&& mAnyTimeCheckBox
&& mAnyTimeCheckBox
->isChecked();
312 if (!mDateEdit
->date().isValid() || !mTimeEdit
->isValid())
314 // The date and/or time is invalid
315 if (!mDateEdit
->date().isValid())
317 if (showErrorMessage
)
318 KAMessageBox::sorry(const_cast<AlarmTimeWidget
*>(this), i18nc("@info", "Invalid date"));
320 *errorWidget
= mDateEdit
;
324 if (showErrorMessage
)
325 KAMessageBox::sorry(const_cast<AlarmTimeWidget
*>(this), i18nc("@info", "Invalid time"));
327 *errorWidget
= mTimeEdit
;
335 result
= KDateTime(mDateEdit
->date(), mTimeSpec
);
336 if (checkExpired
&& result
.date() < now
.date())
338 if (showErrorMessage
)
339 KAMessageBox::sorry(const_cast<AlarmTimeWidget
*>(this), i18nc("@info", "Alarm date has already expired"));
341 *errorWidget
= mDateEdit
;
347 result
= KDateTime(mDateEdit
->date(), mTimeEdit
->time(), mTimeSpec
);
348 if (checkExpired
&& result
<= now
.addSecs(1))
350 if (showErrorMessage
)
351 KAMessageBox::sorry(const_cast<AlarmTimeWidget
*>(this), i18nc("@info", "Alarm time has already expired"));
353 *errorWidget
= mTimeEdit
;
361 /******************************************************************************
364 void AlarmTimeWidget::setDateTime(const DateTime
& dt
)
366 // Set the time zone first so that the call to dateTimeChanged() works correctly.
368 mTimeSpec
= dt
.timeSpec().isValid() ? dt
.timeSpec() : KDateTime::LocalZone
;
371 KTimeZone tz
= dt
.timeZone();
372 mNoTimeZone
->setChecked(!tz
.isValid());
373 mTimeZone
->setTimeZone(tz
.isValid() ? tz
: Preferences::timeZone());
374 slotTimeZoneChanged();
377 if (dt
.date().isValid())
379 mTimeEdit
->setValue(dt
.effectiveTime());
380 mDateEdit
->setDate(dt
.date());
381 dateTimeChanged(); // update the delay time edit box
385 mTimeEdit
->setValid(false);
386 mDateEdit
->setDate(QDate());
387 mDelayTimeEdit
->setValid(false);
389 if (mAnyTimeCheckBox
)
391 bool dateOnly
= dt
.isDateOnly();
393 mAnyTimeAllowed
= true;
394 mAnyTimeCheckBox
->setChecked(dateOnly
);
399 /******************************************************************************
400 * Set the minimum date/time to track the current time.
402 void AlarmTimeWidget::setMinDateTimeIsCurrent()
404 mMinDateTimeIsNow
= true;
405 mMinDateTime
= KDateTime();
406 KDateTime now
= KDateTime::currentDateTime(mTimeSpec
);
407 mDateEdit
->setMinimumDate(now
.date());
408 setMaxMinTimeIf(now
);
411 /******************************************************************************
412 * Set the minimum date/time, adjusting the entered date/time if necessary.
413 * If 'dt' is invalid, any current minimum date/time is cleared.
415 void AlarmTimeWidget::setMinDateTime(const KDateTime
& dt
)
417 mMinDateTimeIsNow
= false;
418 mMinDateTime
= dt
.toTimeSpec(mTimeSpec
);
419 mDateEdit
->setMinimumDate(mMinDateTime
.date());
420 setMaxMinTimeIf(KDateTime::currentDateTime(mTimeSpec
));
423 /******************************************************************************
424 * Set the maximum date/time, adjusting the entered date/time if necessary.
425 * If 'dt' is invalid, any current maximum date/time is cleared.
427 void AlarmTimeWidget::setMaxDateTime(const DateTime
& dt
)
430 if (dt
.isValid() && dt
.isDateOnly())
431 mMaxDateTime
= dt
.effectiveKDateTime().addSecs(24*3600 - 60).toTimeSpec(mTimeSpec
);
433 mMaxDateTime
= dt
.kDateTime().toTimeSpec(mTimeSpec
);
434 mDateEdit
->setMaximumDate(mMaxDateTime
.date());
435 KDateTime now
= KDateTime::currentDateTime(mTimeSpec
);
436 setMaxMinTimeIf(now
);
437 setMaxDelayTime(now
);
440 /******************************************************************************
441 * If the minimum and maximum date/times fall on the same date, set the minimum
442 * and maximum times in the time edit box.
444 void AlarmTimeWidget::setMaxMinTimeIf(const KDateTime
& now
)
447 QTime maxt
= time_23_59
;
448 mMinMaxTimeSet
= false;
449 if (mMaxDateTime
.isValid())
453 if (mMinDateTimeIsNow
)
454 minDT
= now
.addSecs(60);
455 else if (mMinDateTime
.isValid())
456 minDT
= mMinDateTime
;
459 if (set
&& mMaxDateTime
.date() == minDT
.date())
461 // The minimum and maximum times are on the same date, so
462 // constrain the time value.
463 mint
= minDT
.time().hour()*60 + minDT
.time().minute();
464 maxt
= mMaxDateTime
.time();
465 mMinMaxTimeSet
= true;
468 mTimeEdit
->setMinimum(mint
);
469 mTimeEdit
->setMaximum(maxt
);
470 mTimeEdit
->setWrapping(!mint
&& maxt
== time_23_59
);
473 /******************************************************************************
474 * Set the maximum value for the delay time edit box, depending on the maximum
475 * value for the date/time.
477 void AlarmTimeWidget::setMaxDelayTime(const KDateTime
& now
)
479 int maxVal
= maxDelayTime
;
480 if (mMaxDateTime
.isValid())
482 if (now
.date().daysTo(mMaxDateTime
.date()) < 100) // avoid possible 32-bit overflow on secsTo()
485 dt
.setTime(QTime(now
.time().hour(), now
.time().minute(), 0)); // round down to nearest minute
486 maxVal
= dt
.secsTo(mMaxDateTime
) / 60;
487 if (maxVal
> maxDelayTime
)
488 maxVal
= maxDelayTime
;
491 mDelayTimeEdit
->setMaximum(maxVal
);
494 /******************************************************************************
495 * Set the status for whether a time is specified, or just a date.
497 void AlarmTimeWidget::setAnyTime()
500 mAnyTime
= (mAtTimeRadio
->isChecked() && mAnyTimeAllowed
&& mAnyTimeCheckBox
&& mAnyTimeCheckBox
->isChecked()) ? 1 : 0;
502 Q_EMIT
dateOnlyToggled(mAnyTime
);
505 /******************************************************************************
506 * Enable/disable the "date only" radio button.
508 void AlarmTimeWidget::enableAnyTime(bool enable
)
510 if (mAnyTimeCheckBox
)
512 mAnyTimeAllowed
= enable
;
513 bool at
= mAtTimeRadio
->isChecked();
514 mAnyTimeCheckBox
->setEnabled(enable
&& at
);
516 mTimeEdit
->setEnabled(!enable
|| !mAnyTimeCheckBox
->isChecked());
521 /******************************************************************************
522 * Called every minute to update the alarm time data entry fields.
523 * If the maximum date/time has been reached, a 'pastMax()' signal is emitted.
525 void AlarmTimeWidget::updateTimes()
528 if (mMinDateTimeIsNow
)
530 // Make sure that the minimum date is updated when the day changes
531 now
= KDateTime::currentDateTime(mTimeSpec
);
532 mDateEdit
->setMinimumDate(now
.date());
534 if (mMaxDateTime
.isValid())
537 now
= KDateTime::currentDateTime(mTimeSpec
);
540 // Check whether the maximum date/time has now been reached
541 if (now
.date() >= mMaxDateTime
.date())
543 // The current date has reached or has passed the maximum date
544 if (now
.date() > mMaxDateTime
.date()
545 || (!mAnyTime
&& now
.time() > mTimeEdit
->maxTime()))
550 else if (mMinDateTimeIsNow
&& !mMinMaxTimeSet
)
552 // The minimum date/time tracks the clock, so set the minimum
554 setMaxMinTimeIf(now
);
558 setMaxDelayTime(now
);
561 if (mAtTimeRadio
->isChecked())
564 delayTimeChanged(mDelayTimeEdit
->value());
568 /******************************************************************************
569 * Called when the radio button states have been changed.
570 * Updates the appropriate edit box.
572 void AlarmTimeWidget::slotButtonSet(QAbstractButton
*)
574 bool at
= mAtTimeRadio
->isChecked();
575 mDateEdit
->setEnabled(at
);
576 mTimeEdit
->setEnabled(at
&& (!mAnyTimeAllowed
|| !mAnyTimeCheckBox
|| !mAnyTimeCheckBox
->isChecked()));
577 if (mAnyTimeCheckBox
)
578 mAnyTimeCheckBox
->setEnabled(at
&& mAnyTimeAllowed
);
579 // Ensure that the value of the delay edit box is > 0.
580 KDateTime
att(mDateEdit
->date(), mTimeEdit
->time(), mTimeSpec
);
581 int minutes
= (KDateTime::currentUtcDateTime().secsTo(att
) + 59) / 60;
583 mDelayTimeEdit
->setValid(true);
584 mDelayTimeEdit
->setEnabled(!at
);
588 /******************************************************************************
589 * Called after the mAnyTimeCheckBox checkbox has been toggled.
591 void AlarmTimeWidget::slotAnyTimeToggled(bool on
)
593 on
= (on
&& mAnyTimeAllowed
);
594 mTimeEdit
->setEnabled(!on
&& mAtTimeRadio
->isChecked());
597 Q_EMIT
changed(KDateTime(mDateEdit
->date(), mTimeSpec
));
599 Q_EMIT
changed(KDateTime(mDateEdit
->date(), mTimeEdit
->time(), mTimeSpec
));
602 /******************************************************************************
603 * Called after a new selection has been made in the time zone combo box.
604 * Re-evaluates the time specification to use.
606 void AlarmTimeWidget::slotTimeZoneChanged()
608 if (mNoTimeZone
->isChecked())
609 mTimeSpec
= KDateTime::ClockTime
;
612 KTimeZone tz
= mTimeZone
->timeZone();
613 mTimeSpec
= tz
.isValid() ? KDateTime::Spec(tz
) : KDateTime::LocalZone
;
615 if (!mTimeZoneBox
->isVisible() && mTimeSpec
!= Preferences::timeZone())
617 // The current time zone is not the default one, so
618 // show the time zone selection controls
619 showTimeZoneSelector();
621 mMinDateTime
= mMinDateTime
.toTimeSpec(mTimeSpec
);
622 mMaxDateTime
= mMaxDateTime
.toTimeSpec(mTimeSpec
);
626 /******************************************************************************
627 * Called after the mNoTimeZone checkbox has been toggled.
629 void AlarmTimeWidget::slotTimeZoneToggled(bool on
)
631 mTimeZone
->setEnabled(!on
);
632 slotTimeZoneChanged();
635 /******************************************************************************
636 * Called after the mTimeZoneButton button has been clicked.
637 * Show the time zone selection controls, and hide the button.
639 void AlarmTimeWidget::showTimeZoneSelector()
641 mTimeZoneButton
->hide();
642 mTimeZoneBox
->show();
646 /******************************************************************************
647 * Show or hide the time zone button.
649 void AlarmTimeWidget::showMoreOptions(bool more
)
653 if (!mTimeZoneBox
->isVisible())
654 mTimeZoneButton
->show();
657 mTimeZoneButton
->hide();
660 /******************************************************************************
661 * Called when the date or time edit box values have changed.
662 * Updates the time delay edit box accordingly.
664 void AlarmTimeWidget::dateTimeChanged()
666 KDateTime
dt(mDateEdit
->date(), mTimeEdit
->time(), mTimeSpec
);
667 int minutes
= (KDateTime::currentUtcDateTime().secsTo(dt
) + 59) / 60;
668 bool blocked
= mDelayTimeEdit
->signalsBlocked();
669 mDelayTimeEdit
->blockSignals(true); // prevent infinite recursion between here and delayTimeChanged()
670 if (minutes
<= 0 || minutes
> mDelayTimeEdit
->maximum())
671 mDelayTimeEdit
->setValid(false);
673 mDelayTimeEdit
->setValue(minutes
);
674 mDelayTimeEdit
->blockSignals(blocked
);
675 if (mAnyTimeAllowed
&& mAnyTimeCheckBox
&& mAnyTimeCheckBox
->isChecked())
676 Q_EMIT
changed(KDateTime(dt
.date(), mTimeSpec
));
681 /******************************************************************************
682 * Called when the delay time edit box value has changed.
683 * Updates the Date and Time edit boxes accordingly.
685 void AlarmTimeWidget::delayTimeChanged(int minutes
)
687 if (mDelayTimeEdit
->isValid())
689 QDateTime dt
= KDateTime::currentUtcDateTime().addSecs(minutes
* 60).toTimeSpec(mTimeSpec
).dateTime();
690 bool blockedT
= mTimeEdit
->signalsBlocked();
691 bool blockedD
= mDateEdit
->signalsBlocked();
692 mTimeEdit
->blockSignals(true); // prevent infinite recursion between here and dateTimeChanged()
693 mDateEdit
->blockSignals(true);
694 mTimeEdit
->setValue(dt
.time());
695 mDateEdit
->setDate(dt
.date());
696 mTimeEdit
->blockSignals(blockedT
);
697 mDateEdit
->blockSignals(blockedD
);
698 Q_EMIT
changed(KDateTime(dt
.date(), dt
.time(), mTimeSpec
));