00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "kalarm.h"
00026
00027 #include <stdlib.h>
00028 #include <ctype.h>
00029 #include <iostream>
00030
00031 #include <qfile.h>
00032
00033 #include <kcmdlineargs.h>
00034 #include <kmessagebox.h>
00035 #include <klocale.h>
00036 #include <kstandarddirs.h>
00037 #include <kconfig.h>
00038 #include <kaboutdata.h>
00039 #include <dcopclient.h>
00040 #include <kprocess.h>
00041 #include <kfileitem.h>
00042 #include <kaction.h>
00043 #include <kstdaction.h>
00044 #include <kdebug.h>
00045
00046 #include <kalarmd/clientinfo.h>
00047
00048 #include <libkcal/calformat.h>
00049
00050 #include "alarmcalendar.h"
00051 #include "mainwindow.h"
00052 #include "messagewin.h"
00053 #include "daemongui.h"
00054 #include "traywindow.h"
00055 #include "prefsettings.h"
00056 #include "prefdlg.h"
00057 #include "kalarmapp.moc"
00058
00059 #include <netwm.h>
00060
00061 extern QCString execArguments;
00062
00063 #define DAEMON_APP_NAME_DEF "kalarmd"
00064 const char* DCOP_OBJECT_NAME = "display";
00065 const char* GUI_DCOP_OBJECT_NAME = "tray";
00066 const char* DAEMON_APP_NAME = DAEMON_APP_NAME_DEF;
00067 const char* DAEMON_DCOP_OBJECT = "ad";
00068
00069 int marginKDE2 = 0;
00070
00071 static bool convWakeTime(const QCString timeParam, QDateTime&, bool& noTime);
00072
00073 KAlarmApp* KAlarmApp::theInstance = 0L;
00074 int KAlarmApp::activeCount = 0;
00075
00076
00077
00078
00079
00080 KAlarmApp::KAlarmApp()
00081 : KUniqueApplication(),
00082 mDcopHandler(0L),
00083 mDaemonGuiHandler(0L),
00084 mTrayWindow(0L),
00085 mCalendar(new AlarmCalendar),
00086 mSettings(new Settings(0L)),
00087 mDaemonCheckInterval(0),
00088 mDaemonRegistered(false),
00089 mDaemonRunning(false),
00090 mSessionClosingDown(false)
00091 {
00092 #if KDE_VERSION < 290
00093 marginKDE2 = KDialog::marginHint();
00094 #endif
00095 mSettings->loadSettings();
00096 connect(mSettings, SIGNAL(settingsChanged()), this, SLOT(slotSettingsChanged()));
00097 CalFormat::setApplication(aboutData()->programName(),
00098 QString::fromLatin1("-//K Desktop Environment//NONSGML %1 " KALARM_VERSION "//EN")
00099 .arg(aboutData()->programName()));
00100 readDaemonCheckInterval();
00101
00102
00103 NETRootInfo nri(qt_xdisplay(), NET::SupportingWMCheck);
00104 const char* wmname = nri.wmName();
00105 mKDEDesktop = wmname && !strcmp(wmname, "KWin");
00106
00107 mOldRunInSystemTray = mKDEDesktop && mSettings->runInSystemTray();
00108 mDisableAlarmsIfStopped = mOldRunInSystemTray && mSettings->disableAlarmsIfStopped();
00109 mStartOfDay = mSettings->startOfDay();
00110 if (mSettings->startOfDayChanged())
00111 mStartOfDay.setHMS(100,0,0);
00112
00113
00114 KActionCollection* actions = new KActionCollection(this);
00115 mActionAlarmEnable = new ActionAlarmsEnabled(Qt::CTRL+Qt::Key_E, this, SLOT(toggleAlarmsEnabled()), actions, "alarmenable");
00116 mActionPrefs = KStdAction::preferences(this, SLOT(slotPreferences()), actions);
00117 #if KDE_VERSION >= 308
00118 mActionDaemonControl = new KAction(i18n("Control Alarm &Daemon..."), mActionPrefs->iconSet(),
00119 #else
00120 mActionDaemonControl = new KAction(i18n("Configure Alarm &Daemon..."), mActionPrefs->iconSet(),
00121 #endif
00122 0, this, SLOT(slotDaemonControl()), actions, "controldaemon");
00123 }
00124
00125
00126
00127 KAlarmApp::~KAlarmApp()
00128 {
00129 mCalendar->close();
00130 }
00131
00132
00133
00134
00135
00136 KAlarmApp* KAlarmApp::getInstance()
00137 {
00138 if (!theInstance)
00139 theInstance = new KAlarmApp;
00140 return theInstance;
00141 }
00142
00143
00144
00145
00146 bool KAlarmApp::restoreSession()
00147 {
00148 if (!isRestored())
00149 return false;
00150
00151
00152 kdDebug(5950) << "KAlarmApp::restoreSession(): Restoring\n";
00153 ++activeCount;
00154 int exitCode = !initCheck(true);
00155 KAlarmMainWindow* trayParent = 0L;
00156 for (int i = 1; KMainWindow::canBeRestored(i); ++i)
00157 {
00158 QString type = KMainWindow::classNameOfToplevel(i);
00159 if (type == QString::fromLatin1("KAlarmMainWindow"))
00160 {
00161 KAlarmMainWindow* win = new KAlarmMainWindow(true);
00162 win->restore(i, false);
00163 if (win->hiddenTrayParent())
00164 trayParent = win;
00165 else
00166 win->show();
00167 }
00168 else if (type == QString::fromLatin1("MessageWin"))
00169 {
00170 MessageWin* win = new MessageWin;
00171 win->restore(i, false);
00172 if (win->errorMessage())
00173 delete win;
00174 else
00175 win->show();
00176 }
00177 }
00178 initCheck();
00179
00180
00181
00182 if (mSettings->autostartTrayIcon()
00183 || KAlarmMainWindow::count() && runInSystemTray())
00184 displayTrayIcon(true, trayParent);
00185
00186 --activeCount;
00187 quitIf(exitCode);
00188 return true;
00189 }
00190
00191
00192
00193
00194
00195 int KAlarmApp::newInstance()
00196 {
00197 kdDebug(5950)<<"KAlarmApp::newInstance()\n";
00198 ++activeCount;
00199 int exitCode = 0;
00200 static bool firstInstance = true;
00201 bool skip = (firstInstance && isRestored());
00202 firstInstance = false;
00203 if (!skip)
00204 {
00205 QString usage;
00206 KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
00207
00208
00209
00210
00211
00212
00213
00214 do
00215 {
00216 if (args->isSet("stop"))
00217 {
00218
00219 kdDebug(5950)<<"KAlarmApp::newInstance(): stop\n";
00220 args->clear();
00221 if (!stopDaemon())
00222 {
00223 exitCode = 1;
00224 break;
00225 }
00226 }
00227 else
00228 if (args->isSet("reset"))
00229 {
00230
00231 kdDebug(5950)<<"KAlarmApp::newInstance(): reset\n";
00232 args->clear();
00233 setUpDcop();
00234 resetDaemon();
00235 }
00236 else
00237 if (args->isSet("tray"))
00238 {
00239
00240 kdDebug(5950)<<"KAlarmApp::newInstance(): tray\n";
00241 args->clear();
00242 setUpDcop();
00243 if (!mKDEDesktop
00244 || !initCheck())
00245 {
00246 exitCode = 1;
00247 break;
00248 }
00249 if (runInSystemTray() && !KAlarmMainWindow::count())
00250 new KAlarmMainWindow;
00251 if (!displayTrayIcon(true))
00252 {
00253 exitCode = 1;
00254 break;
00255 }
00256 }
00257 else
00258 if (args->isSet("handleEvent") || args->isSet("triggerEvent") || args->isSet("cancelEvent") || args->isSet("calendarURL")
00259 || args->isSet("displayEvent"))
00260 {
00261
00262 kdDebug(5950)<<"KAlarmApp::newInstance(): handle event\n";
00263 EventFunc function = EVENT_HANDLE;
00264 int count = 0;
00265 const char* option = 0;
00266 if (args->isSet("handleEvent")) { function = EVENT_HANDLE; option = "handleEvent"; ++count; }
00267 if (args->isSet("displayEvent")) { function = EVENT_TRIGGER; option = "displayEvent"; ++count; }
00268 if (args->isSet("triggerEvent")) { function = EVENT_TRIGGER; option = "triggerEvent"; ++count; }
00269 if (args->isSet("cancelEvent")) { function = EVENT_CANCEL; option = "cancelEvent"; ++count; }
00270 if (!count)
00271 {
00272 usage = i18n("%1 requires %2, %3 or %4").arg(QString::fromLatin1("--calendarURL")).arg(QString::fromLatin1("--handleEvent")).arg(QString::fromLatin1("--triggerEvent")).arg(QString::fromLatin1("--cancelEvent"));
00273 break;
00274 }
00275 if (count > 1)
00276 {
00277 usage = i18n("%1, %2, %3 mutually exclusive").arg(QString::fromLatin1("--handleEvent")).arg(QString::fromLatin1("--triggerEvent")).arg(QString::fromLatin1("--cancelEvent"));
00278 break;
00279 }
00280 if (!initCheck(true))
00281 {
00282 exitCode = 1;
00283 break;
00284 }
00285 if (args->isSet("calendarURL"))
00286 {
00287 QString calendarUrl = args->getOption("calendarURL");
00288 if (KURL(calendarUrl).url() != mCalendar->urlString())
00289 {
00290 usage = i18n("%1: wrong calendar file").arg(QString::fromLatin1("--calendarURL"));
00291 break;
00292 }
00293 }
00294 QString eventID = args->getOption(option);
00295 args->clear();
00296 setUpDcop();
00297 if (!handleEvent(eventID, function))
00298 {
00299 exitCode = 1;
00300 break;
00301 }
00302 }
00303 else
00304 if (args->isSet("file") || args->isSet("exec") || args->count())
00305 {
00306
00307 KAlarmAlarm::Type type = KAlarmAlarm::MESSAGE;
00308 QCString alMessage;
00309 if (args->isSet("file"))
00310 {
00311 kdDebug(5950)<<"KAlarmApp::newInstance(): file\n";
00312 if (args->isSet("exec"))
00313 {
00314 usage = i18n("%1 incompatible with %2").arg(QString::fromLatin1("--exec")).arg(QString::fromLatin1("--file"));
00315 break;
00316 }
00317 if (args->count())
00318 {
00319 usage = i18n("message incompatible with %1").arg(QString::fromLatin1("--file"));
00320 break;
00321 }
00322 alMessage = args->getOption("file");
00323 type = KAlarmAlarm::FILE;
00324 }
00325 else if (args->isSet("exec"))
00326 {
00327 kdDebug(5950)<<"KAlarmApp::newInstance(): exec\n";
00328 alMessage = execArguments;
00329 type = KAlarmAlarm::COMMAND;
00330 }
00331 #ifdef KALARM_EMAIL
00332 else if (args->isSet("mail"))
00333 {
00334 kdDebug(5950)<<"KAlarmApp::newInstance(): mail\n";
00335 if (args->isSet("subject"))
00336 alSubject = args->getOption("subject");
00337 alAddrs = args->getOptionList("mail");
00338 for (QCStringList::iterator i = alAddrs.begin(); i != alAddrs.end(); ++i)
00339 {
00340 QString addr = QString::fromLatin1(*i);
00341 if (!KAMail::checkEmailAddress(addr))
00342 USAGE(i18n("%1: invalid email address").arg(QString::fromLatin1("--mail")))
00343 alAddresses += addr;
00344 }
00345 alMessage = args->arg(0);
00346 type = KAlarmAlarm::EMAIL;
00347 }
00348 #endif
00349 else
00350 {
00351 kdDebug(5950)<<"KAlarmApp::newInstance(): message\n";
00352 alMessage = args->arg(0);
00353 }
00354
00355 bool alarmNoTime = false;
00356 QDateTime alarmTime, endTime;
00357 QColor bgColour = mSettings->defaultBgColour();
00358 int repeatCount = 0;
00359 int repeatInterval = 0;
00360 KAlarmEvent::RecurType recurType = KAlarmEvent::NO_RECUR;
00361 if (args->isSet("color"))
00362 {
00363
00364 QCString colourText = args->getOption("color");
00365 if (static_cast<const char*>(colourText)[0] == '0'
00366 && tolower(static_cast<const char*>(colourText)[1]) == 'x')
00367 colourText.replace(0, 2, "#");
00368 bgColour.setNamedColor(colourText);
00369 if (!bgColour.isValid())
00370 {
00371 usage = i18n("Invalid %1 parameter").arg(QString::fromLatin1("--color"));
00372 break;
00373 }
00374 }
00375
00376 if (args->isSet("time"))
00377 {
00378 QCString dateTime = args->getOption("time");
00379 if (!convWakeTime(dateTime, alarmTime, alarmNoTime))
00380 {
00381 usage = i18n("Invalid %1 parameter").arg(QString::fromLatin1("--time"));
00382 break;
00383 }
00384 }
00385 else
00386 alarmTime = QDateTime::currentDateTime();
00387
00388 if (args->isSet("interval"))
00389 {
00390
00391 if (args->isSet("login"))
00392 {
00393 usage = i18n("%1 incompatible with %2").arg(QString::fromLatin1("--login")).arg(QString::fromLatin1("--interval"));
00394 break;
00395 }
00396 if (!args->isSet("repeat") && !args->isSet("until"))
00397 {
00398 usage = i18n("%1 requires %2 or %3").arg(QString::fromLatin1("--interval")).arg(QString::fromLatin1("--repeat")).arg(QString::fromLatin1("--until"));
00399 break;
00400 }
00401 bool ok;
00402 if (args->isSet("repeat"))
00403 {
00404 repeatCount = args->getOption("repeat").toInt(&ok);
00405 if (!ok || !repeatCount || repeatCount < -1)
00406 {
00407 usage = i18n("Invalid %1 parameter").arg(QString::fromLatin1("--repeat"));
00408 break;
00409 }
00410 }
00411 else
00412 {
00413 QCString dateTime = args->getOption("until");
00414 if (!convWakeTime(dateTime, endTime, alarmNoTime))
00415 {
00416 usage = i18n("Invalid %1 parameter").arg(QString::fromLatin1("--until"));
00417 break;
00418 }
00419 if (endTime < alarmTime)
00420 {
00421 usage = i18n("%1 earlier than %2").arg(QString::fromLatin1("--until")).arg(QString::fromLatin1("--time"));
00422 break;
00423 }
00424 }
00425
00426
00427 ok = true;
00428 uint interval = 0;
00429 QCString optval = args->getOption("interval");
00430 uint length = optval.length();
00431 switch (optval[length - 1])
00432 {
00433 case 'Y':
00434 recurType = KAlarmEvent::ANNUAL_DATE;
00435 optval = optval.left(length - 1);
00436 break;
00437 case 'W':
00438 recurType = KAlarmEvent::WEEKLY;
00439 optval = optval.left(length - 1);
00440 break;
00441 case 'D':
00442 recurType = KAlarmEvent::DAILY;
00443 optval = optval.left(length - 1);
00444 break;
00445 case 'M':
00446 {
00447 int i = optval.find('H');
00448 if (i < 0)
00449 recurType = KAlarmEvent::MONTHLY_DAY;
00450 else
00451 {
00452 recurType = KAlarmEvent::MINUTELY;
00453 interval = optval.left(i).toUInt(&ok) * 60;
00454 optval = optval.right(length - i - 1);
00455 }
00456 break;
00457 }
00458 default:
00459 recurType = KAlarmEvent::MINUTELY;
00460 break;
00461 }
00462 if (ok)
00463 interval += optval.toUInt(&ok);
00464 repeatInterval = static_cast<int>(interval);
00465 if (!ok || repeatInterval < 0)
00466 {
00467 usage = i18n("Invalid %1 parameter").arg(QString::fromLatin1("--interval"));
00468 break;
00469 }
00470 }
00471 else
00472 {
00473 if (args->isSet("repeat"))
00474 {
00475 usage = i18n("%1 requires %2").arg(QString::fromLatin1("--repeat")).arg(QString::fromLatin1("--interval"));
00476 break;
00477 }
00478 if (args->isSet("until"))
00479 {
00480 usage = i18n("%1 requires %2").arg(QString::fromLatin1("--until")).arg(QString::fromLatin1("--interval"));
00481 break;
00482 }
00483 }
00484
00485 QCString audioFile;
00486 if (args->isSet("sound"))
00487 {
00488
00489 if (args->isSet("beep"))
00490 {
00491 usage = i18n("%1 incompatible with %2").arg(QString::fromLatin1("--beep")).arg(QString::fromLatin1("--sound"));
00492 break;
00493 }
00494 audioFile = args->getOption("sound");
00495 }
00496
00497 int flags = 0;
00498 if (args->isSet("ack-confirm"))
00499 flags |= KAlarmEvent::CONFIRM_ACK;
00500 if (args->isSet("beep"))
00501 flags |= KAlarmEvent::BEEP;
00502 if (args->isSet("late-cancel"))
00503 flags |= KAlarmEvent::LATE_CANCEL;
00504 if (args->isSet("login"))
00505 flags |= KAlarmEvent::REPEAT_AT_LOGIN;
00506 args->clear();
00507
00508
00509 setUpDcop();
00510 if (!scheduleEvent(alMessage, alarmTime, bgColour, flags, audioFile, type, recurType,
00511 repeatInterval, repeatCount, endTime))
00512 {
00513 exitCode = 1;
00514 break;
00515 }
00516 }
00517 else
00518 {
00519
00520 kdDebug(5950)<<"KAlarmApp::newInstance(): interactive\n";
00521 if (args->isSet("ack-confirm"))
00522 usage += QString::fromLatin1("--ack-confirm ");
00523 if (args->isSet("beep"))
00524 usage += QString::fromLatin1("--beep ");
00525 if (args->isSet("color"))
00526 usage += QString::fromLatin1("--color ");
00527 if (args->isSet("late-cancel"))
00528 usage += QString::fromLatin1("--late-cancel ");
00529 if (args->isSet("login"))
00530 usage += QString::fromLatin1("--login ");
00531 if (args->isSet("sound"))
00532 usage += QString::fromLatin1("--sound ");
00533 if (args->isSet("time"))
00534 usage += QString::fromLatin1("--time ");
00535 if (!usage.isEmpty())
00536 {
00537 usage += i18n(": option(s) only valid with a message/%1/%2").arg(QString::fromLatin1("--file")).arg(QString::fromLatin1("--exec"));
00538 break;
00539 }
00540
00541 args->clear();
00542 setUpDcop();
00543 if (!initCheck())
00544 {
00545 exitCode = 1;
00546 break;
00547 }
00548
00549 (new KAlarmMainWindow)->show();
00550 }
00551 } while (0);
00552
00553 if (!usage.isEmpty())
00554 {
00555
00556
00557 std::cerr << usage << i18n("\nUse --help to get a list of available command line options.\n");
00558 exitCode = 1;
00559 }
00560 }
00561 --activeCount;
00562
00563
00564
00565
00566 quitIf(exitCode);
00567 return exitCode;
00568 }
00569
00570
00571
00572
00573 void KAlarmApp::quitIf(int exitCode)
00574 {
00575 if (activeCount <= 0 && !KAlarmMainWindow::count() && !MessageWin::instanceCount() && !mTrayWindow)
00576 {
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 kdDebug(5950) << "KAlarmApp::quitIf(" << exitCode << "): quitting" << endl;
00592 dcopClient()->registerAs(QCString(aboutData()->appName()) + "-quitting");
00593 exit(exitCode);
00594 }
00595 }
00596
00597
00598
00599
00600 void KAlarmApp::commitData(QSessionManager& sm)
00601 {
00602 mSessionClosingDown = true;
00603 KUniqueApplication::commitData(sm);
00604 mSessionClosingDown = false;
00605 }
00606
00607
00608
00609
00610 void KAlarmApp::removeWindow(TrayWindow*)
00611 {
00612 mTrayWindow = 0L;
00613 quitIf();
00614 }
00615
00616
00617
00618
00619 bool KAlarmApp::displayTrayIcon(bool show, KAlarmMainWindow* parent)
00620 {
00621 if (show)
00622 {
00623 if (!mTrayWindow)
00624 {
00625 if (!mKDEDesktop)
00626 return false;
00627 mTrayWindow = new TrayWindow(parent ? parent : KAlarmMainWindow::firstWindow());
00628 connect(mTrayWindow, SIGNAL(deleted()), this, SIGNAL(trayIconToggled()));
00629 mTrayWindow->show();
00630 emit trayIconToggled();
00631 }
00632 }
00633 else if (mTrayWindow)
00634 delete mTrayWindow;
00635 return true;
00636 }
00637
00638
00639
00640
00641 void KAlarmApp::displayMainWindow()
00642 {
00643 KAlarmMainWindow* win = KAlarmMainWindow::firstWindow();
00644 if (!win)
00645 {
00646 if (initCheck())
00647 (new KAlarmMainWindow)->show();
00648 }
00649 else
00650 {
00651
00652 if (!win->isVisible())
00653 {
00654 win->hide();
00655 win->showNormal();
00656 }
00657 win->raise();
00658 win->setActiveWindow();
00659 }
00660 }
00661
00662 KAlarmMainWindow* KAlarmApp::trayMainWindow() const
00663 {
00664 return mTrayWindow ? mTrayWindow->assocMainWindow() : 0L;
00665 }
00666
00667
00668
00669
00670
00671
00672 void KAlarmApp::toggleAlarmsEnabled()
00673 {
00674 if (mDaemonGuiHandler)
00675 mDaemonGuiHandler->setAlarmsEnabled(!mActionAlarmEnable->alarmsEnabled());
00676 }
00677
00678
00679
00680
00681 void KAlarmApp::slotPreferences()
00682 {
00683 (new KAlarmPrefDlg(mSettings))->exec();
00684 }
00685
00686
00687
00688
00689
00690 void KAlarmApp::slotDaemonControl()
00691 {
00692 KProcess proc;
00693 proc << locate("exe", QString::fromLatin1("kcmshell"));
00694 #if KDE_VERSION >= 308
00695 proc << QString::fromLatin1("kcmkded");
00696 #else
00697 proc << QString::fromLatin1("alarmdaemonctrl");
00698 #endif
00699 proc.start(KProcess::DontCare);
00700 }
00701
00702
00703
00704
00705 void KAlarmApp::slotSettingsChanged()
00706 {
00707 bool newRunInSysTray = mSettings->runInSystemTray() && mKDEDesktop;
00708 if (newRunInSysTray != mOldRunInSystemTray)
00709 {
00710
00711 ++activeCount;
00712 KAlarmMainWindow* win = mTrayWindow ? mTrayWindow->assocMainWindow() : 0L;
00713 delete mTrayWindow;
00714 mTrayWindow = 0L;
00715 mOldRunInSystemTray = newRunInSysTray;
00716 if (newRunInSysTray)
00717 {
00718 if (!KAlarmMainWindow::count())
00719 new KAlarmMainWindow;
00720 displayTrayIcon(true);
00721 }
00722 else
00723 {
00724 if (win && win->isHidden())
00725 delete win;
00726 displayTrayIcon(true);
00727 }
00728 --activeCount;
00729 }
00730
00731 bool newDisableIfStopped = mKDEDesktop && mSettings->runInSystemTray() && mSettings->disableAlarmsIfStopped();
00732 if (newDisableIfStopped != mDisableAlarmsIfStopped)
00733 {
00734 mDisableAlarmsIfStopped = newDisableIfStopped;
00735 registerWithDaemon(true);
00736 }
00737
00738
00739 if (mSettings->startOfDay() != mStartOfDay)
00740 changeStartOfDay();
00741 }
00742
00743
00744
00745
00746 void KAlarmApp::changeStartOfDay()
00747 {
00748 if (KAlarmEvent::adjustStartOfDay(mCalendar->events()))
00749 {
00750 mCalendar->save();
00751 reloadDaemon();
00752 }
00753 mSettings->updateStartOfDayCheck();
00754 mStartOfDay = mSettings->startOfDay();
00755 }
00756
00757
00758
00759
00760 bool KAlarmApp::runInSystemTray() const
00761 {
00762 return mSettings->runInSystemTray() && mKDEDesktop;
00763 }
00764
00765
00766
00767
00768
00769
00770 bool KAlarmApp::scheduleEvent(const QString& message, const QDateTime& dateTime, const QColor& bg,
00771 int flags, const QString& audioFile, KAlarmAlarm::Type type,
00772 KAlarmEvent::RecurType recurType, int repeatInterval, int repeatCount,
00773 const QDateTime& endTime)
00774 {
00775 kdDebug(5950) << "KAlarmApp::scheduleEvent(): " << message << endl;
00776 if (!dateTime.isValid())
00777 return false;
00778 QDateTime now = QDateTime::currentDateTime();
00779 if ((flags & KAlarmEvent::LATE_CANCEL) && dateTime < now.addSecs(-maxLateness()))
00780 return true;
00781 QDateTime alarmTime = dateTime;
00782
00783 alarmTime.setTime(QTime(alarmTime.time().hour(), alarmTime.time().minute(), 0));
00784 bool display = (alarmTime <= now);
00785
00786 KAlarmEvent event(alarmTime, message, bg, type, flags);
00787 if (!audioFile.isEmpty())
00788 event.setAudioFile(audioFile);
00789 switch (recurType)
00790 {
00791 case KAlarmEvent::MINUTELY:
00792 event.setRecurMinutely(repeatInterval, repeatCount, endTime);
00793 break;
00794 case KAlarmEvent::DAILY:
00795 event.setRecurDaily(repeatInterval, repeatCount, endTime.date());
00796 break;
00797 case KAlarmEvent::WEEKLY:
00798 {
00799 QBitArray days(7);
00800 days.setBit(QDate::currentDate().dayOfWeek() - 1);
00801 event.setRecurWeekly(repeatInterval, days, repeatCount, endTime.date());
00802 break;
00803 }
00804 case KAlarmEvent::MONTHLY_DAY:
00805 {
00806 QValueList<int> days;
00807 days.append(QDate::currentDate().day());
00808 event.setRecurMonthlyByDate(repeatInterval, days, repeatCount, endTime.date());
00809 break;
00810 }
00811 case KAlarmEvent::ANNUAL_DATE:
00812 {
00813 QValueList<int> months;
00814 months.append(QDate::currentDate().month());
00815 event.setRecurAnnualByDate(repeatInterval, months, repeatCount, endTime.date());
00816 break;
00817 }
00818 default:
00819 recurType = KAlarmEvent::NO_RECUR;
00820 break;
00821 }
00822 if (display)
00823 {
00824
00825 execAlarm(event, event.firstAlarm(), false);
00826 if (recurType == KAlarmEvent::NO_RECUR
00827 || event.setNextOccurrence(now) == KAlarmEvent::NO_OCCURRENCE)
00828 return true;
00829 }
00830 return addEvent(event, 0L);
00831 }
00832
00833
00834
00835
00836
00837
00838
00839 void KAlarmApp::handleEvent(const QString& urlString, const QString& eventID, EventFunc function)
00840 {
00841 kdDebug(5950) << "KAlarmApp::handleEvent(DCOP): " << eventID << endl;
00842 if (KURL(urlString).url() != mCalendar->urlString())
00843 kdError(5950) << "KAlarmApp::handleEvent(DCOP): wrong calendar file " << urlString << endl;
00844 else
00845 handleEvent(eventID, function);
00846 }
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856 bool KAlarmApp::handleEvent(const QString& eventID, EventFunc function)
00857 {
00858 kdDebug(5950) << "KAlarmApp::handleEvent(): " << eventID << ", " << (function==EVENT_TRIGGER?"TRIGGER":function==EVENT_CANCEL?"CANCEL":function==EVENT_HANDLE?"HANDLE":"?") << endl;
00859 Event* kcalEvent = mCalendar->event(eventID);
00860 if (!kcalEvent)
00861 {
00862 kdError(5950) << "KAlarmApp::handleEvent(): event ID not found: " << eventID << endl;
00863 return false;
00864 }
00865 KAlarmEvent event(*kcalEvent);
00866 AlarmFunc alfunction = ALARM_TRIGGER;
00867 switch (function)
00868 {
00869 case EVENT_TRIGGER:
00870 {
00871
00872
00873 KAlarmAlarm alarm = event.firstAlarm();
00874 if (alarm.valid())
00875 handleAlarm(event, alarm, ALARM_TRIGGER, true);
00876 break;
00877 }
00878 case EVENT_CANCEL:
00879 deleteEvent(event, 0L, false);
00880 break;
00881
00882 case EVENT_HANDLE:
00883 {
00884 QDateTime now = QDateTime::currentDateTime();
00885 bool updateCalAndDisplay = false;
00886 KAlarmAlarm displayAlarm;
00887
00888
00889 for (KAlarmAlarm alarm = event.firstAlarm(); alarm.valid(); alarm = event.nextAlarm(alarm))
00890 {
00891
00892 int secs = alarm.dateTime().secsTo(now);
00893 if (secs < 0)
00894 {
00895 kdDebug(5950) << "KAlarmApp::handleEvent(): alarm " << alarm.id() << ": not due\n";
00896 continue;
00897 }
00898 if (alarm.repeatAtLogin())
00899 {
00900
00901
00902
00903
00904 kdDebug(5950) << "KAlarmApp::handleEvent(): alarm " << alarm.id() << ": REPEAT_AT_LOGIN\n";
00905 if (secs < maxLateness())
00906 continue;
00907
00908
00909
00910 if (displayAlarm.valid())
00911 continue;
00912 }
00913 if (alarm.lateCancel())
00914 {
00915
00916 kdDebug(5950) << "KAlarmApp::handleEvent(): alarm " << alarm.id() << ": LATE_CANCEL\n";
00917 bool late = false;
00918 bool cancel = false;
00919 if (event.anyTime())
00920 {
00921
00922 QDateTime limit(alarm.date().addDays(1), mSettings->startOfDay());
00923 if (now >= limit)
00924 {
00925
00926
00927 QDateTime next;
00928 KAlarmEvent::OccurType type = event.previousOccurrence(now, next);
00929 switch (type)
00930 {
00931 case KAlarmEvent::FIRST_OCCURRENCE:
00932 case KAlarmEvent::RECURRENCE_DATE:
00933 case KAlarmEvent::RECURRENCE_DATE_TIME:
00934 case KAlarmEvent::LAST_OCCURRENCE:
00935 limit.setDate(next.date().addDays(1));
00936 limit.setTime(mSettings->startOfDay());
00937 if (now >= limit)
00938 {
00939 if (type == KAlarmEvent::LAST_OCCURRENCE)
00940 cancel = true;
00941 else
00942 late = true;
00943 }
00944 break;
00945 case KAlarmEvent::NO_OCCURRENCE:
00946 default:
00947 late = true;
00948 break;
00949 }
00950 }
00951 }
00952 else
00953 {
00954
00955 int maxlate = maxLateness();
00956 if (secs > maxlate)
00957 {
00958
00959
00960 QDateTime next;
00961 KAlarmEvent::OccurType type = event.previousOccurrence(now, next);
00962 switch (type)
00963 {
00964 case KAlarmEvent::FIRST_OCCURRENCE:
00965 case KAlarmEvent::RECURRENCE_DATE:
00966 case KAlarmEvent::RECURRENCE_DATE_TIME:
00967 case KAlarmEvent::LAST_OCCURRENCE:
00968 if (next.secsTo(now) > maxlate)
00969 {
00970 if (type == KAlarmEvent::LAST_OCCURRENCE)
00971 cancel = true;
00972 else
00973 late = true;
00974 }
00975 break;
00976 case KAlarmEvent::NO_OCCURRENCE:
00977 default:
00978 late = true;
00979 break;
00980 }
00981 }
00982 }
00983
00984 if (cancel)
00985 {
00986
00987 handleAlarm(event, alarm, ALARM_CANCEL, false);
00988 updateCalAndDisplay = true;
00989 continue;
00990 }
00991 if (late)
00992 {
00993
00994 handleAlarm(event, alarm, ALARM_RESCHEDULE, false);
00995 updateCalAndDisplay = true;
00996 continue;
00997 }
00998 }
00999 if (alfunction == ALARM_TRIGGER)
01000 {
01001 kdDebug(5950) << "KAlarmApp::handleEvent(): alarm " << alarm.id() << ": display\n";
01002 displayAlarm = alarm;
01003 alfunction = ALARM_RESCHEDULE;
01004 }
01005 else
01006 kdDebug(5950) << "KAlarmApp::handleEvent(): alarm " << alarm.id() << ": skip\n";
01007 }
01008
01009
01010
01011 if (displayAlarm.valid())
01012 handleAlarm(event, displayAlarm, ALARM_TRIGGER, true);
01013 else if (updateCalAndDisplay)
01014 updateEvent(event, 0L);
01015 else
01016 kdDebug(5950) << "KAlarmApp::handleEvent(): no action\n";
01017 break;
01018 }
01019 }
01020 return true;
01021 }
01022
01023
01024
01025
01026
01027 void KAlarmApp::rescheduleAlarm(KAlarmEvent& event, int alarmID)
01028 {
01029 kdDebug(5950) << "KAlarmApp::rescheduleAlarm(): " << event.id() << ":" << alarmID << endl;
01030 Event* kcalEvent = mCalendar->event(event.id());
01031 if (!kcalEvent)
01032 kdError(5950) << "KAlarmApp::rescheduleAlarm(): event ID not found: " << event.id() << endl;
01033 else
01034 {
01035 KAlarmAlarm alarm = event.alarm(alarmID);
01036 if (!alarm.valid())
01037 kdError(5950) << "KAlarmApp::rescheduleAlarm(): alarm sequence not found: " << event.id() << ":" << alarmID << endl;
01038 handleAlarm(event, alarm, ALARM_RESCHEDULE, true);
01039 }
01040 }
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050 void KAlarmApp::handleAlarm(KAlarmEvent& event, KAlarmAlarm& alarm, AlarmFunc function, bool updateCalAndDisplay)
01051 {
01052 switch (function)
01053 {
01054 case ALARM_TRIGGER:
01055 kdDebug(5950) << "KAlarmApp::handleAlarm(): TRIGGER" << endl;
01056 execAlarm(event, alarm, true);
01057 break;
01058
01059 case ALARM_RESCHEDULE:
01060 {
01061
01062 kdDebug(5950) << "KAlarmApp::handleAlarm(): RESCHEDULE" << endl;
01063 bool update = false;
01064 if (alarm.deferred())
01065 {
01066
01067 event.removeAlarm(alarm.id());
01068 update = true;
01069 }
01070 else if (!alarm.repeatAtLogin())
01071 {
01072 switch (event.setNextOccurrence(QDateTime::currentDateTime()))
01073 {
01074 case KAlarmEvent::NO_OCCURRENCE:
01075
01076 if (alarm.id() == KAlarmEvent::MAIN_ALARM_ID && !event.audioFile().isEmpty())
01077 event.removeAlarm(KAlarmEvent::AUDIO_ALARM_ID);
01078 handleAlarm(event, alarm, ALARM_CANCEL, updateCalAndDisplay);
01079 break;
01080 case KAlarmEvent::RECURRENCE_DATE:
01081 case KAlarmEvent::RECURRENCE_DATE_TIME:
01082 case KAlarmEvent::LAST_OCCURRENCE:
01083
01084 if (updateCalAndDisplay)
01085 update = true;
01086 else
01087 event.setUpdated();
01088 break;
01089 case KAlarmEvent::FIRST_OCCURRENCE:
01090
01091 default:
01092 break;
01093 }
01094 if (event.deferred())
01095 {
01096 event.removeAlarm(KAlarmEvent::MAIN_ALARM_ID + KAlarmEvent::DEFERRAL_OFFSET);
01097 update = true;
01098 }
01099 }
01100 else if (updateCalAndDisplay && event.updated())
01101 update = true;
01102 if (update)
01103 updateEvent(event, 0);
01104 break;
01105 }
01106 case ALARM_CANCEL:
01107 {
01108 kdDebug(5950) << "KAlarmApp::handleAlarm(): CANCEL" << endl;
01109 event.removeAlarm(alarm.id());
01110 if (!event.alarmCount())
01111 deleteEvent(event, 0L, false);
01112 else if (updateCalAndDisplay)
01113 updateEvent(event, 0L);
01114 break;
01115 }
01116 default:
01117 kdError(5950) << "KAlarmApp::handleAlarm(): unknown function" << endl;
01118 }
01119 }
01120
01121
01122
01123
01124
01125 bool KAlarmApp::execAlarm(KAlarmEvent& event, const KAlarmAlarm& alarm, bool reschedule, bool allowDefer)
01126 {
01127 bool result = true;
01128 if (alarm.type() == KAlarmAlarm::COMMAND)
01129 {
01130 QString command = event.cleanText();
01131 kdDebug(5950) << "KAlarmApp::execAlarm(): COMMAND: " << command << endl;
01132 KShellProcess proc;
01133 proc << command;
01134 if (!proc.start(KProcess::DontCare))
01135 {
01136 kdDebug(5950) << "KAlarmApp::execAlarm(): failed\n";
01137 QString msg = i18n("Failed to execute command:");
01138 (new MessageWin(QString("%1\n%2").arg(msg).arg(command), event, alarm, reschedule))->show();
01139 result = false;
01140 }
01141 #if 0
01142 else (!proc.normalExit())
01143 {
01144 kdDebug(5950) << "KAlarmApp::execAlarm(): killed\n";
01145 (new MessageWin(i18n("Command execution error:"), event, alarm, reschedule))->show();
01146 result = false;
01147 }
01148 #endif
01149 if (reschedule)
01150 rescheduleAlarm(event, alarm.id());
01151 }
01152 #ifdef KALARM_EMAIL
01153 else if (alarm.type() == KAlarmAlarm::EMAIL)
01154 {
01155 QString addresses = event.emailAddresses();
01156 kdDebug(5950) << "KAlarmApp::execAlarm(): EMAIL: " << command << endl;
01157 if (1)
01158 {
01159 kdDebug(5950) << "KAlarmApp::execAlarm(): failed\n";
01160 (new MessageWin(i18n("Failed to send email"), event, alarm, reschedule))->show();
01161 result = false;
01162 }
01163 if (reschedule)
01164 rescheduleAlarm(event, alarm.id());
01165 }
01166 #endif
01167 else
01168 {
01169
01170 MessageWin* win = MessageWin::findEvent(event.id());
01171 if (win && (win->hasDefer() || alarm.repeatAtLogin()))
01172 win->repeat();
01173 else
01174 {
01175
01176
01177
01178 delete win;
01179 (new MessageWin(event, alarm, reschedule, allowDefer))->show();
01180 }
01181 }
01182 return result;
01183 }
01184
01185
01186
01187
01188
01189
01190
01191 bool KAlarmApp::addEvent(const KAlarmEvent& event, KAlarmMainWindow* win)
01192 {
01193 kdDebug(5950) << "KAlarmApp::addEvent(): " << event.id() << endl;
01194 if (!initCheck())
01195 return false;
01196
01197
01198 mCalendar->addEvent(event);
01199 mCalendar->save();
01200
01201
01202 reloadDaemon();
01203
01204
01205 KAlarmMainWindow::addEvent(event, win);
01206 return true;
01207 }
01208
01209
01210
01211
01212
01213
01214
01215 void KAlarmApp::modifyEvent(const QString& oldEventID, const KAlarmEvent& newEvent, KAlarmMainWindow* win)
01216 {
01217 kdDebug(5950) << "KAlarmApp::modifyEvent(): '" << oldEventID << endl;
01218
01219
01220 mCalendar->deleteEvent(oldEventID);
01221 mCalendar->addEvent(newEvent);
01222 mCalendar->save();
01223
01224
01225 reloadDaemon();
01226
01227
01228 KAlarmMainWindow::modifyEvent(oldEventID, newEvent, win);
01229 }
01230
01231
01232
01233
01234
01235
01236
01237 void KAlarmApp::updateEvent(const KAlarmEvent& event, KAlarmMainWindow* win)
01238 {
01239 kdDebug(5950) << "KAlarmApp::updateEvent(): " << event.id() << endl;
01240
01241
01242 const_cast<KAlarmEvent&>(event).incrementRevision();
01243 mCalendar->updateEvent(event);
01244 mCalendar->save();
01245
01246
01247 reloadDaemon();
01248
01249
01250 KAlarmMainWindow::modifyEvent(event, win);
01251 }
01252
01253
01254
01255
01256
01257
01258 void KAlarmApp::deleteEvent(KAlarmEvent& event, KAlarmMainWindow* win, bool tellDaemon)
01259 {
01260 kdDebug(5950) << "KAlarmApp::deleteEvent(): " << event.id() << endl;
01261
01262
01263 KAlarmMainWindow::deleteEvent(event, win);
01264
01265
01266 mCalendar->deleteEvent(event.id());
01267 mCalendar->save();
01268
01269
01270 if (tellDaemon)
01271 reloadDaemon();
01272 }
01273
01274
01275
01276
01277 void KAlarmApp::setUpDcop()
01278 {
01279 if (!mDcopHandler)
01280 {
01281 mDcopHandler = new DcopHandler(QString::fromLatin1(DCOP_OBJECT_NAME));
01282 mDaemonGuiHandler = new DaemonGuiHandler(QString::fromLatin1(GUI_DCOP_OBJECT_NAME));
01283 }
01284 }
01285
01286
01287
01288
01289
01290 bool KAlarmApp::initCheck(bool calendarOnly)
01291 {
01292 if (!mCalendar->isOpen())
01293 {
01294 kdDebug(5950) << "KAlarmApp::initCheck(): opening calendar\n";
01295
01296
01297 if (!mCalendar->open())
01298 return false;
01299
01300 if (!mStartOfDay.isValid())
01301 changeStartOfDay();
01302
01303 if (!calendarOnly)
01304 startDaemon();
01305 }
01306 else if (!mDaemonRegistered)
01307 startDaemon();
01308
01309 if (!calendarOnly)
01310 setUpDcop();
01311 return true;
01312 }
01313
01314
01315
01316
01317 void KAlarmApp::startDaemon()
01318 {
01319 kdDebug(5950) << "KAlarmApp::startDaemon()\n";
01320 mCalendar->getURL();
01321 if (!dcopClient()->isApplicationRegistered(DAEMON_APP_NAME))
01322 {
01323
01324
01325 QString execStr = locate("exe",QString::fromLatin1(DAEMON_APP_NAME));
01326 system(QFile::encodeName(execStr));
01327 kdDebug(5950) << "KAlarmApp::startDaemon(): Alarm daemon started" << endl;
01328 }
01329
01330
01331 registerWithDaemon(false);
01332
01333
01334 {
01335 QByteArray data;
01336 QDataStream arg(data, IO_WriteOnly);
01337 arg << QCString(aboutData()->appName()) << mCalendar->urlString();
01338 if (!dcopClient()->send(DAEMON_APP_NAME, DAEMON_DCOP_OBJECT, "addMsgCal(QCString,QString)", data))
01339 kdDebug(5950) << "KAlarmApp::startDaemon(): addCal dcop send failed" << endl;
01340 }
01341
01342 mDaemonRegistered = true;
01343 kdDebug(5950) << "KAlarmApp::startDaemon(): started daemon" << endl;
01344 }
01345
01346
01347
01348
01349 void KAlarmApp::registerWithDaemon(bool reregister)
01350 {
01351 kdDebug(5950) << (reregister ? "KAlarmApp::reregisterWithDaemon()" : "KAlarmApp::registerWithDaemon()") << endl;
01352 QByteArray data;
01353 QDataStream arg(data, IO_WriteOnly);
01354 arg << QCString(aboutData()->appName()) << aboutData()->programName()
01355 << QCString(DCOP_OBJECT_NAME)
01356 << (int)(mDisableAlarmsIfStopped ? ClientInfo::NO_START_NOTIFY : ClientInfo::COMMAND_LINE_NOTIFY)
01357 << (Q_INT8)0;
01358 const char* func = reregister ? "reregisterApp(QCString,QString,QCString,int,bool)" : "registerApp(QCString,QString,QCString,int,bool)";
01359 if (!dcopClient()->send(DAEMON_APP_NAME, DAEMON_DCOP_OBJECT, func, data))
01360 kdDebug(5950) << "KAlarmApp::registerWithDaemon(): registerApp dcop send failed" << endl;
01361 }
01362
01363
01364
01365
01366 bool KAlarmApp::stopDaemon()
01367 {
01368 kdDebug(5950) << "KAlarmApp::stopDaemon()" << endl;
01369 if (dcopClient()->isApplicationRegistered(DAEMON_APP_NAME))
01370 {
01371 QByteArray data;
01372 if (!dcopClient()->send(DAEMON_APP_NAME, DAEMON_DCOP_OBJECT, "quit()", data))
01373 {
01374 kdError(5950) << "KAlarmApp::stopDaemon(): quit dcop send failed" << endl;
01375 return false;
01376 }
01377 }
01378 return true;
01379 }
01380
01381
01382
01383
01384
01385 void KAlarmApp::resetDaemon()
01386 {
01387 kdDebug(5950) << "KAlarmApp::resetDaemon()" << endl;
01388 mCalendar->reload();
01389 KAlarmMainWindow::refresh();
01390 if (!dcopClient()->isApplicationRegistered(DAEMON_APP_NAME))
01391 startDaemon();
01392 else
01393 {
01394 QByteArray data;
01395 QDataStream arg(data, IO_WriteOnly);
01396 arg << QCString(aboutData()->appName()) << mCalendar->urlString();
01397 if (!dcopClient()->send(DAEMON_APP_NAME, DAEMON_DCOP_OBJECT, "resetMsgCal(QCString,QString)", data))
01398 kdDebug(5950) << "KAlarmApp::resetDaemon(): addCal dcop send failed" << endl;
01399 }
01400 }
01401
01402
01403
01404
01405 void KAlarmApp::reloadDaemon()
01406 {
01407 QByteArray data;
01408 QDataStream arg(data, IO_WriteOnly);
01409 arg << QCString(aboutData()->appName()) << mCalendar->urlString();
01410 if (!dcopClient()->send(DAEMON_APP_NAME, DAEMON_DCOP_OBJECT, "reloadMsgCal(QCString,QString)", data))
01411 kdDebug(5950) << "KAlarmApp::reloadDaemon(): dcop send failed" << endl;
01412 }
01413
01414
01415
01416
01417 bool KAlarmApp::isDaemonRunning()
01418 {
01419 bool running = dcopClient()->isApplicationRegistered(DAEMON_APP_NAME);
01420 if (running != mDaemonRunning)
01421 {
01422
01423 mDaemonRunning = running;
01424 if (mDaemonRunning)
01425 startDaemon();
01426 }
01427 return mDaemonRunning;
01428 }
01429
01430
01431
01432
01433
01434
01435
01436 void KAlarmApp::readDaemonCheckInterval()
01437 {
01438 KConfig config(locate("config", DAEMON_APP_NAME_DEF"rc"));
01439 config.setGroup("General");
01440 int checkInterval = 60 * config.readNumEntry("CheckInterval", 1);
01441 if (checkInterval < mDaemonCheckInterval)
01442 {
01443
01444
01445 QDateTime now = QDateTime::currentDateTime();
01446 mLastDaemonCheck = now.addSecs(-mDaemonCheckInterval);
01447 mNextDaemonCheck = now.addSecs(checkInterval);
01448 }
01449 mDaemonCheckInterval = checkInterval;
01450 }
01451
01452
01453
01454
01455
01456
01457 int KAlarmApp::maxLateness()
01458 {
01459 static const int LATENESS_LEEWAY = 5;
01460
01461 readDaemonCheckInterval();
01462 if (mLastDaemonCheck.isValid())
01463 {
01464 QDateTime now = QDateTime::currentDateTime();
01465 if (mNextDaemonCheck > now)
01466 {
01467
01468 return mLastDaemonCheck.secsTo(now) + LATENESS_LEEWAY;
01469 }
01470 mLastDaemonCheck = QDateTime();
01471 }
01472 return mDaemonCheckInterval + LATENESS_LEEWAY;
01473 }
01474
01475
01476
01477
01478
01479
01480 QSize KAlarmApp::readConfigWindowSize(const char* window, const QSize& defaultSize)
01481 {
01482 KConfig* config = KGlobal::config();
01483 config->setGroup(QString::fromLatin1(window));
01484 QWidget* desktop = KApplication::desktop();
01485 return QSize(config->readNumEntry(QString::fromLatin1("Width %1").arg(desktop->width()), defaultSize.width()),
01486 config->readNumEntry(QString::fromLatin1("Height %1").arg(desktop->height()), defaultSize.height()));
01487 }
01488
01489
01490
01491
01492
01493 void KAlarmApp::writeConfigWindowSize(const char* window, const QSize& size)
01494 {
01495 KConfig* config = KGlobal::config();
01496 config->setGroup(QString::fromLatin1(window));
01497 QWidget* desktop = KApplication::desktop();
01498 config->writeEntry(QString::fromLatin1("Width %1").arg(desktop->width()), size.width());
01499 config->writeEntry(QString::fromLatin1("Height %1").arg(desktop->height()), size.height());
01500 config->sync();
01501 }
01502
01503
01504
01505
01506
01507
01508
01509 int KAlarmApp::isTextFile(const KURL& url)
01510 {
01511 static const char* applicationTypes[] = {
01512 "x-shellscript", "x-nawk", "x-awk", "x-perl", "x-python",
01513 "x-desktop", "x-troff", 0 };
01514 static const char* formattedTextTypes[] = {
01515 "html", "xml", 0 };
01516
01517 QString mimetype = KFileItem(-1, -1, url).mimetype();
01518 int slash = mimetype.find('/');
01519 if (slash < 0)
01520 return 0;
01521 QString subtype = mimetype.mid(slash + 1);
01522 if (mimetype.startsWith(QString::fromLatin1("application")))
01523 {
01524 for (int i = 0; applicationTypes[i]; ++i)
01525 if (!strcmp(subtype, applicationTypes[i]))
01526 return 1;
01527 }
01528 else if (mimetype.startsWith(QString::fromLatin1("text")))
01529 {
01530 for (int i = 0; formattedTextTypes[i]; ++i)
01531 if (!strcmp(subtype, formattedTextTypes[i]))
01532 return 2;
01533 return 1;
01534 }
01535 return 0;
01536 }
01537
01538
01539
01540
01541 DcopHandler::DcopHandler(const char* dcopObject)
01542 : QWidget(),
01543 DCOPObject(dcopObject)
01544 {
01545 kdDebug(5950) << "DcopHandler::DcopHandler()\n";
01546 }
01547
01548
01549
01550
01551 bool DcopHandler::process(const QCString& func, const QByteArray& data, QCString& replyType, QByteArray&)
01552 {
01553 kdDebug(5950) << "DcopHandler::process(): " << func << endl;
01554 enum
01555 {
01556 ERR = 0,
01557 OPERATION = 0x0007,
01558 HANDLE = 0x0001,
01559 CANCEL = 0x0002,
01560 TRIGGER = 0x0003,
01561 SCHEDULE = 0x0004,
01562 ALARM_TYPE = 0x00F0,
01563 MESSAGE = 0x0010,
01564 FILE = 0x0020,
01565 COMMAND = 0x0030,
01566 SCH_FLAGS = 0x0F00,
01567 REP_COUNT = 0x0100,
01568 REP_END = 0x0200,
01569 OLD = 0x1000
01570 };
01571 int function;
01572 if (func == "handleEvent(const QString&,const QString&)"
01573 || func == "handleEvent(QString,QString)")
01574 function = HANDLE;
01575 else if (func == "cancelEvent(const QString&,const QString&)"
01576 || func == "cancelEvent(QString,QString)"
01577 || func == "cancelMessage(const QString&,const QString&)"
01578 || func == "cancelMessage(QString,QString)")
01579 function = CANCEL;
01580 else if (func == "triggerEvent(const QString&,const QString&)"
01581 || func == "triggerEvent(QString,QString)"
01582 || func == "displayMessage(const QString&,const QString&)"
01583 || func == "displayMessage(QString,QString)")
01584 function = TRIGGER;
01585
01586 else if (func == "scheduleMessage(const QString&,const QDateTime&,QColor,Q_UINT32,const QString&)"
01587 || func == "scheduleMessage(QString,QDateTime,QColor,Q_UINT32,QString)")
01588 function = SCHEDULE | MESSAGE;
01589 else if (func == "scheduleFile(const QString&,const QDateTime&,QColor,Q_UINT32,const QString&)"
01590 || func == "scheduleFile(QString,QDateTime,QColor,Q_UINT32,QString)")
01591 function = SCHEDULE | FILE;
01592 else if (func == "scheduleCommand(const QString&,const QDateTime&,Q_UINT32)"
01593 || func == "scheduleCommand(QString,QDateTime,Q_UINT32)")
01594 function = SCHEDULE | COMMAND;
01595
01596 else if (func == "scheduleMessage(const QString&,const QDateTime&,QColor,Q_UINT32,const QString&,Q_INT32,Q_INT32,Q_INT32)"
01597 || func == "scheduleMessage(QString,QDateTime,QColor,Q_UINT32,QString,Q_INT32,Q_INT32,Q_INT32)")
01598 function = SCHEDULE | MESSAGE | REP_COUNT;
01599 else if (func == "scheduleFile(const QString&,const QDateTime&,QColor,Q_UINT32,const QString&,Q_INT32,Q_INT32,Q_INT32)"
01600 || func == "scheduleFile(QString,QDateTime,QColor,Q_UINT32,QString,Q_INT32,Q_INT32,Q_INT32)")
01601 function = SCHEDULE | FILE | REP_COUNT;
01602 else if (func == "scheduleCommand(const QString&,const QDateTime&,Q_UINT32,Q_INT32,Q_INT32,Q_INT32)"
01603 || func == "scheduleCommand(QString,QDateTime,Q_UINT32,Q_INT32,Q_INT32,Q_INT32)")
01604 function = SCHEDULE | COMMAND | REP_COUNT;
01605
01606 else if (func == "scheduleMessage(const QString&,const QDateTime&,QColor,Q_UINT32,const QString&,Q_INT32,Q_INT32,const QDateTime&)"
01607 || func == "scheduleMessage(QString,QDateTime,QColor,Q_UINT32,QString,Q_INT32,Q_INT32,QDateTime)")
01608 function = SCHEDULE | MESSAGE | REP_END;
01609 else if (func == "scheduleFile(const QString&,const QDateTime&,QColor,Q_UINT32,const QString&,Q_INT32,Q_INT32,const QDateTime&)"
01610 || func == "scheduleFile(QString,QDateTime,QColor,Q_UINT32,QString,Q_INT32,Q_INT32,QDateTime)")
01611 function = SCHEDULE | FILE | REP_END;
01612 else if (func == "scheduleCommand(const QString&,const QDateTime&,Q_UINT32,Q_INT32,Q_INT32,const QDateTime&)"
01613 || func == "scheduleCommand(QString,QDateTime,Q_UINT32,Q_INT32,Q_INT32,QDateTime)")
01614 function = SCHEDULE | COMMAND | REP_END;
01615
01616
01617 else if (func == "scheduleMessage(const QString&,const QDateTime&,QColor,Q_UINT32,Q_INT32,Q_INT32)"
01618 || func == "scheduleMessage(QString,QDateTime,QColor,Q_UINT32,Q_INT32,Q_INT32)")
01619 function = SCHEDULE | MESSAGE | REP_COUNT | OLD;
01620 else if (func == "scheduleFile(const QString&,const QDateTime&,QColor,Q_UINT32,Q_INT32,Q_INT32)"
01621 || func == "scheduleFile(QString,QDateTime,QColor,Q_UINT32,Q_INT32,Q_INT32)")
01622 function = SCHEDULE | FILE | REP_COUNT | OLD;
01623 else if (func == "scheduleCommand(const QString&,const QDateTime&,Q_UINT32,Q_INT32,Q_INT32)"
01624 || func == "scheduleCommand(QString,QDateTime,Q_UINT32,Q_INT32,Q_INT32)")
01625 function = SCHEDULE | COMMAND | REP_COUNT | OLD;
01626 else
01627 {
01628 kdDebug(5950) << "DcopHandler::process(): unknown DCOP function" << endl;
01629 return false;
01630 }
01631
01632 switch (function & OPERATION)
01633 {
01634 case HANDLE:
01635 case CANCEL:
01636 case TRIGGER:
01637 {
01638
01639 QDataStream arg(data, IO_ReadOnly);
01640 QString urlString, vuid;
01641 arg >> urlString >> vuid;
01642 replyType = "void";
01643 switch (function)
01644 {
01645 case HANDLE:
01646 theApp()->handleEvent(urlString, vuid);
01647 break;
01648 case CANCEL:
01649 theApp()->deleteEvent(urlString, vuid);
01650 break;
01651 case TRIGGER:
01652 theApp()->triggerEvent(urlString, vuid);
01653 break;
01654 }
01655 break;
01656 }
01657 case SCHEDULE:
01658 {
01659 KAlarmAlarm::Type type;
01660 switch (function & ALARM_TYPE)
01661 {
01662 case MESSAGE: type = KAlarmAlarm::MESSAGE; break;
01663 case FILE: type = KAlarmAlarm::FILE; break;
01664 case COMMAND: type = KAlarmAlarm::COMMAND; break;
01665 default: return false;
01666 }
01667 QDataStream arg(data, IO_ReadOnly);
01668 QString text, audioFile;
01669 QDateTime dateTime, endTime;
01670 QColor bgColour;
01671 Q_UINT32 flags;
01672 KAlarmEvent::RecurType recurType = KAlarmEvent::NO_RECUR;
01673 Q_INT32 repeatCount = 0;
01674 Q_INT32 repeatInterval = 0;
01675 arg >> text;
01676 arg.readRawBytes((char*)&dateTime, sizeof(dateTime));
01677 if (type != KAlarmAlarm::COMMAND)
01678 arg.readRawBytes((char*)&bgColour, sizeof(bgColour));
01679 arg >> flags;
01680 if (!(function & OLD))
01681 arg >> audioFile;
01682 if (function & (REP_COUNT | REP_END))
01683 {
01684 if (function & OLD)
01685 {
01686
01687 recurType = KAlarmEvent::MINUTELY;
01688 arg >> repeatCount >> repeatInterval;
01689 ++repeatCount;
01690 }
01691 else
01692 {
01693 Q_INT32 type;
01694 arg >> type >> repeatInterval;
01695 recurType = KAlarmEvent::RecurType(type);
01696 switch (recurType)
01697 {
01698 case KAlarmEvent::MINUTELY:
01699 case KAlarmEvent::DAILY:
01700 case KAlarmEvent::WEEKLY:
01701 case KAlarmEvent::MONTHLY_DAY:
01702 case KAlarmEvent::ANNUAL_DATE:
01703 break;
01704 default:
01705 kdDebug(5950) << "DcopHandler::process(): invalid simple repetition type: " << type << endl;
01706 return false;
01707 }
01708 if (function & REP_COUNT)
01709 arg >> repeatCount;
01710 else
01711 arg.readRawBytes((char*)&endTime, sizeof(endTime));
01712
01713 }
01714 }
01715 theApp()->scheduleEvent(text, dateTime, bgColour, flags, audioFile, type, recurType, repeatInterval, repeatCount, endTime);
01716 break;
01717 }
01718 }
01719 replyType = "void";
01720 return true;
01721 }
01722
01723
01724
01725
01726
01727
01728 static bool convWakeTime(const QCString timeParam, QDateTime& dateTime, bool& noTime)
01729 {
01730 if (timeParam.length() > 19)
01731 return false;
01732 char timeStr[20];
01733 strcpy(timeStr, timeParam);
01734 int dt[5] = { -1, -1, -1, -1, -1 };
01735 char* s;
01736 char* end;
01737
01738 if ((s = strchr(timeStr, ':')) == 0L)
01739 noTime = true;
01740 else
01741 {
01742 noTime = false;
01743 *s++ = 0;
01744 dt[4] = strtoul(s, &end, 10);
01745 if (end == s || *end || dt[4] >= 60)
01746 return false;
01747
01748 if ((s = strrchr(timeStr, '-')) == 0L)
01749 s = timeStr;
01750 else
01751 *s++ = 0;
01752 dt[3] = strtoul(s, &end, 10);
01753 if (end == s || *end || dt[3] >= 24)
01754 return false;
01755 }
01756 bool dateSet = false;
01757 if (s != timeStr)
01758 {
01759 dateSet = true;
01760
01761 if ((s = strrchr(timeStr, '-')) == 0L)
01762 s = timeStr;
01763 else
01764 *s++ = 0;
01765 dt[2] = strtoul(s, &end, 10);
01766 if (end == s || *end || dt[2] == 0 || dt[2] > 31)
01767 return false;
01768 if (s != timeStr)
01769 {
01770
01771 if ((s = strrchr(timeStr, '-')) == 0L)
01772 s = timeStr;
01773 else
01774 *s++ = 0;
01775 dt[1] = strtoul(s, &end, 10);
01776 if (end == s || *end || dt[1] == 0 || dt[1] > 12)
01777 return false;
01778 if (s != timeStr)
01779 {
01780
01781 dt[0] = strtoul(timeStr, &end, 10);
01782 if (end == timeStr || *end)
01783 return false;
01784 }
01785 }
01786 }
01787
01788 QDate date(dt[0], dt[1], dt[2]);
01789 QTime time(0, 0, 0);
01790 if (noTime)
01791 {
01792
01793 if (dt[0] < 0)
01794 return false;
01795 }
01796 else
01797 {
01798
01799 QDateTime now = QDateTime::currentDateTime();
01800 if (dt[0] < 0)
01801 date.setYMD(now.date().year(),
01802 (dt[1] < 0 ? now.date().month() : dt[1]),
01803 (dt[2] < 0 ? now.date().day() : dt[2]));
01804 time.setHMS(dt[3], dt[4], 0);
01805 if (!dateSet && time < now.time())
01806 date = date.addDays(1);
01807 }
01808 if (!date.isValid())
01809 return false;
01810 dateTime.setDate(date);
01811 dateTime.setTime(time);
01812 return true;
01813 }