File indexing completed on 2024-04-28 05:11:29
0001 /* 0002 SPDX-FileCopyrightText: 2010 Bertjan Broeksema <broeksema@kde.org> 0003 SPDX-FileCopyrightText: 2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info@kdab.net> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "alarmdialog.h" 0009 #include "editorconfig.h" 0010 #include "ui_alarmdialog.h" 0011 0012 #include <KLocalizedString> 0013 #include <QDialogButtonBox> 0014 #include <QPushButton> 0015 #include <QVBoxLayout> 0016 0017 using namespace IncidenceEditorNG; 0018 0019 AlarmDialog::AlarmDialog(KCalendarCore::Incidence::IncidenceType incidenceType, QWidget *parent) 0020 : QDialog(parent) 0021 , mUi(new Ui::AlarmDialog) 0022 , mIncidenceType(incidenceType) 0023 { 0024 setWindowTitle(i18nc("@title:window", "Create a new reminder")); 0025 auto mainLayout = new QVBoxLayout(this); 0026 auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); 0027 QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); 0028 okButton->setDefault(true); 0029 okButton->setShortcut(Qt::CTRL | Qt::Key_Return); 0030 connect(buttonBox, &QDialogButtonBox::accepted, this, &AlarmDialog::accept); 0031 connect(buttonBox, &QDialogButtonBox::rejected, this, &AlarmDialog::reject); 0032 0033 auto mainWidget = new QWidget(this); 0034 mUi->setupUi(mainWidget); 0035 mainLayout->addWidget(mainWidget); 0036 mainLayout->addWidget(buttonBox); 0037 0038 const int defaultReminderTime = IncidenceEditorNG::EditorConfig::instance()->reminderTime(); 0039 mUi->mAlarmOffset->setValue(defaultReminderTime); 0040 0041 int defaultReminderUnits = IncidenceEditorNG::EditorConfig::instance()->reminderTimeUnits(); 0042 if (defaultReminderUnits < 0 || defaultReminderUnits > 2) { 0043 defaultReminderUnits = 0; // minutes 0044 } 0045 0046 mUi->mOffsetUnit->setCurrentIndex(defaultReminderUnits); 0047 mUi->mSoundFile->setMimeTypeFilters({QStringLiteral("audio/x-wav"), QStringLiteral("audio/x-mp3"), QStringLiteral("application/ogg")}); 0048 0049 if (IncidenceEditorNG::EditorConfig::instance()->defaultAudioFileReminders()) { 0050 mUi->mSoundFile->setUrl(IncidenceEditorNG::EditorConfig::instance()->audioFilePath()); 0051 } 0052 0053 fillCombo(); 0054 } 0055 0056 AlarmDialog::~AlarmDialog() 0057 { 0058 delete mUi; 0059 } 0060 0061 void AlarmDialog::load(const KCalendarCore::Alarm::Ptr &alarm) 0062 { 0063 if (!alarm) { 0064 return; 0065 } 0066 0067 setWindowTitle(i18nc("@title:window", "Edit existing reminder")); 0068 0069 // Offsets 0070 int offset; 0071 int beforeafterpos = 0; 0072 0073 if (alarm->hasEndOffset()) { 0074 beforeafterpos = 2; 0075 offset = alarm->endOffset().asSeconds(); 0076 } else { 0077 // TODO: Also allow alarms at fixed times, not relative to start/end 0078 offset = alarm->startOffset().asSeconds(); 0079 } 0080 // Negative offset means before the start/end... 0081 if (offset < 0) { 0082 offset = -offset; 0083 } else { 0084 ++beforeafterpos; 0085 } 0086 mUi->mBeforeAfter->setCurrentIndex(beforeafterpos); 0087 0088 offset = offset / 60; // make minutes 0089 int useoffset = offset; 0090 0091 if (offset % (24 * 60) == 0 && offset > 0) { // divides evenly into days? 0092 useoffset = offset / (24 * 60); 0093 mUi->mOffsetUnit->setCurrentIndex(2); 0094 } else if (offset % 60 == 0 && offset > 0) { // divides evenly into hours? 0095 useoffset = offset / 60; 0096 mUi->mOffsetUnit->setCurrentIndex(1); 0097 } else { 0098 useoffset = offset; 0099 mUi->mOffsetUnit->setCurrentIndex(0); 0100 } 0101 mUi->mAlarmOffset->setValue(useoffset); 0102 0103 // Repeating 0104 mUi->mRepeats->setChecked(alarm->repeatCount() > 0); 0105 if (alarm->repeatCount() > 0) { 0106 mUi->mRepeatCount->setValue(alarm->repeatCount()); 0107 mUi->mRepeatInterval->setValue(alarm->snoozeTime().asSeconds() / 60); // show as minutes 0108 } 0109 int id = 0; 0110 0111 switch (alarm->type()) { 0112 case KCalendarCore::Alarm::Audio: 0113 mUi->mTypeCombo->setCurrentIndex(1); 0114 mUi->mSoundFile->setUrl(QUrl::fromLocalFile(alarm->audioFile())); 0115 id = 1; 0116 break; 0117 case KCalendarCore::Alarm::Email: 0118 case KCalendarCore::Alarm::Procedure: 0119 case KCalendarCore::Alarm::Display: 0120 case KCalendarCore::Alarm::Invalid: 0121 default: 0122 mUi->mTypeCombo->setCurrentIndex(0); 0123 mUi->mDisplayText->setPlainText(alarm->text()); 0124 break; 0125 } 0126 0127 mUi->mTypeStack->setCurrentIndex(id); 0128 if (alarm->audioFile().isEmpty() && IncidenceEditorNG::EditorConfig::instance()->defaultAudioFileReminders()) { 0129 mUi->mSoundFile->setUrl(IncidenceEditorNG::EditorConfig::instance()->audioFilePath()); 0130 } 0131 } 0132 0133 void AlarmDialog::save(const KCalendarCore::Alarm::Ptr &alarm) const 0134 { 0135 // Offsets 0136 int offset = mUi->mAlarmOffset->value() * 60; // minutes 0137 int offsetunit = mUi->mOffsetUnit->currentIndex(); 0138 if (offsetunit >= 1) { 0139 offset *= 60; // hours 0140 } 0141 if (offsetunit >= 2) { 0142 offset *= 24; // days 0143 } 0144 if (offsetunit >= 3) { 0145 offset *= 7; // weeks 0146 } 0147 0148 const int beforeafterpos = mUi->mBeforeAfter->currentIndex(); 0149 if (beforeafterpos % 2 == 0) { // before -> negative 0150 offset = -offset; 0151 } 0152 0153 // Note: if this triggers, fix the logic at the place causing it. It really makes 0154 // no sense to have both disabled. 0155 Q_ASSERT(mAllowBeginReminders || mAllowEndReminders); 0156 0157 // TODO: Add possibility to specify a given time for the reminder 0158 0159 // We assume that if mAllowBeginReminders is not set, that mAllowBeginReminders 0160 // is set. 0161 if (!mAllowBeginReminders) { // before or after DTDUE 0162 alarm->setEndOffset(KCalendarCore::Duration(offset)); 0163 } else if (beforeafterpos == 0 || beforeafterpos == 1) { // before or after DTSTART 0164 alarm->setStartOffset(KCalendarCore::Duration(offset)); 0165 } else if (beforeafterpos == 2 || beforeafterpos == 3) { // before or after DTEND/DTDUE 0166 alarm->setEndOffset(KCalendarCore::Duration(offset)); 0167 } 0168 0169 // Repeating 0170 if (mUi->mRepeats->isChecked()) { 0171 alarm->setRepeatCount(mUi->mRepeatCount->value()); 0172 alarm->setSnoozeTime(mUi->mRepeatInterval->value() * 60); // convert back to seconds 0173 } else { 0174 alarm->setRepeatCount(0); 0175 } 0176 0177 if (mUi->mTypeCombo->currentIndex() == 1) { // Audio 0178 alarm->setAudioAlarm(mUi->mSoundFile->url().toLocalFile()); 0179 } else { // Display 0180 alarm->setDisplayAlarm(mUi->mDisplayText->toPlainText()); 0181 } 0182 } 0183 0184 void AlarmDialog::fillCombo() 0185 { 0186 QStringList items; 0187 0188 if (mIncidenceType == KCalendarCore::Incidence::TypeTodo) { 0189 mUi->mBeforeAfter->clear(); 0190 0191 if (mAllowBeginReminders) { 0192 items << i18n("Before the to-do starts") << i18n("After the to-do starts"); 0193 } 0194 0195 if (mAllowEndReminders) { 0196 items << i18n("Before the to-do is due") << i18n("After the to-do is due"); 0197 } 0198 } else { 0199 if (mAllowBeginReminders) { 0200 items << i18n("Before the event starts") << i18n("After the event starts"); 0201 } 0202 if (mAllowEndReminders) { 0203 items << i18n("Before the event ends") << i18n("After the event ends"); 0204 } 0205 } 0206 0207 mUi->mBeforeAfter->clear(); 0208 mUi->mBeforeAfter->addItems(items); 0209 } 0210 0211 void AlarmDialog::setAllowBeginReminders(bool allow) 0212 { 0213 mAllowBeginReminders = allow; 0214 fillCombo(); 0215 } 0216 0217 void AlarmDialog::setAllowEndReminders(bool allow) 0218 { 0219 mAllowEndReminders = allow; 0220 fillCombo(); 0221 } 0222 0223 void AlarmDialog::setOffset(int offset) 0224 { 0225 Q_ASSERT(offset > 0); 0226 mUi->mAlarmOffset->setValue(offset); 0227 } 0228 0229 void AlarmDialog::setUnit(Unit unit) 0230 { 0231 mUi->mOffsetUnit->setCurrentIndex(unit); 0232 } 0233 0234 void AlarmDialog::setWhen(When when) 0235 { 0236 Q_ASSERT(when <= mUi->mBeforeAfter->count()); 0237 mUi->mBeforeAfter->setCurrentIndex(when); 0238 } 0239 0240 #include "moc_alarmdialog.cpp"