File indexing completed on 2024-11-24 04:42:27
0001 /* 0002 * synchtimer.h - timers which synchronize to time boundaries 0003 * Program: kalarm 0004 * SPDX-FileCopyrightText: 2004-2020 David Jarvie <djarvie@kde.org> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #pragma once 0010 0011 /* @file synchtimer.h - timers which synchronize to time boundaries */ 0012 0013 #include <QByteArray> 0014 #include <QDate> 0015 #include <QList> 0016 #include <QObject> 0017 #include <QTime> 0018 class QTimer; 0019 0020 /** SynchTimer is a virtual base class for application-wide timers synchronized 0021 * to a time boundary. 0022 * 0023 * @author David Jarvie <djarvie@kde.org> 0024 */ 0025 class SynchTimer : public QObject 0026 { 0027 Q_OBJECT 0028 public: 0029 ~SynchTimer() override; 0030 // Prevent copying. 0031 SynchTimer(const SynchTimer&) = delete; 0032 SynchTimer& operator=(const SynchTimer&) = delete; 0033 0034 struct Connection 0035 { 0036 Connection() = default; 0037 Connection(QObject* r, const char* s) : receiver(r), slot(s) { } 0038 bool operator==(const Connection& c) const { return receiver == c.receiver && slot == c.slot; } 0039 QObject* receiver; 0040 QByteArray slot; 0041 }; 0042 protected: 0043 SynchTimer(); 0044 virtual void start() = 0; 0045 void connecT(QObject* receiver, const char* member); 0046 virtual void disconnecT(QObject* receiver, const char* member = nullptr); 0047 bool hasConnections() const { return !mConnections.isEmpty(); } 0048 0049 QTimer* mTimer; 0050 0051 protected Q_SLOTS: 0052 virtual void slotTimer() = 0; 0053 0054 private Q_SLOTS: 0055 void slotReceiverGone(QObject* r) { disconnecT(r); } 0056 0057 private: 0058 QList<Connection> mConnections; // list of current clients 0059 }; 0060 0061 0062 /** MinuteTimer is an application-wide timer synchronized to the minute boundary. 0063 * 0064 * @author David Jarvie <djarvie@kde.org> 0065 */ 0066 class MinuteTimer : public SynchTimer 0067 { 0068 Q_OBJECT 0069 public: 0070 ~MinuteTimer() override { mInstance = nullptr; } 0071 0072 /** Connect to the timer signal. 0073 * @param receiver Receiving object. 0074 * @param member Slot to activate. 0075 */ 0076 static void connect(QObject* receiver, const char* member) 0077 { instance()->connecT(receiver, member); } 0078 0079 /** Disconnect from the timer signal. 0080 * @param receiver Receiving object. 0081 * @param member Slot to disconnect. If null, all slots belonging to 0082 * @p receiver will be disconnected. 0083 */ 0084 static void disconnect(QObject* receiver, const char* member = nullptr) 0085 { if (mInstance) mInstance->disconnecT(receiver, member); } 0086 0087 protected: 0088 MinuteTimer() = default; 0089 static MinuteTimer* instance(); 0090 void start() override { slotTimer(); } 0091 0092 protected Q_SLOTS: 0093 void slotTimer() override; 0094 0095 private: 0096 static MinuteTimer* mInstance; // the one and only instance 0097 }; 0098 0099 0100 /** DailyTimer is an application-wide timer synchronized to a specified time of day, local time. 0101 * 0102 * Daily timers come in two flavors: fixed, which can only be accessed through 0103 * static methods, and variable, whose time can be adjusted and which are 0104 * accessed through non-static methods. 0105 * 0106 * @author David Jarvie <djarvie@kde.org> 0107 */ 0108 class DailyTimer : public SynchTimer 0109 { 0110 Q_OBJECT 0111 public: 0112 ~DailyTimer() override; 0113 0114 /** Connect to the timer signal which triggers at the given fixed time of day. 0115 * A new timer is created if necessary. 0116 * @param timeOfDay Time at which the timer is to trigger. 0117 * @param receiver Receiving object. 0118 * @param member Slot to activate. 0119 */ 0120 static void connect(const QTime& timeOfDay, QObject* receiver, const char* member) 0121 { fixedInstance(timeOfDay)->connecT(receiver, member); } 0122 0123 /** Disconnect from the timer signal which triggers at the given fixed time of day. 0124 * If there are no remaining connections to that timer, it is destroyed. 0125 * @param timeOfDay Time at which the timer triggers. 0126 * @param receiver Receiving object. 0127 * @param member Slot to disconnect. If null, all slots belonging to 0128 * @p receiver will be disconnected. 0129 */ 0130 static void disconnect(const QTime& timeOfDay, QObject* receiver, const char* member = nullptr); 0131 0132 protected: 0133 /** Construct an instance. 0134 * The constructor is protected to ensure that for variable timers, only 0135 * derived classes can construct instances. This ensures that multiple 0136 * timers are not created for the same use. 0137 */ 0138 DailyTimer(const QTime&, bool fixed); 0139 0140 void disconnecT(QObject* receiver, const char* member = nullptr) override; 0141 0142 /** Change the time at which this variable timer triggers. 0143 * @param newTimeOfDay New time at which the timer should trigger. 0144 * @param triggerMissed If true, and if @p newTimeOfDay < @p oldTimeOfDay, and if the current 0145 * time is between @p newTimeOfDay and @p oldTimeOfDay, the timer will be 0146 * triggered immediately so as to avoid missing today's trigger. 0147 */ 0148 void changeTime(const QTime& newTimeOfDay, bool triggerMissed = true); 0149 0150 /** Return the current time of day at which this variable timer triggers. */ 0151 QTime timeOfDay() const { return mTime; } 0152 0153 /** Return the instance which triggers at the specified fixed time of day, 0154 * optionally creating a new instance if necessary. 0155 * @param timeOfDay Time at which the timer triggers. 0156 * @param create If true, create a new instance if none already exists 0157 * for @p timeOfDay. 0158 * @return The instance for @p timeOfDay, or 0 if it does not exist. 0159 */ 0160 static DailyTimer* fixedInstance(const QTime& timeOfDay, bool create = true); 0161 0162 void start() override; 0163 0164 protected Q_SLOTS: 0165 void slotTimer() override; 0166 0167 private: 0168 static QList<DailyTimer*> mFixedTimers; // list of timers whose trigger time is fixed 0169 QTime mTime; 0170 QDate mLastDate; // the date on which the timer was last triggered 0171 bool mFixed; // the time at which the timer triggers cannot be changed 0172 }; 0173 0174 0175 /** MidnightTimer is an application-wide timer synchronized to midnight, local time. 0176 * 0177 * @author David Jarvie <djarvie@kde.org> 0178 */ 0179 class MidnightTimer 0180 { 0181 public: 0182 /** Connect to the timer signal. 0183 * @param receiver Receiving object. 0184 * @param member Slot to activate. 0185 */ 0186 static void connect(QObject* receiver, const char* member) 0187 { DailyTimer::connect(QTime(0,0), receiver, member); } 0188 0189 /** Disconnect from the timer signal. 0190 * @param receiver Receiving object. 0191 * @param member Slot to disconnect. If null, all slots belonging to 0192 * @p receiver will be disconnected. 0193 */ 0194 static void disconnect(QObject* receiver, const char* member = nullptr) 0195 { DailyTimer::disconnect(QTime(0,0), receiver, member); } 0196 }; 0197 0198 // vim: et sw=4: