Waste less space in nested layouts.
[kdepim.git] / kalarm / dbushandler.cpp
blobc93342174aa6001e95af891824650b667f700361
1 /*
2 * dbushandler.cpp - handler for D-Bus calls by other applications
3 * Program: kalarm
4 * Copyright © 2002-2010 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 <stdlib.h>
25 #include <QtDBus/QtDBus>
26 #include <kdebug.h>
27 #include <kcal/duration.h>
29 #include "alarmcalendar.h"
30 #include "functions.h"
31 #include "identities.h"
32 #include "kalarmapp.h"
33 #include "kamail.h"
34 #include "karecurrence.h"
35 #include "mainwindow.h"
36 #include "preferences.h"
37 #include "dbushandler.moc"
38 #include <kalarmadaptor.h>
39 static const char* REQUEST_DBUS_OBJECT = "/kalarm"; // D-Bus object path of KAlarm's request interface
42 /*=============================================================================
43 = DBusHandler
44 = This class's function is to handle D-Bus requests by other applications.
45 =============================================================================*/
46 DBusHandler::DBusHandler()
48 kDebug();
49 new KalarmAdaptor(this);
50 QDBusConnection::sessionBus().registerObject(REQUEST_DBUS_OBJECT, this);
54 bool DBusHandler::cancelEvent(const QString& eventId)
56 return theApp()->dbusDeleteEvent(eventId);
59 bool DBusHandler::triggerEvent(const QString& eventId)
61 return theApp()->dbusTriggerEvent(eventId);
64 bool DBusHandler::scheduleMessage(const QString& message, const QString& startDateTime, int lateCancel, unsigned flags,
65 const QString& bgColor, const QString& fgColor, const QString& font,
66 const QString& audioUrl, int reminderMins, const QString& recurrence,
67 int subRepeatInterval, int subRepeatCount)
69 KDateTime start;
70 KARecurrence recur;
71 KCal::Duration subRepeatDuration;
72 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
73 return false;
74 return scheduleMessage(message, start, lateCancel, flags, bgColor, fgColor, font, KUrl(audioUrl), reminderMins, recur, subRepeatDuration, subRepeatCount);
77 bool DBusHandler::scheduleMessage(const QString& message, const QString& startDateTime, int lateCancel, unsigned flags,
78 const QString& bgColor, const QString& fgColor, const QString& font,
79 const QString& audioUrl, int reminderMins,
80 int recurType, int recurInterval, int recurCount)
82 KDateTime start;
83 KARecurrence recur;
84 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
85 return false;
86 return scheduleMessage(message, start, lateCancel, flags, bgColor, fgColor, font, KUrl(audioUrl), reminderMins, recur);
89 bool DBusHandler::scheduleMessage(const QString& message, const QString& startDateTime, int lateCancel, unsigned flags,
90 const QString& bgColor, const QString& fgColor, const QString& font,
91 const QString& audioUrl, int reminderMins,
92 int recurType, int recurInterval, const QString& endDateTime)
94 KDateTime start;
95 KARecurrence recur;
96 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
97 return false;
98 return scheduleMessage(message, start, lateCancel, flags, bgColor, fgColor, font, KUrl(audioUrl), reminderMins, recur);
101 bool DBusHandler::scheduleFile(const QString& url, const QString& startDateTime, int lateCancel, unsigned flags, const QString& bgColor,
102 const QString& audioUrl, int reminderMins, const QString& recurrence,
103 int subRepeatInterval, int subRepeatCount)
105 KDateTime start;
106 KARecurrence recur;
107 KCal::Duration subRepeatDuration;
108 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
109 return false;
110 return scheduleFile(KUrl(url), start, lateCancel, flags, bgColor, KUrl(audioUrl), reminderMins, recur, subRepeatDuration, subRepeatCount);
113 bool DBusHandler::scheduleFile(const QString& url, const QString& startDateTime, int lateCancel, unsigned flags, const QString& bgColor,
114 const QString& audioUrl, int reminderMins, int recurType, int recurInterval, int recurCount)
116 KDateTime start;
117 KARecurrence recur;
118 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
119 return false;
120 return scheduleFile(KUrl(url), start, lateCancel, flags, bgColor, KUrl(audioUrl), reminderMins, recur);
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, const QString& endDateTime)
126 KDateTime start;
127 KARecurrence recur;
128 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
129 return false;
130 return scheduleFile(KUrl(url), start, lateCancel, flags, bgColor, KUrl(audioUrl), reminderMins, recur);
133 bool DBusHandler::scheduleCommand(const QString& commandLine, const QString& startDateTime, int lateCancel, unsigned flags,
134 const QString& recurrence, int subRepeatInterval, int subRepeatCount)
136 KDateTime start;
137 KARecurrence recur;
138 KCal::Duration subRepeatDuration;
139 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
140 return false;
141 return scheduleCommand(commandLine, start, lateCancel, flags, recur, subRepeatDuration, subRepeatCount);
144 bool DBusHandler::scheduleCommand(const QString& commandLine, const QString& startDateTime, int lateCancel, unsigned flags,
145 int recurType, int recurInterval, int recurCount)
147 KDateTime start = convertDateTime(startDateTime);
148 if (!start.isValid())
149 return false;
150 KARecurrence recur;
151 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
152 return false;
153 return scheduleCommand(commandLine, start, lateCancel, flags, recur);
156 bool DBusHandler::scheduleCommand(const QString& commandLine, const QString& startDateTime, int lateCancel, unsigned flags,
157 int recurType, int recurInterval, const QString& endDateTime)
159 KDateTime start;
160 KARecurrence recur;
161 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
162 return false;
163 return scheduleCommand(commandLine, start, lateCancel, flags, recur);
166 bool DBusHandler::scheduleEmail(const QString& fromID, const QString& addresses, const QString& subject, const QString& message,
167 const QString& attachments, const QString& startDateTime, int lateCancel, unsigned flags,
168 const QString& recurrence, int subRepeatInterval, int subRepeatCount)
170 KDateTime start;
171 KARecurrence recur;
172 KCal::Duration subRepeatDuration;
173 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
174 return false;
175 return scheduleEmail(fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur, subRepeatDuration, subRepeatCount);
178 bool DBusHandler::scheduleEmail(const QString& fromID, const QString& addresses, const QString& subject, const QString& message,
179 const QString& attachments, const QString& startDateTime, int lateCancel, unsigned flags,
180 int recurType, int recurInterval, int recurCount)
182 KDateTime start;
183 KARecurrence recur;
184 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
185 return false;
186 return scheduleEmail(fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur);
189 bool DBusHandler::scheduleEmail(const QString& fromID, const QString& addresses, const QString& subject, const QString& message,
190 const QString& attachments, const QString& startDateTime, int lateCancel, unsigned flags,
191 int recurType, int recurInterval, const QString& endDateTime)
193 KDateTime start;
194 KARecurrence recur;
195 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
196 return false;
197 return scheduleEmail(fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur);
200 bool DBusHandler::scheduleAudio(const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
201 unsigned flags, const QString& recurrence, int subRepeatInterval, int subRepeatCount)
203 KDateTime start;
204 KARecurrence recur;
205 KCal::Duration subRepeatDuration;
206 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval, subRepeatDuration))
207 return false;
208 return scheduleAudio(audioUrl, volumePercent, start, lateCancel, flags, recur, subRepeatDuration, subRepeatCount);
211 bool DBusHandler::scheduleAudio(const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
212 unsigned flags, int recurType, int recurInterval, int recurCount)
214 KDateTime start = convertDateTime(startDateTime);
215 if (!start.isValid())
216 return false;
217 KARecurrence recur;
218 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
219 return false;
220 return scheduleAudio(audioUrl, volumePercent, start, lateCancel, flags, recur);
223 bool DBusHandler::scheduleAudio(const QString& audioUrl, int volumePercent, const QString& startDateTime, int lateCancel,
224 unsigned flags, int recurType, int recurInterval, const QString& endDateTime)
226 KDateTime start;
227 KARecurrence recur;
228 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
229 return false;
230 return scheduleAudio(audioUrl, volumePercent, start, lateCancel, flags, recur);
233 bool DBusHandler::edit(const QString& eventID)
235 return KAlarm::editAlarm(eventID);
238 bool DBusHandler::editNew(int type)
240 EditAlarmDlg::Type dlgtype;
241 switch (type)
243 case DISPLAY: dlgtype = EditAlarmDlg::DISPLAY; break;
244 case COMMAND: dlgtype = EditAlarmDlg::COMMAND; break;
245 case EMAIL: dlgtype = EditAlarmDlg::EMAIL; break;
246 case AUDIO: dlgtype = EditAlarmDlg::AUDIO; break;
247 default:
248 kError() << "D-Bus call: invalid alarm type:" << type;
249 return false;
251 KAlarm::editNewAlarm(dlgtype);
252 return true;
255 bool DBusHandler::editNew(const QString& templateName)
257 return KAlarm::editNewAlarm(templateName);
261 /******************************************************************************
262 * Schedule a message alarm, after converting the parameters from strings.
264 bool DBusHandler::scheduleMessage(const QString& message, const KDateTime& start, int lateCancel, unsigned flags,
265 const QString& bgColor, const QString& fgColor, const QString& fontStr,
266 const KUrl& audioFile, int reminderMins, const KARecurrence& recurrence,
267 const KCal::Duration& subRepeatDuration, int subRepeatCount)
269 unsigned kaEventFlags = convertStartFlags(start, flags);
270 KAEvent::Action action = (kaEventFlags & KAEvent::DISPLAY_COMMAND) ? KAEvent::COMMAND : KAEvent::MESSAGE;
271 QColor bg = convertBgColour(bgColor);
272 if (!bg.isValid())
273 return false;
274 QColor fg;
275 if (fgColor.isEmpty())
276 fg = Preferences::defaultFgColour();
277 else
279 fg.setNamedColor(fgColor);
280 if (!fg.isValid())
282 kError() << "D-Bus call: invalid foreground color:" << fgColor;
283 return false;
286 QFont font;
287 if (fontStr.isEmpty())
288 kaEventFlags |= KAEvent::DEFAULT_FONT;
289 else
291 if (!font.fromString(fontStr)) // N.B. this doesn't do good validation
293 kError() << "D-Bus call: invalid font:" << fontStr;
294 return false;
297 return theApp()->scheduleEvent(action, message, start, lateCancel, kaEventFlags, bg, fg, font,
298 audioFile.url(), -1, reminderMins, recurrence, subRepeatDuration, subRepeatCount);
301 /******************************************************************************
302 * Schedule a file alarm, after converting the parameters from strings.
304 bool DBusHandler::scheduleFile(const KUrl& file,
305 const KDateTime& start, int lateCancel, unsigned flags, const QString& bgColor,
306 const KUrl& audioFile, int reminderMins, const KARecurrence& recurrence,
307 const KCal::Duration& subRepeatDuration, int subRepeatCount)
309 unsigned kaEventFlags = convertStartFlags(start, flags);
310 QColor bg = convertBgColour(bgColor);
311 if (!bg.isValid())
312 return false;
313 return theApp()->scheduleEvent(KAEvent::FILE, file.url(), start, lateCancel, kaEventFlags, bg, Qt::black, QFont(),
314 audioFile.url(), -1, reminderMins, recurrence, subRepeatDuration, subRepeatCount);
317 /******************************************************************************
318 * Schedule a command alarm, after converting the parameters from strings.
320 bool DBusHandler::scheduleCommand(const QString& commandLine,
321 const KDateTime& start, int lateCancel, unsigned flags,
322 const KARecurrence& recurrence, const KCal::Duration& subRepeatDuration, int subRepeatCount)
324 unsigned kaEventFlags = convertStartFlags(start, flags);
325 return theApp()->scheduleEvent(KAEvent::COMMAND, commandLine, start, lateCancel, kaEventFlags, Qt::black, Qt::black, QFont(),
326 QString(), -1, 0, recurrence, subRepeatDuration, subRepeatCount);
329 /******************************************************************************
330 * Schedule an email alarm, after validating the addresses and attachments.
332 bool DBusHandler::scheduleEmail(const QString& fromID, const QString& addresses, const QString& subject,
333 const QString& message, const QString& attachments,
334 const KDateTime& start, int lateCancel, unsigned flags,
335 const KARecurrence& recurrence, const KCal::Duration& subRepeatDuration, int subRepeatCount)
337 unsigned kaEventFlags = convertStartFlags(start, flags);
338 uint senderId = 0;
339 if (!fromID.isEmpty())
341 senderId = Identities::identityUoid(fromID);
342 if (!senderId)
344 kError() << "D-Bus call scheduleEmail(): unknown sender ID:" << fromID;
345 return false;
348 EmailAddressList addrs;
349 QString bad = KAMail::convertAddresses(addresses, addrs);
350 if (!bad.isEmpty())
352 kError() << "D-Bus call scheduleEmail(): invalid email addresses:" << bad;
353 return false;
355 if (addrs.isEmpty())
357 kError() << "D-Bus call scheduleEmail(): no email address";
358 return false;
360 QStringList atts;
361 bad = KAMail::convertAttachments(attachments, atts);
362 if (!bad.isEmpty())
364 kError() << "D-Bus call scheduleEmail(): invalid email attachment:" << bad;
365 return false;
367 return theApp()->scheduleEvent(KAEvent::EMAIL, message, start, lateCancel, kaEventFlags, Qt::black, Qt::black, QFont(),
368 QString(), -1, 0, recurrence, subRepeatDuration, subRepeatCount, senderId, addrs, subject, atts);
371 /******************************************************************************
372 * Schedule a audio alarm, after converting the parameters from strings.
374 bool DBusHandler::scheduleAudio(const QString& audioUrl, int volumePercent,
375 const KDateTime& start, int lateCancel, unsigned flags,
376 const KARecurrence& recurrence, const KCal::Duration& subRepeatDuration, int subRepeatCount)
378 unsigned kaEventFlags = convertStartFlags(start, flags);
379 float volume = (volumePercent >= 0) ? volumePercent / 100.0f : -1;
380 return theApp()->scheduleEvent(KAEvent::AUDIO, QString(), start, lateCancel, kaEventFlags, Qt::black, Qt::black, QFont(),
381 audioUrl, volume, 0, recurrence, subRepeatDuration, subRepeatCount);
385 /******************************************************************************
386 * Convert the start date/time string to a KDateTime. The date/time string is in
387 * the format YYYY-MM-DD[THH:MM[:SS]][ TZ] or [T]HH:MM[:SS].
388 * The time zone specifier (TZ) is a system time zone name, e.g. "Europe/London".
389 * If no time zone is specified, it defaults to the local clock time (which is
390 * not the same as the local time zone).
392 KDateTime DBusHandler::convertDateTime(const QString& dateTime, const KDateTime& defaultDt)
394 int i = dateTime.indexOf(QChar(' '));
395 QString dtString = dateTime.left(i);
396 QString zone = dateTime.mid(i);
397 QDate date;
398 QTime time;
399 bool haveTime = true;
400 bool error = false;
401 if (dtString.length() > 10)
403 // Both a date and a time are specified
404 QDateTime dt = QDateTime::fromString(dtString, Qt::ISODate);
405 error = !dt.isValid();
406 date = dt.date();
407 time = dt.time();
409 else
411 // Check whether a time is specified
412 QString t;
413 if (dtString[0] == QChar('T'))
414 t = dtString.mid(1); // it's a time: remove the leading 'T'
415 else if (!dtString[2].isDigit())
416 t = dtString; // it's a time with no leading 'T'
418 if (t.isEmpty())
420 // It's a date only
421 date = QDate::fromString(dtString, Qt::ISODate);
422 error = !date.isValid();
423 haveTime = false;
425 else
427 // It's a time only
428 time = QTime::fromString(t, Qt::ISODate);
429 error = !time.isValid();
432 KDateTime result;
433 if (!error)
434 result = KAlarm::applyTimeZone(zone, date, time, haveTime, defaultDt);
435 if (error || !result.isValid())
437 if (!defaultDt.isValid())
438 kError() << "D-Bus call: invalid start date/time: '" << dateTime << "'";
439 else
440 kError() << "D-Bus call: invalid recurrence end date/time: '" << dateTime << "'";
442 return result;
445 /******************************************************************************
446 * Convert the flag bits to KAEvent flag bits.
448 unsigned DBusHandler::convertStartFlags(const KDateTime& start, unsigned flags)
450 unsigned kaEventFlags = 0;
451 if (flags & REPEAT_AT_LOGIN) kaEventFlags |= KAEvent::REPEAT_AT_LOGIN;
452 if (flags & BEEP) kaEventFlags |= KAEvent::BEEP;
453 if (flags & SPEAK) kaEventFlags |= KAEvent::SPEAK;
454 if (flags & CONFIRM_ACK) kaEventFlags |= KAEvent::CONFIRM_ACK;
455 if (flags & REPEAT_SOUND) kaEventFlags |= KAEvent::REPEAT_SOUND;
456 if (flags & AUTO_CLOSE) kaEventFlags |= KAEvent::AUTO_CLOSE;
457 if (flags & EMAIL_BCC) kaEventFlags |= KAEvent::EMAIL_BCC;
458 if (flags & DISPLAY_COMMAND) kaEventFlags |= KAEvent::DISPLAY_COMMAND;
459 if (flags & SCRIPT) kaEventFlags |= KAEvent::SCRIPT;
460 if (flags & EXEC_IN_XTERM) kaEventFlags |= KAEvent::EXEC_IN_XTERM;
461 if (flags & SHOW_IN_KORG) kaEventFlags |= KAEvent::COPY_KORGANIZER;
462 if (flags & EXCL_HOLIDAYS) kaEventFlags |= KAEvent::EXCL_HOLIDAYS;
463 if (flags & WORK_TIME_ONLY) kaEventFlags |= KAEvent::WORK_TIME_ONLY;
464 if (flags & DISABLED) kaEventFlags |= KAEvent::DISABLED;
465 if (start.isDateOnly()) kaEventFlags |= KAEvent::ANY_TIME;
466 return kaEventFlags;
469 /******************************************************************************
470 * Convert the background colour string to a QColor.
472 QColor DBusHandler::convertBgColour(const QString& bgColor)
474 if (bgColor.isEmpty())
475 return Preferences::defaultBgColour();
476 QColor bg(bgColor);
477 if (!bg.isValid())
478 kError() << "D-Bus call: invalid background color:" << bgColor;
479 return bg;
482 bool DBusHandler::convertRecurrence(KDateTime& start, KARecurrence& recurrence,
483 const QString& startDateTime, const QString& icalRecurrence,
484 int subRepeatInterval, KCal::Duration& subRepeatDuration)
486 start = convertDateTime(startDateTime);
487 if (!start.isValid())
488 return false;
489 if (!recurrence.set(icalRecurrence))
490 return false;
491 if (subRepeatInterval && recurrence.type() == KARecurrence::NO_RECUR)
493 subRepeatInterval = 0;
494 kWarning() << "D-Bus call: no recurrence specified, so sub-repetition ignored";
496 if (subRepeatInterval && !(subRepeatInterval % (24*60)))
497 subRepeatDuration = KCal::Duration(subRepeatInterval / (24*60), KCal::Duration::Days);
498 else
499 subRepeatDuration = KCal::Duration(subRepeatInterval * 60, KCal::Duration::Seconds);
500 return true;
503 bool DBusHandler::convertRecurrence(KDateTime& start, KARecurrence& recurrence, const QString& startDateTime,
504 int recurType, int recurInterval, int recurCount)
506 start = convertDateTime(startDateTime);
507 if (!start.isValid())
508 return false;
509 return convertRecurrence(recurrence, start, recurType, recurInterval, recurCount, KDateTime());
512 bool DBusHandler::convertRecurrence(KDateTime& start, KARecurrence& recurrence, const QString& startDateTime,
513 int recurType, int recurInterval, const QString& endDateTime)
515 start = convertDateTime(startDateTime);
516 if (!start.isValid())
517 return false;
518 KDateTime end = convertDateTime(endDateTime, start);
519 if (end.isDateOnly() && !start.isDateOnly())
521 kError() << "D-Bus call: alarm is date-only, but recurrence end is date/time";
522 return false;
524 if (!end.isDateOnly() && start.isDateOnly())
526 kError() << "D-Bus call: alarm is timed, but recurrence end is date-only";
527 return false;
529 return convertRecurrence(recurrence, start, recurType, recurInterval, 0, end);
532 bool DBusHandler::convertRecurrence(KARecurrence& recurrence, const KDateTime& start, int recurType,
533 int recurInterval, int recurCount, const KDateTime& end)
535 KARecurrence::Type type;
536 switch (recurType)
538 case MINUTELY: type = KARecurrence::MINUTELY; break;
539 case DAILY: type = KARecurrence::DAILY; break;
540 case WEEKLY: type = KARecurrence::WEEKLY; break;
541 case MONTHLY: type = KARecurrence::MONTHLY_DAY; break;
542 case YEARLY: type = KARecurrence::ANNUAL_DATE; break;
543 default:
544 kError() << "D-Bus call: invalid recurrence type:" << recurType;
545 return false;
547 recurrence.set(type, recurInterval, recurCount, start, end);
548 return true;