Commit c41d5432 authored by David Jarvie's avatar David Jarvie

Implement pre- and post-alarm shell command actions

svn path=/trunk/kdepim/; revision=311491
parent d7e9b6b9
KAlarm
=== Version 1.1.0 --- 6 May 2004 ===
=== Version 1.1.0 --- 14 May 2004 ===
Add facility to define alarm templates.
Add option to play sound file repeatedly until alarm window is closed.
Add volume control for playing sound file.
Add 'stop sound' button to alarm message window when sound file is played.
Add facility to specify pre- and post-alarm shell command actions.
Rename command line option --sound to --play, add option --play-repeat.
Add command line option --volume.
After creating/editing alarm, prompt to re-enable alarms if currently disabled.
......
......@@ -16,7 +16,7 @@ kalarm_SOURCES = birthdaydlg.cpp alarmevent.cpp editdlg.cpp alarmcalendar.cpp \
traywindow.cpp dcophandler.cpp alarmguiiface.skel \
recurrenceedit.cpp deferdlg.cpp functions.cpp \
fontcolour.cpp fontcolourbutton.cpp alarmtimewidget.cpp \
datetime.cpp reminder.cpp synchtimer.cpp \
specialactions.cpp datetime.cpp reminder.cpp synchtimer.cpp \
eventlistviewbase.cpp alarmlistview.cpp kamail.cpp \
templatelistview.cpp templatepickdlg.cpp templatedlg.cpp
kalarm_LDFLAGS = $(all_libraries) $(KDE_RPATH)
......@@ -32,8 +32,8 @@ noinst_HEADERS = alarmcalendar.h alarmevent.h alarmlistview.h alarmtimewidget.h
fontcolourbutton.h functions.h kalarm.h kalarmapp.h kamail.h \
mainwindow.h mainwindowbase.h messagewin.h prefdlg.h preferences.h \
recurrenceedit.h recurrenceeditprivate.h reminder.h soundpicker.h \
synchtimer.h templatedlg.h templatelistview.h templatepickdlg.h \
traywindow.h
specialactions.h synchtimer.h templatedlg.h templatelistview.h \
templatepickdlg.h traywindow.h
kalarm_COMPILE_FIRST = ../kalarmd/alarmdaemoniface_stub.h
METASOURCES = AUTO
......
......@@ -59,6 +59,8 @@ static const QString ARCHIVE_REMINDER_ONCE_TYPE = QString::fromLatin1("ONCE");
static const QString TIME_DEFERRAL_TYPE = QString::fromLatin1("DEFERRAL");
static const QString DATE_DEFERRAL_TYPE = QString::fromLatin1("DATE_DEFERRAL");
static const QString DISPLAYING_TYPE = QString::fromLatin1("DISPLAYING"); // used only in displaying calendar
static const QString PRE_ACTION_TYPE = QString::fromLatin1("PRE");
static const QString POST_ACTION_TYPE = QString::fromLatin1("POST");
static const QCString FONT_COLOUR_PROPERTY("FONTCOLOR"); // X-KDE-KALARM-FONTCOLOR property
static const QCString VOLUME_PROPERTY("VOLUME"); // X-KDE-KALARM-VOLUME property
......@@ -108,6 +110,8 @@ void KAEvent::copy(const KAEvent& event)
KAAlarmEventBase::copy(event);
mTemplateName = event.mTemplateName;
mAudioFile = event.mAudioFile;
mPreAction = event.mPreAction;
mPostAction = event.mPostAction;
mStartDateTime = event.mStartDateTime;
mSaveDateTime = event.mSaveDateTime;
mAtLoginDateTime = event.mAtLoginDateTime;
......@@ -145,10 +149,8 @@ void KAEvent::set(const Event& event)
mEventID = event.uid();
mRevision = event.revision();
mTemplateName = QString::null;
mSoundVolume = -1;
mTemplateDefaultTime = false;
mBeep = false;
mRepeatSound = false;
mEmailBcc = false;
mConfirmAck = false;
mLateCancel = false;
......@@ -217,15 +219,19 @@ void KAEvent::set(const Event& event)
// Extract status from the event's alarms.
// First set up defaults.
mActionType = T_MESSAGE;
mMainExpired = true;
mRecursFeb29 = false;
mRepeatAtLogin = false;
mDeferral = false;
mReminderDeferral = false;
mDisplaying = false;
mMainExpired = true;
mRepeatSound = false;
mSoundVolume = -1;
mReminderMinutes = 0;
mText = "";
mAudioFile = "";
mPreAction = "";
mPostAction = "";
mEmailSubject = "";
mEmailAddresses.clear();
mEmailAttachments.clear();
......@@ -291,6 +297,12 @@ void KAEvent::set(const Event& event)
mSoundVolume = !mBeep ? data.soundVolume : -1;
mRepeatSound = !mBeep && (data.repeatCount < 0);
break;
case KAAlarm::PRE_ACTION__ALARM:
mPreAction = data.cleanText;
break;
case KAAlarm::POST_ACTION__ALARM:
mPostAction = data.cleanText;
break;
case KAAlarm::INVALID__ALARM:
default:
break;
......@@ -298,7 +310,9 @@ void KAEvent::set(const Event& event)
if (data.reminderOnceOnly)
mReminderOnceOnly = true;
if (data.action != T_AUDIO)
if (data.type != KAAlarm::AUDIO__ALARM
&& data.type != KAAlarm::PRE_ACTION__ALARM
&& data.type != KAAlarm::POST_ACTION__ALARM)
{
// Ensure that the basic fields are set up even if there is no main
// alarm in the event (if it has expired and then been deferred)
......@@ -468,6 +482,10 @@ void KAEvent::readAlarm(const Alarm& alarm, AlarmData& data)
dateDeferral = deferral = true;
else if (type == DISPLAYING_TYPE)
data.type = KAAlarm::DISPLAYING__ALARM;
else if (type == PRE_ACTION_TYPE && data.action == T_COMMAND)
data.type = KAAlarm::PRE_ACTION__ALARM;
else if (type == POST_ACTION_TYPE && data.action == T_COMMAND)
data.type = KAAlarm::POST_ACTION__ALARM;
}
if (reminder)
......@@ -518,6 +536,8 @@ void KAEvent::set(const QDateTime& dateTime, const QString& text, const QColor&
}
mText = (mActionType == T_COMMAND) ? text.stripWhiteSpace() : text;
mTemplateName = QString::null;
mPreAction = QString::null;
mPostAction = QString::null;
mAudioFile = "";
mSoundVolume = -1;
mBgColour = bg;
......@@ -753,12 +773,12 @@ bool KAEvent::updateKCalEvent(Event& ev, bool checkUid, bool original) const
ev.setHasEndDate(false);
DateTime dtMain = original ? mStartDateTime : mDateTime;
DateTime audioTime;
DateTime ancillaryTime; // time for ancillary alarms (audio, pre-action, etc)
if (!mMainExpired || original)
{
// Add the main alarm
initKcalAlarm(ev, dtMain, QStringList());
audioTime = dtMain;
ancillaryTime = dtMain;
}
// Add subsidiary alarms
......@@ -774,16 +794,16 @@ bool KAEvent::updateKCalEvent(Event& ev, bool checkUid, bool original) const
else
dtl = QDateTime::currentDateTime();
initKcalAlarm(ev, dtl, AT_LOGIN_TYPE);
if (!audioTime.isValid())
audioTime = dtl;
if (!ancillaryTime.isValid())
ancillaryTime = dtl;
}
if (mReminderMinutes || mArchiveReminderMinutes && original)
{
int minutes = mReminderMinutes ? mReminderMinutes : mArchiveReminderMinutes;
DateTime reminderTime = dtMain.addSecs(-minutes * 60);
initKcalAlarm(ev, reminderTime, QStringList(mReminderOnceOnly ? REMINDER_ONCE_TYPE : REMINDER_TYPE));
if (!audioTime.isValid())
audioTime = reminderTime;
if (!ancillaryTime.isValid())
ancillaryTime = reminderTime;
}
if (mDeferral)
{
......@@ -795,8 +815,8 @@ bool KAEvent::updateKCalEvent(Event& ev, bool checkUid, bool original) const
if (mReminderDeferral)
list += mReminderOnceOnly ? REMINDER_ONCE_TYPE : REMINDER_TYPE;
initKcalAlarm(ev, mDeferralTime, list);
if (!audioTime.isValid())
audioTime = mDeferralTime;
if (!ancillaryTime.isValid())
ancillaryTime = mDeferralTime;
}
if (!mTemplateName.isEmpty())
ev.setSummary(mTemplateName);
......@@ -815,16 +835,23 @@ bool KAEvent::updateKCalEvent(Event& ev, bool checkUid, bool original) const
if (mDisplayingFlags & REMINDER)
list += mReminderOnceOnly ? REMINDER_ONCE_TYPE : REMINDER_TYPE;
initKcalAlarm(ev, mDisplayingTime, list);
if (!audioTime.isValid())
audioTime = mDisplayingTime;
if (!ancillaryTime.isValid())
ancillaryTime = mDisplayingTime;
}
if (mBeep || !mAudioFile.isEmpty())
{
// A sound is specified
KAAlarmEventBase::Type actType = mActionType;
const_cast<KAEvent*>(this)->mActionType = T_AUDIO;
initKcalAlarm(ev, audioTime, QStringList());
const_cast<KAEvent*>(this)->mActionType = actType;
initKcalAlarm(ev, ancillaryTime, QStringList(), KAAlarm::AUDIO_ALARM);
}
if (!mPreAction.isEmpty())
{
// A pre-display action is specified
initKcalAlarm(ev, ancillaryTime, QStringList(PRE_ACTION_TYPE), KAAlarm::PRE_ACTION_ALARM);
}
if (!mPostAction.isEmpty())
{
// A post-display action is specified
initKcalAlarm(ev, ancillaryTime, QStringList(POST_ACTION_TYPE), KAAlarm::POST_ACTION_ALARM);
}
// Add recurrence data
......@@ -884,10 +911,10 @@ bool KAEvent::updateKCalEvent(Event& ev, bool checkUid, bool original) const
/******************************************************************************
* Create a new alarm for a libkcal event, and initialise it according to the
* alarm action. If 'type' is non-null, it is appended to the X-KDE-KALARM-TYPE
* alarm action. If 'types' is non-null, it is appended to the X-KDE-KALARM-TYPE
* property value list.
*/
Alarm* KAEvent::initKcalAlarm(Event& event, const DateTime& dt, const QStringList& types) const
Alarm* KAEvent::initKcalAlarm(Event& event, const DateTime& dt, const QStringList& types, KAAlarm::Type type) const
{
QStringList alltypes;
Alarm* alarm = event.newAlarm();
......@@ -897,25 +924,9 @@ Alarm* KAEvent::initKcalAlarm(Event& event, const DateTime& dt, const QStringLis
alarm->setStartOffset(dt.isDateOnly() ? mStartDateTime.secsTo(dt)
: mStartDateTime.dateTime().secsTo(dt.dateTime()));
switch (mActionType)
{
case T_FILE:
alltypes += FILE_TYPE;
// fall through to T_MESSAGE
case T_MESSAGE:
alarm->setDisplayAlarm(mText);
alarm->setCustomProperty(APPNAME, FONT_COLOUR_PROPERTY,
QString::fromLatin1("%1;%2;%3").arg(mBgColour.name())
.arg(mFgColour.name())
.arg(mDefaultFont ? QString::null : mFont.toString()));
break;
case T_COMMAND:
setProcedureAlarm(alarm, mText);
break;
case T_EMAIL:
alarm->setEmailAlarm(mEmailSubject, mText, mEmailAddresses, mEmailAttachments);
break;
case T_AUDIO:
switch (type)
{
case KAAlarm::AUDIO_ALARM:
alarm->setAudioAlarm(mAudioFile); // empty for a beep
if (mRepeatSound)
{
......@@ -925,6 +936,42 @@ Alarm* KAEvent::initKcalAlarm(Event& event, const DateTime& dt, const QStringLis
if (!mAudioFile.isEmpty() && mSoundVolume >= 0)
alarm->setCustomProperty(APPNAME, VOLUME_PROPERTY, QString::number(mSoundVolume, 'f', 2));
break;
case KAAlarm::PRE_ACTION_ALARM:
setProcedureAlarm(alarm, mPreAction);
break;
case KAAlarm::POST_ACTION_ALARM:
setProcedureAlarm(alarm, mPostAction);
break;
case KAAlarm::INVALID_ALARM:
switch (mActionType)
{
case T_FILE:
alltypes += FILE_TYPE;
// fall through to T_MESSAGE
case T_MESSAGE:
alarm->setDisplayAlarm(mText);
alarm->setCustomProperty(APPNAME, FONT_COLOUR_PROPERTY,
QString::fromLatin1("%1;%2;%3").arg(mBgColour.name())
.arg(mFgColour.name())
.arg(mDefaultFont ? QString::null : mFont.toString()));
break;
case T_COMMAND:
setProcedureAlarm(alarm, mText);
break;
case T_EMAIL:
alarm->setEmailAlarm(mEmailSubject, mText, mEmailAddresses, mEmailAttachments);
break;
case T_AUDIO:
break;
}
break;
case KAAlarm::MAIN_ALARM:
case KAAlarm::REMINDER_ALARM:
case KAAlarm::DEFERRED_ALARM:
case KAAlarm::DEFERRED_REMINDER_ALARM:
case KAAlarm::AT_LOGIN_ALARM:
case KAAlarm::DISPLAYING_ALARM:
break;
}
alltypes += types;
if (alltypes.count() > 0)
......@@ -1012,6 +1059,8 @@ KAAlarm KAEvent::alarm(KAAlarm::Type type) const
}
break;
case KAAlarm::AUDIO_ALARM:
case KAAlarm::PRE_ACTION_ALARM:
case KAAlarm::POST_ACTION_ALARM:
case KAAlarm::INVALID_ALARM:
default:
break;
......@@ -1070,6 +1119,8 @@ KAAlarm KAEvent::nextAlarm(KAAlarm::Type prevType) const
case KAAlarm::DISPLAYING_ALARM:
// fall through to default
case KAAlarm::AUDIO_ALARM:
case KAAlarm::PRE_ACTION_ALARM:
case KAAlarm::POST_ACTION_ALARM:
case KAAlarm::INVALID_ALARM:
default:
break;
......@@ -1125,6 +1176,8 @@ void KAEvent::removeExpiredAlarm(KAAlarm::Type type)
}
break;
case KAAlarm::AUDIO_ALARM:
case KAAlarm::PRE_ACTION_ALARM:
case KAAlarm::POST_ACTION_ALARM:
case KAAlarm::INVALID_ALARM:
default:
break;
......@@ -2522,7 +2575,12 @@ void KAEvent::dumpDebug() const
kdDebug(5950) << "-- mTemplateName:" << mTemplateName << ":\n";
kdDebug(5950) << "-- mTemplateDefaultTime:" << (mTemplateDefaultTime ? "true" : "false") << ":\n";
}
kdDebug(5950) << "-- mAudioFile:" << mAudioFile << ":\n";
if (mActionType == T_MESSAGE || mActionType == T_FILE)
{
kdDebug(5950) << "-- mAudioFile:" << mAudioFile << ":\n";
kdDebug(5950) << "-- mPreAction:" << mPreAction << ":\n";
kdDebug(5950) << "-- mPostAction:" << mPostAction << ":\n";
}
kdDebug(5950) << "-- mStartDateTime:" << mStartDateTime.toString() << ":\n";
kdDebug(5950) << "-- mSaveDateTime:" << mSaveDateTime.toString() << ":\n";
if (mRepeatAtLogin)
......@@ -2587,6 +2645,8 @@ void KAAlarm::dumpDebug() const
case AT_LOGIN__ALARM: altype = "LOGIN"; break;
case DISPLAYING__ALARM: altype = "DISPLAYING"; break;
case AUDIO__ALARM: altype = "AUDIO"; break;
case PRE_ACTION__ALARM: altype = "PRE_ACTION"; break;
case POST_ACTION__ALARM: altype = "POST_ACTION"; break;
default: altype = "INVALID"; break;
}
kdDebug(5950) << "-- mType:" << altype << ":\n";
......@@ -2605,6 +2665,8 @@ const char* KAAlarm::debugType(Type type)
case AT_LOGIN_ALARM: return "LOGIN";
case DISPLAYING_ALARM: return "DISPLAYING";
case AUDIO_ALARM: return "AUDIO";
case PRE_ACTION_ALARM: return "PRE_ACTION";
case POST_ACTION_ALARM: return "POST_ACTION";
default: return "INVALID";
}
}
......
......@@ -121,18 +121,23 @@ class KAAlarmEventBase
};
// KAAlarm corresponds to a single KCal::Alarm instance
// KAAlarm corresponds to a single KCal::Alarm instance.
// A KAEvent may contain multiple KAAlarm's.
class KAAlarm : public KAAlarmEventBase
{
public:
// Define the basic KAAlaem action types
enum Action
{
MESSAGE = T_MESSAGE,
FILE = T_FILE,
COMMAND = T_COMMAND,
EMAIL = T_EMAIL,
AUDIO = T_AUDIO
MESSAGE = T_MESSAGE, // KCal::Alarm::Display type: display a text message
FILE = T_FILE, // KCal::Alarm::Display type: display a file (URL given by the alarm text)
COMMAND = T_COMMAND, // KCal::Alarm::Procedure type: execute a shell command
EMAIL = T_EMAIL, // KCal::Alarm::Email type: send an email
AUDIO = T_AUDIO // KCal::Alarm::Audio type: play a sound file
};
// Define the KAAlarm types.
// KAAlarm's of different types may be contained in a KAEvent,
// each defining a different component of the overall alarm.
enum Type
{
INVALID_ALARM = 0, // not an alarm
......@@ -146,7 +151,9 @@ class KAAlarm : public KAAlarmEventBase
AT_LOGIN_ALARM = 0x10, // additional repeat-at-login trigger
DISPLAYING_ALARM = 0x20, // copy of the alarm currently being displayed
// The following values are for internal KAEvent use only
AUDIO_ALARM = 0x30 // sound to play when displaying the alarm.
AUDIO_ALARM = 0x30, // sound to play when displaying the alarm
PRE_ACTION_ALARM = 0x40, // command to execute before displaying the alarm
POST_ACTION_ALARM = 0x50 // command to execute after the alarm window is closed
};
enum SubType
{
......@@ -164,7 +171,9 @@ class KAAlarm : public KAAlarmEventBase
AT_LOGIN__ALARM = AT_LOGIN_ALARM,
DISPLAYING__ALARM = DISPLAYING_ALARM,
// The following values are for internal KAEvent use only
AUDIO__ALARM = AUDIO_ALARM
AUDIO__ALARM = AUDIO_ALARM,
PRE_ACTION__ALARM = PRE_ACTION_ALARM,
POST_ACTION__ALARM = POST_ACTION_ALARM
};
KAAlarm() : mType(INVALID__ALARM) { }
......@@ -294,6 +303,7 @@ class KAEvent : public KAAlarmEventBase
void setEmail(const EmailAddressList&, const QString& subject, const QStringList& attachments);
void setAudioFile(const QString& filename, float volume) { mAudioFile = filename; mSoundVolume = volume; mUpdated = true; }
void setTemplate(const QString& name, bool defaultTime){ mTemplateName = name; mTemplateDefaultTime = defaultTime; }
void setActions(const QString& pre, const QString& post) { mPreAction = pre; mPostAction = post; }
OccurType setNextOccurrence(const QDateTime& preDateTime);
void setFirstRecurrence();
void setEventID(const QString& id) { mEventID = id; mUpdated = true; }
......@@ -344,6 +354,8 @@ class KAEvent : public KAAlarmEventBase
const QString& audioFile() const { return mAudioFile; }
float soundVolume() const { return mSoundVolume >= 0 && !mAudioFile.isEmpty() ? mSoundVolume : -1; }
bool repeatSound() const { return mRepeatSound && !mAudioFile.isEmpty(); }
const QString& preAction() const { return mPreAction; }
const QString& postAction() const { return mPostAction; }
bool recurs() const { return checkRecur() != NO_RECUR; }
RecurType recurType() const { return checkRecur(); }
KCal::Recurrence* recurrence() const { return mRecurrence; }
......@@ -474,12 +486,14 @@ class KAEvent : public KAAlarmEventBase
RecurType checkRecur() const;
OccurType nextRecurrence(const QDateTime& preDateTime, DateTime& result, int& remainingCount) const;
OccurType previousRecurrence(const QDateTime& afterDateTime, DateTime& result) const;
KCal::Alarm* initKcalAlarm(KCal::Event&, const DateTime&, const QStringList& types) const;
KCal::Alarm* initKcalAlarm(KCal::Event&, const DateTime&, const QStringList& types, KAAlarm::Type = KAAlarm::INVALID_ALARM) const;
static void readAlarms(const KCal::Event&, void* alarmMap);
static void readAlarm(const KCal::Alarm&, AlarmData&);
QString mTemplateName; // alarm template's name, or null if normal event
QString mAudioFile; // ATTACH: audio file to play
QString mPreAction; // command to execute before alarm is displayed
QString mPostAction; // command to execute after alarm window is closed
DateTime mStartDateTime; // DTSTART and DTEND: start and end time for event
QDateTime mSaveDateTime; // CREATED: date event was created, or saved in expired calendar
QDateTime mAtLoginDateTime; // repeat-at-login time
......
......@@ -75,8 +75,10 @@ void AlarmTimeWidget::init(int mode)
connect(this, SIGNAL(buttonSet(int)), SLOT(slotButtonSet(int)));
QBoxLayout* topLayout = new QVBoxLayout(this, 0, KDialog::spacingHint());
if (!title().isEmpty())
{
topLayout->setMargin(marginKDE2 + KDialog::marginHint());
topLayout->addSpacing(fontMetrics().lineSpacing()/2);
topLayout->addSpacing(fontMetrics().lineSpacing()/2);
}
// At time radio button/label
mAtTimeRadio = new RadioButton(((mode & DEFER_TIME) ? i18n("&Defer to date/time:") : i18n("At &date/time:")), this, "atTimeRadio");
......
......@@ -79,7 +79,9 @@
#include "radiobutton.h"
#include "recurrenceedit.h"
#include "reminder.h"
#include "shellprocess.h"
#include "soundpicker.h"
#include "specialactions.h"
#include "spinbox.h"
#include "templatepickdlg.h"
#include "timeperiod.h"
......@@ -111,14 +113,15 @@ QString EditAlarmDlg::i18n_s_CopyEmailToSelf() { return i18n("Copy email to &se
* event != to initialise the dialogue to show the specified event's data.
*/
EditAlarmDlg::EditAlarmDlg(bool Template, const QString& caption, QWidget* parent, const char* name,
const KAEvent* event, bool readOnly)
: KDialogBase(parent, name, true, caption,
(readOnly ? Cancel|Try : Template ? Ok|Cancel|Try : Ok|Cancel|Try|Default),
(readOnly ? Cancel : Ok)),
const KAEvent* event, bool readOnly)
: KDialogBase(parent, name, true, caption,
(readOnly ? Cancel|Try : Template ? Ok|Cancel|Try : Ok|Cancel|Try|Default),
(readOnly ? Cancel : Ok)),
mMainPageShown(false),
mRecurPageShown(false),
mRecurSetDefaultEndDate(true),
mTemplateName(0),
mSpecialActionsButton(0),
mReminderDeferral(false),
mReminderArchived(false),
mEmailRemoveButton(0),
......@@ -371,11 +374,6 @@ void EditAlarmDlg::initDisplayAlarms(QWidget* parent)
mSoundPicker->setFixedSize(mSoundPicker->sizeHint());
frameLayout->addWidget(mSoundPicker, 0, Qt::AlignLeft);
// Acknowledgement confirmation required - default = no confirmation
mConfirmAck = createConfirmAckCheckbox(mDisplayAlarmsFrame);
mConfirmAck->setFixedSize(mConfirmAck->sizeHint());
frameLayout->addWidget(mConfirmAck, 0, Qt::AlignLeft);
// Reminder
static const QString reminderText = i18n("Enter how long in advance of the main alarm to display a reminder alarm.");
mReminder = new Reminder(i18n("Rem&inder:"),
......@@ -385,6 +383,22 @@ void EditAlarmDlg::initDisplayAlarms(QWidget* parent)
mReminder->setFixedSize(mReminder->sizeHint());
frameLayout->addWidget(mReminder, 0, Qt::AlignLeft);
// Acknowledgement confirmation required - default = no confirmation
layout = new QHBoxLayout(frameLayout);
mConfirmAck = createConfirmAckCheckbox(mDisplayAlarmsFrame);
mConfirmAck->setFixedSize(mConfirmAck->sizeHint());
layout->addWidget(mConfirmAck);
layout->addSpacing(2*KDialog::spacingHint());
layout->addStretch();
if (ShellProcess::authorised()) // don't display if shell commands not allowed (e.g. kiosk mode)
{
// Special actions button
mSpecialActionsButton = new SpecialActionsButton(i18n("Special Actions..."), mDisplayAlarmsFrame);
mSpecialActionsButton->setFixedSize(mSpecialActionsButton->sizeHint());
layout->addWidget(mSpecialActionsButton);
}
// Top-adjust the controls
mFilePadding = new QHBox(mDisplayAlarmsFrame);
frameLayout->addWidget(mFilePadding);
......@@ -495,7 +509,7 @@ list->setGeometry(rect.left() - 50, rect.top(), rect.width(), rect.height());
void EditAlarmDlg::initialise(const KAEvent* event)
{
mReadOnly = mDesiredReadOnly;
if (!mTemplate && event && event->action() == KAEvent::COMMAND && theApp()->noShellAccess())
if (!mTemplate && event && event->action() == KAEvent::COMMAND && !ShellProcess::authorised())
mReadOnly = true; // don't allow editing of existing command alarms in kiosk mode
setReadOnly();
......@@ -573,6 +587,8 @@ void EditAlarmDlg::initialise(const KAEvent* event)
mReminder->setMinutes(reminder, (mTimeWidget ? mTimeWidget->anyTime() : mTemplateAnyTime->isOn()));
mReminder->setOnceOnly(event->reminderOnceOnly());
mReminder->enableOnceOnly(event->recurs());
if (mSpecialActionsButton)
mSpecialActionsButton->setActions(event->preAction(), event->postAction());
mRecurrenceText->setText(event->recurrenceText());
mRecurrenceEdit->set(*event); // must be called after mTimeWidget is set up, to ensure correct date-only enabling
mSoundPicker->set(event->beep(), event->audioFile(), event->soundVolume(), event->repeatSound());
......@@ -583,8 +599,13 @@ void EditAlarmDlg::initialise(const KAEvent* event)
else
{
// Set the values to their defaults
if (theApp()->noShellAccess())
mCommandRadio->setEnabled(false); // don't allow shell commands in kiosk mode
if (!ShellProcess::authorised())
{
// Don't allow shell commands in kiosk mode
mCommandRadio->setEnabled(false);
if (mSpecialActionsButton)
mSpecialActionsButton->setEnabled(false);
}
Preferences* preferences = Preferences::instance();
mFontColourButton->setDefaultFont();
mFontColourButton->setBgColour(preferences->defaultBgColour());
......@@ -603,6 +624,8 @@ void EditAlarmDlg::initialise(const KAEvent* event)
mConfirmAck->setChecked(preferences->defaultConfirmAck());
mReminder->setMinutes(0, false);
mReminder->enableOnceOnly(false);
if (mSpecialActionsButton)
mSpecialActionsButton->setActions(preferences->defaultPreAction(), preferences->defaultPostAction());
mRecurrenceEdit->setDefaults(defaultTime); // must be called after mTimeWidget is set up, to ensure correct date-only enabling
slotRecurFrequencyChange(); // update the Recurrence text
mSoundPicker->set(preferences->defaultBeep(), preferences->defaultSoundFile(),
......@@ -655,6 +678,8 @@ void EditAlarmDlg::setReadOnly()
mSoundPicker->setReadOnly(mReadOnly);
mConfirmAck->setReadOnly(mReadOnly);
mReminder->setReadOnly(mReadOnly);
if (mSpecialActionsButton)
mSpecialActionsButton->setReadOnly(mReadOnly);
if (mReadOnly)
{
mFileBrowseButton->hide();
......@@ -786,6 +811,11 @@ void EditAlarmDlg::saveState(const KAEvent* event)
mSavedBgColour = mBgColourChoose->color();
mSavedReminder = mReminder->getMinutes();
mSavedOnceOnly = mReminder->isOnceOnly();
if (mSpecialActionsButton)
{
mSavedPreAction = mSpecialActionsButton->preAction();
mSavedPostAction = mSpecialActionsButton->postAction();
}
checkText(mSavedTextFileCommandMessage, false);
mSavedEmailTo = mEmailToEdit->text();
mSavedEmailSubject = mEmailSubjectEdit->text();
......@@ -832,6 +862,12 @@ bool EditAlarmDlg::stateChanged() const
|| mSavedReminder != mReminder->getMinutes()
|| mSavedOnceOnly != mReminder->isOnceOnly())
return true;
if (mSpecialActionsButton)
{
if (mSavedPreAction != mSpecialActionsButton->preAction()
|| mSavedPostAction != mSpecialActionsButton->postAction())
return true;
}
if (!mSavedBeep)
{
if (mSavedSoundFile != mSoundPicker->file())
......@@ -896,6 +932,9 @@ void EditAlarmDlg::getEvent(KAEvent& event)
case KAEvent::FILE:
event.setAudioFile(mSoundPicker->file(), mSoundPicker->volume());
event.setReminder(mReminder->getMinutes(), mReminder->isOnceOnly());
if (mSpecialActionsButton)
event.setActions(mSpecialActionsButton->preAction(),
mSpecialActionsButton->postAction());
break;
case KAEvent::EMAIL:
event.setEmail(mEmailAddresses, mEmailSubjectEdit->text(), mEmailAttachments);
......@@ -990,7 +1029,7 @@ void EditAlarmDlg::resizeEvent(QResizeEvent* re)
/******************************************************************************
* Called when the OK button is clicked.
* Set up the new alarm.
* Validate the input data.
*/
void EditAlarmDlg::slotOk()
{
......@@ -1106,15 +1145,17 @@ void EditAlarmDlg::slotTry()
event.set(QDateTime(), text, mBgColourChoose->color(), mFontColourButton->fgColour(),
mFontColourButton->font(), getAlarmType(), getAlarmFlags());
event.setAudioFile(mSoundPicker->file(), mSoundPicker->volume());
if (mSpecialActionsButton)
event.setActions(mSpecialActionsButton->preAction(), mSpecialActionsButton->postAction());
event.setEmail(mEmailAddresses, mEmailSubjectEdit->text(), mEmailAttachments);
void* proc = theApp()->execAlarm(event, event.firstAlarm(), false, false);
if (proc)
{
if (mCommandRadio->isOn())
{
theApp()->commandMessage((KProcess*)proc, this);
theApp()->commandMessage((ShellProcess*)proc, this);
KMessageBox::information(this, i18n("Command executed:\n%1").arg(text));
theApp()->commandMessage((KProcess*)proc, 0);
theApp()->commandMessage((ShellProcess*)proc, 0);
}
else if (mEmailRadio->isOn())
{
......
......@@ -57,6 +57,7 @@ class AlarmTimeWidget;
class RecurrenceEdit;
class SoundPicker;
class Reminder;
class SpecialActionsButton;
class LineEdit;
class TextEdit;
......@@ -154,6 +155,7 @@ class EditAlarmDlg : public KDialogBase
CheckBox* mConfirmAck;
FontColourButton* mFontColourButton;
ColourCombo* mBgColourChoose;
SpecialActionsButton* mSpecialActionsButton;
Reminder* mReminder;
bool mReminderDeferral;
bool mReminderArchived;
......@@ -213,6 +215,8 @@ class EditAlarmDlg : public KDialogBase
QFont mSavedFont; // mFontColourButton font
QColor mSavedBgColour; // mBgColourChoose selection
QColor mSavedFgColour; // mFontColourButton foreground colour
QString mSavedPreAction; // mSpecialActionsButton pre-alarm action
QString mSavedPostAction; // mSpecialActionsButton post-alarm action
int mSavedReminder; // mReminder value
bool mSavedOnceOnly; // mReminder once-only status
QString mSavedTextFileCommandMessage; // mTextMessageEdit/mFileMessageEdit/mCommandMessageEdit/mEmailMessageEdit value
......
<
......@@ -59,17 +59,18 @@
#include "alarmcalendar.h"
#include "alarmlistview.h"
#include "mainwindow.h"
#include "editdlg.h"
#include "messagewin.h"