2 * dbushandler.cpp - handler for D-Bus calls by other applications
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.
25 #include <QtDBus/QtDBus>
27 #include <kcal/duration.h>
29 #include "alarmcalendar.h"
30 #include "functions.h"
31 #include "identities.h"
32 #include "kalarmapp.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 /*=============================================================================
44 = This class's function is to handle D-Bus requests by other applications.
45 =============================================================================*/
46 DBusHandler::DBusHandler()
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
)
71 KCal::Duration subRepeatDuration
;
72 if (!convertRecurrence(start
, recur
, startDateTime
, recurrence
, subRepeatInterval
, subRepeatDuration
))
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
)
84 if (!convertRecurrence(start
, recur
, startDateTime
, recurType
, recurInterval
, recurCount
))
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
)
96 if (!convertRecurrence(start
, recur
, startDateTime
, recurType
, recurInterval
, endDateTime
))
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
)
107 KCal::Duration subRepeatDuration
;
108 if (!convertRecurrence(start
, recur
, startDateTime
, recurrence
, subRepeatInterval
, subRepeatDuration
))
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
)
118 if (!convertRecurrence(start
, recur
, startDateTime
, recurType
, recurInterval
, recurCount
))
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
)
128 if (!convertRecurrence(start
, recur
, startDateTime
, recurType
, recurInterval
, endDateTime
))
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
)
138 KCal::Duration subRepeatDuration
;
139 if (!convertRecurrence(start
, recur
, startDateTime
, recurrence
, subRepeatInterval
, subRepeatDuration
))
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())
151 if (!convertRecurrence(start
, recur
, startDateTime
, recurType
, recurInterval
, recurCount
))
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
)
161 if (!convertRecurrence(start
, recur
, startDateTime
, recurType
, recurInterval
, endDateTime
))
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
)
172 KCal::Duration subRepeatDuration
;
173 if (!convertRecurrence(start
, recur
, startDateTime
, recurrence
, subRepeatInterval
, subRepeatDuration
))
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
)
184 if (!convertRecurrence(start
, recur
, startDateTime
, recurType
, recurInterval
, recurCount
))
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
)
195 if (!convertRecurrence(start
, recur
, startDateTime
, recurType
, recurInterval
, endDateTime
))
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
)
205 KCal::Duration subRepeatDuration
;
206 if (!convertRecurrence(start
, recur
, startDateTime
, recurrence
, subRepeatInterval
, subRepeatDuration
))
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())
218 if (!convertRecurrence(start
, recur
, startDateTime
, recurType
, recurInterval
, recurCount
))
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
)
228 if (!convertRecurrence(start
, recur
, startDateTime
, recurType
, recurInterval
, endDateTime
))
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
;
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;
248 kError() << "D-Bus call: invalid alarm type:" << type
;
251 KAlarm::editNewAlarm(dlgtype
);
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
);
275 if (fgColor
.isEmpty())
276 fg
= Preferences::defaultFgColour();
279 fg
.setNamedColor(fgColor
);
282 kError() << "D-Bus call: invalid foreground color:" << fgColor
;
287 if (fontStr
.isEmpty())
288 kaEventFlags
|= KAEvent::DEFAULT_FONT
;
291 if (!font
.fromString(fontStr
)) // N.B. this doesn't do good validation
293 kError() << "D-Bus call: invalid font:" << fontStr
;
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
);
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
);
339 if (!fromID
.isEmpty())
341 senderId
= Identities::identityUoid(fromID
);
344 kError() << "D-Bus call scheduleEmail(): unknown sender ID:" << fromID
;
348 EmailAddressList addrs
;
349 QString bad
= KAMail::convertAddresses(addresses
, addrs
);
352 kError() << "D-Bus call scheduleEmail(): invalid email addresses:" << bad
;
357 kError() << "D-Bus call scheduleEmail(): no email address";
361 bad
= KAMail::convertAttachments(attachments
, atts
);
364 kError() << "D-Bus call scheduleEmail(): invalid email attachment:" << bad
;
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
);
399 bool haveTime
= true;
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();
411 // Check whether a time is specified
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'
421 date
= QDate::fromString(dtString
, Qt::ISODate
);
422 error
= !date
.isValid();
428 time
= QTime::fromString(t
, Qt::ISODate
);
429 error
= !time
.isValid();
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
<< "'";
440 kError() << "D-Bus call: invalid recurrence end date/time: '" << dateTime
<< "'";
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
;
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();
478 kError() << "D-Bus call: invalid background color:" << bgColor
;
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())
489 if (!recurrence
.set(icalRecurrence
))
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
);
499 subRepeatDuration
= KCal::Duration(subRepeatInterval
* 60, KCal::Duration::Seconds
);
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())
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())
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";
524 if (!end
.isDateOnly() && start
.isDateOnly())
526 kError() << "D-Bus call: alarm is timed, but recurrence end is date-only";
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
;
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;
544 kError() << "D-Bus call: invalid recurrence type:" << recurType
;
547 recurrence
.set(type
, recurInterval
, recurCount
, start
, end
);