File indexing completed on 2024-06-16 05:22:24

0001 /*
0002  * Copyright 2020 Han Young <hanyoung@protonmail.com>
0003  * Copyright 2020-2022 Devin Lin <devin@kde.org>
0004  *
0005  * SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #pragma once
0009 
0010 #include "alarmmodel.h"
0011 #include "alarmplayer.h"
0012 #include "alarmwaitworker.h"
0013 
0014 #include <KLocalizedString>
0015 #include <KNotification>
0016 
0017 #include <QDebug>
0018 #include <QFileDialog>
0019 #include <QMediaPlayer>
0020 #include <QObject>
0021 #include <QStandardPaths>
0022 #include <QString>
0023 #include <QThread>
0024 #include <QTime>
0025 #include <QTimer>
0026 #include <QUrl>
0027 #include <QUuid>
0028 
0029 const QString ALARM_CFG_GROUP = QStringLiteral("Alarms");
0030 
0031 class AlarmModel;
0032 
0033 class Alarm : public QObject
0034 {
0035     Q_OBJECT
0036     Q_CLASSINFO("D-Bus Interface", "org.kde.kclock.Alarm")
0037     Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
0038     Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
0039     Q_PROPERTY(int hours READ hours WRITE setHours NOTIFY hoursChanged)
0040     Q_PROPERTY(int minutes READ minutes WRITE setMinutes NOTIFY minutesChanged)
0041     Q_PROPERTY(int daysOfWeek READ daysOfWeek WRITE setDaysOfWeek NOTIFY daysOfWeekChanged)
0042     Q_PROPERTY(QString audioPath READ audioPath WRITE setAudioPath NOTIFY audioPathChanged)
0043     Q_PROPERTY(int ringDuration READ ringDuration WRITE setRingDuration NOTIFY ringDurationChanged)
0044     Q_PROPERTY(int snoozeDuration READ snoozeDuration WRITE setSnoozeDuration NOTIFY snoozeDurationChanged)
0045     Q_PROPERTY(int snoozedLength READ snoozedLength NOTIFY snoozedLengthChanged)
0046     Q_PROPERTY(bool ringing READ ringing NOTIFY ringingChanged)
0047     Q_PROPERTY(quint64 nextRingTime READ nextRingTime NOTIFY nextRingTimeChanged)
0048 
0049 public:
0050     explicit Alarm(const QString &serialized, AlarmModel *parent = nullptr);
0051     explicit Alarm(const QString &name = i18n("Alarm"),
0052                    int hours = 0,
0053                    int minutes = 0,
0054                    int daysOfWeek = 0,
0055                    QString audioPath = QString{},
0056                    int ringDuration = 5,
0057                    int snoozeDuration = 5,
0058                    AlarmModel *parent = nullptr);
0059 
0060     void init(AlarmModel *parent);
0061 
0062     ~Alarm();
0063 
0064     // serialize this alarm to json
0065     QString serialize();
0066 
0067     Q_SCRIPTABLE QString uuid() const;
0068 
0069     QString name() const;
0070     void setName(const QString &name);
0071 
0072     bool enabled() const;
0073     void setEnabled(bool enabled);
0074 
0075     int hours() const;
0076     void setHours(int hours);
0077 
0078     int minutes() const;
0079     void setMinutes(int minutes);
0080 
0081     int daysOfWeek() const;
0082     void setDaysOfWeek(int daysOfWeek);
0083 
0084     QString audioPath() const;
0085     void setAudioPath(QString path);
0086 
0087     int ringDuration() const;
0088     void setRingDuration(int ringDuration);
0089 
0090     int snoozeDuration() const;
0091     void setSnoozeDuration(int snoozeDuration);
0092 
0093     int snoozedLength() const;
0094 
0095     bool ringing() const;
0096 
0097     // ring the alarm now
0098     void ring();
0099 
0100     // get the next time the alarm will ring (unix time), or 0 if it will never ring
0101     quint64 nextRingTime();
0102 
0103 public Q_SLOTS:
0104     Q_SCRIPTABLE void dismiss();
0105     Q_SCRIPTABLE void snooze();
0106     Q_SCRIPTABLE void save(); // serialize and save to config
0107 
0108 Q_SIGNALS:
0109     Q_SCRIPTABLE void nameChanged();
0110     Q_SCRIPTABLE void enabledChanged();
0111     Q_SCRIPTABLE void hoursChanged();
0112     Q_SCRIPTABLE void minutesChanged();
0113     Q_SCRIPTABLE void daysOfWeekChanged();
0114     Q_SCRIPTABLE void audioPathChanged();
0115     Q_SCRIPTABLE void ringDurationChanged();
0116     Q_SCRIPTABLE void snoozeDurationChanged();
0117 
0118     Q_SCRIPTABLE void snoozedLengthChanged();
0119     Q_SCRIPTABLE void ringingChanged();
0120     Q_SCRIPTABLE void nextRingTimeChanged();
0121 
0122     // the time that the alarm is going to ring has changed
0123     Q_SCRIPTABLE void rescheduleRequested();
0124 
0125 private:
0126     void setSnoozedLength(int snoozedLength);
0127     void setRinging(bool ringing);
0128     void setNextRingTime(quint64 nextRingTime);
0129     void calculateNextRingTime();
0130 
0131     QUuid m_uuid;
0132 
0133     // -- properties that persist to storage: --
0134 
0135     // name of the alarm
0136     QString m_name;
0137 
0138     // whether the alarm is enabled
0139     bool m_enabled;
0140 
0141     // hour of the day the alarm rings at
0142     int m_hours;
0143 
0144     // minute of the hour the alarm rings at
0145     int m_minutes;
0146 
0147     // bitmask of the days of the week that the alarm rings (if zero, it rings once)
0148     int m_daysOfWeek;
0149 
0150     // the path to the audio file to ring
0151     QUrl m_audioPath;
0152 
0153     // the amount of time the alarm rings for, in minutes
0154     int m_ringDuration;
0155 
0156     // the amount of time the alarm adds when snoozed, in minutes
0157     int m_snoozeDuration;
0158 
0159     // the amount of time snoozing has added to the current ring, in seconds
0160     int m_snoozedLength = 0;
0161 
0162     // -- properties only relevant for the current state of the alarm (not persisted): --
0163 
0164     // whether the alarm is ringing
0165     bool m_ringing = false;
0166 
0167     // cache calculated next ring time (unix time)
0168     quint64 m_nextRingTime = 0;
0169 
0170     // saves the original ring time (without snoozing applied to it)
0171     quint64 m_originalRingTime = 0;
0172 
0173     // whether snooze just occurred
0174     bool m_justSnoozed;
0175 
0176     KNotification *m_notification = new KNotification{QStringLiteral("alarm"), KNotification::NotificationFlag::Persistent, this};
0177 
0178     QTimer *m_ringTimer = new QTimer(this);
0179 };