SVN_SILENT made messages (.desktop file)
[kdepim.git] / kalarm / dbushandler.cpp
blob990e921287516a6598b654876ee6a00a637f1c1f
1 /*
2 * dbushandler.cpp - handler for D-Bus calls by other applications
3 * Program: kalarm
4 * Copyright © 2002-2012 by David Jarvie <djarvie@kde.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "kalarm.h"
23 #include "alarmcalendar.h"
24 #include "alarmtime.h"
25 #include "functions.h"
26 #include "kalarmapp.h"
27 #include "kamail.h"
28 #include "mainwindow.h"
29 #include "preferences.h"
30 #include "dbushandler.h"
31 #include <kalarmadaptor.h>
33 #include <kalarmcal/identities.h>
34 #include <kalarmcal/karecurrence.h>
36 #include <KCalCore/Duration>
37 using namespace KCalCore;
39 #include <QtDBus/QtDBus>
40 #include "kalarm_debug.h"
42 #include <stdlib.h>
44 static const char* REQUEST_DBUS_OBJECT = "/kalarm"; // D-Bus object path of KAlarm's request interface
47 /*=============================================================================
48 = DBusHandler
49 = This class's function is to handle D-Bus requests by other applications.
50 =============================================================================*/
51 DBusHandler::DBusHandler()
53 qCDebug(KALARM_LOG);
54 new KalarmAdaptor(this);
55 QDBusConnection::sessionBus().registerObject(QLatin1String(REQUEST_DBUS_OBJECT), this);
59 bool DBusHandler::cancelEvent(const QString& eventId)
61 return theApp()->dbusDeleteEvent(EventId(eventId));
64 bool DBusHandler::triggerEvent(const QString& eventId)
66 return theApp()->dbusTriggerEvent(EventId(eventId));
69 QString DBusHandler::list()
71 return theApp()->dbusList();
74 bool DBusHandler::scheduleMessage(const QString& message, const QString& startDateTime, int lateCancel, unsigned flags,
75 const QString& bgColor, const QString& fgColor, const QString& font,
76 const QString& audioUrl, int reminderMins, const QString& recurrence,
77 int subRepeatInterval, int subRepeatCount)
79 KDateTime start;
80 KARecurrence recur;
81 Duration subRepeatDuration;
82 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
83 return false;
84 return scheduleMessage(message, start, lateCancel, flags, bgColor, fgColor, font, KUrl(audioUrl), reminderMins, recur, subRepeatDuration, subRepeatCount);
87 bool DBusHandler::scheduleMessage(const QString& message, const QString& startDateTime, int lateCancel, unsigned flags,
88 const QString& bgColor, const QString& fgColor, const QString& font,
89 const QString& audioUrl, int reminderMins,
90 int recurType, int recurInterval, int recurCount)
92 KDateTime start;
93 KARecurrence recur;
94 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
95 return false;
96 return scheduleMessage(message, start, lateCancel, flags, bgColor, fgColor, font, KUrl(audioUrl), reminderMins, recur);
99 bool DBusHandler::scheduleMessage(const QString& message, const QString& startDateTime, int lateCancel, unsigned flags,
100 const QString& bgColor, const QString& fgColor, const QString& font,
101 const QString& audioUrl, int reminderMins,
102 int recurType, int recurInterval, const QString& endDateTime)
104 KDateTime start;
105 KARecurrence recur;
106 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
107 return false;
108 return scheduleMessage(message, start, lateCancel, flags, bgColor, fgColor, font, KUrl(audioUrl), reminderMins, recur);
111 bool DBusHandler::scheduleFile(const QString& url, const QString& startDateTime, int lateCancel, unsigned flags, const QString& bgColor,
112 const QString& audioUrl, int reminderMins, const QString& recurrence,
113 int subRepeatInterval, int subRepeatCount)
115 KDateTime start;
116 KARecurrence recur;
117 Duration subRepeatDuration;
118 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
119 return false;
120 return scheduleFile(KUrl(url), start, lateCancel, flags, bgColor, KUrl(audioUrl), reminderMins, recur, subRepeatDuration, subRepeatCount);
123 bool DBusHandler::scheduleFile(const QString& url, const QString& startDateTime, int lateCancel, unsigned flags, const QString& bgColor,
124 const QString& audioUrl, int reminderMins, int recurType, int recurInterval, int recurCount)
126 KDateTime start;
127 KARecurrence recur;
128 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
129 return false;
130 return scheduleFile(KUrl(url), start, lateCancel, flags, bgColor, KUrl(audioUrl), reminderMins, recur);
133 bool DBusHandler::scheduleFile(const QString& url, const QString& startDateTime, int lateCancel, unsigned flags, const QString& bgColor,
134 const QString& audioUrl, int reminderMins, int recurType, int recurInterval, const QString& endDateTime)
136 KDateTime start;
137 KARecurrence recur;
138 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
139 return false;
140 return scheduleFile(KUrl(url), start, lateCancel, flags, bgColor, KUrl(audioUrl), reminderMins, recur);
143 bool DBusHandler::scheduleCommand(const QString& commandLine, const QString& startDateTime, int lateCancel, unsigned flags,
144 const QString& recurrence, int subRepeatInterval, int subRepeatCount)
146 KDateTime start;
147 KARecurrence recur;
148 Duration subRepeatDuration;
149 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
150 return false;
151 return scheduleCommand(commandLine, start, lateCancel, flags, recur, subRepeatDuration, subRepeatCount);
154 bool DBusHandler::scheduleCommand(const QString& commandLine, const QString& startDateTime, int lateCancel, unsigned flags,
155 int recurType, int recurInterval, int recurCount)
157 KDateTime start = convertDateTime(startDateTime);
158 if (!start.isValid())
159 return false;
160 KARecurrence recur;
161 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
162 return false;
163 return scheduleCommand(commandLine, start, lateCancel, flags, recur);
166 bool DBusHandler::scheduleCommand(const QString& commandLine, const QString& startDateTime, int lateCancel, unsigned flags,
167 int recurType, int recurInterval, const QString& endDateTime)
169 KDateTime start;
170 KARecurrence recur;
171 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
172 return false;
173 return scheduleCommand(commandLine, start, lateCancel, flags, recur);
176 bool DBusHandler::scheduleEmail(const QString& fromID, const QString& addresses, const QString& subject, const QString& message,
177 const QString& attachments, const QString& startDateTime, int lateCancel, unsigned flags,
178 const QString& recurrence, int subRepeatInterval, int subRepeatCount)
180 KDateTime start;
181 KARecurrence recur;
182 Duration subRepeatDuration;
183 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
184 return false;
185 return scheduleEmail(fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur, subRepeatDuration, subRepeatCount);
188 bool DBusHandler::scheduleEmail(const QString& fromID, const QString& addresses, const QString& subject, const QString& message,
189 const QString& attachments, const QString& startDateTime, int lateCancel, unsigned flags,
190 int recurType, int recurInterval, int recurCount)
192 KDateTime start;
193 KARecurrence recur;
194 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
195 return false;
196 return scheduleEmail(fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur);
199 bool DBusHandler::scheduleEmail(const QString& fromID, const QString& addresses, const QString& subject, const QString& message,
200 const QString& attachments, const QString& startDateTime, int lateCancel, unsigned flags,
201 int recurType, int recurInterval, const QString& endDateTime)
203 KDateTime start;
204 KARecurrence recur;
205 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
206 return false;
207 return scheduleEmail(fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur);
210 bool DBusHandler::scheduleAudio(const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
211 unsigned flags, const QString& recurrence, int subRepeatInterval, int subRepeatCount)
213 KDateTime start;
214 KARecurrence recur;
215 Duration subRepeatDuration;
216 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
217 return false;
218 return scheduleAudio(audioUrl, volumePercent, start, lateCancel, flags, recur, subRepeatDuration, subRepeatCount);
221 bool DBusHandler::scheduleAudio(const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
222 unsigned flags, int recurType, int recurInterval, int recurCount)
224 KDateTime start = convertDateTime(startDateTime);
225 if (!start.isValid())
226 return false;
227 KARecurrence recur;
228 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
229 return false;
230 return scheduleAudio(audioUrl, volumePercent, start, lateCancel, flags, recur);
233 bool DBusHandler::scheduleAudio(const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
234 unsigned flags, int recurType, int recurInterval, const QString& endDateTime)
236 KDateTime start;
237 KARecurrence recur;
238 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
239 return false;
240 return scheduleAudio(audioUrl, volumePercent, start, lateCancel, flags, recur);
243 bool DBusHandler::edit(const QString& eventID)
245 return KAlarm::editAlarmById(EventId(eventID));
248 bool DBusHandler::editNew(int type)
250 EditAlarmDlg::Type dlgtype;
251 switch (type)
253 case DISPLAY: dlgtype = EditAlarmDlg::DISPLAY; break;
254 case COMMAND: dlgtype = EditAlarmDlg::COMMAND; break;
255 case EMAIL: dlgtype = EditAlarmDlg::EMAIL; break;
256 case AUDIO: dlgtype = EditAlarmDlg::AUDIO; break;
257 default:
258 qCritical() << "D-Bus call: invalid alarm type:" << type;
259 return false;
261 KAlarm::editNewAlarm(dlgtype);
262 return true;
265 bool DBusHandler::editNew(const QString& templateName)
267 return KAlarm::editNewAlarm(templateName);
271 /******************************************************************************
272 * Schedule a message alarm, after converting the parameters from strings.
274 bool DBusHandler::scheduleMessage(const QString& message, const KDateTime& start, int lateCancel, unsigned flags,
275 const QString& bgColor, const QString& fgColor, const QString& fontStr,
276 const KUrl& audioFile, int reminderMins, const KARecurrence& recurrence,
277 const Duration& subRepeatDuration, int subRepeatCount)
279 KAEvent::Flags kaEventFlags = convertStartFlags(start, flags);
280 KAEvent::SubAction action = (kaEventFlags & KAEvent::DISPLAY_COMMAND) ? KAEvent::COMMAND : KAEvent::MESSAGE;
281 QColor bg = convertBgColour(bgColor);
282 if (!bg.isValid())
283 return false;
284 QColor fg;
285 if (fgColor.isEmpty())
286 fg = Preferences::defaultFgColour();
287 else
289 fg.setNamedColor(fgColor);
290 if (!fg.isValid())
292 qCritical() << "D-Bus call: invalid foreground color:" << fgColor;
293 return false;
296 QFont font;
297 if (fontStr.isEmpty())
298 kaEventFlags |= KAEvent::DEFAULT_FONT;
299 else
301 if (!font.fromString(fontStr)) // N.B. this doesn't do good validation
303 qCritical() << "D-Bus call: invalid font:" << fontStr;
304 return false;
307 return theApp()->scheduleEvent(action, message, start, lateCancel, kaEventFlags, bg, fg, font,
308 audioFile.url(), -1, reminderMins, recurrence, subRepeatDuration, subRepeatCount);
311 /******************************************************************************
312 * Schedule a file alarm, after converting the parameters from strings.
314 bool DBusHandler::scheduleFile(const KUrl& file,
315 const KDateTime& start, int lateCancel, unsigned flags, const QString& bgColor,
316 const KUrl& audioFile, int reminderMins, const KARecurrence& recurrence,
317 const Duration& subRepeatDuration, int subRepeatCount)
319 KAEvent::Flags kaEventFlags = convertStartFlags(start, flags);
320 QColor bg = convertBgColour(bgColor);
321 if (!bg.isValid())
322 return false;
323 return theApp()->scheduleEvent(KAEvent::FILE, file.url(), start, lateCancel, kaEventFlags, bg, Qt::black, QFont(),
324 audioFile.url(), -1, reminderMins, recurrence, subRepeatDuration, subRepeatCount);
327 /******************************************************************************
328 * Schedule a command alarm, after converting the parameters from strings.
330 bool DBusHandler::scheduleCommand(const QString& commandLine,
331 const KDateTime& start, int lateCancel, unsigned flags,
332 const KARecurrence& recurrence, const Duration& subRepeatDuration, int subRepeatCount)
334 KAEvent::Flags kaEventFlags = convertStartFlags(start, flags);
335 return theApp()->scheduleEvent(KAEvent::COMMAND, commandLine, start, lateCancel, kaEventFlags, Qt::black, Qt::black, QFont(),
336 QString(), -1, 0, recurrence, subRepeatDuration, subRepeatCount);
339 /******************************************************************************
340 * Schedule an email alarm, after validating the addresses and attachments.
342 bool DBusHandler::scheduleEmail(const QString& fromID, const QString& addresses, const QString& subject,
343 const QString& message, const QString& attachments,
344 const KDateTime& start, int lateCancel, unsigned flags,
345 const KARecurrence& recurrence, const Duration& subRepeatDuration, int subRepeatCount)
347 KAEvent::Flags kaEventFlags = convertStartFlags(start, flags);
348 uint senderId = 0;
349 if (!fromID.isEmpty())
351 senderId = Identities::identityUoid(fromID);
352 if (!senderId)
354 qCritical() << "D-Bus call scheduleEmail(): unknown sender ID:" << fromID;
355 return false;
358 KCalCore::Person::List addrs;
359 QString bad = KAMail::convertAddresses(addresses, addrs);
360 if (!bad.isEmpty())
362 qCritical() << "D-Bus call scheduleEmail(): invalid email addresses:" << bad;
363 return false;
365 if (addrs.isEmpty())
367 qCritical() << "D-Bus call scheduleEmail(): no email address";
368 return false;
370 QStringList atts;
371 bad = KAMail::convertAttachments(attachments, atts);
372 if (!bad.isEmpty())
374 qCritical() << "D-Bus call scheduleEmail(): invalid email attachment:" << bad;
375 return false;
377 return theApp()->scheduleEvent(KAEvent::EMAIL, message, start, lateCancel, kaEventFlags, Qt::black, Qt::black, QFont(),
378 QString(), -1, 0, recurrence, subRepeatDuration, subRepeatCount, senderId, addrs, subject, atts);
381 /******************************************************************************
382 * Schedule a audio alarm, after converting the parameters from strings.
384 bool DBusHandler::scheduleAudio(const QString& audioUrl, int volumePercent,
385 const KDateTime& start, int lateCancel, unsigned flags,
386 const KARecurrence& recurrence, const Duration& subRepeatDuration, int subRepeatCount)
388 KAEvent::Flags kaEventFlags = convertStartFlags(start, flags);
389 float volume = (volumePercent >= 0) ? volumePercent / 100.0f : -1;
390 return theApp()->scheduleEvent(KAEvent::AUDIO, QString(), start, lateCancel, kaEventFlags, Qt::black, Qt::black, QFont(),
391 audioUrl, volume, 0, recurrence, subRepeatDuration, subRepeatCount);
395 /******************************************************************************
396 * Convert the start date/time string to a KDateTime. The date/time string is in
397 * the format YYYY-MM-DD[THH:MM[:SS]][ TZ] or [T]HH:MM[:SS].
398 * The time zone specifier (TZ) is a system time zone name, e.g. "Europe/London".
399 * If no time zone is specified, it defaults to the local clock time (which is
400 * not the same as the local time zone).
402 KDateTime DBusHandler::convertDateTime(const QString& dateTime, const KDateTime& defaultDt)
404 int i = dateTime.indexOf(QLatin1Char(' '));
405 QString dtString = dateTime.left(i);
406 QString zone = dateTime.mid(i);
407 QDate date;
408 QTime time;
409 bool haveTime = true;
410 bool error = false;
411 if (dtString.length() > 10)
413 // Both a date and a time are specified
414 QDateTime dt = QDateTime::fromString(dtString, Qt::ISODate);
415 error = !dt.isValid();
416 date = dt.date();
417 time = dt.time();
419 else
421 // Check whether a time is specified
422 QString t;
423 if (dtString[0] == QLatin1Char('T'))
424 t = dtString.mid(1); // it's a time: remove the leading 'T'
425 else if (!dtString[2].isDigit())
426 t = dtString; // it's a time with no leading 'T'
428 if (t.isEmpty())
430 // It's a date only
431 date = QDate::fromString(dtString, Qt::ISODate);
432 error = !date.isValid();
433 haveTime = false;
435 else
437 // It's a time only
438 time = QTime::fromString(t, Qt::ISODate);
439 error = !time.isValid();
442 KDateTime result;
443 if (!error)
444 result = AlarmTime::applyTimeZone(zone, date, time, haveTime, defaultDt);
445 if (error || !result.isValid())
447 if (!defaultDt.isValid())
448 qCritical() << "D-Bus call: invalid start date/time: '" << dateTime << "'";
449 else
450 qCritical() << "D-Bus call: invalid recurrence end date/time: '" << dateTime << "'";
452 return result;
455 /******************************************************************************
456 * Convert the flag bits to KAEvent flag bits.
458 KAEvent::Flags DBusHandler::convertStartFlags(const KDateTime& start, unsigned flags)
460 KAEvent::Flags kaEventFlags = 0;
461 if (flags & REPEAT_AT_LOGIN) kaEventFlags |= KAEvent::REPEAT_AT_LOGIN;
462 if (flags & BEEP) kaEventFlags |= KAEvent::BEEP;
463 if (flags & SPEAK) kaEventFlags |= KAEvent::SPEAK;
464 if (flags & CONFIRM_ACK) kaEventFlags |= KAEvent::CONFIRM_ACK;
465 if (flags & REPEAT_SOUND) kaEventFlags |= KAEvent::REPEAT_SOUND;
466 if (flags & AUTO_CLOSE) kaEventFlags |= KAEvent::AUTO_CLOSE;
467 if (flags & EMAIL_BCC) kaEventFlags |= KAEvent::EMAIL_BCC;
468 if (flags & DISPLAY_COMMAND) kaEventFlags |= KAEvent::DISPLAY_COMMAND;
469 if (flags & SCRIPT) kaEventFlags |= KAEvent::SCRIPT;
470 if (flags & EXEC_IN_XTERM) kaEventFlags |= KAEvent::EXEC_IN_XTERM;
471 if (flags & SHOW_IN_KORG) kaEventFlags |= KAEvent::COPY_KORGANIZER;
472 if (flags & EXCL_HOLIDAYS) kaEventFlags |= KAEvent::EXCL_HOLIDAYS;
473 if (flags & WORK_TIME_ONLY) kaEventFlags |= KAEvent::WORK_TIME_ONLY;
474 if (flags & DISABLED) kaEventFlags |= KAEvent::DISABLED;
475 if (start.isDateOnly()) kaEventFlags |= KAEvent::ANY_TIME;
476 return kaEventFlags;
479 /******************************************************************************
480 * Convert the background colour string to a QColor.
482 QColor DBusHandler::convertBgColour(const QString& bgColor)
484 if (bgColor.isEmpty())
485 return Preferences::defaultBgColour();
486 QColor bg(bgColor);
487 if (!bg.isValid())
488 qCritical() << "D-Bus call: invalid background color:" << bgColor;
489 return bg;
492 bool DBusHandler::convertRecurrence(KDateTime& start, KARecurrence& recurrence,
493 const QString& startDateTime, const QString& icalRecurrence,
494 int subRepeatInterval, Duration& subRepeatDuration)
496 start = convertDateTime(startDateTime);
497 if (!start.isValid())
498 return false;
499 if (!recurrence.set(icalRecurrence))
500 return false;
501 if (subRepeatInterval && recurrence.type() == KARecurrence::NO_RECUR)
503 subRepeatInterval = 0;
504 qCWarning(KALARM_LOG) << "D-Bus call: no recurrence specified, so sub-repetition ignored";
506 if (subRepeatInterval && !(subRepeatInterval % (24*60)))
507 subRepeatDuration = Duration(subRepeatInterval / (24*60), Duration::Days);
508 else
509 subRepeatDuration = Duration(subRepeatInterval * 60, Duration::Seconds);
510 return true;
513 bool DBusHandler::convertRecurrence(KDateTime& start, KARecurrence& recurrence, const QString& startDateTime,
514 int recurType, int recurInterval, int recurCount)
516 start = convertDateTime(startDateTime);
517 if (!start.isValid())
518 return false;
519 return convertRecurrence(recurrence, start, recurType, recurInterval, recurCount, KDateTime());
522 bool DBusHandler::convertRecurrence(KDateTime& start, KARecurrence& recurrence, const QString& startDateTime,
523 int recurType, int recurInterval, const QString& endDateTime)
525 start = convertDateTime(startDateTime);
526 if (!start.isValid())
527 return false;
528 KDateTime end = convertDateTime(endDateTime, start);
529 if (end.isDateOnly() && !start.isDateOnly())
531 qCritical() << "D-Bus call: alarm is date-only, but recurrence end is date/time";
532 return false;
534 if (!end.isDateOnly() && start.isDateOnly())
536 qCritical() << "D-Bus call: alarm is timed, but recurrence end is date-only";
537 return false;
539 return convertRecurrence(recurrence, start, recurType, recurInterval, 0, end);
542 bool DBusHandler::convertRecurrence(KARecurrence& recurrence, const KDateTime& start, int recurType,
543 int recurInterval, int recurCount, const KDateTime& end)
545 KARecurrence::Type type;
546 switch (recurType)
548 case MINUTELY: type = KARecurrence::MINUTELY; break;
549 case DAILY: type = KARecurrence::DAILY; break;
550 case WEEKLY: type = KARecurrence::WEEKLY; break;
551 case MONTHLY: type = KARecurrence::MONTHLY_DAY; break;
552 case YEARLY: type = KARecurrence::ANNUAL_DATE; break;
553 default:
554 qCritical() << "D-Bus call: invalid recurrence type:" << recurType;
555 return false;
557 recurrence.set(type, recurInterval, recurCount, start, end);
558 return true;
561 // vim: et sw=4: