File indexing completed on 2024-05-12 05:14:56
0001 /* 0002 * reminder.cpp - reminder setting widget 0003 * Program: kalarm 0004 * SPDX-FileCopyrightText: 2003-2022 David Jarvie <djarvie@kde.org> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "reminder.h" 0010 0011 #include "preferences.h" 0012 #include "timeselector.h" 0013 #include "lib/checkbox.h" 0014 #include "lib/combobox.h" 0015 #include "kalarmcalendar/kadatetime.h" 0016 0017 #include <KCalendarCore/Duration> 0018 0019 #include <KLocalizedString> 0020 0021 #include <QVBoxLayout> 0022 #include <QHBoxLayout> 0023 0024 using namespace KAlarmCal; 0025 using namespace KCalendarCore; 0026 0027 // Collect these widget labels together to ensure consistent wording and 0028 // translations across different modules. 0029 QString Reminder::i18n_chk_FirstRecurrenceOnly() { return i18nc("@option:check", "Reminder for first recurrence only"); } 0030 0031 #define i18n_in_advance i18nc("@item:inlistbox", "in advance") 0032 0033 0034 Reminder::Reminder(const QString& reminderWhatsThis, const QString& valueWhatsThis, 0035 const QString& beforeAfterWhatsThis, bool allowHourMinute, 0036 bool showOnceOnly, QWidget* parent) 0037 : QFrame(parent) 0038 , mOnceOnlyEnabled(showOnceOnly) 0039 { 0040 auto topLayout = new QVBoxLayout(this); 0041 topLayout->setContentsMargins(0, 0, 0, 0); 0042 0043 mTime = new TimeSelector(i18nc("@option:check", "Reminder:"), reminderWhatsThis, 0044 valueWhatsThis, allowHourMinute, this); 0045 mTimeSignCombo = mTime->createSignCombo(); 0046 mTimeSignCombo->addItem(i18n_in_advance); 0047 mTimeSignCombo->addItem(i18nc("@item:inlistbox", "afterwards")); 0048 mTimeSignCombo->setWhatsThis(beforeAfterWhatsThis); 0049 mTimeSignCombo->setCurrentIndex(0); // default to "in advance" 0050 connect(mTime, &TimeSelector::toggled, this, &Reminder::slotReminderToggled); 0051 connect(mTime, &TimeSelector::valueChanged, this, &Reminder::changed); 0052 connect(mTimeSignCombo, static_cast<void (ComboBox::*)(int)>(&ComboBox::currentIndexChanged), this, &Reminder::changed); 0053 topLayout->addWidget(mTime, 0, Qt::AlignLeft); 0054 0055 if (showOnceOnly) 0056 { 0057 auto layout = new QHBoxLayout(); 0058 layout->setContentsMargins(0, 0, 0, 0); 0059 const int indent = CheckBox::textIndent(mTime); 0060 if (layoutDirection() == Qt::LeftToRight) 0061 layout->setContentsMargins(indent, 0, 0, 0); 0062 else 0063 layout->setContentsMargins(0, 0, indent, 0); 0064 topLayout->addLayout(layout); 0065 mOnceOnly = new CheckBox(i18n_chk_FirstRecurrenceOnly(), this); 0066 connect(mOnceOnly, &CheckBox::toggled, this, &Reminder::changed); 0067 mOnceOnly->setWhatsThis(i18nc("@info:whatsthis", "Display the reminder only for the first time the alarm is scheduled")); 0068 layout->addWidget(mOnceOnly); 0069 layout->addStretch(); 0070 } 0071 else 0072 mOnceOnly = nullptr; 0073 } 0074 0075 /****************************************************************************** 0076 * Allow or disallow advance reminder selection. 0077 */ 0078 void Reminder::setAfterOnly(bool afterOnly) 0079 { 0080 if (afterOnly && mTimeSignCombo->count() == 2) 0081 mTimeSignCombo->removeItem(0); 0082 else if (!afterOnly && mTimeSignCombo->count() == 1) 0083 mTimeSignCombo->insertItem(0, i18n_in_advance); 0084 } 0085 0086 /****************************************************************************** 0087 * Set the read-only status. 0088 */ 0089 void Reminder::setReadOnly(bool ro) 0090 { 0091 if (ro != mReadOnly) 0092 { 0093 mReadOnly = ro; 0094 mTime->setReadOnly(mReadOnly); 0095 if (mOnceOnly) 0096 mOnceOnly->setReadOnly(mReadOnly); 0097 } 0098 } 0099 0100 bool Reminder::isReminder() const 0101 { 0102 return mTime->isChecked(); 0103 } 0104 0105 bool Reminder::isOnceOnly() const 0106 { 0107 return mOnceOnly && mOnceOnly->isEnabled() && mOnceOnly->isChecked(); 0108 } 0109 0110 void Reminder::setOnceOnly(bool onceOnly) 0111 { 0112 if (mOnceOnly) 0113 mOnceOnly->setChecked(onceOnly); 0114 } 0115 0116 /****************************************************************************** 0117 * Specify whether the once-only checkbox is allowed to be enabled. 0118 */ 0119 void Reminder::enableOnceOnly(bool enable) 0120 { 0121 if (mOnceOnly) 0122 { 0123 mOnceOnlyEnabled = enable; 0124 mOnceOnly->setEnabled(enable && mTime->isChecked()); 0125 } 0126 } 0127 0128 void Reminder::setMaximum(int hourmin, int days) 0129 { 0130 mTime->setMaximum(hourmin, days); 0131 } 0132 0133 /****************************************************************************** 0134 * Get the specified number of minutes in advance of the main alarm the 0135 * reminder is to be. 0136 * Reply > 0 if advance reminder 0137 * < 0 if reminder after main alarm 0138 * = 0 if no reminder. 0139 */ 0140 int Reminder::minutes() const 0141 { 0142 int index = mTimeSignCombo->currentIndex(); 0143 if (mTimeSignCombo->count() == 1) 0144 ++index; // "in advance" is not available 0145 int sign = index ? -1 : 1; 0146 return mTime->period().asSeconds() * sign / 60; 0147 } 0148 0149 /****************************************************************************** 0150 * Initialise the controls with a specified reminder time. 0151 */ 0152 void Reminder::setMinutes(int minutes, bool dateOnly) 0153 { 0154 bool neg = (minutes < 0); 0155 minutes = abs(minutes); 0156 Duration period; 0157 if (minutes % (24*60)) 0158 period = Duration(minutes * 60, Duration::Seconds); 0159 else 0160 period = Duration(minutes / (24*60), Duration::Days); 0161 mTime->setPeriod(period, dateOnly, Preferences::defaultReminderUnits()); 0162 mTimeSignCombo->setCurrentIndex(neg ? 1 : 0); 0163 } 0164 0165 /****************************************************************************** 0166 * Set the reminder units to days if "Any time" is checked. 0167 */ 0168 void Reminder::setDateOnly(bool dateOnly) 0169 { 0170 mTime->setDateOnly(dateOnly); 0171 } 0172 0173 /****************************************************************************** 0174 * Set the input focus on the count field. 0175 */ 0176 void Reminder::setFocusOnCount() 0177 { 0178 mTime->setFocusOnCount(); 0179 } 0180 0181 /****************************************************************************** 0182 * Called when the Reminder checkbox is toggled. 0183 */ 0184 void Reminder::slotReminderToggled(bool on) 0185 { 0186 if (mOnceOnly) 0187 mOnceOnly->setEnabled(on && mOnceOnlyEnabled); 0188 } 0189 0190 /****************************************************************************** 0191 * Called when the start time relating to the reminder has changed. 0192 * Sets the default reminder time units appropriately, if no reminder time is 0193 * currently set. 0194 */ 0195 void Reminder::setDefaultUnits(const KADateTime& dt) 0196 { 0197 if (mTime->isChecked()) 0198 return; // don't change units if reminder is already set 0199 TimePeriod::Units units; 0200 TimePeriod::Units currentUnits = mTime->units(); 0201 if (KADateTime::currentDateTime(dt.timeSpec()).daysTo(dt) < 7) 0202 { 0203 if (currentUnits == TimePeriod::Minutes || currentUnits == TimePeriod::HoursMinutes) 0204 return; 0205 units = (Preferences::defaultReminderUnits() == TimePeriod::Minutes) 0206 ? TimePeriod::Minutes : TimePeriod::HoursMinutes; 0207 } 0208 else 0209 { 0210 if (currentUnits == TimePeriod::Days || currentUnits == TimePeriod::Weeks) 0211 return; 0212 units = TimePeriod::Days; 0213 } 0214 mTime->setUnits(units); 0215 } 0216 0217 #include "moc_reminder.cpp" 0218 0219 // vim: et sw=4: