00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kalarm.h"
00022
00023 #include <stdlib.h>
00024 #include <ctype.h>
00025 #include <iostream>
00026
00027 #include <qobjectlist.h>
00028 #include <qtimer.h>
00029 #include <qregexp.h>
00030 #include <qfile.h>
00031
00032 #include <kcmdlineargs.h>
00033 #include <klocale.h>
00034 #include <kstandarddirs.h>
00035 #include <kconfig.h>
00036 #include <kaboutdata.h>
00037 #include <dcopclient.h>
00038 #include <kprocess.h>
00039 #include <ktempfile.h>
00040 #include <kfileitem.h>
00041 #include <kstdguiitem.h>
00042 #include <ktrader.h>
00043 #include <kstaticdeleter.h>
00044 #include <kdebug.h>
00045
00046 #include <libkcal/calformat.h>
00047
00048 #include <kalarmd/clientinfo.h>
00049
00050 #include "alarmcalendar.h"
00051 #include "alarmlistview.h"
00052 #include "editdlg.h"
00053 #include "daemon.h"
00054 #include "dcophandler.h"
00055 #include "functions.h"
00056 #include "kamail.h"
00057 #include "karecurrence.h"
00058 #include "mainwindow.h"
00059 #include "messagebox.h"
00060 #include "messagewin.h"
00061 #include "preferences.h"
00062 #include "prefdlg.h"
00063 #include "shellprocess.h"
00064 #include "traywindow.h"
00065 #include "kalarmapp.moc"
00066
00067 #include <netwm.h>
00068
00069
00070 static bool convWakeTime(const QCString& timeParam, QDateTime&, bool& noTime);
00071 static bool convInterval(const QCString& timeParam, KARecurrence::Type&, int& timeInterval, bool allowMonthYear = false);
00072
00073
00074
00075
00076
00077
00078 static inline int maxLateness(int lateCancel)
00079 {
00080 static const int LATENESS_LEEWAY = 5;
00081 int lc = (lateCancel >= 1) ? (lateCancel - 1)*60 : 0;
00082 return Daemon::maxTimeSinceCheck() + LATENESS_LEEWAY + lc;
00083 }
00084
00085
00086 KAlarmApp* KAlarmApp::theInstance = 0;
00087 int KAlarmApp::mActiveCount = 0;
00088 int KAlarmApp::mFatalError = 0;
00089 QString KAlarmApp::mFatalMessage;
00090
00091
00092
00093
00094
00095 KAlarmApp::KAlarmApp()
00096 : KUniqueApplication(),
00097 mInitialised(false),
00098 mDcopHandler(new DcopHandler()),
00099 #ifdef OLD_DCOP
00100 mDcopHandlerOld(new DcopHandlerOld()),
00101 #endif
00102 mTrayWindow(0),
00103 mPendingQuit(false),
00104 mProcessingQueue(false),
00105 mCheckingSystemTray(false),
00106 mSessionClosingDown(false),
00107 mRefreshExpiredAlarms(false),
00108 mSpeechEnabled(false)
00109 {
00110 Preferences::initialise();
00111 Preferences::connect(SIGNAL(preferencesChanged()), this, SLOT(slotPreferencesChanged()));
00112 KCal::CalFormat::setApplication(aboutData()->programName(), AlarmCalendar::icalProductId());
00113 KARecurrence::setDefaultFeb29Type(Preferences::defaultFeb29Type());
00114
00115
00116 mHaveSystemTray = true;
00117
00118 if (AlarmCalendar::initialiseCalendars())
00119 {
00120 connect(AlarmCalendar::expiredCalendar(), SIGNAL(purged()), SLOT(slotExpiredPurged()));
00121
00122 KConfig* config = kapp->config();
00123 config->setGroup(QString::fromLatin1("General"));
00124 mNoSystemTray = config->readBoolEntry(QString::fromLatin1("NoSystemTray"), false);
00125 mSavedNoSystemTray = mNoSystemTray;
00126 mOldRunInSystemTray = wantRunInSystemTray();
00127 mDisableAlarmsIfStopped = mOldRunInSystemTray && !mNoSystemTray && Preferences::disableAlarmsIfStopped();
00128 mStartOfDay = Preferences::startOfDay();
00129 if (Preferences::hasStartOfDayChanged())
00130 mStartOfDay.setHMS(100,0,0);
00131 DateTime::setStartOfDay(mStartOfDay);
00132 mPrefsExpiredColour = Preferences::expiredColour();
00133 mPrefsExpiredKeepDays = Preferences::expiredKeepDays();
00134 }
00135
00136
00137 mSpeechEnabled = (KTrader::self()->query("DCOP/Text-to-Speech", "Name == 'KTTSD'").count() > 0);
00138 if (!mSpeechEnabled)
00139 kdDebug(5950) << "KAlarmApp::KAlarmApp(): speech synthesis disabled (KTTSD not found)" << endl;
00140
00141 QString korg = QString::fromLatin1("korganizer");
00142 mKOrganizerEnabled = !locate("exe", korg).isNull() || !KStandardDirs::findExe(korg).isNull();
00143 if (!mKOrganizerEnabled)
00144 kdDebug(5950) << "KAlarmApp::KAlarmApp(): KOrganizer options disabled (KOrganizer not found)" << endl;
00145 }
00146
00147
00148
00149 KAlarmApp::~KAlarmApp()
00150 {
00151 while (!mCommandProcesses.isEmpty())
00152 {
00153 ProcData* pd = mCommandProcesses.first();
00154 mCommandProcesses.pop_front();
00155 delete pd;
00156 }
00157 AlarmCalendar::terminateCalendars();
00158 }
00159
00160
00161
00162
00163
00164 KAlarmApp* KAlarmApp::getInstance()
00165 {
00166 if (!theInstance)
00167 {
00168 theInstance = new KAlarmApp;
00169
00170 if (mFatalError)
00171 theInstance->quitFatal();
00172 else
00173 {
00174
00175 Daemon::initialise();
00176 }
00177 }
00178 return theInstance;
00179 }
00180
00181
00182
00183
00184 bool KAlarmApp::restoreSession()
00185 {
00186 if (!isRestored())
00187 return false;
00188 if (mFatalError)
00189 {
00190 quitFatal();
00191 return false;
00192 }
00193
00194
00195 kdDebug(5950) << "KAlarmApp::restoreSession(): Restoring\n";
00196 ++mActiveCount;
00197 if (!initCheck(true))
00198 {
00199 --mActiveCount;
00200 quitIf(1, true);
00201 return true;
00202 }
00203 MainWindow* trayParent = 0;
00204 for (int i = 1; KMainWindow::canBeRestored(i); ++i)
00205 {
00206 QString type = KMainWindow::classNameOfToplevel(i);
00207 if (type == QString::fromLatin1("MainWindow"))
00208 {
00209 MainWindow* win = MainWindow::create(true);
00210 win->restore(i, false);
00211 if (win->isHiddenTrayParent())
00212 trayParent = win;
00213 else
00214 win->show();
00215 }
00216 else if (type == QString::fromLatin1("MessageWin"))
00217 {
00218 MessageWin* win = new MessageWin;
00219 win->restore(i, false);
00220 if (win->isValid())
00221 win->show();
00222 else
00223 delete win;
00224 }
00225 }
00226 initCheck();
00227
00228
00229
00230 if (Preferences::autostartTrayIcon()
00231 || MainWindow::count() && wantRunInSystemTray())
00232 {
00233 displayTrayIcon(true, trayParent);
00234
00235
00236 if (trayParent)
00237 trayParent->hide();
00238 }
00239
00240 --mActiveCount;
00241 quitIf(0);
00242 return true;
00243 }
00244
00245
00246
00247
00248
00249 int KAlarmApp::newInstance()
00250 {
00251 kdDebug(5950)<<"KAlarmApp::newInstance()\n";
00252 if (mFatalError)
00253 {
00254 quitFatal();
00255 return 1;
00256 }
00257 ++mActiveCount;
00258 int exitCode = 0;
00259 static bool firstInstance = true;
00260 bool dontRedisplay = false;
00261 if (!firstInstance || !isRestored())
00262 {
00263 QString usage;
00264 KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
00265
00266
00267
00268
00269
00270
00271
00272 do
00273 {
00274 #define USAGE(message) { usage = message; break; }
00275 if (args->isSet("stop"))
00276 {
00277
00278 kdDebug(5950)<<"KAlarmApp::newInstance(): stop\n";
00279 args->clear();
00280 if (!Daemon::stop())
00281 {
00282 exitCode = 1;
00283 break;
00284 }
00285 dontRedisplay = true;
00286 }
00287 else
00288 if (args->isSet("reset"))
00289 {
00290
00291
00292 kdDebug(5950)<<"KAlarmApp::newInstance(): reset\n";
00293 args->clear();
00294 Daemon::reset();
00295 dontRedisplay = true;
00296 }
00297 else
00298 if (args->isSet("tray"))
00299 {
00300
00301 kdDebug(5950)<<"KAlarmApp::newInstance(): tray\n";
00302 args->clear();
00303 if (!mHaveSystemTray)
00304 {
00305 exitCode = 1;
00306 break;
00307 }
00308 if (!initCheck())
00309 {
00310 exitCode = 1;
00311 break;
00312 }
00313 if (!displayTrayIcon(true))
00314 {
00315 exitCode = 1;
00316 break;
00317 }
00318 }
00319 else
00320 if (args->isSet("handleEvent") || args->isSet("triggerEvent") || args->isSet("cancelEvent") || args->isSet("calendarURL"))
00321 {
00322
00323 kdDebug(5950)<<"KAlarmApp::newInstance(): handle event\n";
00324 EventFunc function = EVENT_HANDLE;
00325 int count = 0;
00326 const char* option = 0;
00327 if (args->isSet("handleEvent")) { function = EVENT_HANDLE; option = "handleEvent"; ++count; }
00328 if (args->isSet("triggerEvent")) { function = EVENT_TRIGGER; option = "triggerEvent"; ++count; }
00329 if (args->isSet("cancelEvent")) { function = EVENT_CANCEL; option = "cancelEvent"; ++count; }
00330 if (!count)
00331 USAGE(i18n("%1 requires %2, %3 or %4").arg(QString::fromLatin1("--calendarURL")).arg(QString::fromLatin1("--handleEvent")).arg(QString::fromLatin1("--triggerEvent")).arg(QString::fromLatin1("--cancelEvent")))
00332 if (count > 1)
00333 USAGE(i18n("%1, %2, %3 mutually exclusive").arg(QString::fromLatin1("--handleEvent")).arg(QString::fromLatin1("--triggerEvent")).arg(QString::fromLatin1("--cancelEvent")));
00334 if (!initCheck(true))
00335 {
00336 exitCode = 1;
00337 break;
00338 }
00339 if (args->isSet("calendarURL"))
00340 {
00341 QString calendarUrl = args->getOption("calendarURL");
00342 if (KURL(calendarUrl).url() != AlarmCalendar::activeCalendar()->urlString())
00343 USAGE(i18n("%1: wrong calendar file").arg(QString::fromLatin1("--calendarURL")))
00344 }
00345 QString eventID = args->getOption(option);
00346 args->clear();
00347 if (eventID.startsWith(QString::fromLatin1("ad:")))
00348 {
00349
00350 eventID = eventID.mid(3);
00351 Daemon::queueEvent(eventID);
00352 }
00353 setUpDcop();
00354 if (!handleEvent(eventID, function))
00355 {
00356 exitCode = 1;
00357 break;
00358 }
00359 }
00360 else
00361 if (args->isSet("edit"))
00362 {
00363 QString eventID = args->getOption("edit");
00364 if (!initCheck())
00365 {
00366 exitCode = 1;
00367 break;
00368 }
00369 if (!KAlarm::edit(eventID))
00370 {
00371 USAGE(i18n("%1: Event %2 not found, or not editable").arg(QString::fromLatin1("--edit")).arg(eventID))
00372 exitCode = 1;
00373 break;
00374 }
00375 }
00376 else
00377 if (args->isSet("edit-new") || args->isSet("edit-new-preset"))
00378 {
00379 QString templ;
00380 if (args->isSet("edit-new-preset"))
00381 templ = args->getOption("edit-new-preset");
00382 if (!initCheck())
00383 {
00384 exitCode = 1;
00385 break;
00386 }
00387 KAlarm::editNew(templ);
00388 }
00389 else
00390 if (args->isSet("file") || args->isSet("exec") || args->isSet("mail") || args->count())
00391 {
00392
00393 KAEvent::Action action = KAEvent::MESSAGE;
00394 QCString alMessage;
00395 uint alFromID = 0;
00396 EmailAddressList alAddresses;
00397 QStringList alAttachments;
00398 QCString alSubject;
00399 if (args->isSet("file"))
00400 {
00401 kdDebug(5950)<<"KAlarmApp::newInstance(): file\n";
00402 if (args->isSet("exec"))
00403 USAGE(i18n("%1 incompatible with %2").arg(QString::fromLatin1("--exec")).arg(QString::fromLatin1("--file")))
00404 if (args->isSet("mail"))
00405 USAGE(i18n("%1 incompatible with %2").arg(QString::fromLatin1("--mail")).arg(QString::fromLatin1("--file")))
00406 if (args->count())
00407 USAGE(i18n("message incompatible with %1").arg(QString::fromLatin1("--file")))
00408 alMessage = args->getOption("file");
00409 action = KAEvent::FILE;
00410 }
00411 else if (args->isSet("exec"))
00412 {
00413 kdDebug(5950)<<"KAlarmApp::newInstance(): exec\n";
00414 if (args->isSet("mail"))
00415 USAGE(i18n("%1 incompatible with %2").arg(QString::fromLatin1("--mail")).arg(QString::fromLatin1("--exec")))
00416 alMessage = args->getOption("exec");
00417 int n = args->count();
00418 for (int i = 0; i < n; ++i)
00419 {
00420 alMessage += ' ';
00421 alMessage += args->arg(i);
00422 }
00423 action = KAEvent::COMMAND;
00424 }
00425 else if (args->isSet("mail"))
00426 {
00427 kdDebug(5950)<<"KAlarmApp::newInstance(): mail\n";
00428 if (args->isSet("subject"))
00429 alSubject = args->getOption("subject");
00430 if (args->isSet("from-id"))
00431 alFromID = KAMail::identityUoid(args->getOption("from-id"));
00432 QCStringList params = args->getOptionList("mail");
00433 for (QCStringList::Iterator i = params.begin(); i != params.end(); ++i)
00434 {
00435 QString addr = QString::fromLocal8Bit(*i);
00436 if (!KAMail::checkAddress(addr))
00437 USAGE(i18n("%1: invalid email address").arg(QString::fromLatin1("--mail")))
00438 alAddresses += KCal::Person(QString::null, addr);
00439 }
00440 params = args->getOptionList("attach");
00441 for (QCStringList::Iterator i = params.begin(); i != params.end(); ++i)
00442 alAttachments += QString::fromLocal8Bit(*i);
00443 alMessage = args->arg(0);
00444 action = KAEvent::EMAIL;
00445 }
00446 else
00447 {
00448 kdDebug(5950)<<"KAlarmApp::newInstance(): message\n";
00449 alMessage = args->arg(0);
00450 }
00451
00452 if (action != KAEvent::EMAIL)
00453 {
00454 if (args->isSet("subject"))
00455 USAGE(i18n("%1 requires %2").arg(QString::fromLatin1("--subject")).arg(QString::fromLatin1("--mail")))
00456 if (args->isSet("from-id"))
00457 USAGE(i18n("%1 requires %2").arg(QString::fromLatin1("--from-id")).arg(QString::fromLatin1("--mail")))
00458 if (args->isSet("attach"))
00459 USAGE(i18n("%1 requires %2").arg(QString::fromLatin1("--attach")).arg(QString::fromLatin1("--mail")))
00460 if (args->isSet("bcc"))
00461 USAGE(i18n("%1 requires %2").arg(QString::fromLatin1("--bcc")).arg(QString::fromLatin1("--mail")))
00462 }
00463
00464 bool alarmNoTime = false;
00465 QDateTime alarmTime, endTime;
00466 QColor bgColour = Preferences::defaultBgColour();
00467 QColor fgColour = Preferences::defaultFgColour();
00468 KARecurrence recurrence;
00469 int repeatCount = 0;
00470 int repeatInterval = 0;
00471 if (args->isSet("color"))
00472 {
00473
00474 QCString colourText = args->getOption("color");
00475 if (static_cast<const char*>(colourText)[0] == '0'
00476 && tolower(static_cast<const char*>(colourText)[1]) == 'x')
00477 colourText.replace(0, 2, "#");
00478 bgColour.setNamedColor(colourText);
00479 if (!bgColour.isValid())
00480 USAGE(i18n("Invalid %1 parameter").arg(QString::fromLatin1("--color")))
00481 }
00482 if (args->isSet("colorfg"))
00483 {
00484
00485 QCString colourText = args->getOption("colorfg");
00486 if (static_cast<const char*>(colourText)[0] == '0'
00487 && tolower(static_cast<const char*>(colourText)[1]) == 'x')
00488 colourText.replace(0, 2, "#");
00489 fgColour.setNamedColor(colourText);
00490 if (!fgColour.isValid())
00491 USAGE(i18n("Invalid %1 parameter").arg(QString::fromLatin1("--colorfg")))
00492 }
00493
00494 if (args->isSet("time"))
00495 {
00496 QCString dateTime = args->getOption("time");
00497 if (!convWakeTime(dateTime, alarmTime, alarmNoTime))
00498 USAGE(i18n("Invalid %1 parameter").arg(QString::fromLatin1("--time")))
00499 }
00500 else
00501 alarmTime = QDateTime::currentDateTime();
00502
00503 bool haveRecurrence = args->isSet("recurrence");
00504 if (haveRecurrence)
00505 {
00506 if (args->isSet("login"))
00507 USAGE(i18n("%1 incompatible with %2").arg(QString::fromLatin1("--login")).arg(QString::fromLatin1("--recurrence")))
00508 if (args->isSet("until"))
00509 USAGE(i18n("%1 incompatible with %2").arg(QString::fromLatin1("--until")).arg(QString::fromLatin1("--recurrence")))
00510 QCString rule = args->getOption("recurrence");
00511 recurrence.set(QString::fromLocal8Bit(static_cast<const char*>(rule)));
00512 }
00513 if (args->isSet("interval"))
00514 {
00515
00516 int count;
00517 if (args->isSet("login"))
00518 USAGE(i18n("%1 incompatible with %2").arg(QString::fromLatin1("--login")).arg(QString::fromLatin1("--interval")))
00519 bool ok;
00520 if (args->isSet("repeat"))
00521 {
00522 count = args->getOption("repeat").toInt(&ok);
00523 if (!ok || !count || count < -1 || (count < 0 && haveRecurrence))
00524 USAGE(i18n("Invalid %1 parameter").arg(QString::fromLatin1("--repeat")))
00525 }
00526 else if (haveRecurrence)
00527 USAGE(i18n("%1 requires %2").arg(QString::fromLatin1("--interval")).arg(QString::fromLatin1("--repeat")))
00528 else if (args->isSet("until"))
00529 {
00530 count = 0;
00531 QCString dateTime = args->getOption("until");
00532 if (!convWakeTime(dateTime, endTime, alarmNoTime))
00533 USAGE(i18n("Invalid %1 parameter").arg(QString::fromLatin1("--until")))
00534 if (endTime < alarmTime)
00535 USAGE(i18n("%1 earlier than %2").arg(QString::fromLatin1("--until")).arg(QString::fromLatin1("--time")))
00536 }
00537 else
00538 count = -1;
00539
00540
00541 int interval;
00542 KARecurrence::Type recurType;
00543 if (!convInterval(args->getOption("interval"), recurType, interval, !haveRecurrence)
00544 || interval < 0)
00545 USAGE(i18n("Invalid %1 parameter").arg(QString::fromLatin1("--interval")))
00546 if (alarmNoTime && recurType == KARecurrence::MINUTELY)
00547 USAGE(i18n("Invalid %1 parameter for date-only alarm").arg(QString::fromLatin1("--interval")))
00548
00549 if (haveRecurrence)
00550 {
00551
00552 int longestInterval = recurrence.longestInterval();
00553 if (count * interval > longestInterval)
00554 USAGE(i18n("Invalid %1 and %2 parameters: repetition is longer than %3 interval").arg(QString::fromLatin1("--interval")).arg(QString::fromLatin1("--repeat")).arg(QString::fromLatin1("--recurrence")));
00555 repeatCount = count;
00556 repeatInterval = interval;
00557 }
00558 else
00559 {
00560
00561
00562 recurrence.set(recurType, interval, count, DateTime(alarmTime, alarmNoTime), endTime);
00563 }
00564 }
00565 else
00566 {
00567 if (args->isSet("repeat"))
00568 USAGE(i18n("%1 requires %2").arg(QString::fromLatin1("--repeat")).arg(QString::fromLatin1("--interval")))
00569 if (args->isSet("until"))
00570 USAGE(i18n("%1 requires %2").arg(QString::fromLatin1("--until")).arg(QString::fromLatin1("--interval")))
00571 }
00572
00573 QCString audioFile;
00574 float audioVolume = -1;
00575 #ifdef WITHOUT_ARTS
00576 bool audioRepeat = false;
00577 #else
00578 bool audioRepeat = args->isSet("play-repeat");
00579 #endif
00580 if (audioRepeat || args->isSet("play"))
00581 {
00582
00583 if (audioRepeat && args->isSet("play"))
00584 USAGE(i18n("%1 incompatible with %2").arg(QString::fromLatin1("--play")).arg(QString::fromLatin1("--play-repeat")))
00585 if (args->isSet("beep"))
00586 USAGE(i18n("%1 incompatible with %2").arg(QString::fromLatin1("--beep")).arg(QString::fromLatin1(audioRepeat ? "--play-repeat" : "--play")))
00587 if (args->isSet("speak"))
00588 USAGE(i18n("%1 incompatible with %2").arg(QString::fromLatin1("--speak")).arg(QString::fromLatin1(audioRepeat ? "--play-repeat" : "--play")))
00589 audioFile = args->getOption(audioRepeat ? "play-repeat" : "play");
00590 #ifndef WITHOUT_ARTS
00591 if (args->isSet("volume"))
00592 {
00593 bool ok;
00594 int volumepc = args->getOption("volume").toInt(&ok);
00595 if (!ok || volumepc < 0 || volumepc > 100)
00596 USAGE(i18n("Invalid %1 parameter").arg(QString::fromLatin1("--volume")))
00597 audioVolume = static_cast<float>(volumepc) / 100;
00598 }
00599 #endif
00600 }
00601 #ifndef WITHOUT_ARTS
00602 else if (args->isSet("volume"))
00603 USAGE(i18n("%1 requires %2 or %3").arg(QString::fromLatin1("--volume")).arg(QString::fromLatin1("--play")).arg(QString::fromLatin1("--play-repeat")))
00604 #endif
00605 if (args->isSet("speak"))
00606 {
00607 if (args->isSet("beep"))
00608 USAGE(i18n("%1 incompatible with %2").arg(QString::fromLatin1("--beep")).arg(QString::fromLatin1("--speak")))
00609 if (!mSpeechEnabled)
00610 USAGE(i18n("%1 requires speech synthesis to be configured using KTTSD").arg(QString::fromLatin1("--speak")))
00611 }
00612 int reminderMinutes = 0;
00613 bool onceOnly = args->isSet("reminder-once");
00614 if (args->isSet("reminder") || onceOnly)
00615 {
00616
00617 if (onceOnly && args->isSet("reminder"))
00618 USAGE(i18n("%1 incompatible with %2").arg(QString::fromLatin1("--reminder")).arg(QString::fromLatin1("--reminder-once")))
00619 QString opt = onceOnly ? QString::fromLatin1("--reminder-once") : QString::fromLatin1("--reminder");
00620 if (args->isSet("exec"))
00621 USAGE(i18n("%1 incompatible with %2").arg(opt).arg(QString::fromLatin1("--exec")))
00622 if (args->isSet("mail"))
00623 USAGE(i18n("%1 incompatible with %2").arg(opt).arg(QString::fromLatin1("--mail")))
00624 KARecurrence::Type recurType;
00625 QString optval = args->getOption(onceOnly ? "reminder-once" : "reminder");
00626 if (!convInterval(args->getOption(onceOnly ? "reminder-once" : "reminder"), recurType, reminderMinutes))
00627 USAGE(i18n("Invalid %1 parameter").arg(opt))
00628 if (recurType == KARecurrence::MINUTELY && alarmNoTime)
00629 USAGE(i18n("Invalid %1 parameter for date-only alarm").arg(opt))
00630 }
00631
00632 int lateCancel = 0;
00633 if (args->isSet("late-cancel"))
00634 {
00635 KARecurrence::Type recurType;
00636 bool ok = convInterval(args->getOption("late-cancel"), recurType, lateCancel);
00637 if (!ok || lateCancel <= 0)
00638 USAGE(i18n("Invalid %1 parameter").arg(QString::fromLatin1("late-cancel")))
00639 }
00640 else if (args->isSet("auto-close"))
00641 USAGE(i18n("%1 requires %2").arg(QString::fromLatin1("--auto-close")).arg(QString::fromLatin1("--late-cancel")))
00642
00643 int flags = KAEvent::DEFAULT_FONT;
00644 if (args->isSet("ack-confirm"))
00645 flags |= KAEvent::CONFIRM_ACK;
00646 if (args->isSet("auto-close"))
00647 flags |= KAEvent::AUTO_CLOSE;
00648 if (args->isSet("beep"))
00649 flags |= KAEvent::BEEP;
00650 if (args->isSet("speak"))
00651 flags |= KAEvent::SPEAK;
00652 if (args->isSet("korganizer"))
00653 flags |= KAEvent::COPY_KORGANIZER;
00654 if (args->isSet("disable"))
00655 flags |= KAEvent::DISABLED;
00656 if (audioRepeat)
00657 flags |= KAEvent::REPEAT_SOUND;
00658 if (args->isSet("login"))
00659 flags |= KAEvent::REPEAT_AT_LOGIN;
00660 if (args->isSet("bcc"))
00661 flags |= KAEvent::EMAIL_BCC;
00662 if (alarmNoTime)
00663 flags |= KAEvent::ANY_TIME;
00664 args->clear();
00665
00666
00667 if (!initCheck())
00668 {
00669 exitCode = 1;
00670 break;
00671 }
00672 if (!scheduleEvent(action, alMessage, alarmTime, lateCancel, flags, bgColour, fgColour, QFont(), audioFile,
00673 audioVolume, reminderMinutes, recurrence, repeatInterval, repeatCount,
00674 alFromID, alAddresses, alSubject, alAttachments))
00675 {
00676 exitCode = 1;
00677 break;
00678 }
00679 }
00680 else
00681 {
00682
00683 kdDebug(5950)<<"KAlarmApp::newInstance(): interactive\n";
00684 if (args->isSet("ack-confirm"))
00685 usage += QString::fromLatin1("--ack-confirm ");
00686 if (args->isSet("attach"))
00687 usage += QString::fromLatin1("--attach ");
00688 if (args->isSet("auto-close"))
00689 usage += QString::fromLatin1("--auto-close ");
00690 if (args->isSet("bcc"))
00691 usage += QString::fromLatin1("--bcc ");
00692 if (args->isSet("beep"))
00693 usage += QString::fromLatin1("--beep ");
00694 if (args->isSet("color"))
00695 usage += QString::fromLatin1("--color ");
00696 if (args->isSet("colorfg"))
00697 usage += QString::fromLatin1("--colorfg ");
00698 if (args->isSet("disable"))
00699 usage += QString::fromLatin1("--disable ");
00700 if (args->isSet("from-id"))
00701 usage += QString::fromLatin1("--from-id ");
00702 if (args->isSet("korganizer"))
00703 usage += QString::fromLatin1("--korganizer ");
00704 if (args->isSet("late-cancel"))
00705 usage += QString::fromLatin1("--late-cancel ");
00706 if (args->isSet("login"))
00707 usage += QString::fromLatin1("--login ");
00708 if (args->isSet("play"))
00709 usage += QString::fromLatin1("--play ");
00710 #ifndef WITHOUT_ARTS
00711 if (args->isSet("play-repeat"))
00712 usage += QString::fromLatin1("--play-repeat ");
00713 #endif
00714 if (args->isSet("reminder"))
00715 usage += QString::fromLatin1("--reminder ");
00716 if (args->isSet("reminder-once"))
00717 usage += QString::fromLatin1("--reminder-once ");
00718 if (args->isSet("speak"))
00719 usage += QString::fromLatin1("--speak ");
00720 if (args->isSet("subject"))
00721 usage += QString::fromLatin1("--subject ");
00722 if (args->isSet("time"))
00723 usage += QString::fromLatin1("--time ");
00724 #ifndef WITHOUT_ARTS
00725 if (args->isSet("volume"))
00726 usage += QString::fromLatin1("--volume ");
00727 #endif
00728 if (!usage.isEmpty())
00729 {
00730 usage += i18n(": option(s) only valid with a message/%1/%2").arg(QString::fromLatin1("--file")).arg(QString::fromLatin1("--exec"));
00731 break;
00732 }
00733
00734 args->clear();
00735
00736
00737
00738
00739
00740 if (!initCheck(true))
00741 {
00742 exitCode = 1;
00743 break;
00744 }
00745
00746 (MainWindow::create())->show();
00747 }
00748 } while (0);
00749
00750 if (!usage.isEmpty())
00751 {
00752
00753
00754 std::cerr << usage.local8Bit().data()
00755 << i18n("\nUse --help to get a list of available command line options.\n").local8Bit().data();
00756 exitCode = 1;
00757 }
00758 }
00759 if (firstInstance && !dontRedisplay && !exitCode)
00760 redisplayAlarms();
00761
00762 --mActiveCount;
00763 firstInstance = false;
00764
00765
00766
00767
00768 quitIf(exitCode);
00769 return exitCode;
00770 }
00771
00772
00773
00774
00775 void KAlarmApp::quitIf(int exitCode, bool force)
00776 {
00777 if (force)
00778 {
00779
00780 MainWindow::closeAll();
00781 displayTrayIcon(false);
00782 if (MessageWin::instanceCount())
00783 return;
00784 }
00785 else
00786 {
00787
00788 mPendingQuit = false;
00789 if (mActiveCount > 0 || MessageWin::instanceCount())
00790 return;
00791 int mwcount = MainWindow::count();
00792 MainWindow* mw = mwcount ? MainWindow::firstWindow() : 0;
00793 if (mwcount > 1 || mwcount && (!mw->isHidden() || !mw->isTrayParent()))
00794 return;
00795
00796 if (mTrayWindow)
00797 {
00798
00799
00800 if (checkSystemTray())
00801 return;
00802 }
00803 if (!mDcopQueue.isEmpty() || !mCommandProcesses.isEmpty())
00804 {
00805
00806 mPendingQuit = true;
00807 mPendingQuitCode = exitCode;
00808 return;
00809 }
00810 }
00811
00812
00813 kdDebug(5950) << "KAlarmApp::quitIf(" << exitCode << "): quitting" << endl;
00814 exit(exitCode);
00815 }
00816
00817
00818
00819
00820
00821
00822 void KAlarmApp::doQuit(QWidget* parent)
00823 {
00824 kdDebug(5950) << "KAlarmApp::doQuit()\n";
00825 if (mDisableAlarmsIfStopped
00826 && MessageBox::warningContinueCancel(parent, KMessageBox::Cancel,
00827 i18n("Quitting will disable alarms\n(once any alarm message windows are closed)."),
00828 QString::null, KStdGuiItem::quit(), Preferences::QUIT_WARN
00829 ) != KMessageBox::Yes)
00830 return;
00831 quitIf(0, true);
00832 }
00833
00834
00835
00836
00837 void KAlarmApp::commitData(QSessionManager& sm)
00838 {
00839 mSessionClosingDown = true;
00840 KUniqueApplication::commitData(sm);
00841 mSessionClosingDown = false;
00842 }
00843
00844
00845
00846
00847
00848 void KAlarmApp::displayFatalError(const QString& message)
00849 {
00850 if (!mFatalError)
00851 {
00852 mFatalError = 1;
00853 mFatalMessage = message;
00854 if (theInstance)
00855 QTimer::singleShot(0, theInstance, SLOT(quitFatal()));
00856 }
00857 }
00858
00859
00860
00861
00862 void KAlarmApp::quitFatal()
00863 {
00864 switch (mFatalError)
00865 {
00866 case 0:
00867 case 2:
00868 return;
00869 case 1:
00870 mFatalError = 2;
00871 KMessageBox::error(0, mFatalMessage);
00872 mFatalError = 3;
00873
00874 case 3:
00875 if (theInstance)
00876 theInstance->quitIf(1, true);
00877 break;
00878 }
00879 QTimer::singleShot(1000, this, SLOT(quitFatal()));
00880 }
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894 void KAlarmApp::processQueue()
00895 {
00896 if (mInitialised && !mProcessingQueue)
00897 {
00898 kdDebug(5950) << "KAlarmApp::processQueue()\n";
00899 mProcessingQueue = true;
00900
00901
00902 KAlarm::resetDaemonIfQueued();
00903
00904
00905 while (!mDcopQueue.isEmpty())
00906 {
00907 DcopQEntry& entry = mDcopQueue.first();
00908 if (entry.eventId.isEmpty())
00909 {
00910
00911 switch (entry.function)
00912 {
00913 case EVENT_TRIGGER:
00914 execAlarm(entry.event, entry.event.firstAlarm(), false);
00915 break;
00916 case EVENT_HANDLE:
00917 KAlarm::addEvent(entry.event, 0);
00918 break;
00919 case EVENT_CANCEL:
00920 break;
00921 }
00922 }
00923 else
00924 handleEvent(entry.eventId, entry.function);
00925 mDcopQueue.pop_front();
00926 }
00927
00928
00929 AlarmCalendar::expiredCalendar()->purgeIfQueued();
00930
00931
00932 if (mPendingQuit)
00933 quitIf(mPendingQuitCode);
00934
00935 mProcessingQueue = false;
00936 }
00937 }
00938
00939
00940
00941
00942
00943
00944
00945 void KAlarmApp::redisplayAlarms()
00946 {
00947 AlarmCalendar* cal = AlarmCalendar::displayCalendar();
00948 if (cal->isOpen())
00949 {
00950 KCal::Event::List events = cal->events();
00951 for (KCal::Event::List::ConstIterator it = events.begin(); it != events.end(); ++it)
00952 {
00953 KCal::Event* kcalEvent = *it;
00954 KAEvent event(*kcalEvent);
00955 event.setUid(KAEvent::ACTIVE);
00956 if (!MessageWin::findEvent(event.id()))
00957 {
00958
00959 kdDebug(5950) << "KAlarmApp::redisplayAlarms(): " << event.id() << endl;
00960 KAAlarm alarm = event.convertDisplayingAlarm();
00961 (new MessageWin(event, alarm, false, !alarm.repeatAtLogin()))->show();
00962 }
00963 }
00964 }
00965 }
00966
00967
00968
00969
00970 void KAlarmApp::removeWindow(TrayWindow*)
00971 {
00972 mTrayWindow = 0;
00973 quitIf();
00974 }
00975
00976
00977
00978
00979 bool KAlarmApp::displayTrayIcon(bool show, MainWindow* parent)
00980 {
00981 static bool creating = false;
00982 if (show)
00983 {
00984 if (!mTrayWindow && !creating)
00985 {
00986 if (!mHaveSystemTray)
00987 return false;
00988 if (!MainWindow::count() && wantRunInSystemTray())
00989 {
00990 creating = true;
00991 parent = MainWindow::create();
00992 creating = false;
00993 }
00994 mTrayWindow = new TrayWindow(parent ? parent : MainWindow::firstWindow());
00995 connect(mTrayWindow, SIGNAL(deleted()), SIGNAL(trayIconToggled()));
00996 mTrayWindow->show();
00997 emit trayIconToggled();
00998
00999
01000
01001 mCheckingSystemTray = true;
01002 mSavedNoSystemTray = mNoSystemTray;
01003 mNoSystemTray = false;
01004 QTimer::singleShot(0, this, SLOT(slotSystemTrayTimer()));
01005 }
01006 }
01007 else if (mTrayWindow)
01008 {
01009 delete mTrayWindow;
01010 mTrayWindow = 0;
01011 }
01012 return true;
01013 }
01014
01015
01016
01017
01018
01019
01020
01021
01022 void KAlarmApp::slotSystemTrayTimer()
01023 {
01024 mCheckingSystemTray = false;
01025 if (!checkSystemTray())
01026 quitIf(0);
01027 }
01028
01029
01030
01031
01032
01033
01034 bool KAlarmApp::checkSystemTray()
01035 {
01036 if (mCheckingSystemTray || !mTrayWindow)
01037 return true;
01038 if (mTrayWindow->inSystemTray() != !mSavedNoSystemTray)
01039 {
01040 kdDebug(5950) << "KAlarmApp::checkSystemTray(): changed -> " << mSavedNoSystemTray << endl;
01041 mNoSystemTray = mSavedNoSystemTray = !mSavedNoSystemTray;
01042
01043
01044
01045
01046
01047
01048 KConfig* config = kapp->config();
01049 config->setGroup(QString::fromLatin1("General"));
01050 config->writeEntry(QString::fromLatin1("NoSystemTray"), mNoSystemTray);
01051 config->sync();
01052
01053
01054 slotPreferencesChanged();
01055 }
01056 else
01057 {
01058 kdDebug(5950) << "KAlarmApp::checkSystemTray(): no change = " << !mSavedNoSystemTray << endl;
01059 mNoSystemTray = mSavedNoSystemTray;
01060 }
01061 return !mNoSystemTray;
01062 }
01063
01064
01065
01066
01067 MainWindow* KAlarmApp::trayMainWindow() const
01068 {
01069 return mTrayWindow ? mTrayWindow->assocMainWindow() : 0;
01070 }
01071
01072
01073
01074
01075 void KAlarmApp::slotPreferencesChanged()
01076 {
01077 bool newRunInSysTray = wantRunInSystemTray();
01078 if (newRunInSysTray != mOldRunInSystemTray)
01079 {
01080
01081 ++mActiveCount;
01082 MainWindow* win = mTrayWindow ? mTrayWindow->assocMainWindow() : 0;
01083 delete mTrayWindow;
01084 mTrayWindow = 0;
01085 mOldRunInSystemTray = newRunInSysTray;
01086 if (!newRunInSysTray)
01087 {
01088 if (win && win->isHidden())
01089 delete win;
01090 }
01091 displayTrayIcon(true);
01092 --mActiveCount;
01093 }
01094
01095 bool newDisableIfStopped = wantRunInSystemTray() && !mNoSystemTray && Preferences::disableAlarmsIfStopped();
01096 if (newDisableIfStopped != mDisableAlarmsIfStopped)
01097 {
01098 mDisableAlarmsIfStopped = newDisableIfStopped;
01099 Preferences::setQuitWarn(true);
01100 Daemon::reregister();
01101 }
01102
01103
01104 if (Preferences::startOfDay() != mStartOfDay)
01105 changeStartOfDay();
01106
01107
01108 KARecurrence::setDefaultFeb29Type(Preferences::defaultFeb29Type());
01109
01110 if (Preferences::expiredColour() != mPrefsExpiredColour)
01111 {
01112
01113 mRefreshExpiredAlarms = true;
01114 mPrefsExpiredColour = Preferences::expiredColour();
01115 }
01116
01117 if (Preferences::expiredKeepDays() != mPrefsExpiredKeepDays)
01118 {
01119
01120
01121 mPrefsExpiredKeepDays = Preferences::expiredKeepDays();
01122 AlarmCalendar::expiredCalendar()->setPurgeDays(mPrefsExpiredKeepDays);
01123 }
01124
01125 if (mRefreshExpiredAlarms)
01126 {
01127 mRefreshExpiredAlarms = false;
01128 MainWindow::updateExpired();
01129 }
01130 }
01131
01132
01133
01134
01135 void KAlarmApp::changeStartOfDay()
01136 {
01137 Daemon::notifyTimeChanged();
01138 QTime sod = Preferences::startOfDay();
01139 DateTime::setStartOfDay(sod);
01140 AlarmCalendar* cal = AlarmCalendar::activeCalendar();
01141 if (KAEvent::adjustStartOfDay(cal->events()))
01142 cal->save();
01143 Preferences::updateStartOfDayCheck();
01144 mStartOfDay = sod;
01145 }
01146
01147
01148
01149
01150
01151 void KAlarmApp::slotExpiredPurged()
01152 {
01153 mRefreshExpiredAlarms = false;
01154 MainWindow::updateExpired();
01155 }
01156
01157
01158
01159
01160 bool KAlarmApp::wantRunInSystemTray() const
01161 {
01162 return Preferences::runInSystemTray() && mHaveSystemTray;
01163 }
01164
01165
01166
01167
01168
01169
01170 bool KAlarmApp::scheduleEvent(KAEvent::Action action, const QString& text, const QDateTime& dateTime,
01171 int lateCancel, int flags, const QColor& bg, const QColor& fg, const QFont& font,
01172 const QString& audioFile, float audioVolume, int reminderMinutes,
01173 const KARecurrence& recurrence, int repeatInterval, int repeatCount,
01174 uint mailFromID, const EmailAddressList& mailAddresses,
01175 const QString& mailSubject, const QStringList& mailAttachments)
01176 {
01177 kdDebug(5950) << "KAlarmApp::scheduleEvent(): " << text << endl;
01178 if (!dateTime.isValid())
01179 return false;
01180 QDateTime now = QDateTime::currentDateTime();
01181 if (lateCancel && dateTime < now.addSecs(-maxLateness(lateCancel)))
01182 return true;
01183 QDateTime alarmTime = dateTime;
01184
01185 alarmTime.setTime(QTime(alarmTime.time().hour(), alarmTime.time().minute(), 0));
01186
01187 KAEvent event(alarmTime, text, bg, fg, font, action, lateCancel, flags);
01188 if (reminderMinutes)
01189 {
01190 bool onceOnly = (reminderMinutes < 0);
01191 event.setReminder((onceOnly ? -reminderMinutes : reminderMinutes), onceOnly);
01192 }
01193 if (!audioFile.isEmpty())
01194 event.setAudioFile(audioFile, audioVolume, -1, 0);
01195 if (!mailAddresses.isEmpty())
01196 event.setEmail(mailFromID, mailAddresses, mailSubject, mailAttachments);
01197 event.setRecurrence(recurrence);
01198 event.setFirstRecurrence();
01199 event.setRepetition(repeatInterval, repeatCount - 1);
01200 if (alarmTime <= now)
01201 {
01202
01203
01204 if (!mInitialised)
01205 mDcopQueue.append(DcopQEntry(event, EVENT_TRIGGER));
01206 else
01207 execAlarm(event, event.firstAlarm(), false);
01208
01209 if (!event.recurs()
01210 || event.setNextOccurrence(now) == KAEvent::NO_OCCURRENCE)
01211 return true;
01212
01213 }
01214
01215
01216 mDcopQueue.append(DcopQEntry(event));
01217 if (mInitialised)
01218 QTimer::singleShot(0, this, SLOT(processQueue()));
01219 return true;
01220 }
01221
01222
01223
01224
01225
01226
01227
01228 bool KAlarmApp::handleEvent(const QString& urlString, const QString& eventID, EventFunc function)
01229 {
01230 kdDebug(5950) << "KAlarmApp::handleEvent(DCOP): " << eventID << endl;
01231 AlarmCalendar* cal = AlarmCalendar::activeCalendar();
01232 if (cal && KURL(urlString).url() != cal->urlString())
01233 {
01234 kdError(5950) << "KAlarmApp::handleEvent(DCOP): wrong calendar file " << urlString << endl;
01235 Daemon::eventHandled(eventID, false);
01236 return false;
01237 }
01238 mDcopQueue.append(DcopQEntry(function, eventID));
01239 if (mInitialised)
01240 QTimer::singleShot(0, this, SLOT(processQueue()));
01241 return true;
01242 }
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252 bool KAlarmApp::handleEvent(const QString& eventID, EventFunc function)
01253 {
01254 kdDebug(5950) << "KAlarmApp::handleEvent(): " << eventID << ", " << (function==EVENT_TRIGGER?"TRIGGER":function==EVENT_CANCEL?"CANCEL":function==EVENT_HANDLE?"HANDLE":"?") << endl;
01255 KCal::Event* kcalEvent = AlarmCalendar::activeCalendar()->event(eventID);
01256 if (!kcalEvent)
01257 {
01258 kdError(5950) << "KAlarmApp::handleEvent(): event ID not found: " << eventID << endl;
01259 Daemon::eventHandled(eventID, false);
01260 return false;
01261 }
01262 KAEvent event(*kcalEvent);
01263 switch (function)
01264 {
01265 case EVENT_CANCEL:
01266 KAlarm::deleteEvent(event, true);
01267 break;
01268
01269 case EVENT_TRIGGER:
01270 case EVENT_HANDLE:
01271 {
01272 QDateTime now = QDateTime::currentDateTime();
01273 bool updateCalAndDisplay = false;
01274 bool alarmToExecuteValid = false;
01275 KAAlarm alarmToExecute;
01276
01277
01278 for (KAAlarm alarm = event.firstAlarm(); alarm.valid(); alarm = event.nextAlarm(alarm))
01279 {
01280
01281 int secs = alarm.dateTime(true).dateTime().secsTo(now);
01282 if (secs < 0)
01283 {
01284
01285 kdDebug(5950) << "KAlarmApp::handleEvent(): alarm " << alarm.type() << ": not due\n";
01286 continue;
01287 }
01288 if (alarm.repeatAtLogin())
01289 {
01290
01291
01292
01293
01294 kdDebug(5950) << "KAlarmApp::handleEvent(): REPEAT_AT_LOGIN\n";
01295 if (secs < maxLateness(1))
01296 continue;
01297
01298
01299
01300 if (alarmToExecute.valid())
01301 continue;
01302
01303
01304 alarm.setTime(now);
01305 }
01306 if (alarm.lateCancel())
01307 {
01308
01309 kdDebug(5950) << "KAlarmApp::handleEvent(): LATE_CANCEL\n";
01310 bool late = false;
01311 bool cancel = false;
01312 if (alarm.dateTime().isDateOnly())
01313 {
01314
01315 int maxlate = alarm.lateCancel() / 1440;
01316 QDateTime limit(alarm.date().addDays(maxlate + 1), Preferences::startOfDay());
01317 if (now >= limit)
01318 {
01319
01320
01321 DateTime next;
01322 KAEvent::OccurType type = event.previousOccurrence(now, next, true);
01323 switch (type & ~KAEvent::OCCURRENCE_REPEAT)
01324 {
01325 case KAEvent::FIRST_OR_ONLY_OCCURRENCE:
01326 case KAEvent::RECURRENCE_DATE:
01327 case KAEvent::RECURRENCE_DATE_TIME:
01328 case KAEvent::LAST_RECURRENCE:
01329 limit.setDate(next.date().addDays(maxlate + 1));
01330 limit.setTime(Preferences::startOfDay());
01331 if (now >= limit)
01332 {
01333 if (type == KAEvent::LAST_RECURRENCE
01334 || type == KAEvent::FIRST_OR_ONLY_OCCURRENCE && !event.recurs())
01335 cancel = true;
01336 else
01337 late = true;
01338 }
01339 break;
01340 case KAEvent::NO_OCCURRENCE:
01341 default:
01342 late = true;
01343 break;
01344 }
01345 }
01346 }
01347 else
01348 {
01349
01350 int maxlate = maxLateness(alarm.lateCancel());
01351 if (secs > maxlate)
01352 {
01353
01354
01355 DateTime next;
01356 KAEvent::OccurType type = event.previousOccurrence(now, next, true);
01357 switch (type & ~KAEvent::OCCURRENCE_REPEAT)
01358 {
01359 case KAEvent::FIRST_OR_ONLY_OCCURRENCE:
01360 case KAEvent::RECURRENCE_DATE:
01361 case KAEvent::RECURRENCE_DATE_TIME:
01362 case KAEvent::LAST_RECURRENCE:
01363 if (next.dateTime().secsTo(now) > maxlate)
01364 {
01365 if (type == KAEvent::LAST_RECURRENCE
01366 || type == KAEvent::FIRST_OR_ONLY_OCCURRENCE && !event.recurs())
01367 cancel = true;
01368 else
01369 late = true;
01370 }
01371 break;
01372 case KAEvent::NO_OCCURRENCE:
01373 default:
01374 late = true;
01375 break;
01376 }
01377 }
01378 }
01379
01380 if (cancel)
01381 {
01382
01383 event.setArchive();
01384 cancelAlarm(event, alarm.type(), false);
01385 updateCalAndDisplay = true;
01386 continue;
01387 }
01388 if (late)
01389 {
01390
01391 rescheduleAlarm(event, alarm, false);
01392 updateCalAndDisplay = true;
01393 continue;
01394 }
01395 }
01396 if (!alarmToExecuteValid)
01397 {
01398 kdDebug(5950) << "KAlarmApp::handleEvent(): alarm " << alarm.type() << ": execute\n";
01399 alarmToExecute = alarm;
01400 alarmToExecuteValid = true;
01401 }
01402 else
01403 kdDebug(5950) << "KAlarmApp::handleEvent(): alarm " << alarm.type() << ": skip\n";
01404 }
01405
01406
01407
01408 if (alarmToExecute.valid())
01409 execAlarm(event, alarmToExecute, true, !alarmToExecute.repeatAtLogin());
01410 else
01411 {
01412 if (function == EVENT_TRIGGER)
01413 {
01414
01415
01416
01417 KAAlarm alarm = event.firstAlarm();
01418 if (alarm.valid())
01419 execAlarm(event, alarm, false);
01420 }
01421 if (updateCalAndDisplay)
01422 KAlarm::updateEvent(event, 0);
01423 else if (function != EVENT_TRIGGER)
01424 {
01425 kdDebug(5950) << "KAlarmApp::handleEvent(): no action\n";
01426 Daemon::eventHandled(eventID, false);
01427 }
01428 }
01429 break;
01430 }
01431 }
01432 return true;
01433 }
01434
01435
01436
01437
01438
01439
01440 void KAlarmApp::alarmShowing(KAEvent& event, KAAlarm::Type alarmType, const DateTime& alarmTime)
01441 {
01442 kdDebug(5950) << "KAlarmApp::alarmShowing(" << event.id() << ", " << KAAlarm::debugType(alarmType) << ")\n";
01443 KCal::Event* kcalEvent = AlarmCalendar::activeCalendar()->event(event.id());
01444 if (!kcalEvent)
01445 kdError(5950) << "KAlarmApp::alarmShowing(): event ID not found: " << event.id() << endl;
01446 else
01447 {
01448 KAAlarm alarm = event.alarm(alarmType);
01449 if (!alarm.valid())
01450 kdError(5950) << "KAlarmApp::alarmShowing(): alarm type not found: " << event.id() << ":" << alarmType << endl;
01451 else
01452 {
01453
01454 KAEvent dispEvent;
01455 dispEvent.setDisplaying(event, alarmType, alarmTime.dateTime());
01456 AlarmCalendar* cal = AlarmCalendar::displayCalendarOpen();
01457 if (cal)
01458 {
01459 cal->deleteEvent(dispEvent.id());
01460 cal->addEvent(dispEvent);
01461 cal->save();
01462 }
01463
01464 rescheduleAlarm(event, alarm, true);
01465 return;
01466 }
01467 }
01468 Daemon::eventHandled(event.id(), false);
01469 }
01470
01471
01472
01473
01474 void KAlarmApp::alarmCompleted(const KAEvent& event)
01475 {
01476 if (!event.postAction().isEmpty() && ShellProcess::authorised())
01477 {
01478 QString command = event.postAction();
01479 kdDebug(5950) << "KAlarmApp::alarmCompleted(" << event.id() << "): " << command << endl;
01480 doShellCommand(command, event, 0, ProcData::POST_ACTION);
01481 }
01482 }
01483
01484
01485
01486
01487
01488
01489 void KAlarmApp::rescheduleAlarm(KAEvent& event, const KAAlarm& alarm, bool updateCalAndDisplay)
01490 {
01491 kdDebug(5950) << "KAlarmApp::rescheduleAlarm()" << endl;
01492 bool update = false;
01493 if (alarm.reminder() || alarm.deferred())
01494 {
01495
01496 event.removeExpiredAlarm(alarm.type());
01497 update = true;
01498 }
01499 else if (alarm.repeatAtLogin())
01500 {
01501
01502 if (updateCalAndDisplay && event.updated())
01503 update = true;
01504 }
01505 else
01506 {
01507
01508 KAEvent::OccurType type = event.setNextOccurrence(QDateTime::currentDateTime());
01509 switch (type)
01510 {
01511 case KAEvent::NO_OCCURRENCE:
01512
01513 cancelAlarm(event, alarm.type(), updateCalAndDisplay);
01514 break;
01515 default:
01516 if (!(type & KAEvent::OCCURRENCE_REPEAT))
01517 break;
01518
01519 case KAEvent::RECURRENCE_DATE:
01520 case KAEvent::RECURRENCE_DATE_TIME:
01521 case KAEvent::LAST_RECURRENCE:
01522
01523 if (updateCalAndDisplay)
01524 update = true;
01525 else
01526 {
01527 event.cancelCancelledDeferral();
01528 event.setUpdated();
01529 }
01530 break;
01531 case KAEvent::FIRST_OR_ONLY_OCCURRENCE:
01532
01533 break;
01534 }
01535 if (event.deferred())
01536 {
01537
01538 event.removeExpiredAlarm(KAAlarm::DEFERRED_ALARM);
01539 update = true;
01540 }
01541 }
01542 if (update)
01543 {
01544 event.cancelCancelledDeferral();
01545 KAlarm::updateEvent(event, 0);
01546 }
01547 }
01548
01549
01550
01551
01552
01553 void KAlarmApp::cancelAlarm(KAEvent& event, KAAlarm::Type alarmType, bool updateCalAndDisplay)
01554 {
01555 kdDebug(5950) << "KAlarmApp::cancelAlarm()" << endl;
01556 event.cancelCancelledDeferral();
01557 if (alarmType == KAAlarm::MAIN_ALARM && !event.displaying() && event.toBeArchived())
01558 {
01559
01560 QString id = event.id();
01561 KAlarm::addExpiredEvent(event);
01562 event.setEventID(id);
01563 }
01564 event.removeExpiredAlarm(alarmType);
01565 if (!event.alarmCount())
01566 KAlarm::deleteEvent(event, false);
01567 else if (updateCalAndDisplay)
01568 KAlarm::updateEvent(event, 0);
01569 }
01570
01571
01572
01573
01574
01575
01576
01577 void* KAlarmApp::execAlarm(KAEvent& event, const KAAlarm& alarm, bool reschedule, bool allowDefer, bool noPreAction)
01578 {
01579 if (!event.enabled())
01580 {
01581
01582 if (reschedule)
01583 rescheduleAlarm(event, alarm, true);
01584 return 0;
01585 }
01586
01587 void* result = (void*)1;
01588 event.setArchive();
01589 switch (alarm.action())
01590 {
01591 case KAAlarm::MESSAGE:
01592 case KAAlarm::FILE:
01593 {
01594
01595 MessageWin* win = MessageWin::findEvent(event.id());
01596
01597 bool reminder = (alarm.type() & KAAlarm::REMINDER_ALARM);
01598 bool replaceReminder = !reminder && win && (win->alarmType() & KAAlarm::REMINDER_ALARM);
01599 if (!reminder && !event.deferred()
01600 && (replaceReminder || !win) && !noPreAction
01601 && !event.preAction().isEmpty() && ShellProcess::authorised())
01602 {
01603
01604
01605
01606
01607 for (QValueList<ProcData*>::Iterator it = mCommandProcesses.begin(); it != mCommandProcesses.end(); ++it)
01608 {
01609 ProcData* pd = *it;
01610 if (pd->event->id() == event.id() && (pd->flags & ProcData::PRE_ACTION))
01611 {
01612 kdDebug(5950) << "KAlarmApp::execAlarm(): already executing pre-DISPLAY command" << endl;
01613 return pd->process;
01614 }
01615 }
01616
01617 QString command = event.preAction();
01618 kdDebug(5950) << "KAlarmApp::execAlarm(): pre-DISPLAY command: " << command << endl;
01619 int flags = (reschedule ? ProcData::RESCHEDULE : 0) | (allowDefer ? ProcData::ALLOW_DEFER : 0);
01620 if (doShellCommand(command, event, &alarm, (flags | ProcData::PRE_ACTION)))
01621 return result;
01622
01623 }
01624 if (!event.enabled())
01625 delete win;
01626 else if (!win
01627 || !win->hasDefer() && !alarm.repeatAtLogin()
01628 || replaceReminder)
01629 {
01630
01631
01632
01633
01634 if (win)
01635 win->setRecreating();
01636 delete win;
01637 (new MessageWin(event, alarm, reschedule, allowDefer))->show();
01638 }
01639 else
01640 {
01641
01642 win->repeat(alarm);
01643 }
01644 break;
01645 }
01646 case KAAlarm::COMMAND:
01647 {
01648 int flags = event.commandXterm() ? ProcData::EXEC_IN_XTERM : 0;
01649 QString command = event.cleanText();
01650 if (event.commandScript())
01651 {
01652
01653 kdDebug(5950) << "KAlarmApp::execAlarm(): COMMAND: (script)" << endl;
01654 QString tmpfile = createTempScriptFile(command, false, event, alarm);
01655 if (tmpfile.isEmpty())
01656 result = 0;
01657 else
01658 result = doShellCommand(tmpfile, event, &alarm, (flags | ProcData::TEMP_FILE));
01659 }
01660 else
01661 {
01662 kdDebug(5950) << "KAlarmApp::execAlarm(): COMMAND: " << command << endl;
01663 result = doShellCommand(command, event, &alarm, flags);
01664 }
01665 if (reschedule)
01666 rescheduleAlarm(event, alarm, true);
01667 break;
01668 }
01669 case KAAlarm::EMAIL:
01670 {
01671 kdDebug(5950) << "KAlarmApp::execAlarm(): EMAIL to: " << event.emailAddresses(", ") << endl;
01672 QStringList errmsgs;
01673 if (!KAMail::send(event, errmsgs, (reschedule || allowDefer)))
01674 result = 0;
01675 if (!errmsgs.isEmpty())
01676 {
01677
01678 if (result)
01679 kdDebug(5950) << "KAlarmApp::execAlarm(): copy error: " << errmsgs[1] << endl;
01680 else
01681 kdDebug(5950) << "KAlarmApp::execAlarm(): failed: " << errmsgs[1] << endl;
01682 (new MessageWin(event, alarm.dateTime(), errmsgs))->show();
01683 }
01684 if (reschedule)
01685 rescheduleAlarm(event, alarm, true);
01686 break;
01687 }
01688 default:
01689 return 0;
01690 }
01691 return result;
01692 }
01693
01694
01695
01696
01697
01698
01699
01700 ShellProcess* KAlarmApp::doShellCommand(const QString& command, const KAEvent& event, const KAAlarm* alarm, int flags)
01701 {
01702 kdDebug(5950) << "KAlarmApp::doShellCommand(" << command << ", " << event.id() << ")" << endl;
01703 KProcess::Communication comms = KProcess::NoCommunication;
01704 QString cmd;
01705 QString tmpXtermFile;
01706 if (flags & ProcData::EXEC_IN_XTERM)
01707 {
01708
01709 cmd = Preferences::cmdXTermCommand();
01710 cmd.replace("%t", aboutData()->programName());
01711 if (cmd.find("%C") >= 0)
01712 {
01713
01714 if (flags & ProcData::TEMP_FILE)
01715 cmd.replace("%C", command);
01716 else
01717 {
01718 tmpXtermFile = createTempScriptFile(command, true, event, *alarm);
01719 if (tmpXtermFile.isEmpty())
01720 return 0;
01721 cmd.replace("%C", tmpXtermFile);
01722 }
01723 }
01724 else if (cmd.find("%W") >= 0)
01725 {
01726
01727
01728 tmpXtermFile = createTempScriptFile(command + QString::fromLatin1("\nsleep 86400\n"), true, event, *alarm);
01729 if (tmpXtermFile.isEmpty())
01730 return 0;
01731 cmd.replace("%W", tmpXtermFile);
01732 }
01733 else if (cmd.find("%w") >= 0)
01734 {
01735
01736
01737 QString exec = KShellProcess::quote(command + QString::fromLatin1("; sleep 86400"));
01738 cmd.replace("%w", exec);
01739 }
01740 else
01741 {
01742
01743
01744 QString exec = KShellProcess::quote(command);
01745 if (cmd.find("%c") >= 0)
01746 cmd.replace("%c", exec);
01747 else
01748 cmd.append(exec);
01749 }
01750 }
01751 else
01752 {
01753 cmd = command;
01754 comms = KProcess::AllOutput;
01755 }
01756 ShellProcess* proc = new ShellProcess(cmd);
01757 connect(proc, SIGNAL(shellExited(ShellProcess*)), SLOT(slotCommandExited(ShellProcess*)));
01758 QGuardedPtr<ShellProcess> logproc = 0;
01759 if (comms == KProcess::AllOutput && !event.logFile().isEmpty())
01760 {
01761
01762
01763 connect(proc, SIGNAL(receivedStdout(KProcess*,char*,int)), SLOT(slotCommandOutput(KProcess*,char*,int)));
01764 connect(proc, SIGNAL(receivedStderr(KProcess*,char*,int)), SLOT(slotCommandOutput(KProcess*,char*,int)));
01765 logproc = new ShellProcess(QString::fromLatin1("cat >>%1").arg(event.logFile()));
01766 connect(logproc, SIGNAL(shellExited(ShellProcess*)), SLOT(slotLogProcExited(ShellProcess*)));
01767 logproc->start(KProcess::Stdin);
01768 QCString heading;
01769 if (alarm && alarm->dateTime().isValid())
01770 {
01771 QString dateTime = alarm->dateTime().isDateOnly()
01772 ? KGlobal::locale()->formatDate(alarm->dateTime().date(), true)
01773 : KGlobal::locale()->formatDateTime(alarm->dateTime().dateTime());
01774 heading.sprintf("\n******* KAlarm %s *******\n", dateTime.latin1());
01775 }
01776 else
01777 heading = "\n******* KAlarm *******\n";
01778 logproc->writeStdin(heading, heading.length()+1);
01779 }
01780 ProcData* pd = new ProcData(proc, logproc, new KAEvent(event), (alarm ? new KAAlarm(*alarm) : 0), flags);
01781 if (flags & ProcData::TEMP_FILE)
01782 pd->tempFiles += command;
01783 if (!tmpXtermFile.isEmpty())
01784 pd->tempFiles += tmpXtermFile;
01785 mCommandProcesses.append(pd);
01786 if (proc->start(comms))
01787 return proc;
01788
01789
01790 kdError(5950) << "KAlarmApp::doShellCommand(): command failed to start\n";
01791 commandErrorMsg(proc, event, alarm, flags);
01792 mCommandProcesses.remove(pd);
01793 delete pd;
01794 return 0;
01795 }
01796
01797
01798
01799
01800
01801 QString KAlarmApp::createTempScriptFile(const QString& command, bool insertShell, const KAEvent& event, const KAAlarm& alarm)
01802 {
01803 KTempFile tmpFile(QString::null, QString::null, 0700);
01804 tmpFile.setAutoDelete(false);
01805 QTextStream* stream = tmpFile.textStream();
01806 if (!stream)
01807 kdError(5950) << "KAlarmApp::createTempScript(): Unable to create a temporary script file" << endl;
01808 else
01809 {
01810 if (insertShell)
01811 *stream << "#!" << ShellProcess::shellPath() << "\n";
01812 *stream << command;
01813 tmpFile.close();
01814 if (tmpFile.status())
01815 kdError(5950) << "KAlarmApp::createTempScript(): Error " << tmpFile.status() << " writing to temporary script file" << endl;
01816 else
01817 return tmpFile.name();
01818 }
01819
01820 QStringList errmsgs(i18n("Error creating temporary script file"));
01821 (new MessageWin(event, alarm.dateTime(), errmsgs))->show();
01822 return QString::null;
01823 }
01824
01825
01826
01827
01828 void KAlarmApp::slotCommandOutput(KProcess* proc, char* buffer, int bufflen)
01829 {
01830
01831
01832 for (QValueList<ProcData*>::Iterator it = mCommandProcesses.begin(); it != mCommandProcesses.end(); ++it)
01833 {
01834 ProcData* pd = *it;
01835 if (pd->process == proc && pd->logProcess)
01836 {
01837 pd->logProcess->writeStdin(buffer, bufflen);
01838 break;
01839 }
01840 }
01841 }
01842
01843
01844
01845
01846 void KAlarmApp::slotLogProcExited(ShellProcess* proc)
01847 {
01848
01849
01850 delete proc;
01851 }
01852
01853
01854
01855
01856 void KAlarmApp::slotCommandExited(ShellProcess* proc)
01857 {
01858 kdDebug(5950) << "KAlarmApp::slotCommandExited()\n";
01859
01860 for (QValueList<ProcData*>::Iterator it = mCommandProcesses.begin(); it != mCommandProcesses.end(); ++it)
01861 {
01862 ProcData* pd = *it;
01863 if (pd->process == proc)
01864 {
01865
01866 if (pd->logProcess)
01867 pd->logProcess->stdinExit();
01868
01869
01870 if (!proc->normalExit())
01871 {
01872 QString errmsg = proc->errorMessage();
01873 kdWarning(5950) << "KAlarmApp::slotCommandExited(" << pd->event->cleanText() << "): " << errmsg << endl;
01874 if (pd->messageBoxParent)
01875 {
01876
01877 QObjectList* dialogs = pd->messageBoxParent->queryList("KDialogBase", 0, false, true);
01878 KDialogBase* dialog = (KDialogBase*)dialogs->getFirst();
01879 delete dialog;
01880 delete dialogs;
01881 if (!pd->tempFile())
01882 {
01883 errmsg += '\n';
01884 errmsg += proc->command();
01885 }
01886 KMessageBox::error(pd->messageBoxParent, errmsg);
01887 }
01888 else
01889 commandErrorMsg(proc, *pd->event, pd->alarm, pd->flags);
01890 }
01891 if (pd->preAction())
01892 execAlarm(*pd->event, *pd->alarm, pd->reschedule(), pd->allowDefer(), true);
01893 mCommandProcesses.remove(it);
01894 delete pd;
01895 break;
01896 }
01897 }
01898
01899
01900 if (mPendingQuit && mCommandProcesses.isEmpty())
01901 quitIf(mPendingQuitCode);
01902 }
01903
01904
01905
01906
01907 void KAlarmApp::commandErrorMsg(const ShellProcess* proc, const KAEvent& event, const KAAlarm* alarm, int flags)
01908 {
01909 QStringList errmsgs;
01910 if (flags & ProcData::PRE_ACTION)
01911 errmsgs += i18n("Pre-alarm action:");
01912 else if (flags & ProcData::POST_ACTION)
01913 errmsgs += i18n("Post-alarm action:");
01914 errmsgs += proc->errorMessage();
01915 if (!(flags & ProcData::TEMP_FILE))
01916 errmsgs += proc->command();
01917 (new MessageWin(event, (alarm ? alarm->dateTime() : DateTime()), errmsgs))->show();
01918 }
01919
01920
01921
01922
01923 void KAlarmApp::commandMessage(ShellProcess* proc, QWidget* parent)
01924 {
01925
01926 for (QValueList<ProcData*>::Iterator it = mCommandProcesses.begin(); it != mCommandProcesses.end(); ++it)
01927 {
01928 ProcData* pd = *it;
01929 if (pd->process == proc)
01930 {
01931 pd->messageBoxParent = parent;
01932 break;
01933 }
01934 }
01935 }
01936
01937
01938
01939
01940 void KAlarmApp::setUpDcop()
01941 {
01942 if (!mInitialised)
01943 {
01944 mInitialised = true;
01945 Daemon::createDcopHandler();
01946 QTimer::singleShot(0, this, SLOT(processQueue()));
01947 }
01948 }
01949
01950
01951
01952
01953
01954 bool KAlarmApp::initCheck(bool calendarOnly)
01955 {
01956 bool startdaemon;
01957 AlarmCalendar* cal = AlarmCalendar::activeCalendar();
01958 if (!cal->isOpen())
01959 {
01960 kdDebug(5950) << "KAlarmApp::initCheck(): opening active calendar\n";
01961
01962
01963 if (!cal->open())
01964 return false;
01965
01966 if (!mStartOfDay.isValid())
01967 changeStartOfDay();
01968
01969
01970
01971
01972
01973
01974 AlarmCalendar::displayCalendar()->open();
01975
01976
01977
01978
01979
01980
01981 AlarmCalendar::expiredCalendar()->open();
01982 AlarmCalendar::expiredCalendar()->setPurgeDays(theInstance->mPrefsExpiredKeepDays);
01983
01984 startdaemon = true;
01985 }
01986 else
01987 startdaemon = !Daemon::isRegistered();
01988
01989 if (!calendarOnly)
01990 {
01991 setUpDcop();
01992 if (startdaemon)
01993 Daemon::start();
01994 }
01995 return true;
01996 }
01997
01998
01999
02000
02001
02002
02003 static bool convWakeTime(const QCString& timeParam, QDateTime& dateTime, bool& noTime)
02004 {
02005 if (timeParam.length() > 19)
02006 return false;
02007 char timeStr[20];
02008 strcpy(timeStr, timeParam);
02009 int dt[5] = { -1, -1, -1, -1, -1 };
02010 char* s;
02011 char* end;
02012
02013 if ((s = strchr(timeStr, ':')) == 0)
02014 noTime = true;
02015 else
02016 {
02017 noTime = false;
02018 *s++ = 0;
02019 dt[4] = strtoul(s, &end, 10);
02020 if (end == s || *end || dt[4] >= 60)
02021 return false;
02022
02023 if ((s = strrchr(timeStr, '-')) == 0)
02024 s = timeStr;
02025 else
02026 *s++ = 0;
02027 dt[3] = strtoul(s, &end, 10);
02028 if (end == s || *end || dt[3] >= 24)
02029 return false;
02030 }
02031 bool dateSet = false;
02032 if (s != timeStr)
02033 {
02034 dateSet = true;
02035
02036 if ((s = strrchr(timeStr, '-')) == 0)
02037 s = timeStr;
02038 else
02039 *s++ = 0;
02040 dt[2] = strtoul(s, &end, 10);
02041 if (end == s || *end || dt[2] == 0 || dt[2] > 31)
02042 return false;
02043 if (s != timeStr)
02044 {
02045
02046 if ((s = strrchr(timeStr, '-')) == 0)
02047 s = timeStr;
02048 else
02049 *s++ = 0;
02050 dt[1] = strtoul(s, &end, 10);
02051 if (end == s || *end || dt[1] == 0 || dt[1] > 12)
02052 return false;
02053 if (s != timeStr)
02054 {
02055
02056 dt[0] = strtoul(timeStr, &end, 10);
02057 if (end == timeStr || *end)
02058 return false;
02059 }
02060 }
02061 }
02062
02063 QDate date(dt[0], dt[1], dt[2]);
02064 QTime time(0, 0, 0);
02065 if (noTime)
02066 {
02067
02068 if (dt[0] < 0)
02069 return false;
02070 }
02071 else
02072 {
02073
02074 QDateTime now = QDateTime::currentDateTime();
02075 if (dt[0] < 0)
02076 date.setYMD(now.date().year(),
02077 (dt[1] < 0 ? now.date().month() : dt[1]),
02078 (dt[2] < 0 ? now.date().day() : dt[2]));
02079 time.setHMS(dt[3], dt[4], 0);
02080 if (!dateSet && time < now.time())
02081 date = date.addDays(1);
02082 }
02083 if (!date.isValid())
02084 return false;
02085 dateTime.setDate(date);
02086 dateTime.setTime(time);
02087 return true;
02088 }
02089
02090
02091
02092
02093
02094
02095
02096 static bool convInterval(const QCString& timeParam, KARecurrence::Type& recurType, int& timeInterval, bool allowMonthYear)
02097 {
02098 QCString timeString = timeParam;
02099
02100 bool ok = true;
02101 uint interval = 0;
02102 bool negative = (timeString[0] == '-');
02103 if (negative)
02104 timeString = timeString.right(1);
02105 uint length = timeString.length();
02106 switch (timeString[length - 1])
02107 {
02108 case 'Y':
02109 if (!allowMonthYear)
02110 ok = false;
02111 recurType = KARecurrence::ANNUAL_DATE;
02112 timeString = timeString.left(length - 1);
02113 break;
02114 case 'W':
02115 recurType = KARecurrence::WEEKLY;
02116 timeString = timeString.left(length - 1);
02117 break;
02118 case 'D':
02119 recurType = KARecurrence::DAILY;
02120 timeString = timeString.left(length - 1);
02121 break;
02122 case 'M':
02123 {
02124 int i = timeString.find('H');
02125 if (i < 0)
02126 {
02127 if (!allowMonthYear)
02128 ok = false;
02129 recurType = KARecurrence::MONTHLY_DAY;
02130 timeString = timeString.left(length - 1);
02131 }
02132 else
02133 {
02134 recurType = KARecurrence::MINUTELY;
02135 interval = timeString.left(i).toUInt(&ok) * 60;
02136 timeString = timeString.mid(i + 1, length - i - 2);
02137 }
02138 break;
02139 }
02140 default:
02141 recurType = KARecurrence::MINUTELY;
02142 break;
02143 }
02144 if (ok)
02145 interval += timeString.toUInt(&ok);
02146 if (!allowMonthYear)
02147 {
02148
02149 switch (recurType)
02150 {
02151 case KARecurrence::WEEKLY:
02152 interval *= 7;
02153
02154 case KARecurrence::DAILY:
02155 interval *= 24*60;
02156 break;
02157 default:
02158 break;
02159 }
02160 }
02161 timeInterval = static_cast<int>(interval);
02162 if (negative)
02163 timeInterval = -timeInterval;
02164 return ok;
02165 }
02166
02167 KAlarmApp::ProcData::ProcData(ShellProcess* p, ShellProcess* logp, KAEvent* e, KAAlarm* a, int f)
02168 : process(p),
02169 logProcess(logp),
02170 event(e),
02171 alarm(a),
02172 messageBoxParent(0),
02173 flags(f)
02174 { }
02175
02176 KAlarmApp::ProcData::~ProcData()
02177 {
02178 while (!tempFiles.isEmpty())
02179 {
02180
02181 QFile f(tempFiles.first());
02182 f.remove();
02183 tempFiles.remove(tempFiles.begin());
02184 }
02185 delete process;
02186 delete event;
02187 delete alarm;
02188 }