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 
38 static 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 =============================================================================*/
45 DcopHandler::DcopHandler()
46  : DCOPObject(DCOP_OBJECT_NAME),
47  TQWidget()
48 {
49  kdDebug(5950) << "DcopHandler::DcopHandler()\n";
50 }
51 
52 
53 bool DcopHandler::cancelEvent(const TQString& url,const TQString& eventId)
54 {
55  return theApp()->deleteEvent(url, eventId);
56 }
57 
58 bool DcopHandler::triggerEvent(const TQString& url,const TQString& eventId)
59 {
60  return theApp()->triggerEvent(url, eventId);
61 }
62 
63 bool 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 
75 bool 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 
87 bool 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 
99 bool 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 
110 bool 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 
120 bool 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 
130 bool 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 
140 bool 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 
152 bool 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 
162 bool 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 
173 bool 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 
184 bool 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 
195 bool DcopHandler::edit(const TQString& eventID)
196 {
197  return KAlarm::edit(eventID);
198 }
199 
200 bool 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 */
209 bool 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 */
248 bool 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 */
264 bool 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 */
276 bool 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 */
320 DateTime 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 */
356 unsigned 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 */
377 TQColor 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 
387 bool 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 
404 bool 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 
413 bool 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 
446 bool 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