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"