Warning, file /pim/kalarm/src/messagedisplayhelper.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  *  messagedisplayhelper.h  -  helper class to display an alarm or error message
0003  *  Program:  kalarm
0004  *  SPDX-FileCopyrightText: 2001-2023 David Jarvie <djarvie@kde.org>
0005  *
0006  *  SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #pragma once
0010 
0011 #include "eventid.h"
0012 #include "resources/resource.h"
0013 #include "lib/file.h"
0014 #include "lib/shellprocess.h"
0015 #include "kalarmcalendar/kaevent.h"
0016 
0017 #include <QObject>
0018 #include <QHash>
0019 #include <QPointer>
0020 #include <QDateTime>
0021 
0022 class KConfigGroup;
0023 class QTemporaryFile;
0024 class AudioPlayer;
0025 class PushButton;
0026 class EditAlarmDlg;
0027 class MessageDisplay;
0028 
0029 using namespace KAlarmCal;
0030 
0031 /**
0032  * Class for use by alarm message display classes, to handle common functions
0033  * for displaying an alarm.
0034  * In order for this class to use signals and slots, it needs to derive from
0035  * QObject. As a result, it has to be a separate class from MessageDisplay;
0036  * otherwise, MessageWindow would derive from two QObject classes, which is
0037  * prohibited.
0038  */
0039 class MessageDisplayHelper : public QObject
0040 {
0041     Q_OBJECT
0042 public:
0043     /** Contains the texts to display in the alarm. */
0044     struct DisplayTexts
0045     {
0046         /** Identifiers for the fields in DisplayTexts. */
0047         enum TextId
0048         {
0049             Title         = 0x01,    //!< DisplayTexts::title
0050             Time          = 0x02,    //!< DisplayTexts::time
0051             TimeFull      = 0x04,    //!< DisplayTexts::timeFull
0052             FileName      = 0x08,    //!< DisplayTexts::fileName
0053             Message       = 0x10,    //!< DisplayTexts::message
0054             MessageAppend = 0x20,    //!< Text has been appended to DisplayTexts::message
0055             RemainingTime = 0x40     //!< DisplayTexts::remainingTime
0056         };
0057         Q_DECLARE_FLAGS(TextIds, TextId)
0058 
0059         QString title;            // window/notification title
0060         QString time;             // header showing alarm trigger time
0061         QString timeFull;         // header showing alarm trigger time and "Reminder" if appropriate
0062         QString fileName;         // if message is a file's contents, the file name
0063         QString message;          // the alarm message
0064         QString remainingTime;    // if advance reminder, the remaining time until the actual alarm
0065         QString errorEmail[4];    // if email alarm error message, the 'To' and 'Subject' contents
0066         File::Type fileType;      // if message is a file's contents, the file type
0067         bool    newLine {false};  // 'message' has a newline stripped from the end
0068     };
0069 
0070     explicit MessageDisplayHelper(MessageDisplay* parent);     // for session management restoration only
0071     MessageDisplayHelper(MessageDisplay* parent, const KAEvent&, const KAAlarm&, int flags);
0072     MessageDisplayHelper(MessageDisplay* parent, const KAEvent&, const DateTime& alarmDateTime,
0073                          const QStringList& errmsgs, const QString& dontShowAgain);
0074     MessageDisplayHelper(const MessageDisplayHelper&) = delete;
0075     MessageDisplayHelper& operator=(const MessageDisplayHelper&) = delete;
0076     ~MessageDisplayHelper() override;
0077     void                setParent(MessageDisplay* parent)  { mParent = parent; }
0078     void                setSilenceButton(PushButton* b)    { mSilenceButton = b; }
0079     void                repeat(const KAAlarm&);
0080     const DateTime&     dateTime()             { return mDateTime; }
0081     KAAlarm::Type       alarmType() const      { return mAlarmType; }
0082     bool                cancelReminder(const KAEvent&, const KAAlarm&);
0083     bool                updateDateTime(const KAEvent&, const KAAlarm&);
0084     bool                isValid() const        { return !mInvalid; }
0085     bool                alwaysHidden() const   { return mAlwaysHide; }
0086     void                initTexts();
0087     const DisplayTexts& texts() const          { return mTexts; }
0088     bool                activateAutoClose();
0089     void                displayComplete(bool audio);
0090     bool                alarmShowing(KAEvent&);
0091     void                playAudio();
0092     EditAlarmDlg*       createEdit();
0093     void                executeEdit();
0094     void                setDeferralLimit(const KAEvent&);
0095 
0096     /** Called when a close request has been received.
0097      *  @return  true to close the alarm message, false to keep it open.
0098      */
0099     bool                closeEvent();
0100 
0101     bool                saveProperties(KConfigGroup&);
0102     bool                readProperties(const KConfigGroup&);
0103     bool                readPropertyValues(const KConfigGroup&);
0104     bool                processPropertyValues();
0105 
0106     static int          instanceCount(bool excludeAlwaysHidden = false);
0107     static bool         shouldShowError(const KAEvent& event, const QStringList& errmsgs, const QString& dontShowAgain = QString());
0108     static MessageDisplay* findEvent(const EventId& eventId, MessageDisplay* exclude = nullptr);
0109     static bool         isAudioPlaying();
0110     static void         stopAudio();
0111     static void         wakeScreen();
0112 
0113 Q_SIGNALS:
0114     /** Signal emitted when texts in the alarm message have changed.
0115      *  @param id      Which text has changed.
0116      *  @param change  If id == MessageAppend, the text which has been appended.
0117      */
0118     void textsChanged(DisplayTexts::TextIds, const QString& change = QString());
0119 
0120     /** Signal emitted on completion of the command providing the alarm message text. */
0121     void commandExited(bool success);
0122 
0123     /** Signal emitted when the alarm should close, after the auto-close time. */
0124     void autoCloseNow();
0125 
0126 private Q_SLOTS:
0127     void    showRestoredAlarm();
0128     void    editCloseOk();
0129     void    editCloseCancel();
0130     void    checkDeferralLimit();
0131     void    slotSpeak();
0132     void    audioTerminating();
0133     void    startAudio();
0134     void    stopAudioPlay()               { stopAudio(); }
0135     void    playReady();
0136     void    playFinished();
0137     void    slotSetRemainingTextDay()     { setRemainingTextDay(true); }
0138     void    slotSetRemainingTextMinute()  { setRemainingTextMinute(true); }
0139     void    readProcessOutput(ShellProcess*);
0140     void    commandCompleted(ShellProcess::Status);
0141 
0142 private:
0143     QString dateTimeToDisplay() const;
0144     void    setRemainingTextDay(bool notify);
0145     void    setRemainingTextMinute(bool notify);
0146     bool    haveErrorMessage(unsigned msg) const;
0147     void    clearErrorMessage(unsigned msg) const;
0148     void    redisplayAlarm();
0149 
0150     static QList<MessageDisplayHelper*> mInstanceList; // list of existing message displays
0151     static QHash<EventId, unsigned> mErrorMessages; // error messages currently displayed, by event ID
0152     // Sound file playing
0153     static QPointer<QThread>     mAudioThread;    // container of thread to play audio file in
0154     static QPointer<AudioPlayer> mAudioPlayer;    // audio file play worker object
0155     static MessageDisplayHelper* mAudioOwner;     // helper instance which owns the unique audio thread
0156 
0157 public:
0158     MessageDisplay*     mParent;
0159     // Properties needed by readProperties()
0160     QString             mMessage;
0161     QFont               mFont;
0162     QColor              mBgColour, mFgColour;
0163     DateTime            mDateTime;                // date/time displayed in the message window
0164     QDateTime           mCloseTime;               // UTC time at which window should be auto-closed
0165     EventId             mEventId;
0166     QString             mAudioFile;
0167     float               mVolume;
0168     float               mFadeVolume;
0169     int                 mFadeSeconds;
0170     int                 mDefaultDeferMinutes;
0171     KAAlarm::Type       mAlarmType;
0172     KAEvent::SubAction  mAction;
0173     KAEvent::EmailId    mEmailId;                 // if email text, message's Akonadi Item ID, else -1
0174     KAEvent::CmdErr     mCommandError;
0175     QStringList         mErrorMsgs;
0176     QString             mDontShowAgain;           // non-null for don't-show-again option with error message
0177     int                 mAudioRepeatPause;
0178     bool                mConfirmAck;
0179     bool                mShowEdit;                // display the Edit button
0180     bool                mNoDefer;                 // don't display a Defer option
0181     bool                mInvalid;                 // restored window is invalid
0182     // Miscellaneous
0183     KAEvent             mEvent;                   // the whole event, for updating the calendar file
0184     KAEvent             mOriginalEvent;           // the original event supplied to the constructor
0185     Resource            mResource;                // resource which the event comes/came from
0186     PushButton*         mSilenceButton {nullptr}; // button to stop audio, enabled when audio playing
0187     EditAlarmDlg*       mEditDlg {nullptr};       // alarm edit dialog invoked by Edit button
0188     QDateTime           mDeferLimit;              // last UTC time to which the message can currently be deferred
0189     bool                mDisableDeferral {false}; // true if past deferral limit, so don't enable Defer button
0190     bool                mNoCloseConfirm {false};  // the Defer or Edit button is closing the dialog
0191     bool                mAlwaysHide {false};      // the window should never be displayed
0192     bool                mErrorWindow {false};     // the window is simply an error message
0193     bool                mNoPostAction;            // don't execute any post-alarm action
0194     bool                mBeep;
0195     bool                mSpeak;                   // the message should be spoken via kttsd
0196 private:
0197     DisplayTexts        mTexts;                   // texts to display in alarm message
0198     QTemporaryFile*     mTempFile {nullptr};      // temporary file used to display image/HTML
0199     QByteArray          mCommandOutput;           // cumulative output from command
0200     bool                mCommandHaveStdout {false}; // true if some stdout has been received from command
0201     bool                mNoRecordCmdError {false}; // don't record command alarm errors
0202     bool                mInitialised {false};     // initTexts() has been called to create the alarm's texts
0203     bool                mRescheduleEvent {false}; // true to delete event after message has been displayed
0204 
0205 //friend class MessageDisplay;
0206 };
0207 
0208 Q_DECLARE_OPERATORS_FOR_FLAGS(MessageDisplayHelper::DisplayTexts::TextIds)
0209 
0210 // vim: et sw=4: