Commit ea84c2f3 authored by David Jarvie's avatar David Jarvie
Browse files

Bug 345922: Implement option to use notifications to display alarms

Add an option to the alarm edit dialog to display an alarm as a
notification instead of in a window.
parent d4d3468a
Pipeline #33837 passed with stage
in 12 minutes and 37 seconds
......@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5)
set(PIM_VERSION "5.15.40")
set(PIM_VERSION ${PIM_VERSION})
set(RELEASE_SERVICE_VERSION "20.11.80")
set(KALARM_VERSION "3.0.2")
set(KALARM_VERSION "3.1.0")
project(kalarm VERSION ${KALARM_VERSION})
......
KAlarm Change Log
=== Version 3.1.0 (KDE Applications 20.12) --- 11 September 2020 ===
+ Add option to show alarm message as a notification instead of in a window [KDE Bug 345922]
=== Version 3.0.2 (KDE Applications 20.08.2) --- 10 September 2020 ===
+ If command generating text for display alarm fails, only display error message,
not the display alarm, and don't redisplay the alarm on every restart.
......
......@@ -96,6 +96,7 @@ set(kalarm_bin_SRCS ${libkalarm_SRCS} ${resources_SRCS}
mainwindow.cpp
messagedisplay.cpp
messagedisplayhelper.cpp
messagenotification.cpp
messagewindow.cpp
preferences.cpp
prefdlg.cpp
......@@ -208,6 +209,7 @@ install(FILES data/org.kde.kalarm.appdata.xml DESTINATION ${KDE_INSTALL_METAINFO
install(FILES data/kalarmconfig.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR})
install(FILES data/kalarmui.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/kalarm)
install(FILES data/org.kde.kalarm.kalarm.xml DESTINATION ${KDE_INSTALL_DBUSINTERFACEDIR})
install(FILES data/kalarm.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFY5RCDIR})
########### KAuth helper ###############
......
[Global]
IconName=kalarm
DesktopEntry=org.kde.kalarm
Comment=KAlarm
[Event/Message]
Name=Alarm message
Action=Popup
[Event/MessageError]
Name=Alarm error message
Action=Popup|Sound
Sound=Oxygen-Sys-App-Error.ogg
<?xml version="1.0" encoding="UTF-8"?>
<!-- Author: David Jarvie <djarvie@kde.org> -->
<!--
SPDX-FileCopyrightText: 2007-2020 David Jarvie <djarvie@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
-->
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
......@@ -259,6 +262,15 @@
</entry>
</group>
<group name="Defaults">
<entry name="DefaultDisplayMethod" key="DisplayMethod" type="Enum">
<label context="@label">Alarm message display method</label>
<whatsthis context="@info:whatsthis">Default setting in the alarm edit dialog for "display method", to determine whether to display alarm messages in windows or in system notifications.</whatsthis>
<choices name="DisplayMethod" prefix="Display_">
<choice name="Window"/>
<choice name="Notification"/>
</choices>
<default>Window</default>
</entry>
<entry name="DefaultLateCancel" key="LateCancel" type="Int">
<label context="@label">Cancel if late (minutes)</label>
<whatsthis context="@info:whatsthis">Default value in the alarm edit dialog for late cancellation time (in minutes). 0 for no late cancellation, >0 how many minutes before cancelling.</whatsthis>
......
......@@ -61,6 +61,7 @@ using namespace KCalendarCore;
using namespace KAlarmCal;
enum { tTEXT, tFILE, tCOMMAND }; // order of mTypeCombo items
enum { dWINDOW, dNOTIFY }; // order of mDisplayMethodCombo items
/*=============================================================================
......@@ -86,9 +87,11 @@ class PickLogFileRadio : public PickFileRadio
= Dialog to edit display alarms.
=============================================================================*/
QString EditDisplayAlarmDlg::i18n_lbl_DisplayMethod() { return i18nc("@label:listbox", "Display method:"); }
QString EditDisplayAlarmDlg::i18n_combo_Window() { return i18nc("@item:inlistbox", "Window"); }
QString EditDisplayAlarmDlg::i18n_combo_Notify() { return i18nc("@item:inlistbox", "Notification"); }
QString EditDisplayAlarmDlg::i18n_chk_ConfirmAck() { return i18nc("@option:check", "Confirm acknowledgment"); }
/******************************************************************************
* Constructor.
* Parameters:
......@@ -135,9 +138,9 @@ void EditDisplayAlarmDlg::type_init(QWidget* parent, QVBoxLayout* frameLayout)
label->setFixedSize(label->sizeHint());
mTypeCombo = new ComboBox(box);
boxHLayout->addWidget(mTypeCombo);
QString textItem = i18nc("@item:inlistbox", "Text message");
QString fileItem = i18nc("@item:inlistbox", "File contents");
QString commandItem = i18nc("@item:inlistbox", "Command output");
const QString textItem = i18nc("@item:inlistbox", "Text message");
const QString fileItem = i18nc("@item:inlistbox", "File contents");
const QString commandItem = i18nc("@item:inlistbox", "Command output");
mTypeCombo->addItem(textItem); // index = tTEXT
mTypeCombo->addItem(fileItem); // index = tFILE
mTypeCombo->addItem(commandItem); // index = tCOMMAND
......@@ -220,13 +223,38 @@ void EditDisplayAlarmDlg::type_init(QWidget* parent, QVBoxLayout* frameLayout)
connect(mFontColourButton, &FontColourButton::selected, this, &EditDisplayAlarmDlg::setColours);
connect(mFontColourButton, &FontColourButton::selected, this, &EditDisplayAlarmDlg::contentsChanged);
// Display method selector
hlayout = new QHBoxLayout();
hlayout->setContentsMargins(0, 0, 0, 0);
frameLayout->addLayout(hlayout);
mDisplayMethodBox = new QWidget(parent); // to group widgets for QWhatsThis text
boxHLayout = new QHBoxLayout(mDisplayMethodBox);
boxHLayout->setContentsMargins(0, 0, 0, 0);
label = new QLabel(i18n_lbl_DisplayMethod(), mDisplayMethodBox);
boxHLayout->addWidget(label);
label->setFixedSize(label->sizeHint());
mDisplayMethodCombo = new ComboBox(mDisplayMethodBox);
boxHLayout->addWidget(mDisplayMethodCombo);
const QString windowItem = i18n_combo_Window();
const QString notifyItem = i18n_combo_Notify();
mDisplayMethodCombo->addItem(windowItem); // index = dWINDOW
mDisplayMethodCombo->addItem(notifyItem); // index = dNOTIFY
mDisplayMethodCombo->setFixedSize(mDisplayMethodCombo->sizeHint());
connect(mDisplayMethodCombo, static_cast<void (ComboBox::*)(int)>(&ComboBox::currentIndexChanged), this, &EditDisplayAlarmDlg::slotDisplayMethodChanged);
connect(mDisplayMethodCombo, static_cast<void (ComboBox::*)(int)>(&ComboBox::currentIndexChanged), this, &EditDisplayAlarmDlg::contentsChanged);
label->setBuddy(mDisplayMethodCombo);
mDisplayMethodBox->setWhatsThis(i18nc("@info:whatsthis", "Select whether to display the alarm in a window or by the notification system."));
hlayout->addWidget(mDisplayMethodBox);
hlayout->addSpacing(2 * style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing));
hlayout->addStretch();
if (ShellProcess::authorised()) // don't display if shell commands not allowed (e.g. kiosk mode)
{
// Special actions button
mSpecialActionsButton = new SpecialActionsButton(false, parent);
mSpecialActionsButton->setFixedSize(mSpecialActionsButton->sizeHint());
connect(mSpecialActionsButton, &SpecialActionsButton::selected, this, &EditDisplayAlarmDlg::contentsChanged);
frameLayout->addWidget(mSpecialActionsButton, 0, Qt::AlignRight);
hlayout->addWidget(mSpecialActionsButton);
}
// Top-adjust the controls
......@@ -279,6 +307,7 @@ void EditDisplayAlarmDlg::type_initValues(const KAEvent* event)
mFontColourButton->setBgColour(event->bgColour());
mFontColourButton->setFgColour(event->fgColour());
setColours(event->fgColour(), event->bgColour());
mDisplayMethodCombo->setCurrentIndex(event->notify() ? dNOTIFY : dWINDOW);
mConfirmAck->setChecked(event->confirmAck());
bool recurs = event->recurs();
int reminderMins = event->reminderMinutes();
......@@ -324,6 +353,7 @@ void EditDisplayAlarmDlg::type_initValues(const KAEvent* event)
mFontColourButton->setBgColour(Preferences::defaultBgColour());
mFontColourButton->setFgColour(Preferences::defaultFgColour());
setColours(Preferences::defaultFgColour(), Preferences::defaultBgColour());
mDisplayMethodCombo->setCurrentIndex(Preferences::defaultDisplayMethod() == Preferences::Display_Window ? dWINDOW : dNOTIFY);
mConfirmAck->setChecked(Preferences::defaultConfirmAck());
reminder()->setMinutes(0, false);
reminder()->enableOnceOnly(isTimedRecurrence()); // must be called after mRecurrenceEdit is set up
......@@ -352,9 +382,15 @@ void EditDisplayAlarmDlg::type_showOptions(bool more)
if (mSpecialActionsButton)
{
if (more)
{
mDisplayMethodBox->show();
mSpecialActionsButton->show();
}
else
{
mDisplayMethodBox->hide();
mSpecialActionsButton->hide();
}
}
}
......@@ -449,6 +485,7 @@ void EditDisplayAlarmDlg::setReadOnly(bool readOnly)
mCmdEdit->setReadOnly(readOnly);
mFontColourButton->setReadOnly(readOnly);
mSoundPicker->setReadOnly(readOnly);
mDisplayMethodCombo->setReadOnly(readOnly);
mConfirmAck->setReadOnly(readOnly);
reminder()->setReadOnly(readOnly);
if (mSpecialActionsButton)
......@@ -466,19 +503,20 @@ void EditDisplayAlarmDlg::setReadOnly(bool readOnly)
void EditDisplayAlarmDlg::saveState(const KAEvent* event)
{
EditAlarmDlg::saveState(event);
mSavedType = mTypeCombo->currentIndex();
mSavedCmdScript = mCmdEdit->isScript();
mSavedSoundType = mSoundPicker->sound();
mSavedSoundFile = mSoundPicker->file();
mSavedSoundVolume = mSoundPicker->volume(mSavedSoundFadeVolume, mSavedSoundFadeSeconds);
mSavedRepeatPause = mSoundPicker->repeatPause();
mSavedConfirmAck = mConfirmAck->isChecked();
mSavedFont = mFontColourButton->font();
mSavedFgColour = mFontColourButton->fgColour();
mSavedBgColour = mFontColourButton->bgColour();
mSavedReminder = reminder()->minutes();
mSavedOnceOnly = reminder()->isOnceOnly();
mSavedAutoClose = lateCancel()->isAutoClose();
mSavedType = mTypeCombo->currentIndex();
mSavedCmdScript = mCmdEdit->isScript();
mSavedSoundType = mSoundPicker->sound();
mSavedSoundFile = mSoundPicker->file();
mSavedSoundVolume = mSoundPicker->volume(mSavedSoundFadeVolume, mSavedSoundFadeSeconds);
mSavedRepeatPause = mSoundPicker->repeatPause();
mSavedDisplayMethod = mDisplayMethodCombo->currentIndex();
mSavedConfirmAck = mConfirmAck->isChecked();
mSavedFont = mFontColourButton->font();
mSavedFgColour = mFontColourButton->fgColour();
mSavedBgColour = mFontColourButton->bgColour();
mSavedReminder = reminder()->minutes();
mSavedOnceOnly = reminder()->isOnceOnly();
mSavedAutoClose = lateCancel()->isAutoClose();
if (mSpecialActionsButton)
{
mSavedPreAction = mSpecialActionsButton->preAction();
......@@ -495,17 +533,22 @@ void EditDisplayAlarmDlg::saveState(const KAEvent* event)
*/
bool EditDisplayAlarmDlg::type_stateChanged() const
{
if (mSavedType != mTypeCombo->currentIndex()
|| mSavedCmdScript != mCmdEdit->isScript()
|| mSavedSoundType != mSoundPicker->sound()
|| mSavedConfirmAck != mConfirmAck->isChecked()
|| mSavedFont != mFontColourButton->font()
|| mSavedFgColour != mFontColourButton->fgColour()
|| mSavedBgColour != mFontColourButton->bgColour()
|| mSavedReminder != reminder()->minutes()
|| mSavedOnceOnly != reminder()->isOnceOnly()
|| mSavedAutoClose != lateCancel()->isAutoClose())
if (mSavedType != mTypeCombo->currentIndex()
|| mSavedCmdScript != mCmdEdit->isScript()
|| mSavedSoundType != mSoundPicker->sound()
|| mSavedDisplayMethod != mDisplayMethodCombo->currentIndex()
|| mSavedReminder != reminder()->minutes()
|| mSavedOnceOnly != reminder()->isOnceOnly()
|| mSavedAutoClose != lateCancel()->isAutoClose())
return true;
if (mDisplayMethodCombo->currentIndex() == dWINDOW)
{
if (mSavedConfirmAck != mConfirmAck->isChecked()
|| mSavedFont != mFontColourButton->font()
|| mSavedFgColour != mFontColourButton->fgColour()
|| mSavedBgColour != mFontColourButton->bgColour())
return true;
}
if (mSpecialActionsButton)
{
if (mSavedPreAction != mSpecialActionsButton->preAction()
......@@ -579,12 +622,13 @@ KAEvent::Flags EditDisplayAlarmDlg::getAlarmFlags() const
if (mFontColourButton->defaultFont()) flags |= KAEvent::DEFAULT_FONT;
if (cmd) flags |= KAEvent::DISPLAY_COMMAND;
if (cmd && mCmdEdit->isScript()) flags |= KAEvent::SCRIPT;
if (mDisplayMethodCombo->currentIndex() == dNOTIFY) flags |= KAEvent::NOTIFY;
return flags;
}
/******************************************************************************
* Called when one of the alarm display type combo box is changed, to display
* the appropriate set of controls for that action type.
* Called when the alarm display type combo box is changed, to display the
* appropriate set of controls for that action type.
*/
void EditDisplayAlarmDlg::slotAlarmTypeChanged(int index)
{
......@@ -624,6 +668,17 @@ void EditDisplayAlarmDlg::slotAlarmTypeChanged(int index)
focus->setFocus();
}
/******************************************************************************
* Called when the display method combo box is changed, to enable/disable the
* appropriate set of controls for that display method.
*/
void EditDisplayAlarmDlg::slotDisplayMethodChanged(int index)
{
const bool enable = (index == dWINDOW);
mConfirmAck->setEnabled(enable);
mFontColourButton->setEnabled(enable);
}
/******************************************************************************
* Called when the file browse button is pressed to select a file to display.
*/
......
This diff is collapsed.
......@@ -17,6 +17,7 @@
#include "kamail.h"
#include "mainwindow.h"
#include "messagewindow.h"
#include "messagenotification.h"
#include "migratekde4files.h"
#include "preferences.h"
#include "prefdlg.h"
......@@ -287,6 +288,8 @@ bool KAlarmApp::restoreSession()
}
}
MessageNotification::sessionRestore();
// Try to display the system tray icon if it is configured to be shown
if (trayParent || wantShowInSystemTray())
{
......@@ -2177,10 +2180,10 @@ void* KAlarmApp::execAlarm(KAEvent& event, const KAAlarm& alarm, ExecAlarmFlags
if (!disp)
{
// There isn't already a message for this event
const int mdFlags = (flags & Reschedule ? 0 : MessageDisplay::NO_RESCHEDULE)
| (flags & AllowDefer ? 0 : MessageDisplay::NO_DEFER)
const int mdFlags = (flags & Reschedule ? 0 : MessageDisplay::NoReschedule)
| (flags & AllowDefer ? 0 : MessageDisplay::NoDefer)
| (flags & NoRecordCmdError ? MessageDisplay::NoRecordCmdError : 0);
(new MessageWindow(&event, alarm, mdFlags))->show();
MessageDisplay::create(event, alarm, mdFlags)->showDisplay();
}
else if (replaceReminder)
{
......@@ -2237,8 +2240,8 @@ void* KAlarmApp::execAlarm(KAEvent& event, const KAAlarm& alarm, ExecAlarmFlags
if (!disp)
{
// There isn't already a message for this event.
const int mdFlags = (flags & Reschedule ? 0 : MessageDisplay::NO_RESCHEDULE) | MessageDisplay::ALWAYS_HIDE;
disp = new MessageWindow(&event, alarm, mdFlags);
const int mdFlags = (flags & Reschedule ? 0 : MessageDisplay::NoReschedule) | MessageDisplay::AlwaysHide;
disp = MessageDisplay::create(event, alarm, mdFlags);
}
else
{
......@@ -2263,7 +2266,7 @@ void KAlarmApp::emailSent(KAMail::JobData& data, const QStringList& errmsgs, boo
// Some error occurred, although the email may have been sent successfully
if (errmsgs.count() > 1)
qCDebug(KALARM_LOG) << "KAlarmApp::emailSent:" << (copyerr ? "Copy error:" : "Failed:") << errmsgs[1];
MessageWindow::showError(data.event, data.alarm.dateTime(), errmsgs);
MessageDisplay::showError(data.event, data.alarm.dateTime(), errmsgs);
}
else if (data.queued)
Q_EMIT execAlarmSuccess();
......@@ -2312,10 +2315,12 @@ ShellProcess* KAlarmApp::execCommandAlarm(const KAEvent& event, const KAAlarm& a
* To connect to the exited signal of the process, specify the name of a method
* to be called by supplying 'receiver' and 'methodExited' parameters.
* To connect to the output ready signals of the process, specify a slot to be
* called by supplying 'receiver' and 'slot' parameters.
* called by supplying 'receiver' and 'slotOutput' parameters.
*
* Note that if shell access is not authorised, the attempt to run the command
* will be errored.
*
* Reply = process which has been started, or null if a process couldn't be started.
*/
ShellProcess* KAlarmApp::doShellCommand(const QString& command, const KAEvent& event, const KAAlarm* alarm, int flags, QObject* receiver, const char* slotOutput, const char* methodExited)
{
......@@ -2484,7 +2489,7 @@ QString KAlarmApp::createTempScriptFile(const QString& command, bool insertShell
}
const QStringList errmsgs(i18nc("@info", "Error creating temporary script file"));
MessageWindow::showError(event, alarm.dateTime(), errmsgs, QStringLiteral("Script"));
MessageDisplay::showError(event, alarm.dateTime(), errmsgs, QStringLiteral("Script"));
return QString();
}
......@@ -2611,7 +2616,7 @@ void KAlarmApp::commandErrorMsg(const ShellProcess* proc, const KAEvent& event,
errmsgs += proc->command();
dontShowAgain += QString::number(proc->status());
}
MessageWindow::showError(event, (alarm ? alarm->dateTime() : DateTime()), errmsgs, dontShowAgain);
MessageDisplay::showError(event, (alarm ? alarm->dateTime() : DateTime()), errmsgs, dontShowAgain);
}
}
......@@ -2741,9 +2746,7 @@ KAlarmApp::ProcData::ProcData(ShellProcess* p, KAEvent* e, KAAlarm* a, int f)
: process(p)
, event(e)
, alarm(a)
, messageBoxParent(nullptr)
, flags(f)
, eventDeleted(false)
{ }
KAlarmApp::ProcData::~ProcData()
......
This diff is collapsed.
......@@ -8,12 +8,17 @@
#include "messagedisplayhelper.h"
#include "messagewindow.h"
//#include "messagenotification.h"
#include "messagenotification.h"
#include "deferdlg.h"
#include "displaycalendar.h"
#include "functions.h"
#include "kalarmapp.h"
#include "resourcescalendar.h"
#include "resources/resources.h"
#include "lib/messagebox.h"
#include <KLocalizedString>
using namespace KAlarmCal;
using namespace KCalendarCore;
......@@ -21,24 +26,60 @@ using namespace KCalendarCore;
bool MessageDisplay::mRedisplayed = false;
MessageDisplay::MessageDisplay(const QString& displayType)
: mDisplayType(displayType)
, mHelper(new MessageDisplayHelper(this))
/******************************************************************************
* Create a new instance of a MessageDisplay, the derived class being dependent
* on 'event.notify()'.
*/
MessageDisplay* MessageDisplay::create(const KAEvent& event, const KAAlarm& alarm, int flags)
{
if (event.notify())
return new MessageNotification(event, alarm, flags);
else
return new MessageWindow(event, alarm, flags);
}
MessageDisplay::MessageDisplay(const QString& displayType, const KAEvent* event, const KAAlarm& alarm, int flags)
: mDisplayType(displayType)
, mHelper(new MessageDisplayHelper(this, event, alarm, flags))
/******************************************************************************
* Show an error message about the execution of an alarm.
* If 'dontShowAgain' is non-null, a "Don't show again" option is displayed. Note
* that the option is specific to 'event'.
*/
void MessageDisplay::showError(const KAEvent& event, const DateTime& alarmDateTime,
const QStringList& errmsgs, const QString& dontShowAgain)
{
if (MessageDisplayHelper::shouldShowError(event, errmsgs, dontShowAgain))
{
MessageDisplay* disp;
if (event.notify())
disp = new MessageNotification(event, alarmDateTime, errmsgs, dontShowAgain);
else
disp = new MessageWindow(event, alarmDateTime, errmsgs, dontShowAgain);
disp->showDisplay();
}
}
MessageDisplay::MessageDisplay(const QString& displayType, const KAEvent* event,
const DateTime& alarmDateTime,
/******************************************************************************
* Constructors.
*/
MessageDisplay::MessageDisplay()
: mHelper(new MessageDisplayHelper(this))
{
}
MessageDisplay::MessageDisplay(const KAEvent& event, const KAAlarm& alarm, int flags)
: mHelper(new MessageDisplayHelper(this, event, alarm, flags))
{
}
MessageDisplay::MessageDisplay(const KAEvent& event, const DateTime& alarmDateTime,
const QStringList& errmsgs, const QString& dontShowAgain)
: mDisplayType(displayType)
, mHelper(new MessageDisplayHelper(this, event, alarmDateTime, errmsgs, dontShowAgain))
: mHelper(new MessageDisplayHelper(this, event, alarmDateTime, errmsgs, dontShowAgain))
{
}
MessageDisplay::MessageDisplay(MessageDisplayHelper* helper)
: mHelper(helper)
{
mHelper->setParent(this);
}
MessageDisplay::~MessageDisplay()
......@@ -83,8 +124,8 @@ void MessageDisplay::redisplayAlarms()
}
qCDebug(KALARM_LOG) << "MessageDisplay::redisplayAlarms:" << eventId;
const bool login = alarm.repeatAtLogin();
const int flags = NO_RESCHEDULE | (login ? NO_DEFER : 0) | NO_INIT_VIEW;
MessageDisplay* d = new MessageWindow(&event, alarm, flags);
const int flags = NoReschedule | (login ? NoDefer : 0) | NoInitView;
MessageDisplay* d = create(event, alarm, flags);
MessageDisplayHelper* h = d->mHelper;
h->mResource = resource;
const bool rw = resource.isWritable(event.category());
......@@ -102,9 +143,9 @@ void MessageDisplay::redisplayAlarms()
* or if not found there, from the archive calendar. 'resource' is set to the
* resource which originally contained the event, or invalid if not known.
*/
bool MessageDisplay::retrieveEvent(KAEvent& event, Resource& resource, bool& showEdit, bool& showDefer)
bool MessageDisplay::retrieveEvent(const EventId& evntId, KAEvent& event, Resource& resource, bool& showEdit, bool& showDefer)
{
const QString eventId = mHelper->mEventId.eventId();
const QString eventId = evntId.eventId();
const Event::Ptr kcalEvent = DisplayCalendar::kcalEvent(CalEvent::uid(eventId, CalEvent::DISPLAYING));
if (!reinstateFromDisplaying(kcalEvent, event, resource, showEdit, showDefer))
{
......@@ -147,4 +188,120 @@ bool MessageDisplay::reinstateFromDisplaying(const Event::Ptr& kcalEvent, KAEven
return true;
}
/******************************************************************************
* Display the main window, with the appropriate alarm selected.
*/
void MessageDisplay::displayMainWindow()
{
KAlarm::displayMainWindowSelected(mEventId().eventId());
}
MessageDisplay::DeferDlgData::~DeferDlgData()
{
delete dlg;
}
/******************************************************************************
* Create a defer message dialog.
*/
MessageDisplay::DeferDlgData* MessageDisplay::createDeferDlg(bool displayClosing)
{
DeferAlarmDlg* dlg = new DeferAlarmDlg(KADateTime::currentDateTime(Preferences::timeSpec()).addSecs(60), mDateTime().isDateOnly(), false, displayParent());
dlg->setObjectName(QStringLiteral("DeferDlg")); // used by LikeBack
dlg->setDeferMinutes(mDefaultDeferMinutes() > 0 ? mDefaultDeferMinutes() : Preferences::defaultDeferTime());
dlg->setLimit(mEvent());
DeferDlgData* data = new DeferDlgData(dlg);
data->eventId = mEventId();
data->alarmType = mAlarmType();
data->commandError = mCommandError();
data->displayOpen = !displayClosing;
return data;
}
/******************************************************************************
* Display a defer message dialog.
*/
void MessageDisplay::executeDeferDlg(DeferDlgData* data)
{
if (data->dlg->exec() == QDialog::Accepted)
{
const DateTime dateTime = data->dlg->getDateTime();
const int delayMins = data->dlg->deferMinutes();
// Fetch the up-to-date alarm from the calendar. Note that it could have
// changed since it was displayed.
KAEvent event;
if (!data->eventId.isEmpty())
event = ResourcesCalendar::event(data->eventId);
if (event.isValid())
{
// The event still exists in the active calendar
qCDebug(KALARM_LOG) << "MessageDisplay::executeDeferDlg: Deferring event" << data->eventId;
KAEvent newev(event);
newev.defer(dateTime, (data->alarmType & KAAlarm::REMINDER_ALARM), true);
newev.setDeferDefaultMinutes(delayMins);
KAlarm::updateEvent(newev, data->dlg, true);
if (data->displayOpen)
{
if (newev.deferred())
mNoPostAction() = true;
}
}
else
{
// Try to retrieve the event from the displaying or archive calendars
Resource resource; // receives the event's original resource, if known
KAEvent event2;
bool showEdit, showDefer;
if (!retrieveEvent(data->eventId, event2, resource, showEdit, showDefer))
{
// The event doesn't exist any more !?!, so recurrence data,
// flags, and more, have been lost.
KAMessageBox::error(displayParent(), xi18nc("@info", "<para>Cannot defer alarm:</para><para>Alarm not found.</para>"));
if (data->displayOpen)
{
raiseDisplay();
enableDeferButton(false);
enableEditButton(false);
}
delete data;
return;
}
qCDebug(KALARM_LOG) << "MessageDisplay::executeDeferDlg: Deferring retrieved event" << data->eventId;
event2.defer(dateTime, (data->alarmType & KAAlarm::REMINDER_ALARM), true);
event2.setDeferDefaultMinutes(delayMins);
event2.setCommandError(data->commandError);
// Add the event back into the calendar file, retaining its ID
// and not updating KOrganizer.
KAlarm::addEvent(event2, resource, data->dlg, KAlarm::USE_EVENT_ID);
if (data->displayOpen)
{
if (event2.deferred())
mNoPostAction() = true;
}
// Finally delete it from the archived calendar now that it has
// been reactivated.
event2.setCategory(CalEvent::ARCHIVED);
Resource res;
KAlarm::deleteEvent(event2, res, false);
}
if (theApp()->wantShowInSystemTray())
{
// Alarms are to be displayed only if the system tray icon is running,
// so start it if necessary so that the deferred alarm will be shown.
theApp()->displayTrayIcon(true);
}
if (data->displayOpen)
{
mHelper->mNoCloseConfirm = true; // allow window to close without confirmation prompt
closeDisplay();
}
}
else
{
if (data->displayOpen)
raiseDisplay();
}
delete data;
}