File indexing completed on 2024-05-12 05:14:41

0001 /*
0002  *  dbushandler.cpp  -  handler for D-Bus calls by other applications
0003  *  Program:  kalarm
0004  *  SPDX-FileCopyrightText: 2002-2023 David Jarvie <djarvie@kde.org>
0005  *
0006  *  SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #include "dbushandler.h"
0010 
0011 #include "functions.h"
0012 #include "kalarmapp.h"
0013 #include "kamail.h"
0014 #include "resources/resources.h"
0015 #include <kalarmadaptor.h>
0016 #include "kalarmcalendar/identities.h"
0017 #include "kalarmcalendar/karecurrence.h"
0018 #include "kalarm_debug.h"
0019 
0020 using namespace KCalendarCore;
0021 
0022 #include <stdlib.h>
0023 
0024 //clazy:excludeall=non-pod-global-static
0025 
0026 namespace
0027 {
0028 const QString REQUEST_DBUS_OBJECT(QStringLiteral("/kalarm"));   // D-Bus object path of KAlarm's request interface
0029 }
0030 
0031 
0032 /*=============================================================================
0033 = DBusHandler
0034 = This class's function is to handle D-Bus requests by other applications.
0035 =============================================================================*/
0036 DBusHandler::DBusHandler()
0037 {
0038     qCDebug(KALARM_LOG) << "DBusHandler:";
0039     new KalarmAdaptor(this);
0040     QDBusConnection::sessionBus().registerObject(REQUEST_DBUS_OBJECT, this);
0041 }
0042 
0043 
0044 bool DBusHandler::cancelEvent(const QString& eventId)
0045 {
0046     if (!Resources::allPopulated())
0047         return false;    // can't access events before calendars are loaded
0048     return theApp()->dbusDeleteEvent(EventId(eventId));
0049 }
0050 
0051 bool DBusHandler::triggerEvent(const QString& eventId)
0052 {
0053     if (!Resources::allPopulated())
0054         return false;    // can't access events before calendars are loaded
0055     return theApp()->dbusTriggerEvent(EventId(eventId));
0056 }
0057 
0058 QString DBusHandler::list()
0059 {
0060     return theApp()->dbusList();
0061 }
0062 
0063 bool DBusHandler::scheduleMessage(const QString& name, const QString& message, const QString& startDateTime, int lateCancel, unsigned flags,
0064                                   const QString& bgColor, const QString& fgColor, const QString& font,
0065                                   const QString& audioUrl, int reminderMins, const QString& recurrence,
0066                                   int subRepeatInterval, int subRepeatCount)
0067 {
0068     KADateTime start;
0069     KARecurrence recur;
0070     Duration subRepeatDuration;
0071     if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
0072         return false;
0073     return scheduleMessage(name, message, start, lateCancel, flags, bgColor, fgColor, font,
0074                            QUrl::fromUserInput(audioUrl, QString(), QUrl::AssumeLocalFile),
0075                            reminderMins, recur, subRepeatDuration, subRepeatCount);
0076 }
0077 
0078 bool DBusHandler::scheduleMessage(const QString& name, const QString& message, const QString& startDateTime, int lateCancel, unsigned flags,
0079                                   const QString& bgColor, const QString& fgColor, const QString& font,
0080                                   const QString& audioUrl, int reminderMins,
0081                                   int recurType, int recurInterval, int recurCount)
0082 {
0083     KADateTime start;
0084     KARecurrence recur;
0085     if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
0086         return false;
0087     return scheduleMessage(name, message, start, lateCancel, flags, bgColor, fgColor, font,
0088                            QUrl::fromUserInput(audioUrl, QString(), QUrl::AssumeLocalFile),
0089                            reminderMins, recur);
0090 }
0091 
0092 bool DBusHandler::scheduleMessage(const QString& name, const QString& message, const QString& startDateTime, int lateCancel, unsigned flags,
0093                                   const QString& bgColor, const QString& fgColor, const QString& font,
0094                                   const QString& audioUrl, int reminderMins,
0095                                   int recurType, int recurInterval, const QString& endDateTime)
0096 {
0097     KADateTime start;
0098     KARecurrence recur;
0099     if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
0100         return false;
0101     return scheduleMessage(name, message, start, lateCancel, flags, bgColor, fgColor, font,
0102                            QUrl::fromUserInput(audioUrl, QString(), QUrl::AssumeLocalFile),
0103                            reminderMins, recur);
0104 }
0105 
0106 bool DBusHandler::scheduleMessage(const QString& message, const QString& startDateTime, int lateCancel, unsigned flags,
0107                                   const QString& bgColor, const QString& fgColor, const QString& font,
0108                                   const QString& audioUrl, int reminderMins, const QString& recurrence,
0109                                   int subRepeatInterval, int subRepeatCount)
0110 {
0111     return scheduleMessage(QString(), message, startDateTime, lateCancel, flags, bgColor, fgColor, font,
0112                            audioUrl, reminderMins, recurrence, subRepeatInterval, subRepeatCount);
0113 }
0114 
0115 bool DBusHandler::scheduleMessage(const QString& message, const QString& startDateTime, int lateCancel, unsigned flags,
0116                                   const QString& bgColor, const QString& fgColor, const QString& font,
0117                                   const QString& audioUrl, int reminderMins,
0118                                   int recurType, int recurInterval, int recurCount)
0119 {
0120     return scheduleMessage(QString(), message, startDateTime, lateCancel, flags, bgColor, fgColor, font,
0121                            audioUrl, reminderMins, recurType, recurInterval, recurCount);
0122 }
0123 
0124 bool DBusHandler::scheduleMessage(const QString& message, const QString& startDateTime, int lateCancel, unsigned flags,
0125                                   const QString& bgColor, const QString& fgColor, const QString& font,
0126                                   const QString& audioUrl, int reminderMins,
0127                                   int recurType, int recurInterval, const QString& endDateTime)
0128 {
0129     return scheduleMessage(QString(), message, startDateTime, lateCancel, flags, bgColor, fgColor, font,
0130                            audioUrl, reminderMins, recurType, recurInterval, endDateTime);
0131 }
0132 
0133 bool DBusHandler::scheduleFile(const QString& name, const QString& url, const QString& startDateTime, int lateCancel, unsigned flags, const QString& bgColor,
0134                                const QString& audioUrl, int reminderMins, const QString& recurrence,
0135                                int subRepeatInterval, int subRepeatCount)
0136 {
0137     KADateTime start;
0138     KARecurrence recur;
0139     Duration subRepeatDuration;
0140     if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
0141         return false;
0142     return scheduleFile(name, QUrl::fromUserInput(url, QString(), QUrl::AssumeLocalFile),
0143                         start, lateCancel, flags, bgColor,
0144                         QUrl::fromUserInput(audioUrl, QString(), QUrl::AssumeLocalFile),
0145                         reminderMins, recur, subRepeatDuration, subRepeatCount);
0146 }
0147 
0148 bool DBusHandler::scheduleFile(const QString& name, const QString& url, const QString& startDateTime, int lateCancel, unsigned flags, const QString& bgColor,
0149                                const QString& audioUrl, int reminderMins, int recurType, int recurInterval, int recurCount)
0150 {
0151     KADateTime start;
0152     KARecurrence recur;
0153     if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
0154         return false;
0155     return scheduleFile(name, QUrl::fromUserInput(url, QString(), QUrl::AssumeLocalFile),
0156                         start, lateCancel, flags, bgColor,
0157                         QUrl::fromUserInput(audioUrl, QString(), QUrl::AssumeLocalFile),
0158                         reminderMins, recur);
0159 }
0160 
0161 bool DBusHandler::scheduleFile(const QString& name, const QString& url, const QString& startDateTime, int lateCancel, unsigned flags, const QString& bgColor,
0162                                const QString& audioUrl, int reminderMins, int recurType, int recurInterval, const QString& endDateTime)
0163 {
0164     KADateTime start;
0165     KARecurrence recur;
0166     if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
0167         return false;
0168     return scheduleFile(name, QUrl::fromUserInput(url, QString(), QUrl::AssumeLocalFile),
0169                         start, lateCancel, flags, bgColor,
0170                         QUrl::fromUserInput(audioUrl, QString(), QUrl::AssumeLocalFile),
0171                         reminderMins, recur);
0172 }
0173 
0174 bool DBusHandler::scheduleFile(const QString& url, const QString& startDateTime, int lateCancel, unsigned flags, const QString& bgColor,
0175                                const QString& audioUrl, int reminderMins, const QString& recurrence,
0176                                int subRepeatInterval, int subRepeatCount)
0177 {
0178     return scheduleFile(QString(), url, startDateTime, lateCancel, flags, bgColor,
0179                         audioUrl, reminderMins, recurrence, subRepeatInterval, subRepeatCount);
0180 }
0181 
0182 bool DBusHandler::scheduleFile(const QString& url, const QString& startDateTime, int lateCancel, unsigned flags, const QString& bgColor,
0183                                const QString& audioUrl, int reminderMins, int recurType, int recurInterval, int recurCount)
0184 {
0185     return scheduleFile(QString(), url, startDateTime, lateCancel, flags, bgColor,
0186                         audioUrl, reminderMins, recurType, recurInterval, recurCount);
0187 }
0188 
0189 bool DBusHandler::scheduleFile(const QString& url, const QString& startDateTime, int lateCancel, unsigned flags, const QString& bgColor,
0190                                const QString& audioUrl, int reminderMins, int recurType, int recurInterval, const QString& endDateTime)
0191 {
0192     return scheduleFile(QString(), url, startDateTime, lateCancel, flags, bgColor,
0193                         audioUrl, reminderMins, recurType, recurInterval, endDateTime);
0194 }
0195 
0196 bool DBusHandler::scheduleCommand(const QString& name, const QString& commandLine, const QString& startDateTime, int lateCancel, unsigned flags,
0197                                   const QString& recurrence, int subRepeatInterval, int subRepeatCount)
0198 {
0199     KADateTime start;
0200     KARecurrence recur;
0201     Duration subRepeatDuration;
0202     if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
0203         return false;
0204     return scheduleCommand(name, commandLine, start, lateCancel, flags, recur, subRepeatDuration, subRepeatCount);
0205 }
0206 
0207 bool DBusHandler::scheduleCommand(const QString& name, const QString& commandLine, const QString& startDateTime, int lateCancel, unsigned flags,
0208                                   int recurType, int recurInterval, int recurCount)
0209 {
0210     KADateTime start = convertDateTime(startDateTime);
0211     if (!start.isValid())
0212         return false;
0213     KARecurrence recur;
0214     if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
0215         return false;
0216     return scheduleCommand(name, commandLine, start, lateCancel, flags, recur);
0217 }
0218 
0219 bool DBusHandler::scheduleCommand(const QString& name, const QString& commandLine, const QString& startDateTime, int lateCancel, unsigned flags,
0220                                   int recurType, int recurInterval, const QString& endDateTime)
0221 {
0222     KADateTime start;
0223     KARecurrence recur;
0224     if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
0225         return false;
0226     return scheduleCommand(name, commandLine, start, lateCancel, flags, recur);
0227 }
0228 
0229 bool DBusHandler::scheduleCommand(const QString& commandLine, const QString& startDateTime, int lateCancel, unsigned flags,
0230                                   const QString& recurrence, int subRepeatInterval, int subRepeatCount)
0231 {
0232     return scheduleCommand(QString(), commandLine, startDateTime, lateCancel, flags, recurrence, subRepeatInterval, subRepeatCount);
0233 }
0234 
0235 bool DBusHandler::scheduleCommand(const QString& commandLine, const QString& startDateTime, int lateCancel, unsigned flags,
0236                                   int recurType, int recurInterval, int recurCount)
0237 {
0238     return scheduleCommand(QString(), commandLine, startDateTime, lateCancel, flags, recurType, recurInterval, recurCount);
0239 }
0240 
0241 bool DBusHandler::scheduleCommand(const QString& commandLine, const QString& startDateTime, int lateCancel, unsigned flags,
0242                                   int recurType, int recurInterval, const QString& endDateTime)
0243 {
0244     return scheduleCommand(QString(), commandLine, startDateTime, lateCancel, flags, recurType, recurInterval, endDateTime);
0245 }
0246 
0247 bool DBusHandler::scheduleEmail(const QString& name, const QString& fromID, const QString& addresses, const QString& subject, const QString& message,
0248                                 const QString& attachments, const QString& startDateTime, int lateCancel, unsigned flags,
0249                                 const QString& recurrence, int subRepeatInterval, int subRepeatCount)
0250 {
0251     KADateTime start;
0252     KARecurrence recur;
0253     Duration subRepeatDuration;
0254     if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
0255         return false;
0256     return scheduleEmail(name, fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur, subRepeatDuration, subRepeatCount);
0257 }
0258 
0259 bool DBusHandler::scheduleEmail(const QString& name, const QString& fromID, const QString& addresses, const QString& subject, const QString& message,
0260                                 const QString& attachments, const QString& startDateTime, int lateCancel, unsigned flags,
0261                                 int recurType, int recurInterval, int recurCount)
0262 {
0263     KADateTime start;
0264     KARecurrence recur;
0265     if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
0266         return false;
0267     return scheduleEmail(name, fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur);
0268 }
0269 
0270 bool DBusHandler::scheduleEmail(const QString& name, const QString& fromID, const QString& addresses, const QString& subject, const QString& message,
0271                                 const QString& attachments, const QString& startDateTime, int lateCancel, unsigned flags,
0272                                 int recurType, int recurInterval, const QString& endDateTime)
0273 {
0274     KADateTime start;
0275     KARecurrence recur;
0276     if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
0277         return false;
0278     return scheduleEmail(name, fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur);
0279 }
0280 
0281 bool DBusHandler::scheduleEmail(const QString& fromID, const QString& addresses, const QString& subject, const QString& message,
0282                                 const QString& attachments, const QString& startDateTime, int lateCancel, unsigned flags,
0283                                 const QString& recurrence, int subRepeatInterval, int subRepeatCount)
0284 {
0285     return scheduleEmail(QString(), fromID, addresses, subject, message, attachments, startDateTime, lateCancel, flags, recurrence, subRepeatInterval, subRepeatCount);
0286 }
0287 
0288 bool DBusHandler::scheduleEmail(const QString& fromID, const QString& addresses, const QString& subject, const QString& message,
0289                                 const QString& attachments, const QString& startDateTime, int lateCancel, unsigned flags,
0290                                 int recurType, int recurInterval, int recurCount)
0291 {
0292     return scheduleEmail(QString(), fromID, addresses, subject, message, attachments, startDateTime, lateCancel, flags, recurType, recurInterval, recurCount);
0293 }
0294 
0295 bool DBusHandler::scheduleEmail(const QString& fromID, const QString& addresses, const QString& subject, const QString& message,
0296                                 const QString& attachments, const QString& startDateTime, int lateCancel, unsigned flags,
0297                                 int recurType, int recurInterval, const QString& endDateTime)
0298 {
0299     return scheduleEmail(QString(), fromID, addresses, subject, message, attachments, startDateTime, lateCancel, flags, recurType, recurInterval, endDateTime);
0300 }
0301 
0302 bool DBusHandler::scheduleAudio(const QString& name, const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
0303                                 unsigned flags, const QString& recurrence, int subRepeatInterval, int subRepeatCount)
0304 {
0305     KADateTime start;
0306     KARecurrence recur;
0307     Duration subRepeatDuration;
0308     if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
0309         return false;
0310     return scheduleAudio(name, audioUrl, volumePercent, start, lateCancel, flags, recur, subRepeatDuration, subRepeatCount);
0311 }
0312 
0313 bool DBusHandler::scheduleAudio(const QString& name, const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
0314                                 unsigned flags, int recurType, int recurInterval, int recurCount)
0315 {
0316     KADateTime start = convertDateTime(startDateTime);
0317     if (!start.isValid())
0318         return false;
0319     KARecurrence recur;
0320     if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
0321         return false;
0322     return scheduleAudio(name, audioUrl, volumePercent, start, lateCancel, flags, recur);
0323 }
0324 
0325 bool DBusHandler::scheduleAudio(const QString& name, const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
0326                                 unsigned flags, int recurType, int recurInterval, const QString& endDateTime)
0327 {
0328     KADateTime start;
0329     KARecurrence recur;
0330     if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
0331         return false;
0332     return scheduleAudio(name, audioUrl, volumePercent, start, lateCancel, flags, recur);
0333 }
0334 
0335 bool DBusHandler::scheduleAudio(const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
0336                                 unsigned flags, const QString& recurrence, int subRepeatInterval, int subRepeatCount)
0337 {
0338     return scheduleAudio(QString(), audioUrl, volumePercent, startDateTime, lateCancel, flags, recurrence, subRepeatInterval, subRepeatCount);
0339 }
0340 
0341 bool DBusHandler::scheduleAudio(const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
0342                                 unsigned flags, int recurType, int recurInterval, int recurCount)
0343 {
0344     return scheduleAudio(QString(), audioUrl, volumePercent, startDateTime, lateCancel, flags, recurType, recurInterval, recurCount);
0345 }
0346 
0347 bool DBusHandler::scheduleAudio(const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
0348                                 unsigned flags, int recurType, int recurInterval, const QString& endDateTime)
0349 {
0350     return scheduleAudio(QString(), audioUrl, volumePercent, startDateTime, lateCancel, flags, recurType, recurInterval, endDateTime);
0351 }
0352 
0353 bool DBusHandler::edit(const QString& eventID)
0354 {
0355     if (!Resources::allPopulated())
0356         return false;    // can't access events before calendars are loaded
0357     return KAlarm::editAlarmById(EventId(eventID));
0358 }
0359 
0360 bool DBusHandler::editNew(int type)
0361 {
0362     EditAlarmDlg::Type dlgtype;
0363     switch (type)
0364     {
0365         case DISPLAY:  dlgtype = EditAlarmDlg::DISPLAY;  break;
0366         case COMMAND:  dlgtype = EditAlarmDlg::COMMAND;  break;
0367         case EMAIL:    dlgtype = EditAlarmDlg::EMAIL;  break;
0368         case AUDIO:    dlgtype = EditAlarmDlg::AUDIO;  break;
0369         default:
0370             qCCritical(KALARM_LOG) << "D-Bus call: invalid alarm type:" << type;
0371             return false;
0372     }
0373     KAlarm::editNewAlarm(dlgtype);
0374     return true;
0375 }
0376 
0377 bool DBusHandler::editNew(const QString& templateName)
0378 {
0379     return KAlarm::editNewAlarm(templateName);
0380 }
0381 
0382 
0383 /******************************************************************************
0384 * Schedule a message alarm, after converting the parameters from strings.
0385 */
0386 bool DBusHandler::scheduleMessage(const QString& name, const QString& message, const KADateTime& start, int lateCancel, unsigned flags,
0387                                   const QString& bgColor, const QString& fgColor, const QString& fontStr,
0388                                   const QUrl& audioFile, int reminderMins, const KARecurrence& recurrence,
0389                                   const KCalendarCore::Duration& subRepeatDuration, int subRepeatCount)
0390 {
0391     KAEvent::Flags kaEventFlags = convertStartFlags(start, flags);
0392     const KAEvent::SubAction action = (kaEventFlags & KAEvent::DISPLAY_COMMAND) ? KAEvent::SubAction::Command : KAEvent::SubAction::Message;
0393     const QColor bg = convertBgColour(bgColor);
0394     if (!bg.isValid())
0395         return false;
0396     QColor fg;
0397     if (fgColor.isEmpty())
0398         fg = Preferences::defaultFgColour();
0399     else
0400     {
0401         fg.setNamedColor(fgColor);
0402         if (!fg.isValid())
0403         {
0404             qCCritical(KALARM_LOG) << "D-Bus call: invalid foreground color:" << fgColor;
0405             return false;
0406         }
0407     }
0408     QFont font;
0409     if (fontStr.isEmpty())
0410         kaEventFlags |= KAEvent::DEFAULT_FONT;
0411     else
0412     {
0413         if (!font.fromString(fontStr))    // N.B. this doesn't do good validation
0414         {
0415             qCCritical(KALARM_LOG) << "D-Bus call: invalid font:" << fontStr;
0416             return false;
0417         }
0418     }
0419     return theApp()->scheduleEvent(action, name, message, start, lateCancel, kaEventFlags, bg, fg, font,
0420                                    audioFile.toString(), -1, reminderMins, recurrence, subRepeatDuration, subRepeatCount);
0421 }
0422 
0423 /******************************************************************************
0424 * Schedule a file alarm, after converting the parameters from strings.
0425 */
0426 bool DBusHandler::scheduleFile(const QString& name, const QUrl& file,
0427                                const KADateTime& start, int lateCancel, unsigned flags, const QString& bgColor,
0428                                const QUrl& audioFile, int reminderMins, const KARecurrence& recurrence,
0429                                const KCalendarCore::Duration& subRepeatDuration, int subRepeatCount)
0430 {
0431     const KAEvent::Flags kaEventFlags = convertStartFlags(start, flags);
0432     const QColor bg = convertBgColour(bgColor);
0433     if (!bg.isValid())
0434         return false;
0435     return theApp()->scheduleEvent(KAEvent::SubAction::File, name, file.toString(), start, lateCancel, kaEventFlags, bg, Qt::black, QFont(),
0436                                    audioFile.toString(), -1, reminderMins, recurrence, subRepeatDuration, subRepeatCount);
0437 }
0438 
0439 /******************************************************************************
0440 * Schedule a command alarm, after converting the parameters from strings.
0441 */
0442 bool DBusHandler::scheduleCommand(const QString& name, const QString& commandLine,
0443                                   const KADateTime& start, int lateCancel, unsigned flags,
0444                                   const KARecurrence& recurrence, const KCalendarCore::Duration& subRepeatDuration, int subRepeatCount)
0445 {
0446     const KAEvent::Flags kaEventFlags = convertStartFlags(start, flags);
0447     return theApp()->scheduleEvent(KAEvent::SubAction::Command, name, commandLine, start, lateCancel, kaEventFlags, Qt::black, Qt::black, QFont(),
0448                                    QString(), -1, 0, recurrence, subRepeatDuration, subRepeatCount);
0449 }
0450 
0451 /******************************************************************************
0452 * Schedule an email alarm, after validating the addresses and attachments.
0453 */
0454 bool DBusHandler::scheduleEmail(const QString& name, const QString& fromID, const QString& addresses, const QString& subject,
0455                                 const QString& message, const QString& attachments,
0456                                 const KADateTime& start, int lateCancel, unsigned flags,
0457                                 const KARecurrence& recurrence, const KCalendarCore::Duration& subRepeatDuration, int subRepeatCount)
0458 {
0459     const KAEvent::Flags kaEventFlags = convertStartFlags(start, flags);
0460     uint senderId = 0;
0461     if (!fromID.isEmpty())
0462     {
0463         senderId = Identities::identityUoid(fromID);
0464         if (!senderId)
0465         {
0466             qCCritical(KALARM_LOG) << "D-Bus call scheduleEmail(): unknown sender ID:" << fromID;
0467             return false;
0468         }
0469     }
0470     KCalendarCore::Person::List addrs;
0471     QString bad = KAMail::convertAddresses(addresses, addrs);
0472     if (!bad.isEmpty())
0473     {
0474         qCCritical(KALARM_LOG) << "D-Bus call scheduleEmail(): invalid email addresses:" << bad;
0475         return false;
0476     }
0477     if (addrs.isEmpty())
0478     {
0479         qCCritical(KALARM_LOG) << "D-Bus call scheduleEmail(): no email address";
0480         return false;
0481     }
0482     QStringList atts;
0483     bad = KAMail::convertAttachments(attachments, atts);
0484     if (!bad.isEmpty())
0485     {
0486         qCCritical(KALARM_LOG) << "D-Bus call scheduleEmail(): invalid email attachment:" << bad;
0487         return false;
0488     }
0489     return theApp()->scheduleEvent(KAEvent::SubAction::Email, name, message, start, lateCancel, kaEventFlags, Qt::black, Qt::black, QFont(),
0490                                    QString(), -1, 0, recurrence, subRepeatDuration, subRepeatCount, senderId, addrs, subject, atts);
0491 }
0492 
0493 /******************************************************************************
0494 * Schedule a audio alarm, after converting the parameters from strings.
0495 */
0496 bool DBusHandler::scheduleAudio(const QString& name, const QString& audioUrl, int volumePercent,
0497                                 const KADateTime& start, int lateCancel, unsigned flags,
0498                                 const KARecurrence& recurrence, const KCalendarCore::Duration& subRepeatDuration, int subRepeatCount)
0499 {
0500     const KAEvent::Flags kaEventFlags = convertStartFlags(start, flags);
0501     const float volume = (volumePercent >= 0) ? volumePercent / 100.0f : -1;
0502     return theApp()->scheduleEvent(KAEvent::SubAction::Audio, name, QString(), start, lateCancel, kaEventFlags, Qt::black, Qt::black, QFont(),
0503                                    audioUrl, volume, 0, recurrence, subRepeatDuration, subRepeatCount);
0504 }
0505 
0506 
0507 /******************************************************************************
0508 * Convert the start date/time string to a KADateTime. The date/time string is in
0509 * the format YYYY-MM-DD[THH:MM[:SS]][ TZ] or [T]HH:MM[:SS].
0510 * The time zone specifier (TZ) is a system time zone name, e.g. "Europe/London".
0511 * If no time zone is specified, it defaults to the local clock time (which is
0512 * not the same as the local time zone).
0513 */
0514 KADateTime DBusHandler::convertDateTime(const QString& dateTime, const KADateTime& defaultDt)
0515 {
0516     int i = dateTime.indexOf(QLatin1Char(' '));
0517     QString dtString = dateTime;
0518     QString zone;
0519     if (i >= 0)
0520     {
0521         dtString = dateTime.left(i);
0522         zone     = dateTime.mid(i);
0523     }
0524     QDate date;
0525     QTime time;
0526     bool haveTime = true;
0527     bool error = false;
0528     if (dtString.length() > 10)
0529     {
0530         // Both a date and a time are specified
0531         const QDateTime dt = QDateTime::fromString(dtString, Qt::ISODate);
0532         error = !dt.isValid();
0533         date = dt.date();
0534         time = dt.time();
0535     }
0536     else
0537     {
0538         // Check whether a time is specified
0539         QString t;
0540         if (dtString[0] == QLatin1Char('T'))
0541             t = dtString.mid(1);     // it's a time: remove the leading 'T'
0542         else if (!dtString[2].isDigit())
0543             t = dtString;            // it's a time with no leading 'T'
0544 
0545         if (t.isEmpty())
0546         {
0547             // It's a date only
0548             date = QDate::fromString(dtString, Qt::ISODate);
0549             error = !date.isValid();
0550             haveTime = false;
0551         }
0552         else
0553         {
0554             // It's a time only
0555             time = QTime::fromString(t, Qt::ISODate);
0556             error = !time.isValid();
0557         }
0558     }
0559     KADateTime result;
0560     if (!error)
0561         result = KAlarm::applyTimeZone(zone, date, time, haveTime, defaultDt);
0562     if (error  ||  !result.isValid())
0563     {
0564         if (!defaultDt.isValid())
0565             qCCritical(KALARM_LOG) << "D-Bus call: invalid start date/time: '" << dateTime << "'";
0566         else
0567             qCCritical(KALARM_LOG) << "D-Bus call: invalid recurrence end date/time: '" << dateTime << "'";
0568     }
0569     return result;
0570 }
0571 
0572 /******************************************************************************
0573 * Convert the flag bits to KAEvent flag bits.
0574 */
0575 KAEvent::Flags DBusHandler::convertStartFlags(const KADateTime& start, unsigned flags)
0576 {
0577     KAEvent::Flags kaEventFlags = {};
0578     if (flags & REPEAT_AT_LOGIN) kaEventFlags |= KAEvent::REPEAT_AT_LOGIN;
0579     if (flags & BEEP)            kaEventFlags |= KAEvent::BEEP;
0580     if (flags & SPEAK)           kaEventFlags |= KAEvent::SPEAK;
0581     if (flags & CONFIRM_ACK)     kaEventFlags |= KAEvent::CONFIRM_ACK;
0582     if (flags & REPEAT_SOUND)    kaEventFlags |= KAEvent::REPEAT_SOUND;
0583     if (flags & AUTO_CLOSE)      kaEventFlags |= KAEvent::AUTO_CLOSE;
0584     if (flags & EMAIL_BCC)       kaEventFlags |= KAEvent::EMAIL_BCC;
0585     if (flags & DISPLAY_COMMAND) kaEventFlags |= KAEvent::DISPLAY_COMMAND;
0586     if (flags & SCRIPT)          kaEventFlags |= KAEvent::SCRIPT;
0587     if (flags & EXEC_IN_XTERM)   kaEventFlags |= KAEvent::EXEC_IN_XTERM;
0588     if (flags & SHOW_IN_KORG)    kaEventFlags |= KAEvent::COPY_KORGANIZER;
0589     if (flags & EXCL_HOLIDAYS)   kaEventFlags |= KAEvent::EXCL_HOLIDAYS;
0590     if (flags & WORK_TIME_ONLY)  kaEventFlags |= KAEvent::WORK_TIME_ONLY;
0591     if (flags & DISABLED)        kaEventFlags |= KAEvent::DISABLED;
0592     if (flags & NOTIFY)          kaEventFlags |= KAEvent::NOTIFY;
0593     if (start.isDateOnly())      kaEventFlags |= KAEvent::ANY_TIME;
0594     return kaEventFlags;
0595 }
0596 
0597 /******************************************************************************
0598 * Convert the background colour string to a QColor.
0599 */
0600 QColor DBusHandler::convertBgColour(const QString& bgColor)
0601 {
0602     if (bgColor.isEmpty())
0603         return Preferences::defaultBgColour();
0604     const QColor bg(bgColor);
0605     if (!bg.isValid())
0606         qCCritical(KALARM_LOG) << "D-Bus call: invalid background color:" << bgColor;
0607     return bg;
0608 }
0609 
0610 bool DBusHandler::convertRecurrence(KADateTime& start, KARecurrence& recurrence,
0611                                     const QString& startDateTime, const QString& icalRecurrence,
0612                     int subRepeatInterval, KCalendarCore::Duration& subRepeatDuration)
0613 {
0614     start = convertDateTime(startDateTime);
0615     if (!start.isValid())
0616         return false;
0617     if (!recurrence.set(icalRecurrence))
0618         return false;
0619     if (subRepeatInterval  &&  recurrence.type() == KARecurrence::NO_RECUR)
0620     {
0621         subRepeatInterval = 0;
0622         qCWarning(KALARM_LOG) << "D-Bus call: no recurrence specified, so sub-repetition ignored";
0623     }
0624     if (subRepeatInterval  &&  !(subRepeatInterval % (24*60)))
0625         subRepeatDuration = Duration(subRepeatInterval / (24*60), Duration::Days);
0626     else
0627         subRepeatDuration = Duration(subRepeatInterval * 60, Duration::Seconds);
0628     return true;
0629 }
0630 
0631 bool DBusHandler::convertRecurrence(KADateTime& start, KARecurrence& recurrence, const QString& startDateTime,
0632                                     int recurType, int recurInterval, int recurCount)
0633 {
0634     start = convertDateTime(startDateTime);
0635     if (!start.isValid())
0636         return false;
0637     return convertRecurrence(recurrence, start, recurType, recurInterval, recurCount, KADateTime());
0638 }
0639 
0640 bool DBusHandler::convertRecurrence(KADateTime& start, KARecurrence& recurrence, const QString& startDateTime,
0641                                     int recurType, int recurInterval, const QString& endDateTime)
0642 {
0643     start = convertDateTime(startDateTime);
0644     if (!start.isValid())
0645         return false;
0646     const KADateTime end = convertDateTime(endDateTime, start);
0647     if (end.isDateOnly()  &&  !start.isDateOnly())
0648     {
0649         qCCritical(KALARM_LOG) << "D-Bus call: alarm is date-only, but recurrence end is date/time";
0650         return false;
0651     }
0652     if (!end.isDateOnly()  &&  start.isDateOnly())
0653     {
0654         qCCritical(KALARM_LOG) << "D-Bus call: alarm is timed, but recurrence end is date-only";
0655         return false;
0656     }
0657     return convertRecurrence(recurrence, start, recurType, recurInterval, 0, end);
0658 }
0659 
0660 bool DBusHandler::convertRecurrence(KARecurrence& recurrence, const KADateTime& start, int recurType,
0661                                     int recurInterval, int recurCount, const KADateTime& end)
0662 {
0663     KARecurrence::Type type;
0664     switch (recurType)
0665     {
0666         case MINUTELY:  type = KARecurrence::MINUTELY;  break;
0667         case DAILY:     type = KARecurrence::DAILY;  break;
0668         case WEEKLY:    type = KARecurrence::WEEKLY;  break;
0669         case MONTHLY:   type = KARecurrence::MONTHLY_DAY;  break;
0670         case YEARLY:    type = KARecurrence::ANNUAL_DATE;  break;
0671         default:
0672             qCCritical(KALARM_LOG) << "D-Bus call: invalid recurrence type:" << recurType;
0673             return false;
0674     }
0675     recurrence.set(type, recurInterval, recurCount, start, end);
0676     return true;
0677 }
0678 
0679 #include "moc_dbushandler.cpp"
0680 
0681 // vim: et sw=4: