kalarmapp.h 12.9 KB
Newer Older
1
/*
David Jarvie's avatar
David Jarvie committed
2
 *  kalarmapp.h  -  the KAlarm application object
3
 *  Program:  kalarm
David Jarvie's avatar
David Jarvie committed
4
 *  Copyright © 2001-2016 by David Jarvie <djarvie@kde.org>
5 6 7 8 9
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
David Jarvie's avatar
David Jarvie committed
10 11 12 13 14 15
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
David Jarvie's avatar
David Jarvie committed
16 17
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
David Jarvie's avatar
David Jarvie committed
18
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 20 21 22 23
 */

#ifndef KALARMAPP_H
#define KALARMAPP_H

24 25
/** @file kalarmapp.h - the KAlarm application object */

26
#include "eventid.h"
27 28 29
#include "kamail.h"
#include "preferences.h"

Laurent Montel's avatar
Laurent Montel committed
30
#include <kalarmcal/kaevent.h>
31

David Jarvie's avatar
David Jarvie committed
32
#include <QApplication>
33
#include <QPointer>
David Jarvie's avatar
David Jarvie committed
34 35
#include <QQueue>
#include <QList>
David Jarvie's avatar
David Jarvie committed
36

37
class KDateTime;
David Jarvie's avatar
David Jarvie committed
38
namespace KCal { class Event; }
39
namespace Akonadi { class Collection; }
40
class DBusHandler;
41
class MainWindow;
42
class TrayWindow;
43
class ShellProcess;
44

45
using namespace KAlarmCal;
46

47

