1 /*
2  *  messagedisplay.h  -  base class to display an alarm or error message
3  *  Program:  kalarm
4  *  SPDX-FileCopyrightText: 2001-2022 David Jarvie <djarvie@kde.org>
5  *
6  *  SPDX-License-Identifier: GPL-2.0-or-later
7  */
8 
9 #pragma once
10 
11 #include "messagedisplayhelper.h"
12 
13 #include <KAlarmCal/KAEvent>
14 
15 
16 class KConfigGroup;
17 class DeferAlarmDlg;
18 class EventId;
19 class MessageDisplayHelper;
20 
21 using namespace KAlarmCal;
22 
23 /**
24  * Abstract base class for alarm message display.
25  */
26 class MessageDisplay
27 {
28 public:
29     /** Flags for constructor. */
30     enum
31     {
32         NoReschedule     = 0x01,    // don't reschedule the event once it has displayed
33         NoDefer          = 0x02,    // don't display an option to defer
34         NoRecordCmdError = 0x04,    // don't record error executing command
35         AlwaysHide       = 0x08,    // never show the window (e.g. for audio-only alarms)
36         NoInitView       = 0x10     // for internal MessageDisplayHelper use only
37     };
38 
39     /** Create a MessageDisplay alarm message instance.
40      *  The instance type is dependent on the event->notify() value.
41      */
42     static MessageDisplay* create(const KAEvent& event, const KAAlarm& alarm, int flags);
43 
44     /** Show an error message about the execution of an alarm.
45      *  The instance type is dependent on the event.notify() value.
46      *  @param event          The event for the alarm.
47      *  @param alarmDateTime  Date/time displayed in the message display.
48      *  @param errmsgs        The error messages to display.
49      *  @param dontShowAgain  The "don't show again" ID of the error message.
50      */
51     static void showError(const KAEvent& event, const DateTime& alarmDateTime,
52                           const QStringList& errmsgs, const QString& dontShowAgain = QString());
53 
54     virtual ~MessageDisplay();
55 
isValid()56     bool isValid() const   { return mHelper->isValid(); }
alarmType()57     KAAlarm::Type alarmType() const   { return mHelper->mAlarmType; }
58 
59     /** Raise the alarm display, re-output any required audio notification, and
60      *  reschedule the alarm in the calendar file.
61      */
62     virtual void repeat(const KAAlarm&) = 0;
63 
64     virtual bool hasDefer() const = 0;
65     virtual void showDefer() = 0;
showDateTime(const KAEvent &,const KAAlarm &)66     virtual void showDateTime(const KAEvent&, const KAAlarm&)  {}
67 
68     /** Convert a reminder display into a normal alarm display. */
cancelReminder(const KAEvent & event,const KAAlarm & alarm)69     virtual void cancelReminder(const KAEvent& event, const KAAlarm& alarm)
70     {
71         mHelper->cancelReminder(event, alarm);
72     }
73 
74     /** Returns the existing message display (if any) which is showing the event with
75      *  the specified ID.
76      */
77     static MessageDisplay* findEvent(const EventId& eventId, MessageDisplay* exclude = nullptr)
78     { return MessageDisplayHelper::findEvent(eventId, exclude); }
79 
80     /** Redisplay alarms which were being shown when the program last exited. */
81     static void redisplayAlarms();
82 
83     /** Retrieve the event with the current ID from the displaying calendar file,
84      *  or if not found there, from the archive calendar.
85      *  @param resource  Is set to the resource which originally contained the
86      *                   event, or invalid if not known.
87      */
88     static bool retrieveEvent(const EventId&, KAEvent&, Resource&, bool& showEdit, bool& showDefer);
89 
playAudio()90     void        playAudio()                    { mHelper->playAudio(); }
91     static void stopAudio(bool wait = false)   { MessageDisplayHelper::stopAudio(wait); }
isAudioPlaying()92     static bool isAudioPlaying()               { return MessageDisplayHelper::isAudioPlaying(); }
93 
94     /** Called when the edit alarm dialog has been cancelled. */
editDlgCancelled()95     virtual void editDlgCancelled()  {}
96 
97     /** For use by MessageDisplayHelper.
98      *  Returns the widget to act as parent for error messages, etc. */
99     virtual QWidget* displayParent() = 0;
100 
101     /** For use by MessageDisplayHelper only. Close the alarm message display. */
102     virtual void closeDisplay() = 0;
103 
104     /** Show the alarm message display. */
105     virtual void showDisplay() = 0;
106 
107     /** For use by MessageDisplayHelper only. Raise the alarm message display. */
108     virtual void raiseDisplay() = 0;
109 
110     static int instanceCount(bool excludeAlwaysHidden = false)    { return MessageDisplayHelper::instanceCount(excludeAlwaysHidden); }
111 
112     // Holds data required by defer dialog.
113     // This is needed because the display may have closed when the defer dialog
114     // is opened.
115     struct DeferDlgData
116     {
117         DeferAlarmDlg*      dlg;
118         QPointer<QObject>   displayObj {nullptr};
119         MessageDisplay*     display;
120         EventId             eventId;
121         KAAlarm::Type       alarmType;
122         KAEvent::CmdErrType commandError;
123 
DeferDlgDataDeferDlgData124         DeferDlgData(MessageDisplay* m, DeferAlarmDlg* d) : dlg(d), display(m) {}
125         ~DeferDlgData();
126     };
127 
128     /** For use by MainWindow only. Called when a defer alarm dialog completes. */
129     static void processDeferDlg(DeferDlgData*, int result);
130 
131 protected:
132     MessageDisplay();
133     MessageDisplay(const KAEvent& event, const KAAlarm& alarm, int flags);
134     MessageDisplay(const KAEvent& event, const DateTime& alarmDateTime,
135                    const QStringList& errmsgs, const QString& dontShowAgain);
136 
137     explicit MessageDisplay(MessageDisplayHelper* helper);
138 
139     /** Called by MessageDisplayHelper to confirm that the alarm message should be
140      *  acknowledged (closed).
141      *  @return  true to close the alarm message, false to keep it open.
142      */
confirmAcknowledgement()143     virtual bool confirmAcknowledgement()  { return true; }
144 
145     /** Set up the alarm message display. */
146     virtual void setUpDisplay() = 0;
147 
148     void displayMainWindow();
149 
150     virtual bool isDeferButtonEnabled() const = 0;
151     virtual void enableDeferButton(bool enable) = 0;
152     virtual void enableEditButton(bool enable) = 0;
153 
154     DeferDlgData* createDeferDlg(QObject* thisObject, bool displayClosing);
155     static void   executeDeferDlg(DeferDlgData*);
156 
157     MessageDisplayHelper* mHelper;
158 
159     // Access to MessageDisplayHelper data.
mAlarmType()160     KAAlarm::Type&      mAlarmType()             { return mHelper->mAlarmType; }
mAction()161     KAEvent::SubAction  mAction() const          { return mHelper->mAction; }
mEventId()162     const EventId&      mEventId() const         { return mHelper->mEventId; }
mEvent()163     const KAEvent&      mEvent() const           { return mHelper->mEvent; }
mOriginalEvent()164     const KAEvent&      mOriginalEvent() const   { return mHelper->mOriginalEvent; }
mFont()165     const QFont&        mFont() const            { return mHelper->mFont; }
mBgColour()166     const QColor&       mBgColour() const        { return mHelper->mBgColour; }
mFgColour()167     const QColor&       mFgColour() const        { return mHelper->mFgColour; }
mAudioFile()168     const QString&      mAudioFile() const       { return mHelper->mAudioFile; }
mVolume()169     float               mVolume() const          { return mHelper->mVolume; }
mFadeVolume()170     float               mFadeVolume() const      { return mHelper->mFadeVolume; }
mDefaultDeferMinutes()171     int                 mDefaultDeferMinutes() const  { return mHelper->mDefaultDeferMinutes; }
mAkonadiItemId()172     Akonadi::Item::Id   mAkonadiItemId() const   { return mHelper->mAkonadiItemId; }
mCommandError()173     KAEvent::CmdErrType mCommandError() const    { return mHelper->mCommandError; }
mNoPostAction()174     bool&               mNoPostAction()          { return mHelper->mNoPostAction; }
175 
mDateTime()176     const DateTime&     mDateTime() const        { return mHelper->mDateTime; }
mEditDlg()177     EditAlarmDlg*       mEditDlg() const         { return mHelper->mEditDlg; }
mIsValid()178     bool                mIsValid() const         { return !mHelper->mInvalid; }
mDisableDeferral()179     bool                mDisableDeferral() const { return mHelper->mDisableDeferral; }
mNoCloseConfirm()180     bool                mNoCloseConfirm() const  { return mHelper->mNoCloseConfirm; }
mAlwaysHidden()181     bool                mAlwaysHidden() const    { return mHelper->mAlwaysHide; }
mErrorWindow()182     bool                mErrorWindow() const     { return mHelper->mErrorWindow; }
mErrorMsgs()183     const QStringList&  mErrorMsgs() const       { return mHelper->mErrorMsgs; }
mNoDefer()184     bool&               mNoDefer()               { return mHelper->mNoDefer; }
mShowEdit()185     bool                mShowEdit() const        { return mHelper->mShowEdit; }
mDontShowAgain()186     const QString&      mDontShowAgain() const   { return mHelper->mDontShowAgain; }
187 
188 private:
189     static bool reinstateFromDisplaying(const KCalendarCore::Event::Ptr&, KAEvent&, Resource&, bool& showEdit, bool& showDefer);
190 
191     static bool     mRedisplayed;   // redisplayAlarms() was called
192 
193 friend class MessageDisplayHelper;
194 };
195 
196 
197 // vim: et sw=4:
198