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