David Jarvie's avatar
David Jarvie committed
48
class KAlarmApp : public QApplication
49
{
50 51 52
        Q_OBJECT
    public:
        ~KAlarmApp();
David Jarvie's avatar
David Jarvie committed
53 54
        static KAlarmApp*  create(int& argc, char** argv);
        static KAlarmApp*  instance()                      { return mInstance; }
55 56 57 58
        bool               checkCalendar()                 { return initCheck(); }
        bool               wantShowInSystemTray() const;
        bool               alarmsEnabled() const           { return mAlarmsEnabled; }
        bool               korganizerEnabled() const       { return mKOrganizerEnabled; }
59 60
        int                activate(const QStringList& args, const QString& workingDirectory, QString& outputText)
                                                           { return activateInstance(args, workingDirectory, &outputText); }
61 62 63 64 65 66 67 68
        bool               restoreSession();
        bool               quitIf()                        { return quitIf(0); }
        void               doQuit(QWidget* parent);
        static void        displayFatalError(const QString& message);
        void               addWindow(TrayWindow* w)        { mTrayWindow = w; }
        void               removeWindow(TrayWindow*);
        TrayWindow*        trayWindow() const              { return mTrayWindow; }
        MainWindow*        trayMainWindow() const;
Laurent Montel's avatar
Laurent Montel committed
69
        bool               displayTrayIcon(bool show, MainWindow* = Q_NULLPTR);
70
        bool               trayIconDisplayed() const       { return mTrayWindow; }
Laurent Montel's avatar
Laurent Montel committed
71
        bool               editNewAlarm(MainWindow* = Q_NULLPTR);
72 73

        void*              execAlarm(KAEvent&, const KAAlarm&, bool reschedule, bool allowDefer = true, bool noPreAction = false);
Laurent Montel's avatar
Laurent Montel committed
74
        ShellProcess*      execCommandAlarm(const KAEvent&, const KAAlarm&, const QObject* receiver = Q_NULLPTR, const char* slot = Q_NULLPTR);
75 76 77 78 79 80
        void               alarmCompleted(const KAEvent&);
        void               rescheduleAlarm(KAEvent& e, const KAAlarm& a)   { rescheduleAlarm(e, a, true); }
        void               purgeAll()             { purge(0); }
        void               commandMessage(ShellProcess*, QWidget* parent);
        void               notifyAudioPlaying(bool playing);
        void               setSpreadWindowsState(bool spread);
81 82
        bool               windowFocusBroken() const;
        bool               needWindowFocusFix() const;
83
        // Methods called indirectly by the DCOP interface
84
        bool               scheduleEvent(KAEvent::SubAction, const QString& text, const KDateTime&,
85
                                         int lateCancel, KAEvent::Flags flags, const QColor& bg, const QColor& fg,
86 87
                                         const QFont&, const QString& audioFile, float audioVolume,
                                         int reminderMinutes, const KARecurrence& recurrence,
88
                                         KCalCore::Duration repeatInterval, int repeatCount,
89
                                         uint mailFromID = 0, const KCalCore::Person::List& mailAddresses = KCalCore::Person::List(),
90 91
                                         const QString& mailSubject = QString(),
                                         const QStringList& mailAttachments = QStringList());
92 93
        bool               dbusTriggerEvent(const EventId& eventID)   { return dbusHandleEvent(eventID, EVENT_TRIGGER); }
        bool               dbusDeleteEvent(const EventId& eventID)    { return dbusHandleEvent(eventID, EVENT_CANCEL); }
94
        QString            dbusList();
95

Laurent Montel's avatar
Laurent Montel committed
96
    public Q_SLOTS:
97
        void               activateByDBus(const QStringList& args, const QString& workingDirectory);
98 99
        void               processQueue();
        void               setAlarmsEnabled(bool);
100
        void               purgeNewArchivedDefault(const Akonadi::Collection&);
101
        void               atLoginEventAdded(const KAEvent&);
102
        void               notifyAudioStopped()  { notifyAudioPlaying(false); }
103 104 105 106
        void               stopAudio();
        void               spreadWindows(bool);
        void               emailSent(KAMail::JobData&, const QStringList& errmsgs, bool copyerr = false);

Laurent Montel's avatar
Laurent Montel committed
107
    Q_SIGNALS:
108 109 110 111 112 113 114 115 116
        void               trayIconToggled();
        void               alarmEnabledToggled(bool);
        void               audioPlaying(bool);
        void               spreadWindowsToggled(bool);
        void               execAlarmSuccess();

    private:
        typedef Preferences::Feb29Type Feb29Type;   // allow it to be used in SIGNAL mechanism

Laurent Montel's avatar
Laurent Montel committed
117
    private Q_SLOTS:
118 119 120 121 122 123 124 125
        void               quitFatal();
        void               checkNextDueAlarm();
        void               checkKtimezoned();
        void               slotShowInSystemTrayChanged();
        void               changeStartOfDay();
        void               slotWorkTimeChanged(const QTime& start, const QTime& end, const QBitArray& days);
        void               slotHolidaysChanged(const KHolidays::HolidayRegion&);
        void               slotFeb29TypeChanged(Feb29Type);
126
        void               checkWritableCalendar();
127 128 129
        void               slotMessageFontChanged(const QFont&);
        void               setArchivePurgeDays();
        void               slotPurge()                     { purge(mArchivedPurgeDays); }
130
        void               purgeAfterDelay();
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
        void               slotCommandExited(ShellProcess*);

    private:
        enum EventFunc
        {
            EVENT_HANDLE,    // if the alarm is due, execute it and then reschedule it
            EVENT_TRIGGER,   // execute the alarm regardless, and then reschedule it if it already due
            EVENT_CANCEL     // delete the alarm
        };
        struct ProcData
        {
            ProcData(ShellProcess*, KAEvent*, KAAlarm*, int flags = 0);
            ~ProcData();
            enum { PRE_ACTION = 0x01, POST_ACTION = 0x02, RESCHEDULE = 0x04, ALLOW_DEFER = 0x08,
                   TEMP_FILE = 0x10, EXEC_IN_XTERM = 0x20, DISP_OUTPUT = 0x40 };
146 147 148 149 150 151 152 153 154 155 156 157 158
            bool  preAction() const   { return flags & PRE_ACTION; }
            bool  postAction() const  { return flags & POST_ACTION; }
            bool  reschedule() const  { return flags & RESCHEDULE; }
            bool  allowDefer() const  { return flags & ALLOW_DEFER; }
            bool  tempFile() const    { return flags & TEMP_FILE; }
            bool  execInXterm() const { return flags & EXEC_IN_XTERM; }
            bool  dispOutput() const  { return flags & DISP_OUTPUT; }
            ShellProcess*     process;
            KAEvent*          event;
            KAAlarm*          alarm;
            QPointer<QWidget> messageBoxParent;
            QStringList       tempFiles;
            int               flags;
159
            bool              eventDeleted;
160
        };
161
        struct ActionQEntry
162
        {
163
            ActionQEntry(EventFunc f, const EventId& id) : function(f), eventId(id) { }
164 165
            ActionQEntry(const KAEvent& e, EventFunc f = EVENT_HANDLE) : function(f), event(e) { }
            ActionQEntry() { }
166
            EventFunc  function;
167
            EventId    eventId;
168 169 170
            KAEvent    event;
        };

David Jarvie's avatar
David Jarvie committed
171
        KAlarmApp(int& argc, char** argv);
172
        bool               initialise();
173
        int                activateInstance(const QStringList& args, const QString& workingDirectory, QString* outputText);
174
        bool               initCheck(bool calendarOnly = false, bool waitForCollection = false, Akonadi::Collection::Id = -1);
175 176 177
        bool               quitIf(int exitCode, bool force = false);
        bool               checkSystemTray();
        void               startProcessQueue();
178 179 180
        void               queueAlarmId(const KAEvent&);
        bool               dbusHandleEvent(const EventId&, EventFunc);
        bool               handleEvent(const EventId&, EventFunc, bool checkDuplicates = false);
181 182
        int                rescheduleAlarm(KAEvent&, const KAAlarm&, bool updateCalAndDisplay,
                                           const KDateTime& nextDt = KDateTime());
183
        bool               cancelAlarm(KAEvent&, KAAlarm::Type, bool updateCalAndDisplay);
184
        bool               cancelReminderAndDeferral(KAEvent&);
185
        ShellProcess*      doShellCommand(const QString& command, const KAEvent&, const KAAlarm*,
Laurent Montel's avatar
Laurent Montel committed
186
                                          int flags = 0, const QObject* receiver = Q_NULLPTR, const char* slot = Q_NULLPTR);
187 188
        QString            composeXTermCommand(const QString& command, const KAEvent&, const KAAlarm*,
                                               int flags, QString& tempScriptFile) const;
189 190 191
        QString            createTempScriptFile(const QString& command, bool insertShell, const KAEvent&, const KAAlarm&) const;
        void               commandErrorMsg(const ShellProcess*, const KAEvent&, const KAAlarm*, int flags = 0);
        void               purge(int daysToKeep);
192
        QStringList        scheduledAlarmList();
193 194 195
        void               setEventCommandError(const KAEvent&, KAEvent::CmdErrType) const;
        void               clearEventCommandError(const KAEvent&, KAEvent::CmdErrType) const;
        ProcData*          findCommandProcess(const QString& eventId) const;
196

David Jarvie's avatar
David Jarvie committed
197
        static KAlarmApp*  mInstance;            // the one and only KAlarmApp instance
198 199 200 201
        static int         mActiveCount;         // number of active instances without main windows
        static int         mFatalError;          // a fatal error has occurred - just wait to exit
        static QString     mFatalMessage;        // fatal error message to output
        bool               mInitialised;         // initialisation complete: ready to process execution queue
202
        bool               mRedisplayAlarms;     // need to redisplay alarms when collection tree fetched
203
        bool               mQuitting;            // a forced quit is in progress
204
        bool               mReadOnly;            // only read-only access to calendars is needed
205
        bool               mLoginAlarmsDone;     // alarms repeated at login have been processed
206
        QString            mActivateArg0;        // activate()'s first arg the first time it was called
207 208 209 210 211 212 213
        DBusHandler*       mDBusHandler;         // the parent of the main DCOP receiver object
        TrayWindow*        mTrayWindow;          // active system tray icon
        QTimer*            mAlarmTimer;          // activates KAlarm when next alarm is due
        QColor             mPrefsArchivedColour; // archived alarms text colour
        int                mArchivedPurgeDays;   // how long to keep archived alarms, 0 = don't keep, -1 = keep indefinitely
        int                mPurgeDaysQueued;     // >= 0 to purge the archive calendar from KAlarmApp::processLoop()
        QList<ProcData*>   mCommandProcesses;    // currently active command alarm processes
214
        QQueue<ActionQEntry> mActionQueue;       // queued commands and actions
215 216
        int                mPendingQuitCode;     // exit code for a pending quit
        bool               mPendingQuit;         // quit once the DCOP command and shell command queues have been processed
217
        bool               mCancelRtcWake;       // cancel RTC wake on quitting
218
        bool               mProcessingQueue;     // a mActionQueue entry is currently being processed
219 220 221 222
        bool               mNoSystemTray;        // no system tray exists
        bool               mOldShowInSystemTray; // showing in system tray was selected
        bool               mAlarmsEnabled;       // alarms are enabled
        bool               mKOrganizerEnabled;   // KOrganizer options are enabled (korganizer exists)
223
        bool               mWindowFocusBroken;   // keyboard focus transfer between windows doesn't work
224 225
};

David Jarvie's avatar
David Jarvie committed
226
inline KAlarmApp* theApp()  { return KAlarmApp::instance(); }
227 228

#endif // KALARMAPP_H
229 230

// vim: et sw=4: