dcophandler.cpp
00001 /* 00002 * dcophandler.cpp - handler for DCOP calls by other applications 00003 * Program: kalarm 00004 * Copyright © 2002-2006,2008 by David Jarvie <djarvie@kde.org> 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License along 00017 * with this program; if not, write to the Free Software Foundation, Inc., 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include "kalarm.h" 00022 00023 #include <stdlib.h> 00024 00025 #include <kdebug.h> 00026 00027 #include "alarmcalendar.h" 00028 #include "daemon.h" 00029 #include "functions.h" 00030 #include "kalarmapp.h" 00031 #include "kamail.h" 00032 #include "karecurrence.h" 00033 #include "mainwindow.h" 00034 #include "preferences.h" 00035 #include "dcophandler.h" 00036 #include "dcophandler.moc" 00037 00038 static const char* DCOP_OBJECT_NAME = "request"; // DCOP name of KAlarm's request interface 00039 00040 00041 /*============================================================================= 00042 = DcopHandler 00043 = This class's function is to handle DCOP requests by other applications. 00044 =============================================================================*/ 00045 DcopHandler::DcopHandler() 00046 : DCOPObject(DCOP_OBJECT_NAME), 00047 TQWidget() 00048 { 00049 kdDebug(5950) << "DcopHandler::DcopHandler()\n"; 00050 } 00051 00052 00053 bool DcopHandler::cancelEvent(const TQString& url,const TQString& eventId) 00054 { 00055 return theApp()->deleteEvent(url, eventId); 00056 } 00057 00058 bool DcopHandler::triggerEvent(const TQString& url,const TQString& eventId) 00059 { 00060 return theApp()->triggerEvent(url, eventId); 00061 } 00062 00063 bool DcopHandler::scheduleMessage(const TQString& message, const TQString& startDateTime, int lateCancel, unsigned flags, 00064 const TQString& bgColor, const TQString& fgColor, const TQString& font, 00065 const KURL& audioFile, int reminderMins, const TQString& recurrence, 00066 int subRepeatInterval, int subRepeatCount) 00067 { 00068 DateTime start; 00069 KARecurrence recur; 00070 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval)) 00071 return false; 00072 return scheduleMessage(message, start, lateCancel, flags, bgColor, fgColor, font, audioFile, reminderMins, recur, subRepeatInterval, subRepeatCount); 00073 } 00074 00075 bool DcopHandler::scheduleMessage(const TQString& message, const TQString& startDateTime, int lateCancel, unsigned flags, 00076 const TQString& bgColor, const TQString& fgColor, const TQString& font, 00077 const KURL& audioFile, int reminderMins, 00078 int recurType, int recurInterval, int recurCount) 00079 { 00080 DateTime start; 00081 KARecurrence recur; 00082 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount)) 00083 return false; 00084 return scheduleMessage(message, start, lateCancel, flags, bgColor, fgColor, font, audioFile, reminderMins, recur); 00085 } 00086 00087 bool DcopHandler::scheduleMessage(const TQString& message, const TQString& startDateTime, int lateCancel, unsigned flags, 00088 const TQString& bgColor, const TQString& fgColor, const TQString& font, 00089 const KURL& audioFile, int reminderMins, 00090 int recurType, int recurInterval, const TQString& endDateTime) 00091 { 00092 DateTime start; 00093 KARecurrence recur; 00094 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime)) 00095 return false; 00096 return scheduleMessage(message, start, lateCancel, flags, bgColor, fgColor, font, audioFile, reminderMins, recur); 00097 } 00098 00099 bool DcopHandler::scheduleFile(const KURL& file, const TQString& startDateTime, int lateCancel, unsigned flags, const TQString& bgColor, 00100 const KURL& audioFile, int reminderMins, const TQString& recurrence, 00101 int subRepeatInterval, int subRepeatCount) 00102 { 00103 DateTime start; 00104 KARecurrence recur; 00105 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval)) 00106 return false; 00107 return scheduleFile(file, start, lateCancel, flags, bgColor, audioFile, reminderMins, recur, subRepeatInterval, subRepeatCount); 00108 } 00109 00110 bool DcopHandler::scheduleFile(const KURL& file, const TQString& startDateTime, int lateCancel, unsigned flags, const TQString& bgColor, 00111 const KURL& audioFile, int reminderMins, int recurType, int recurInterval, int recurCount) 00112 { 00113 DateTime start; 00114 KARecurrence recur; 00115 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount)) 00116 return false; 00117 return scheduleFile(file, start, lateCancel, flags, bgColor, audioFile, reminderMins, recur); 00118 } 00119 00120 bool DcopHandler::scheduleFile(const KURL& file, const TQString& startDateTime, int lateCancel, unsigned flags, const TQString& bgColor, 00121 const KURL& audioFile, int reminderMins, int recurType, int recurInterval, const TQString& endDateTime) 00122 { 00123 DateTime start; 00124 KARecurrence recur; 00125 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime)) 00126 return false; 00127 return scheduleFile(file, start, lateCancel, flags, bgColor, audioFile, reminderMins, recur); 00128 } 00129 00130 bool DcopHandler::scheduleCommand(const TQString& commandLine, const TQString& startDateTime, int lateCancel, unsigned flags, 00131 const TQString& recurrence, int subRepeatInterval, int subRepeatCount) 00132 { 00133 DateTime start; 00134 KARecurrence recur; 00135 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval)) 00136 return false; 00137 return scheduleCommand(commandLine, start, lateCancel, flags, recur, subRepeatInterval, subRepeatCount); 00138 } 00139 00140 bool DcopHandler::scheduleCommand(const TQString& commandLine, const TQString& startDateTime, int lateCancel, unsigned flags, 00141 int recurType, int recurInterval, int recurCount) 00142 { 00143 DateTime start = convertStartDateTime(startDateTime); 00144 if (!start.isValid()) 00145 return false; 00146 KARecurrence recur; 00147 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount)) 00148 return false; 00149 return scheduleCommand(commandLine, start, lateCancel, flags, recur); 00150 } 00151 00152 bool DcopHandler::scheduleCommand(const TQString& commandLine, const TQString& startDateTime, int lateCancel, unsigned flags, 00153 int recurType, int recurInterval, const TQString& endDateTime) 00154 { 00155 DateTime start; 00156 KARecurrence recur; 00157 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime)) 00158 return false; 00159 return scheduleCommand(commandLine, start, lateCancel, flags, recur); 00160 } 00161 00162 bool DcopHandler::scheduleEmail(const TQString& fromID, const TQString& addresses, const TQString& subject, const TQString& message, 00163 const TQString& attachments, const TQString& startDateTime, int lateCancel, unsigned flags, 00164 const TQString& recurrence, int subRepeatInterval, int subRepeatCount) 00165 { 00166 DateTime start; 00167 KARecurrence recur; 00168 if (!convertRecurrence(start, recur, startDateTime, recurrence, subRepeatInterval)) 00169 return false; 00170 return scheduleEmail(fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur, subRepeatInterval, subRepeatCount); 00171 } 00172 00173 bool DcopHandler::scheduleEmail(const TQString& fromID, const TQString& addresses, const TQString& subject, const TQString& message, 00174 const TQString& attachments, const TQString& startDateTime, int lateCancel, unsigned flags, 00175 int recurType, int recurInterval, int recurCount) 00176 { 00177 DateTime start; 00178 KARecurrence recur; 00179 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, recurCount)) 00180 return false; 00181 return scheduleEmail(fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur); 00182 } 00183 00184 bool DcopHandler::scheduleEmail(const TQString& fromID, const TQString& addresses, const TQString& subject, const TQString& message, 00185 const TQString& attachments, const TQString& startDateTime, int lateCancel, unsigned flags, 00186 int recurType, int recurInterval, const TQString& endDateTime) 00187 { 00188 DateTime start; 00189 KARecurrence recur; 00190 if (!convertRecurrence(start, recur, startDateTime, recurType, recurInterval, endDateTime)) 00191 return false; 00192 return scheduleEmail(fromID, addresses, subject, message, attachments, start, lateCancel, flags, recur); 00193 } 00194 00195 bool DcopHandler::edit(const TQString& eventID) 00196 { 00197 return KAlarm::edit(eventID); 00198 } 00199 00200 bool DcopHandler::editNew(const TQString& templateName) 00201 { 00202 return KAlarm::editNew(templateName); 00203 } 00204 00205 00206 /****************************************************************************** 00207 * Schedule a message alarm, after converting the parameters from strings. 00208 */ 00209 bool DcopHandler::scheduleMessage(const TQString& message, const DateTime& start, int lateCancel, unsigned flags, 00210 const TQString& bgColor, const TQString& fgColor, const TQString& fontStr, 00211 const KURL& audioFile, int reminderMins, const KARecurrence& recurrence, 00212 int subRepeatInterval, int subRepeatCount) 00213 { 00214 unsigned kaEventFlags = convertStartFlags(start, flags); 00215 TQColor bg = convertBgColour(bgColor); 00216 if (!bg.isValid()) 00217 return false; 00218 TQColor fg; 00219 if (fgColor.isEmpty()) 00220 fg = Preferences::defaultFgColour(); 00221 else 00222 { 00223 fg.setNamedColor(fgColor); 00224 if (!fg.isValid()) 00225 { 00226 kdError(5950) << "DCOP call: invalid foreground color: " << fgColor << endl; 00227 return false; 00228 } 00229 } 00230 TQFont font; 00231 if (fontStr.isEmpty()) 00232 kaEventFlags |= KAEvent::DEFAULT_FONT; 00233 else 00234 { 00235 if (!font.fromString(fontStr)) // N.B. this doesn't do good validation 00236 { 00237 kdError(5950) << "DCOP call: invalid font: " << fontStr << endl; 00238 return false; 00239 } 00240 } 00241 return theApp()->scheduleEvent(KAEvent::MESSAGE, message, start.dateTime(), lateCancel, kaEventFlags, bg, fg, font, 00242 audioFile.url(), -1, reminderMins, recurrence, subRepeatInterval, subRepeatCount); 00243 } 00244 00245 /****************************************************************************** 00246 * Schedule a file alarm, after converting the parameters from strings. 00247 */ 00248 bool DcopHandler::scheduleFile(const KURL& file, 00249 const DateTime& start, int lateCancel, unsigned flags, const TQString& bgColor, 00250 const KURL& audioFile, int reminderMins, const KARecurrence& recurrence, 00251 int subRepeatInterval, int subRepeatCount) 00252 { 00253 unsigned kaEventFlags = convertStartFlags(start, flags); 00254 TQColor bg = convertBgColour(bgColor); 00255 if (!bg.isValid()) 00256 return false; 00257 return theApp()->scheduleEvent(KAEvent::FILE, file.url(), start.dateTime(), lateCancel, kaEventFlags, bg, TQt::black, TQFont(), 00258 audioFile.url(), -1, reminderMins, recurrence, subRepeatInterval, subRepeatCount); 00259 } 00260 00261 /****************************************************************************** 00262 * Schedule a command alarm, after converting the parameters from strings. 00263 */ 00264 bool DcopHandler::scheduleCommand(const TQString& commandLine, 00265 const DateTime& start, int lateCancel, unsigned flags, 00266 const KARecurrence& recurrence, int subRepeatInterval, int subRepeatCount) 00267 { 00268 unsigned kaEventFlags = convertStartFlags(start, flags); 00269 return theApp()->scheduleEvent(KAEvent::COMMAND, commandLine, start.dateTime(), lateCancel, kaEventFlags, TQt::black, TQt::black, TQFont(), 00270 TQString(), -1, 0, recurrence, subRepeatInterval, subRepeatCount); 00271 } 00272 00273 /****************************************************************************** 00274 * Schedule an email alarm, after validating the addresses and attachments. 00275 */ 00276 bool DcopHandler::scheduleEmail(const TQString& fromID, const TQString& addresses, const TQString& subject, 00277 const TQString& message, const TQString& attachments, 00278 const DateTime& start, int lateCancel, unsigned flags, 00279 const KARecurrence& recurrence, int subRepeatInterval, int subRepeatCount) 00280 { 00281 unsigned kaEventFlags = convertStartFlags(start, flags); 00282 uint senderId = 0; 00283 if (!fromID.isEmpty()) 00284 { 00285 senderId = KAMail::identityUoid(fromID); 00286 if (!senderId) 00287 { 00288 kdError(5950) << "DCOP call scheduleEmail(): unknown sender ID: " << fromID << endl; 00289 return false; 00290 } 00291 } 00292 EmailAddressList addrs; 00293 TQString bad = KAMail::convertAddresses(addresses, addrs); 00294 if (!bad.isEmpty()) 00295 { 00296 kdError(5950) << "DCOP call scheduleEmail(): invalid email addresses: " << bad << endl; 00297 return false; 00298 } 00299 if (addrs.isEmpty()) 00300 { 00301 kdError(5950) << "DCOP call scheduleEmail(): no email address\n"; 00302 return false; 00303 } 00304 TQStringList atts; 00305 bad = KAMail::convertAttachments(attachments, atts); 00306 if (!bad.isEmpty()) 00307 { 00308 kdError(5950) << "DCOP call scheduleEmail(): invalid email attachment: " << bad << endl; 00309 return false; 00310 } 00311 return theApp()->scheduleEvent(KAEvent::EMAIL, message, start.dateTime(), lateCancel, kaEventFlags, TQt::black, TQt::black, TQFont(), 00312 TQString(), -1, 0, recurrence, subRepeatInterval, subRepeatCount, senderId, addrs, subject, atts); 00313 } 00314 00315 00316 /****************************************************************************** 00317 * Convert the start date/time string to a DateTime. The date/time string is in 00318 * the format YYYY-MM-DD[THH:MM[:SS]] or [T]HH:MM[:SS] 00319 */ 00320 DateTime DcopHandler::convertStartDateTime(const TQString& startDateTime) 00321 { 00322 DateTime start; 00323 if (startDateTime.length() > 10) 00324 { 00325 // Both a date and a time are specified 00326 start = TQDateTime::fromString(startDateTime, Qt::ISODate); 00327 } 00328 else 00329 { 00330 // Check whether a time is specified 00331 TQString t; 00332 if (startDateTime[0] == 'T') 00333 t = startDateTime.mid(1); // it's a time: remove the leading 'T' 00334 else if (!startDateTime[2].isDigit()) 00335 t = startDateTime; // it's a time with no leading 'T' 00336 00337 if (t.isEmpty()) 00338 { 00339 // It's a date 00340 start = TQDate::fromString(startDateTime, Qt::ISODate); 00341 } 00342 else 00343 { 00344 // It's a time, so use today as the date 00345 start.set(TQDate::currentDate(), TQTime::fromString(t, Qt::ISODate)); 00346 } 00347 } 00348 if (!start.isValid()) 00349 kdError(5950) << "DCOP call: invalid start date/time: " << startDateTime << endl; 00350 return start; 00351 } 00352 00353 /****************************************************************************** 00354 * Convert the flag bits to KAEvent flag bits. 00355 */ 00356 unsigned DcopHandler::convertStartFlags(const DateTime& start, unsigned flags) 00357 { 00358 unsigned kaEventFlags = 0; 00359 if (flags & REPEAT_AT_LOGIN) kaEventFlags |= KAEvent::REPEAT_AT_LOGIN; 00360 if (flags & BEEP) kaEventFlags |= KAEvent::BEEP; 00361 if (flags & SPEAK) kaEventFlags |= KAEvent::SPEAK; 00362 if (flags & CONFIRM_ACK) kaEventFlags |= KAEvent::CONFIRM_ACK; 00363 if (flags & REPEAT_SOUND) kaEventFlags |= KAEvent::REPEAT_SOUND; 00364 if (flags & AUTO_CLOSE) kaEventFlags |= KAEvent::AUTO_CLOSE; 00365 if (flags & EMAIL_BCC) kaEventFlags |= KAEvent::EMAIL_BCC; 00366 if (flags & SCRIPT) kaEventFlags |= KAEvent::SCRIPT; 00367 if (flags & EXEC_IN_XTERM) kaEventFlags |= KAEvent::EXEC_IN_XTERM; 00368 if (flags & SHOW_IN_KORG) kaEventFlags |= KAEvent::COPY_KORGANIZER; 00369 if (flags & DISABLED) kaEventFlags |= KAEvent::DISABLED; 00370 if (start.isDateOnly()) kaEventFlags |= KAEvent::ANY_TIME; 00371 return kaEventFlags; 00372 } 00373 00374 /****************************************************************************** 00375 * Convert the background colour string to a TQColor. 00376 */ 00377 TQColor DcopHandler::convertBgColour(const TQString& bgColor) 00378 { 00379 if (bgColor.isEmpty()) 00380 return Preferences::defaultBgColour(); 00381 TQColor bg(bgColor); 00382 if (!bg.isValid()) 00383 kdError(5950) << "DCOP call: invalid background color: " << bgColor << endl; 00384 return bg; 00385 } 00386 00387 bool DcopHandler::convertRecurrence(DateTime& start, KARecurrence& recurrence, 00388 const TQString& startDateTime, const TQString& icalRecurrence, 00389 int& subRepeatInterval) 00390 { 00391 start = convertStartDateTime(startDateTime); 00392 if (!start.isValid()) 00393 return false; 00394 if (!recurrence.set(icalRecurrence)) 00395 return false; 00396 if (subRepeatInterval && recurrence.type() == KARecurrence::NO_RECUR) 00397 { 00398 subRepeatInterval = 0; 00399 kdWarning(5950) << "DCOP call: no recurrence specified, so sub-repetition ignored" << endl; 00400 } 00401 return true; 00402 } 00403 00404 bool DcopHandler::convertRecurrence(DateTime& start, KARecurrence& recurrence, const TQString& startDateTime, 00405 int recurType, int recurInterval, int recurCount) 00406 { 00407 start = convertStartDateTime(startDateTime); 00408 if (!start.isValid()) 00409 return false; 00410 return convertRecurrence(recurrence, start, recurType, recurInterval, recurCount, TQDateTime()); 00411 } 00412 00413 bool DcopHandler::convertRecurrence(DateTime& start, KARecurrence& recurrence, const TQString& startDateTime, 00414 int recurType, int recurInterval, const TQString& endDateTime) 00415 { 00416 start = convertStartDateTime(startDateTime); 00417 if (!start.isValid()) 00418 return false; 00419 TQDateTime end; 00420 if (endDateTime.find('T') < 0) 00421 { 00422 if (!start.isDateOnly()) 00423 { 00424 kdError(5950) << "DCOP call: alarm is date-only, but recurrence end is date/time" << endl; 00425 return false; 00426 } 00427 end.setDate(TQDate::fromString(endDateTime, Qt::ISODate)); 00428 } 00429 else 00430 { 00431 if (start.isDateOnly()) 00432 { 00433 kdError(5950) << "DCOP call: alarm is timed, but recurrence end is date-only" << endl; 00434 return false; 00435 } 00436 end = TQDateTime::fromString(endDateTime, Qt::ISODate); 00437 } 00438 if (!end.isValid()) 00439 { 00440 kdError(5950) << "DCOP call: invalid recurrence end date/time: " << endDateTime << endl; 00441 return false; 00442 } 00443 return convertRecurrence(recurrence, start, recurType, recurInterval, 0, end); 00444 } 00445 00446 bool DcopHandler::convertRecurrence(KARecurrence& recurrence, const DateTime& start, int recurType, 00447 int recurInterval, int recurCount, const TQDateTime& end) 00448 { 00449 KARecurrence::Type type; 00450 switch (recurType) 00451 { 00452 case MINUTELY: type = KARecurrence::MINUTELY; break; 00453 case DAILY: type = KARecurrence::DAILY; break; 00454 case WEEKLY: type = KARecurrence::WEEKLY; break; 00455 case MONTHLY: type = KARecurrence::MONTHLY_DAY; break; 00456 case YEARLY: type = KARecurrence::ANNUAL_DATE; break; 00457 break; 00458 default: 00459 kdError(5950) << "DCOP call: invalid recurrence type: " << recurType << endl; 00460 return false; 00461 } 00462 recurrence.set(type, recurInterval, recurCount, start, end); 00463 return true; 00464 }