Commit cd3f181f authored by David Jarvie's avatar David Jarvie

Improve audio alarms: allow sound repetition, add D-Bus and command line options

svn path=/trunk/KDE/kdepim/; revision=1041972
parent ec30a78d
......@@ -79,6 +79,7 @@ static const QString DATE_DEFERRAL_TYPE = QLatin1String("DATE_DEFERRAL")
static const QString DISPLAYING_TYPE = QLatin1String("DISPLAYING"); // used only in displaying calendar
static const QString PRE_ACTION_TYPE = QLatin1String("PRE");
static const QString POST_ACTION_TYPE = QLatin1String("POST");
static const QString SOUND_REPEAT_TYPE = QLatin1String("SOUNDREPEAT");
static const QByteArray NEXT_REPEAT_PROPERTY("NEXTREPEAT"); // X-KDE-KALARM-NEXTREPEAT property
// - Display alarm properties
static const QByteArray FONT_COLOUR_PROPERTY("FONTCOLOR"); // X-KDE-KALARM-FONTCOLOR property
......@@ -119,6 +120,7 @@ struct AlarmData
bool isEmailText;
bool commandScript;
bool cancelOnPreActErr;
bool repeatSound;
};
typedef QMap<KAAlarm::SubType, AlarmData> AlarmMap;
......@@ -643,7 +645,8 @@ void KAEventData::set(const Event* event)
mEmailAttachments = data.alarm->mailAttachments();
break;
case T_AUDIO:
// Already handled above
// Already mostly handled above
mRepeatSound = data.repeatSound;
break;
default:
break;
......@@ -890,6 +893,7 @@ void KAEventData::readAlarm(const Alarm* alarm, AlarmData& data, bool audioMain,
bool deferral = false;
bool dateDeferral = false;
data.reminderOnceOnly = false;
data.repeatSound = false;
data.type = KAAlarm::MAIN__ALARM;
QString property = alarm->customProperty(KCalendar::APPNAME, TYPE_PROPERTY);
QStringList types = property.split(QLatin1Char(','), QString::SkipEmptyParts);
......@@ -914,6 +918,8 @@ void KAEventData::readAlarm(const Alarm* alarm, AlarmData& data, bool audioMain,
data.type = KAAlarm::PRE_ACTION__ALARM;
else if (type == POST_ACTION_TYPE && data.action == T_COMMAND)
data.type = KAAlarm::POST_ACTION__ALARM;
else if (type == SOUND_REPEAT_TYPE && data.action == T_AUDIO)
data.repeatSound = true;
}
if (reminder)
......@@ -1521,6 +1527,8 @@ Alarm* KAEventData::initKCalAlarm(Event* event, int startOffsetSecs, const QStri
break;
case T_AUDIO:
setAudioAlarm(alarm);
if (mRepeatSound)
alltypes += SOUND_REPEAT_TYPE;
break;
}
if (display)
......
......@@ -142,16 +142,33 @@ CommandOptions::CommandOptions()
mEditAction = KAEventData::EMAIL;
mEditActionSet = true;
}
if (mError.isEmpty() && mCommand == NONE && mArgs->count())
if (checkCommand("edit-new-audio", EDIT_NEW, EditAlarmDlg::AUDIO))
{
kDebug() << "Message";
mCommand = NEW;
mCommandName = "message";
mEditType = EditAlarmDlg::DISPLAY;
mEditAction = KAEventData::MESSAGE;
mEditType = EditAlarmDlg::AUDIO;
mEditAction = KAEventData::AUDIO;
mEditActionSet = true;
if (mArgs->count())
mText = mArgs->arg(0);
}
if (mError.isEmpty() && mCommand == NONE)
{
if (!mArgs->count())
{
if (checkCommand("play", NEW) || checkCommand("play-repeat", NEW))
{
mEditType = EditAlarmDlg::AUDIO;
mEditAction = KAEventData::AUDIO;
mEditActionSet = true;
}
}
else
{
kDebug() << "Message";
mCommand = NEW;
mCommandName = "message";
mEditType = EditAlarmDlg::DISPLAY;
mEditAction = KAEventData::MESSAGE;
mEditActionSet = true;
mText = mArgs->arg(0);
}
}
if (mEditAction == KAEventData::EMAIL)
{
......@@ -178,9 +195,9 @@ CommandOptions::CommandOptions()
// correct main command options.
checkEditType(EditAlarmDlg::DISPLAY, "color");
checkEditType(EditAlarmDlg::DISPLAY, "colorfg");
checkEditType(EditAlarmDlg::DISPLAY, "play");
checkEditType(EditAlarmDlg::DISPLAY, "play-repeat");
checkEditType(EditAlarmDlg::DISPLAY, "volume");
checkEditType(EditAlarmDlg::DISPLAY, EditAlarmDlg::AUDIO, "play");
checkEditType(EditAlarmDlg::DISPLAY, EditAlarmDlg::AUDIO, "play-repeat");
checkEditType(EditAlarmDlg::DISPLAY, EditAlarmDlg::AUDIO, "volume");
checkEditType(EditAlarmDlg::DISPLAY, "speak");
checkEditType(EditAlarmDlg::DISPLAY, "beep");
checkEditType(EditAlarmDlg::DISPLAY, "reminder");
......@@ -512,10 +529,10 @@ void CommandOptions::setErrorIncompatible(const QByteArray& opt1, const QByteArr
setError(i18nc("@info:shell", "<icode>%1</icode> incompatible with <icode>%2</icode>", QString::fromLatin1(o1), QString::fromLatin1(o2)));
}
void CommandOptions::checkEditType(EditAlarmDlg::Type type, const QByteArray& optName)
void CommandOptions::checkEditType(EditAlarmDlg::Type type1, EditAlarmDlg::Type type2, const QByteArray& optName)
{
if (mArgs->isSet(optName) && mCommand != NONE
&& ((mCommand != NEW && mCommand != EDIT_NEW) || mEditType != type))
&& ((mCommand != NEW && mCommand != EDIT_NEW) || (mEditType != type1 && (type2 == EditAlarmDlg::NO_TYPE || mEditType != type2))))
setErrorIncompatible(optName, mCommandName);
}
......
......@@ -78,7 +78,9 @@ class CommandOptions
void setErrorRequires(const char* opt, const char* opt2, const char* opt3 = 0);
void setErrorParameter(const char* opt);
void setErrorIncompatible(const QByteArray& opt1, const QByteArray& opt2);
void checkEditType(EditAlarmDlg::Type, const QByteArray& opt);
void checkEditType(EditAlarmDlg::Type type, const QByteArray& opt)
{ checkEditType(type, EditAlarmDlg::NO_TYPE, opt); }
void checkEditType(EditAlarmDlg::Type, EditAlarmDlg::Type, const QByteArray& opt);
KCmdLineArgs* mArgs;
QString mError; // error message
......
......@@ -197,6 +197,39 @@ bool DBusHandler::scheduleEmail(const QString& fromID, const QString& addresses,
return scheduleEmail(fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur);
}
bool DBusHandler::scheduleAudio(const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
unsigned flags, const QString& recurrence, int subRepeatInterval, int subRepeatCount)
{
KDateTime start;
KARecurrence recur;
KCal::Duration subRepeatDuration;
if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
return false;
return scheduleAudio(audioUrl, volumePercent, start, lateCancel, flags, recur, subRepeatDuration, subRepeatCount);
}
bool DBusHandler::scheduleAudio(const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
unsigned flags, int recurType, int recurInterval, int recurCount)
{
KDateTime start = convertDateTime(startDateTime);
if (!start.isValid())
return false;
KARecurrence recur;
if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
return false;
return scheduleAudio(audioUrl, volumePercent, start, lateCancel, flags, recur);
}
bool DBusHandler::scheduleAudio(const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
unsigned flags, int recurType, int recurInterval, const QString& endDateTime)
{
KDateTime start;
KARecurrence recur;
if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
return false;
return scheduleAudio(audioUrl, volumePercent, start, lateCancel, flags, recur);
}
bool DBusHandler::edit(const QString& eventID)
{
return KAlarm::editAlarm(eventID);
......@@ -210,6 +243,7 @@ bool DBusHandler::editNew(int type)
case DISPLAY: dlgtype = EditAlarmDlg::DISPLAY; break;
case COMMAND: dlgtype = EditAlarmDlg::COMMAND; break;
case EMAIL: dlgtype = EditAlarmDlg::EMAIL; break;
case AUDIO: dlgtype = EditAlarmDlg::AUDIO; break;
default:
kError() << "D-Bus call: invalid alarm type:" << type;
return false;
......@@ -334,6 +368,19 @@ bool DBusHandler::scheduleEmail(const QString& fromID, const QString& addresses,
QString(), -1, 0, recurrence, subRepeatDuration, subRepeatCount, senderId, addrs, subject, atts);
}
/******************************************************************************
* Schedule a audio alarm, after converting the parameters from strings.
*/
bool DBusHandler::scheduleAudio(const QString& audioUrl, int volumePercent,
const KDateTime& start, int lateCancel, unsigned flags,
const KARecurrence& recurrence, const KCal::Duration& subRepeatDuration, int subRepeatCount)
{
unsigned kaEventFlags = convertStartFlags(start, flags);
float volume = (volumePercent >= 0) ? volumePercent / 100.0f : -1;
return theApp()->scheduleEvent(KAEventData::AUDIO, QString(), start, lateCancel, kaEventFlags, Qt::black, Qt::black, QFont(),
audioUrl, volume, 0, recurrence, subRepeatDuration, subRepeatCount);
}
/******************************************************************************
* Convert the start date/time string to a KDateTime. The date/time string is in
......
/*
* dbushandler.h - handler for D-Bus calls by other applications
* Program: kalarm
* Copyright © 2001,2002,2004-2007 by David Jarvie <djarvie@kde.org>
* Copyright © 2001,2002,2004-2007,2009 by David Jarvie <djarvie@kde.org>
*
* 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
......@@ -73,6 +73,12 @@ class DBusHandler : public QObject, public KAlarmIface
Q_SCRIPTABLE bool scheduleEmail(const QString& fromID, const QString& addresses, const QString& subject, const QString& message,
const QString& attachments, const QString& startDateTime, int lateCancel, unsigned flags,
int recurType, int recurInterval, const QString& endDateTime);
Q_SCRIPTABLE bool scheduleAudio(const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
unsigned flags, const QString& recurrence, int subRepeatInterval, int subRepeatCount);
Q_SCRIPTABLE bool scheduleAudio(const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
unsigned flags, int recurType, int recurInterval, int recurCount);
Q_SCRIPTABLE bool scheduleAudio(const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
unsigned flags, int recurType, int recurInterval, const QString& endDateTime);
Q_SCRIPTABLE bool edit(const QString& eventID);
Q_SCRIPTABLE bool editNew(int type);
Q_SCRIPTABLE bool editNew(const QString& templateName);
......@@ -90,6 +96,8 @@ class DBusHandler : public QObject, public KAlarmIface
static bool scheduleEmail(const QString& fromID, const QString& addresses, const QString& subject, const QString& message,
const QString& attachments, const KDateTime& start, int lateCancel, unsigned flags,
const KARecurrence&, const KCal::Duration& subRepeatDuration = KCal::Duration(0), int subRepeatCount = 0);
static bool scheduleAudio(const QString& audioUrl, int volumePercent, const KDateTime& start, int lateCancel, unsigned flags,
const KARecurrence&, const KCal::Duration& subRepeatDuration = KCal::Duration(0), int subRepeatCount = 0);
static KDateTime convertDateTime(const QString& dateTime, const KDateTime& = KDateTime());
static unsigned convertStartFlags(const KDateTime& start, unsigned flags);
static QColor convertBgColour(const QString& bgColor);
......
......@@ -1464,7 +1464,7 @@ QString EditAudioAlarmDlg::type_caption(bool newAlarm) const
void EditAudioAlarmDlg::type_init(QWidget* parent, QVBoxLayout* frameLayout)
{
// File name edit box
mSoundConfig = new SoundWidget(false, false, parent);
mSoundConfig = new SoundWidget(false, true, parent);
connect(mSoundConfig, SIGNAL(changed()), SLOT(contentsChanged()));
frameLayout->addWidget(mSoundConfig);
......@@ -1482,7 +1482,8 @@ void EditAudioAlarmDlg::type_initValues(const KAEvent* event)
{
if (event)
{
mSoundConfig->set(event->audioFile(), event->soundVolume(), event->fadeVolume(), event->fadeSeconds(), false);
mSoundConfig->set(event->audioFile(), event->soundVolume(), event->fadeVolume(), event->fadeSeconds(),
(event->flags() & KAEvent::REPEAT_SOUND));
}
else
{
......@@ -1522,8 +1523,8 @@ void EditAudioAlarmDlg::setReadOnly(bool readOnly)
void EditAudioAlarmDlg::saveState(const KAEvent* event)
{
EditAlarmDlg::saveState(event);
mSavedFile = mSoundConfig->fileName();
mSoundConfig->getVolume(mSavedVolume, mSavedFadeVolume, mSavedFadeSeconds);
mSavedFile = mSoundConfig->fileName();
mSavedRepeat = mSoundConfig->getVolume(mSavedVolume, mSavedFadeVolume, mSavedFadeSeconds);
}
/******************************************************************************
......@@ -1540,8 +1541,8 @@ bool EditAudioAlarmDlg::type_stateChanged() const
{
float volume, fadeVolume;
int fadeSecs;
mSoundConfig->getVolume(volume, fadeVolume, fadeSecs);
if (mSavedVolume != volume
if (mSavedRepeat != mSoundConfig->getVolume(volume, fadeVolume, fadeSecs)
|| mSavedVolume != volume
|| mSavedFadeVolume != fadeVolume
|| mSavedFadeSeconds != fadeSecs)
return true;
......@@ -1569,7 +1570,8 @@ void EditAudioAlarmDlg::type_setEvent(KAEvent& event, const KDateTime& dt, const
*/
int EditAudioAlarmDlg::getAlarmFlags() const
{
return EditAlarmDlg::getAlarmFlags();
return EditAlarmDlg::getAlarmFlags()
| (mSoundConfig->getRepeat() ? KAEvent::REPEAT_SOUND : 0);
}
/******************************************************************************
......
......@@ -296,6 +296,7 @@ class EditAudioAlarmDlg : public EditAlarmDlg
float mSavedVolume; // volume
float mSavedFadeVolume; // fade volume
int mSavedFadeSeconds; // fade time
bool mSavedRepeat; // repeat sound file
};
#endif // EDITDLGTYPES_H
/*
* kalarmiface.h - D-Bus interface to KAlarm
* Program: kalarm
* Copyright © 2004-2008 by David Jarvie <djarvie@kde.org>
* Copyright © 2004-2009 by David Jarvie <djarvie@kde.org>
*
* 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
......@@ -88,7 +88,8 @@ class KAlarmIface
{
DISPLAY = 1, // display alarm
COMMAND = 2, // command alarm
EMAIL = 3 // email alarm
EMAIL = 3, // email alarm
AUDIO = 4 // audio alarm
};
};
......
......@@ -69,6 +69,7 @@ int main(int argc, char *argv[])
options.add("edit-new-display", ki18n("Display the alarm edit dialog to edit a new display alarm"));
options.add("edit-new-command", ki18n("Display the alarm edit dialog to edit a new command alarm"));
options.add("edit-new-email", ki18n("Display the alarm edit dialog to edit a new email alarm"));
options.add("edit-new-audio", ki18n("Display the alarm edit dialog to edit a new audio alarm"));
options.add("edit-new-preset <templateName>", ki18n("Display the alarm edit dialog, preset with a template"));
options.add("f");
options.add("file <url>", ki18n("File to display"));
......
......@@ -165,6 +165,39 @@
<arg name="recurInterval" type="i" direction="in"/>
<arg name="endDateTime" type="s" direction="in"/>
</method>
<method name="scheduleAudio">
<arg type="b" direction="out"/>
<arg name="audioFile" type="s" direction="in"/>
<arg name="volumePercent" type="i" direction="in"/>
<arg name="startDateTime" type="s" direction="in"/>
<arg name="lateCancel" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="recurrence" type="s" direction="in"/>
<arg name="subRepeatInterval" type="i" direction="in"/>
<arg name="subRepeatCount" type="i" direction="in"/>
</method>
<method name="scheduleAudio">
<arg type="b" direction="out"/>
<arg name="audioFile" type="s" direction="in"/>
<arg name="volumePercent" type="i" direction="in"/>
<arg name="startDateTime" type="s" direction="in"/>
<arg name="lateCancel" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="recurType" type="i" direction="in"/>
<arg name="recurInterval" type="i" direction="in"/>
<arg name="recurCount" type="i" direction="in"/>
</method>
<method name="scheduleAudio">
<arg type="b" direction="out"/>
<arg name="audioFile" type="s" direction="in"/>
<arg name="volumePercent" type="i" direction="in"/>
<arg name="startDateTime" type="s" direction="in"/>
<arg name="lateCancel" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="recurType" type="i" direction="in"/>
<arg name="recurInterval" type="i" direction="in"/>
<arg name="endDateTime" type="s" direction="in"/>
</method>
<method name="edit">
<arg type="b" direction="out"/>
<arg name="eventID" type="s" direction="in"/>
......
......@@ -339,6 +339,15 @@ bool SoundWidget::getVolume(float& volume, float& fadeVolume, int& fadeSeconds)
return mRepeatCheckbox && mRepeatCheckbox->isChecked();
}
/******************************************************************************
* Return the entered repetition setting.
* Reply = whether to repeat or not.
*/
bool SoundWidget::getRepeat() const
{
return mRepeatCheckbox && mRepeatCheckbox->isChecked();
}
/******************************************************************************
* Called when the dialog's size has changed.
* Records the new size in the config file.
......
......@@ -50,6 +50,7 @@ class SoundWidget : public QWidget
QString fileName() const;
KUrl file(bool showErrorMessage = true) const;
bool getVolume(float& volume, float& fadeVolume, int& fadeSeconds) const;
bool getRepeat() const;
QString defaultDir() const { return mDefaultDir; }
bool validate(bool showErrorMessage) const;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment