Merge branch 'master' of git://anongit.kde.org/kdepim
[kdepim.git] / kalarm / alarmtimewidget.cpp
blob8df69186f3c451b61a8627b3da1d5f4887c23cc6
1 /*
2 * alarmtimewidget.cpp - alarm date/time entry widget
3 * Program: kalarm
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.
21 #include "kalarm.h"
23 #include "buttongroup.h"
24 #include "checkbox.h"
25 #include "messagebox.h"
26 #include "preferences.h"
27 #include "pushbutton.h"
28 #include "radiobutton.h"
29 #include "synchtimer.h"
30 #include "timeedit.h"
31 #include "timespinbox.h"
32 #include "timezonecombo.h"
33 #include "alarmtimewidget.h"
35 #include <kalarmcal/datetime.h>
36 #include <KTimeZone>
37 #include <kdatecombobox.h>
38 #include <KLocalizedString>
40 #include <QGroupBox>
41 #include <QGridLayout>
42 #include <QLabel>
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)
61 : QFrame(parent),
62 mMinDateTimeIsNow(false),
63 mPastMax(false),
64 mMinMaxTimeSet(false)
66 init(mode, groupBoxTitle);
69 /******************************************************************************
70 * Construct a widget without a group box or title.
72 AlarmTimeWidget::AlarmTimeWidget(Mode mode, QWidget* parent)
73 : QFrame(parent),
74 mMinDateTimeIsNow(false),
75 mPastMax(false),
76 mMinMaxTimeSet(false)
78 init(mode);
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.");
89 QWidget* topWidget;
90 if (title.isEmpty())
91 topWidget = this;
92 else
94 QBoxLayout* layout = new QVBoxLayout(this);
95 layout->setMargin(0);
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);
114 // Date edit box
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>"
134 "<para>%1</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;
143 else
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();
172 grid->setMargin(0);
173 topLayout->addLayout(grid);
174 if (mDeferring)
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();
187 else
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();
237 mNoTimeZone->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);
259 if (!mDeferring)
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);
273 if (minutes > 0)
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
288 if (minsFromNow)
289 *minsFromNow = 0;
290 if (errorWidget)
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"));
300 if (errorWidget)
301 *errorWidget = mDelayTimeEdit;
302 return KDateTime();
304 int delayMins = mDelayTimeEdit->value();
305 if (minsFromNow)
306 *minsFromNow = delayMins;
307 return now.addSecs(delayMins * 60).toTimeSpec(mTimeSpec);
309 else
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"));
319 if (errorWidget)
320 *errorWidget = mDateEdit;
322 else
324 if (showErrorMessage)
325 KAMessageBox::sorry(const_cast<AlarmTimeWidget*>(this), i18nc("@info", "Invalid time"));
326 if (errorWidget)
327 *errorWidget = mTimeEdit;
329 return KDateTime();
332 KDateTime result;
333 if (dateOnly)
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"));
340 if (errorWidget)
341 *errorWidget = mDateEdit;
342 return KDateTime();
345 else
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"));
352 if (errorWidget)
353 *errorWidget = mTimeEdit;
354 return KDateTime();
357 return result;
361 /******************************************************************************
362 * Set the date/time.
364 void AlarmTimeWidget::setDateTime(const DateTime& dt)
366 // Set the time zone first so that the call to dateTimeChanged() works correctly.
367 if (mDeferring)
368 mTimeSpec = dt.timeSpec().isValid() ? dt.timeSpec() : KDateTime::LocalZone;
369 else
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
383 else
385 mTimeEdit->setValid(false);
386 mDateEdit->setDate(QDate());
387 mDelayTimeEdit->setValid(false);
389 if (mAnyTimeCheckBox)
391 bool dateOnly = dt.isDateOnly();
392 if (dateOnly)
393 mAnyTimeAllowed = true;
394 mAnyTimeCheckBox->setChecked(dateOnly);
395 setAnyTime();
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)
429 mPastMax = false;
430 if (dt.isValid() && dt.isDateOnly())
431 mMaxDateTime = dt.effectiveKDateTime().addSecs(24*3600 - 60).toTimeSpec(mTimeSpec);
432 else
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)
446 int mint = 0;
447 QTime maxt = time_23_59;
448 mMinMaxTimeSet = false;
449 if (mMaxDateTime.isValid())
451 bool set = true;
452 KDateTime minDT;
453 if (mMinDateTimeIsNow)
454 minDT = now.addSecs(60);
455 else if (mMinDateTime.isValid())
456 minDT = mMinDateTime;
457 else
458 set = false;
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()
484 KDateTime dt(now);
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()
499 int old = mAnyTime;
500 mAnyTime = (mAtTimeRadio->isChecked() && mAnyTimeAllowed && mAnyTimeCheckBox && mAnyTimeCheckBox->isChecked()) ? 1 : 0;
501 if (mAnyTime != old)
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);
515 if (at)
516 mTimeEdit->setEnabled(!enable || !mAnyTimeCheckBox->isChecked());
517 setAnyTime();
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()
527 KDateTime now;
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())
536 if (!now.isValid())
537 now = KDateTime::currentDateTime(mTimeSpec);
538 if (!mPastMax)
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()))
547 mPastMax = true;
548 Q_EMIT pastMax();
550 else if (mMinDateTimeIsNow && !mMinMaxTimeSet)
552 // The minimum date/time tracks the clock, so set the minimum
553 // and maximum times
554 setMaxMinTimeIf(now);
558 setMaxDelayTime(now);
561 if (mAtTimeRadio->isChecked())
562 dateTimeChanged();
563 else
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;
582 if (minutes <= 0)
583 mDelayTimeEdit->setValid(true);
584 mDelayTimeEdit->setEnabled(!at);
585 setAnyTime();
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());
595 setAnyTime();
596 if (on)
597 Q_EMIT changed(KDateTime(mDateEdit->date(), mTimeSpec));
598 else
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;
610 else
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);
623 updateTimes();
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();
643 mNoTimeZone->show();
646 /******************************************************************************
647 * Show or hide the time zone button.
649 void AlarmTimeWidget::showMoreOptions(bool more)
651 if (more)
653 if (!mTimeZoneBox->isVisible())
654 mTimeZoneButton->show();
656 else
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);
672 else
673 mDelayTimeEdit->setValue(minutes);
674 mDelayTimeEdit->blockSignals(blocked);
675 if (mAnyTimeAllowed && mAnyTimeCheckBox && mAnyTimeCheckBox->isChecked())
676 Q_EMIT changed(KDateTime(dt.date(), mTimeSpec));
677 else
678 Q_EMIT changed(dt);
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));
702 // vim: et sw=4: