kalarm

dcophandler.cpp
1/*
2 * dcophandler.cpp - handler for DCOP calls by other applications
3 * Program: kalarm
4 * Copyright © 2002-2006,2008 by David Jarvie <djarvie@kde.org>
5 *
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.
10 *
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.
15 *
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.
19 */
20
21#include "kalarm.h"
22
23#include <stdlib.h>
24
25#include <kdebug.h>
26
27#include "alarmcalendar.h"
28#include "daemon.h"
29#include "functions.h"
30#include "kalarmapp.h"
31#include "kamail.h"
32#include "karecurrence.h"
33#include "mainwindow.h"
34#include "preferences.h"
35#include "dcophandler.h"
36#include "dcophandler.moc"
37
38static const char* DCOP_OBJECT_NAME = "request"; // DCOP name of KAlarm's request interface
39
40
41/*=============================================================================
42= DcopHandler
43= This class's function is to handle DCOP requests by other applications.
44=============================================================================*/
45DcopHandler::DcopHandler()
46 : DCOPObject(DCOP_OBJECT_NAME),
47 TQWidget()
48{
49 kdDebug(5950) << "DcopHandler::DcopHandler()\n";
50}
51
52
53bool DcopHandler::cancelEvent(const TQString& url,const TQString& eventId)
54{
55 return theApp()->deleteEvent(url, eventId);
56}
57
58bool DcopHandler::triggerEvent(const TQString& url,const TQString& eventId)
59{
60 return theApp()->triggerEvent(url, eventId);
61}
62
63bool DcopHandler::scheduleMessage(const TQString& message, const TQString& startDateTime, int lateCancel, unsigned flags,
64 const TQString& bgColor, const TQString& fgColor, const TQString& font,
65 const KURL& audioFile, int reminderMins, const TQString& recurrence,
66 int subRepeatInterval, int subRepeatCount)
67{
68 DateTime start;
69 KARecurrence recur;
70 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval))
71 return false;
72 return scheduleMessage(message, start, lateCancel, flags, bgColor, fgColor, font, audioFile, reminderMins, recur, subRepeatInterval, subRepeatCount);
73}
74
75bool DcopHandler::scheduleMessage(const TQString& message, const TQString& startDateTime, int lateCancel, unsigned flags,
76 const TQString& bgColor, const TQString& fgColor, const TQString& font,
77 const KURL& audioFile, int reminderMins,
78 int recurType, int recurInterval, int recurCount)
79{
80 DateTime start;
81 KARecurrence recur;
82 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
83 return false;
84 return scheduleMessage(message, start, lateCancel, flags, bgColor, fgColor, font, audioFile, reminderMins, recur);
85}
86
87bool DcopHandler::scheduleMessage(const TQString& message, const TQString& startDateTime, int lateCancel, unsigned flags,
88 const TQString& bgColor, const TQString& fgColor, const TQString& font,
89 const KURL& audioFile, int reminderMins,
90 int recurType, int recurInterval, const TQString& endDateTime)
91{
92 DateTime start;
93 KARecurrence recur;
94 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
95 return false;
96 return scheduleMessage(message, start, lateCancel, flags, bgColor, fgColor, font, audioFile, reminderMins, recur);
97}
98
99bool DcopHandler::scheduleFile(const KURL& file, const TQString& startDateTime, int lateCancel, unsigned flags, const TQString& bgColor,
100 const KURL& audioFile, int reminderMins, const TQString& recurrence,
101 int subRepeatInterval, int subRepeatCount)
102{
103 DateTime start;
104 KARecurrence recur;
105 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval))
106 return false;
107 return scheduleFile(file, start, lateCancel, flags, bgColor, audioFile, reminderMins, recur, subRepeatInterval, subRepeatCount);
108}
109
110bool DcopHandler::scheduleFile(const KURL& file, const TQString& startDateTime, int lateCancel, unsigned flags, const TQString& bgColor,
111 const KURL& audioFile, int reminderMins, int recurType, int recurInterval, int recurCount)
112{
113 DateTime start;
114 KARecurrence recur;
115 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
116 return false;
117 return scheduleFile(file, start, lateCancel, flags, bgColor, audioFile, reminderMins, recur);
118}
119
120bool DcopHandler::scheduleFile(const KURL& file, const TQString& startDateTime, int lateCancel, unsigned flags, const TQString& bgColor,
121 const KURL& audioFile, int reminderMins, int recurType, int recurInterval, const TQString& endDateTime)
122{
123 DateTime start;
124 KARecurrence recur;
125 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
126 return false;
127 return scheduleFile(file, start, lateCancel, flags, bgColor, audioFile, reminderMins, recur);
128}
129
130bool DcopHandler::scheduleCommand(const TQString& commandLine, const TQString& startDateTime, int lateCancel, unsigned flags,
131 const TQString& recurrence, int subRepeatInterval, int subRepeatCount)
132{
133 DateTime start;
134 KARecurrence recur;
135 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval))
136 return false;
137 return scheduleCommand(commandLine, start, lateCancel, flags, recur, subRepeatInterval, subRepeatCount);
138}
139
140bool DcopHandler::scheduleCommand(const TQString& commandLine, const TQString& startDateTime, int lateCancel, unsigned flags,
141 int recurType, int recurInterval, int recurCount)
142{
143 DateTime start = convertStartDateTime(startDateTime);
144 if (!start.isValid())
145 return false;
146 KARecurrence recur;
147 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
148 return false;
149 return scheduleCommand(commandLine, start, lateCancel, flags, recur);
150}
151
152bool DcopHandler::scheduleCommand(const TQString& commandLine, const TQString& startDateTime, int lateCancel, unsigned flags,
153 int recurType, int recurInterval, const TQString& endDateTime)
154{
155 DateTime start;
156 KARecurrence recur;
157 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
158 return false;
159 return scheduleCommand(commandLine, start, lateCancel, flags, recur);
160}
161
162bool DcopHandler::scheduleEmail(const TQString& fromID, const TQString& addresses, const TQString& subject, const TQString& message,
163 const TQString& attachments, const TQString& startDateTime, int lateCancel, unsigned flags,
164 const TQString& recurrence, int subRepeatInterval, int subRepeatCount)
165{
166 DateTime start;
167 KARecurrence recur;
168 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval))
169 return false;
170 return scheduleEmail(fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur, subRepeatInterval, subRepeatCount);
171}
172
173bool DcopHandler::scheduleEmail(const TQString& fromID, const TQString& addresses, const TQString& subject, const TQString& message,
174 const TQString& attachments, const TQString& startDateTime, int lateCancel, unsigned flags,
175 int recurType, int recurInterval, int recurCount)
176{
177 DateTime start;
178 KARecurrence recur;
179 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount))
180 return false;
181 return scheduleEmail(fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur);
182}
183
184bool DcopHandler::scheduleEmail(const TQString& fromID, const TQString& addresses, const TQString& subject, const TQString& message,
185 const TQString& attachments, const TQString& startDateTime, int lateCancel, unsigned flags,
186 int recurType, int recurInterval, const TQString& endDateTime)
187{
188 DateTime start;
189 KARecurrence recur;
190 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime))
191 return false;
192 return scheduleEmail(fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur);
193}
194
195bool DcopHandler::edit(const TQString& eventID)
196{
197 return KAlarm::edit(eventID);
198}
199
200bool DcopHandler::editNew(const TQString& templateName)
201{
202 return KAlarm::editNew(templateName);
203}
204
205
206/******************************************************************************
207* Schedule a message alarm, after converting the parameters from strings.
208*/
209bool DcopHandler::scheduleMessage(const TQString& message, const DateTime& start, int lateCancel, unsigned flags,
210 const TQString& bgColor, const TQString& fgColor, const TQString& fontStr,
211 const KURL& audioFile, int reminderMins, const KARecurrence& recurrence,
212 int subRepeatInterval, int subRepeatCount)
213{
214 unsigned kaEventFlags = convertStartFlags(start, flags);
215 TQColor bg = convertBgColour(bgColor);
216 if (!bg.isValid())
217 return false;
218 TQColor fg;
219 if (fgColor.isEmpty())
220 fg = Preferences::defaultFgColour();
221 else
222 {
223 fg.setNamedColor(fgColor);
224 if (!fg.isValid())
225 {
226 kdError(5950) << "DCOP call: invalid foreground color: " << fgColor << endl;
227 return false;
228 }
229 }
230 TQFont font;
231 if (fontStr.isEmpty())
232 kaEventFlags |= KAEvent::DEFAULT_FONT;
233 else
234 {
235 if (!font.fromString(fontStr)) // N.B. this doesn't do good validation
236 {
237 kdError(5950) << "DCOP call: invalid font: " << fontStr << endl;
238 return false;
239 }
240 }
241 return theApp()->scheduleEvent(KAEvent::MESSAGE, message, start.dateTime(), lateCancel, kaEventFlags, bg, fg, font,
242 audioFile.url(), -1, reminderMins, recurrence, subRepeatInterval, subRepeatCount);
243}
244
245/******************************************************************************
246* Schedule a file alarm, after converting the parameters from strings.
247*/
248bool DcopHandler::scheduleFile(const KURL& file,
249 const DateTime& start, int lateCancel, unsigned flags, const TQString& bgColor,
250 const KURL& audioFile, int reminderMins, const KARecurrence& recurrence,
251 int subRepeatInterval, int subRepeatCount)
252{
253 unsigned kaEventFlags = convertStartFlags(start, flags);
254 TQColor bg = convertBgColour(bgColor);
255 if (!bg.isValid())
256 return false;
257 return theApp()->scheduleEvent(KAEvent::FILE, file.url(), start.dateTime(), lateCancel, kaEventFlags, bg, TQt::black, TQFont(),
258 audioFile.url(), -1, reminderMins, recurrence, subRepeatInterval, subRepeatCount);
259}
260
261/******************************************************************************
262* Schedule a command alarm, after converting the parameters from strings.
263*/
264bool DcopHandler::scheduleCommand(const TQString& commandLine,
265 const DateTime& start, int lateCancel, unsigned flags,
266 const KARecurrence& recurrence, int subRepeatInterval, int subRepeatCount)
267{
268 unsigned kaEventFlags = convertStartFlags(start, flags);
269 return theApp()->scheduleEvent(KAEvent::COMMAND, commandLine, start.dateTime(), lateCancel, kaEventFlags, TQt::black, TQt::black, TQFont(),
270 TQString(), -1, 0, recurrence, subRepeatInterval, subRepeatCount);
271}
272
273/******************************************************************************
274* Schedule an email alarm, after validating the addresses and attachments.
275*/
276bool DcopHandler::scheduleEmail(const TQString& fromID, const TQString& addresses, const TQString& subject,
277 const TQString& message, const TQString& attachments,
278 const DateTime& start, int lateCancel, unsigned flags,
279 const KARecurrence& recurrence, int subRepeatInterval, int subRepeatCount)
280{
281 unsigned kaEventFlags = convertStartFlags(start, flags);
282 uint senderId = 0;
283 if (!fromID.isEmpty())
284 {
285 senderId = KAMail::identityUoid(fromID);
286 if (!senderId)
287 {
288 kdError(5950) << "DCOP call scheduleEmail(): unknown sender ID: " << fromID << endl;
289 return false;
290 }
291 }
292 EmailAddressList addrs;
293 TQString bad = KAMail::convertAddresses(addresses, addrs);
294 if (!bad.isEmpty())
295 {
296 kdError(5950) << "DCOP call scheduleEmail(): invalid email addresses: " << bad << endl;
297 return false;
298 }
299 if (addrs.isEmpty())
300 {
301 kdError(5950) << "DCOP call scheduleEmail(): no email address\n";
302 return false;
303 }
304 TQStringList atts;
305 bad = KAMail::convertAttachments(attachments, atts);
306 if (!bad.isEmpty())
307 {
308 kdError(5950) << "DCOP call scheduleEmail(): invalid email attachment: " << bad << endl;
309 return false;
310 }
311 return theApp()->scheduleEvent(KAEvent::EMAIL, message, start.dateTime(), lateCancel, kaEventFlags, TQt::black, TQt::black, TQFont(),
312 TQString(), -1, 0, recurrence, subRepeatInterval, subRepeatCount, senderId, addrs, subject, atts);
313}
314
315
316/******************************************************************************
317* Convert the start date/time string to a DateTime. The date/time string is in
318* the format YYYY-MM-DD[THH:MM[:SS]] or [T]HH:MM[:SS]
319*/
320DateTime DcopHandler::convertStartDateTime(const TQString& startDateTime)
321{
322 DateTime start;
323 if (startDateTime.length() > 10)
324 {
325 // Both a date and a time are specified
326 start = TQDateTime::fromString(startDateTime, TQt::ISODate);
327 }
328 else
329 {
330 // Check whether a time is specified
331 TQString t;
332 if (startDateTime[0] == 'T')
333 t = startDateTime.mid(1); // it's a time: remove the leading 'T'
334 else if (!startDateTime[2].isDigit())
335 t = startDateTime; // it's a time with no leading 'T'
336
337 if (t.isEmpty())
338 {
339 // It's a date
340 start = TQDate::fromString(startDateTime, TQt::ISODate);
341 }
342 else
343 {
344 // It's a time, so use today as the date
345 start.set(TQDate::currentDate(), TQTime::fromString(t, TQt::ISODate));
346 }
347 }
348 if (!start.isValid())
349 kdError(5950) << "DCOP call: invalid start date/time: " << startDateTime << endl;
350 return start;
351}
352
353/******************************************************************************
354* Convert the flag bits to KAEvent flag bits.
355*/
356unsigned DcopHandler::convertStartFlags(const DateTime& start, unsigned flags)
357{
358 unsigned kaEventFlags = 0;
359 if (flags & REPEAT_AT_LOGIN) kaEventFlags |= KAEvent::REPEAT_AT_LOGIN;
360 if (flags & BEEP) kaEventFlags |= KAEvent::BEEP;
361 if (flags & SPEAK) kaEventFlags |= KAEvent::SPEAK;
362 if (flags & CONFIRM_ACK) kaEventFlags |= KAEvent::CONFIRM_ACK;
363 if (flags & REPEAT_SOUND) kaEventFlags |= KAEvent::REPEAT_SOUND;
364 if (flags & AUTO_CLOSE) kaEventFlags |= KAEvent::AUTO_CLOSE;
365 if (flags & EMAIL_BCC) kaEventFlags |= KAEvent::EMAIL_BCC;
366 if (flags & SCRIPT) kaEventFlags |= KAEvent::SCRIPT;
367 if (flags & EXEC_IN_XTERM) kaEventFlags |= KAEvent::EXEC_IN_XTERM;
368 if (flags & SHOW_IN_KORG) kaEventFlags |= KAEvent::COPY_KORGANIZER;
369 if (flags & DISABLED) kaEventFlags |= KAEvent::DISABLED;
370 if (start.isDateOnly()) kaEventFlags |= KAEvent::ANY_TIME;
371 return kaEventFlags;
372}
373
374/******************************************************************************
375* Convert the background colour string to a TQColor.
376*/
377TQColor DcopHandler::convertBgColour(const TQString& bgColor)
378{
379 if (bgColor.isEmpty())
380 return Preferences::defaultBgColour();
381 TQColor bg(bgColor);
382 if (!bg.isValid())
383 kdError(5950) << "DCOP call: invalid background color: " << bgColor << endl;
384 return bg;
385}
386
387bool DcopHandler::convertRecurrence(DateTime& start, KARecurrence& recurrence,
388 const TQString& startDateTime, const TQString& icalRecurrence,
389 int& subRepeatInterval)
390{
391 start = convertStartDateTime(startDateTime);
392 if (!start.isValid())
393 return false;
394 if (!recurrence.set(icalRecurrence))
395 return false;
396 if (subRepeatInterval && recurrence.type() == KARecurrence::NO_RECUR)
397 {
398 subRepeatInterval = 0;
399 kdWarning(5950) << "DCOP call: no recurrence specified, so sub-repetition ignored" << endl;
400 }
401 return true;
402}
403
404bool DcopHandler::convertRecurrence(DateTime& start, KARecurrence& recurrence, const TQString& startDateTime,
405 int recurType, int recurInterval, int recurCount)
406{
407 start = convertStartDateTime(startDateTime);
408 if (!start.isValid())
409 return false;
410 return convertRecurrence(recurrence, start, recurType, recurInterval, recurCount, TQDateTime());
411}
412
413bool DcopHandler::convertRecurrence(DateTime& start, KARecurrence& recurrence, const TQString& startDateTime,
414 int recurType, int recurInterval, const TQString& endDateTime)
415{
416 start = convertStartDateTime(startDateTime);
417 if (!start.isValid())
418 return false;
419 TQDateTime end;
420 if (endDateTime.find('T') < 0)
421 {
422 if (!start.isDateOnly())
423 {
424 kdError(5950) << "DCOP call: alarm is date-only, but recurrence end is date/time" << endl;
425 return false;
426 }
427 end.setDate(TQDate::fromString(endDateTime, TQt::ISODate));
428 }
429 else
430 {
431 if (start.isDateOnly())
432 {
433 kdError(5950) << "DCOP call: alarm is timed, but recurrence end is date-only" << endl;
434 return false;
435 }
436 end = TQDateTime::fromString(endDateTime, TQt::ISODate);
437 }
438 if (!end.isValid())
439 {
440 kdError(5950) << "DCOP call: invalid recurrence end date/time: " << endDateTime << endl;
441 return false;
442 }
443 return convertRecurrence(recurrence, start, recurType, recurInterval, 0, end);
444}
445
446bool DcopHandler::convertRecurrence(KARecurrence& recurrence, const DateTime& start, int recurType,
447 int recurInterval, int recurCount, const TQDateTime& end)
448{
449 KARecurrence::Type type;
450 switch (recurType)
451 {
452 case MINUTELY: type = KARecurrence::MINUTELY; break;
453 case DAILY: type = KARecurrence::DAILY; break;
454 case WEEKLY: type = KARecurrence::WEEKLY; break;
455 case MONTHLY: type = KARecurrence::MONTHLY_DAY; break;
456 case YEARLY: type = KARecurrence::ANNUAL_DATE; break;
457 break;
458 default:
459 kdError(5950) << "DCOP call: invalid recurrence type: " << recurType << endl;
460 return false;
461 }
462 recurrence.set(type, recurInterval, recurCount, start, end);
463 return true;
464}
miscellaneous functions
the KAlarm application object
main application window