kalarm

daemon.cpp

00001 /*
00002  *  daemon.cpp  -  interface with alarm daemon
00003  *  Program:  kalarm
00004  *  Copyright (c) 2001 - 2005 by David Jarvie <software@astrojar.org.uk>
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  */
00020 
00021 #include "kalarm.h"
00022 
00023 #include <qtimer.h>
00024 #include <qiconset.h>
00025 
00026 #include <kstandarddirs.h>
00027 #include <kconfig.h>
00028 #include <kaboutdata.h>
00029 #include <kmessagebox.h>
00030 #include <dcopclient.h>
00031 #include <kdebug.h>
00032 
00033 #include "kalarmd/kalarmd.h"
00034 #include "kalarmd/alarmdaemoniface.h"
00035 #include "kalarmd/alarmdaemoniface_stub.h"
00036 #include "kalarmd/alarmguiiface.h"
00037 
00038 #include "alarmcalendar.h"
00039 #include "kalarmapp.h"
00040 #include "preferences.h"
00041 #include "daemon.moc"
00042 
00043 
00044 static const int    REGISTER_TIMEOUT = 20;     // seconds to wait before assuming registration with daemon has failed
00045 static const char*  NOTIFY_DCOP_OBJECT  = "notify";    // DCOP name of KAlarm's interface for notification by alarm daemon
00046 
00047 static QString expandURL(const QString& urlString);
00048 
00049 
00050 /*=============================================================================
00051 =  Class: NotificationHandler
00052 =  Handles the the alarm daemon's client notification DCOP interface.
00053 =============================================================================*/
00054 
00055 class NotificationHandler : public QObject, virtual public AlarmGuiIface
00056 {
00057     public:
00058         NotificationHandler();
00059     private:
00060         // DCOP interface
00061         void  alarmDaemonUpdate(int calendarStatus, const QString& calendarURL);
00062         void  handleEvent(const QString& calendarURL, const QString& eventID);
00063         void  registered(bool reregister, int result);
00064 };
00065 
00066 
00067 Daemon*              Daemon::mInstance = 0;
00068 NotificationHandler* Daemon::mDcopHandler = 0;
00069 QTimer*              Daemon::mStartTimer = 0;
00070 QTimer*              Daemon::mRegisterTimer = 0;
00071 QTimer*              Daemon::mStatusTimer = 0;
00072 int                  Daemon::mStatusTimerCount = 0;
00073 int                  Daemon::mStatusTimerInterval;
00074 int                  Daemon::mStartTimeout = 0;
00075 Daemon::Status       Daemon::mStatus = Daemon::STOPPED;
00076 bool                 Daemon::mRunning = false;
00077 bool                 Daemon::mCalendarDisabled = false;
00078 bool                 Daemon::mEnableCalPending = false;
00079 bool                 Daemon::mRegisterFailMsg = false;
00080 
00081 // How frequently to check the daemon's status after starting it.
00082 // This is equal to the length of time we wait after the daemon is registered with DCOP
00083 // before we assume that it is ready to accept DCOP calls.
00084 static const int startCheckInterval = 500;     // 500 milliseconds
00085 
00086 
00087 /******************************************************************************
00088 * Initialise.
00089 * A Daemon instance needs to be constructed only in order for slots to work.
00090 * All external access is via static methods.
00091 */
00092 void Daemon::initialise()
00093 {
00094     if (!mInstance)
00095         mInstance = new Daemon();
00096     connect(AlarmCalendar::activeCalendar(), SIGNAL(calendarSaved(AlarmCalendar*)), mInstance, SLOT(slotCalendarSaved(AlarmCalendar*)));
00097 }
00098 
00099 /******************************************************************************
00100 * Initialise the daemon status timer.
00101 */
00102 void Daemon::createDcopHandler()
00103 {
00104     if (mDcopHandler)
00105         return;
00106     mDcopHandler = new NotificationHandler();
00107     // Check if the alarm daemon is running, but don't start it yet, since
00108     // the program is still initialising.
00109     mRunning = isRunning(false);
00110 
00111     mStatusTimerInterval = Preferences::daemonTrayCheckInterval();
00112     Preferences::connect(SIGNAL(preferencesChanged()), mInstance, SLOT(slotPreferencesChanged()));
00113 
00114     mStatusTimer = new QTimer(mInstance);
00115     connect(mStatusTimer, SIGNAL(timeout()), mInstance, SLOT(timerCheckIfRunning()));
00116     mStatusTimer->start(mStatusTimerInterval * 1000);  // check regularly if daemon is running
00117 }
00118 
00119 /******************************************************************************
00120 * Start the alarm daemon if necessary, and register this application with it.
00121 * Reply = false if the daemon definitely couldn't be started or registered with.
00122 */
00123 bool Daemon::start()
00124 {
00125     kdDebug(5950) << "Daemon::start()\n";
00126     updateRegisteredStatus();
00127     switch (mStatus)
00128     {
00129         case STOPPED:
00130         {
00131             if (mStartTimer)
00132                 return true;     // we're currently waiting for the daemon to start
00133             // Start the alarm daemon. It is a KUniqueApplication, which means that
00134             // there is automatically only one instance of the alarm daemon running.
00135             QString execStr = locate("exe", QString::fromLatin1(DAEMON_APP_NAME));
00136             if (execStr.isEmpty())
00137             {
00138                 KMessageBox::error(0, i18n("Alarm daemon not found."));
00139                 kdError() << "Daemon::startApp(): " DAEMON_APP_NAME " not found" << endl;
00140                 return false;
00141             }
00142             KApplication::kdeinitExec(execStr);
00143             kdDebug(5950) << "Daemon::start(): Alarm daemon started" << endl;
00144             mStartTimeout = 5000/startCheckInterval + 1;    // check daemon status for 5 seconds before giving up
00145             mStartTimer = new QTimer(mInstance);
00146             connect(mStartTimer, SIGNAL(timeout()), mInstance, SLOT(checkIfStarted()));
00147             mStartTimer->start(startCheckInterval);
00148             mInstance->checkIfStarted();
00149             return true;
00150         }
00151         case RUNNING:
00152             return true;     // we're waiting for the daemon to be completely ready
00153         case READY:
00154             // Daemon is ready. Register this application with it.
00155             if (!registerWith(false))
00156                 return false;
00157             break;
00158         case REGISTERED:
00159             break;
00160     }
00161     return true;
00162 }
00163 
00164 /******************************************************************************
00165 * Register this application with the alarm daemon, and tell it to load the
00166 * calendar.
00167 * Set 'reregister' true in order to notify the daemon of a change in the
00168 * 'disable alarms if stopped' setting.
00169 */
00170 bool Daemon::registerWith(bool reregister)
00171 {
00172     if (mRegisterTimer)
00173         return true;
00174     if (mStatus == STOPPED  ||  mStatus == RUNNING)
00175         return false;
00176     if (mStatus == REGISTERED  &&  !reregister)
00177         return true;
00178 
00179     bool disabledIfStopped = theApp()->alarmsDisabledIfStopped();
00180     kdDebug(5950) << (reregister ? "Daemon::reregisterWith(): " : "Daemon::registerWith(): ") << (disabledIfStopped ? "NO_START" : "COMMAND_LINE") << endl;
00181     QCString appname  = kapp->aboutData()->appName();
00182     AlarmDaemonIface_stub s(DAEMON_APP_NAME, DAEMON_DCOP_OBJECT);
00183     if (reregister)
00184         s.registerChange(appname, !disabledIfStopped);
00185     else
00186         s.registerApp(appname, kapp->aboutData()->programName(), QCString(NOTIFY_DCOP_OBJECT), AlarmCalendar::activeCalendar()->urlString(), !disabledIfStopped);
00187     if (!s.ok())
00188     {
00189         registrationResult(reregister, KAlarmd::FAILURE);
00190         return false;
00191     }
00192     mRegisterTimer = new QTimer(mInstance);
00193     connect(mRegisterTimer, SIGNAL(timeout()), mInstance, SLOT(registerTimerExpired()));
00194     mRegisterTimer->start(REGISTER_TIMEOUT * 1000);     // wait for the reply
00195     return true;
00196 }
00197 
00198 /******************************************************************************
00199 * Called when the daemon has notified us of the result of the register() DCOP call.
00200 */
00201 void Daemon::registrationResult(bool reregister, int result)
00202 {
00203     kdDebug(5950) << "Daemon::registrationResult(" << reregister << ")\n";
00204     delete mRegisterTimer;
00205     mRegisterTimer = 0;
00206     switch (result)
00207     {
00208         case KAlarmd::SUCCESS:
00209             break;
00210         case KAlarmd::NOT_FOUND:
00211             kdError(5950) << "Daemon::registrationResult(" << reregister << "): registerApp dcop call: " << kapp->aboutData()->appName() << " not found\n";
00212             KMessageBox::error(0, i18n("Alarms will be disabled if you stop KAlarm.\n"
00213                                        "(Installation or configuration error: %1 cannot locate %2 executable.)")
00214                                        .arg(QString::fromLatin1(DAEMON_APP_NAME))
00215                                        .arg(kapp->aboutData()->appName()));
00216             break;
00217         case KAlarmd::FAILURE:
00218         default:
00219             kdError(5950) << "Daemon::registrationResult(" << reregister << "): registerApp dcop call failed -> " << result << endl;
00220             if (!reregister)
00221             {
00222                 if (mStatus == REGISTERED)
00223                     mStatus = READY;
00224                 if (!mRegisterFailMsg)
00225                 {
00226                     mRegisterFailMsg = true;
00227                     KMessageBox::error(0, i18n("Cannot enable alarms:\nFailed to register with Alarm Daemon (%1)")
00228                                                .arg(QString::fromLatin1(DAEMON_APP_NAME)));
00229                 }
00230             }
00231             return;
00232     }
00233 
00234     if (!reregister)
00235     {
00236         // The alarm daemon has loaded the calendar
00237         mStatus = REGISTERED;
00238         mRegisterFailMsg = false;
00239         kdDebug(5950) << "Daemon::start(): daemon startup complete" << endl;
00240     }
00241 }
00242 
00243 /******************************************************************************
00244 * Check whether the alarm daemon has started yet, and if so, register with it.
00245 */
00246 void Daemon::checkIfStarted()
00247 {
00248     updateRegisteredStatus();
00249     bool err = false;
00250     switch (mStatus)
00251     {
00252         case STOPPED:
00253             if (--mStartTimeout > 0)
00254                 return;     // wait a bit more to check again
00255             // Output error message, but delete timer first to prevent
00256             // multiple messages.
00257             err = true;
00258             break;
00259         case RUNNING:
00260         case READY:
00261         case REGISTERED:
00262             break;
00263     }
00264     delete mStartTimer;
00265     mStartTimer = 0;
00266     if (err)
00267     {
00268         kdError(5950) << "Daemon::checkIfStarted(): failed to start daemon" << endl;
00269         KMessageBox::error(0, i18n("Cannot enable alarms:\nFailed to start Alarm Daemon (%1)").arg(QString::fromLatin1(DAEMON_APP_NAME)));
00270     }
00271 }
00272 
00273 /******************************************************************************
00274 * Check whether the alarm daemon has started yet, and if so, whether it is
00275 * ready to accept DCOP calls.
00276 */
00277 void Daemon::updateRegisteredStatus(bool timeout)
00278 {
00279     if (!kapp->dcopClient()->isApplicationRegistered(DAEMON_APP_NAME))
00280     {
00281         mStatus = STOPPED;
00282         mRegisterFailMsg = false;
00283     }
00284     else
00285     {
00286         switch (mStatus)
00287         {
00288             case STOPPED:
00289                 // The daemon has newly been detected as registered with DCOP.
00290                 // Wait for a short time to ensure that it is ready for DCOP calls.
00291                 mStatus = RUNNING;
00292                 QTimer::singleShot(startCheckInterval, mInstance, SLOT(slotStarted()));
00293                 break;
00294             case RUNNING:
00295                 if (timeout)
00296                 {
00297                     mStatus = READY;
00298                     start();
00299                 }
00300                 break;
00301             case READY:
00302             case REGISTERED:
00303                 break;
00304         }
00305     }
00306     kdDebug(5950) << "Daemon::updateRegisteredStatus() -> " << mStatus << endl;
00307 }
00308 
00309 /******************************************************************************
00310 * Stop the alarm daemon if it is running.
00311 */
00312 bool Daemon::stop()
00313 {
00314     kdDebug(5950) << "Daemon::stop()" << endl;
00315     if (kapp->dcopClient()->isApplicationRegistered(DAEMON_APP_NAME))
00316     {
00317         AlarmDaemonIface_stub s(DAEMON_APP_NAME, DAEMON_DCOP_OBJECT);
00318         s.quit();
00319         if (!s.ok())
00320         {
00321             kdError(5950) << "Daemon::stop(): dcop call failed" << endl;
00322             return false;
00323         }
00324     }
00325     return true;
00326 }
00327 
00328 /******************************************************************************
00329 * Reset the alarm daemon.
00330 * Reply = true if daemon was told to reset
00331 *       = false if daemon is not running.
00332 */
00333 bool Daemon::reset()
00334 {
00335     kdDebug(5950) << "Daemon::reset()" << endl;
00336     if (!kapp->dcopClient()->isApplicationRegistered(DAEMON_APP_NAME))
00337         return false;
00338     AlarmDaemonIface_stub s(DAEMON_APP_NAME, DAEMON_DCOP_OBJECT);
00339     s.resetCalendar(QCString(kapp->aboutData()->appName()), AlarmCalendar::activeCalendar()->urlString());
00340     if (!s.ok())
00341         kdError(5950) << "Daemon::reset(): resetCalendar dcop send failed" << endl;
00342     return true;
00343 }
00344 
00345 /******************************************************************************
00346 * Tell the alarm daemon to reread the calendar file.
00347 */
00348 void Daemon::reload()
00349 {
00350     kdDebug(5950) << "Daemon::reload()\n";
00351     AlarmDaemonIface_stub s(DAEMON_APP_NAME, DAEMON_DCOP_OBJECT);
00352     s.reloadCalendar(QCString(kapp->aboutData()->appName()), AlarmCalendar::activeCalendar()->urlString());
00353     if (!s.ok())
00354         kdError(5950) << "Daemon::reload(): reloadCalendar dcop send failed" << endl;
00355 }
00356 
00357 /******************************************************************************
00358 * Tell the alarm daemon to enable/disable monitoring of the calendar file.
00359 */
00360 void Daemon::enableCalendar(bool enable)
00361 {
00362     AlarmDaemonIface_stub s(DAEMON_APP_NAME, DAEMON_DCOP_OBJECT);
00363     s.enableCalendar(AlarmCalendar::activeCalendar()->urlString(), enable);
00364     mEnableCalPending = false;
00365 }
00366 
00367 /******************************************************************************
00368 * Tell the alarm daemon to enable/disable autostart at login.
00369 */
00370 void Daemon::enableAutoStart(bool enable)
00371 {
00372     // Tell the alarm daemon in case it is running.
00373     AlarmDaemonIface_stub s(DAEMON_APP_NAME, DAEMON_DCOP_OBJECT);
00374     s.enableAutoStart(enable);
00375     if (!s.ok())
00376     {
00377         // Failure - the daemon probably isn't running, so rewrite its config file for it
00378         KConfig adconfig(locate("config", DAEMON_APP_NAME"rc"));
00379         adconfig.setGroup(QString::fromLatin1(DAEMON_AUTOSTART_SECTION));
00380         adconfig.writeEntry(QString::fromLatin1(DAEMON_AUTOSTART_KEY), enable);
00381         adconfig.sync();
00382     }
00383 }
00384 
00385 /******************************************************************************
00386 * Read the alarm daemon's autostart-at-login setting.
00387 */
00388 bool Daemon::autoStart(bool defaultAutoStart)
00389 {
00390     KConfig adconfig(locate("config", DAEMON_APP_NAME"rc"));
00391     adconfig.setGroup(QString::fromLatin1(DAEMON_AUTOSTART_SECTION));
00392     return adconfig.readBoolEntry(QString::fromLatin1(DAEMON_AUTOSTART_KEY), defaultAutoStart);
00393 }
00394 
00395 /******************************************************************************
00396 * Notification that the alarm daemon has enabled/disabled monitoring of the
00397 * calendar file.
00398 */
00399 void Daemon::calendarIsEnabled(bool enabled)
00400 {
00401     mCalendarDisabled = !enabled;
00402     emit mInstance->daemonRunning(enabled);
00403 }
00404 
00405 /******************************************************************************
00406 * Tell the alarm daemon to stop or start monitoring the calendar file as
00407 * appropriate.
00408 */
00409 void Daemon::setAlarmsEnabled(bool enable)
00410 {
00411     kdDebug(5950) << "Daemon::setAlarmsEnabled(" << enable << ")\n";
00412     if (enable  &&  !checkIfRunning())
00413     {
00414         // The daemon is not running, so start it
00415         if (!start())
00416         {
00417             emit daemonRunning(false);
00418             return;
00419         }
00420         mEnableCalPending = true;
00421         setFastCheck();
00422     }
00423 
00424     // If the daemon is now running, tell it to enable/disable the calendar
00425     if (checkIfRunning())
00426         enableCalendar(enable);
00427 }
00428 
00429 /******************************************************************************
00430 * Return whether the alarm daemon is monitoring alarms.
00431 */
00432 bool Daemon::monitoringAlarms()
00433 {
00434     bool ok = !mCalendarDisabled  &&  isRunning();
00435     emit mInstance->daemonRunning(ok);
00436     return ok;
00437 }
00438 
00439 /******************************************************************************
00440 * Check whether the alarm daemon is currently running and available.
00441 */
00442 bool Daemon::isRunning(bool startdaemon)
00443 {
00444     static bool runState = false;
00445     updateRegisteredStatus();
00446     bool newRunState = (mStatus == READY  ||  mStatus == REGISTERED);
00447     if (newRunState != runState)
00448     {
00449         // Daemon's status has changed
00450         runState = newRunState;
00451         if (runState  &&  startdaemon)
00452             start();      // re-register with the daemon
00453     }
00454     return runState  &&  (mStatus == REGISTERED);
00455 }
00456 
00457 /******************************************************************************
00458 * Called by the timer to check whether the daemon is running.
00459 */
00460 void Daemon::timerCheckIfRunning()
00461 {
00462     checkIfRunning();
00463     // Limit how long we check at the fast rate
00464     if (mStatusTimerCount > 0  &&  --mStatusTimerCount <= 0)
00465         mStatusTimer->changeInterval(mStatusTimerInterval * 1000);
00466 }
00467 
00468 /******************************************************************************
00469 * Check whether the alarm daemon is currently running.
00470 * If its status has changed, trigger GUI updates.
00471 */
00472 bool Daemon::checkIfRunning()
00473 {
00474     bool newstatus = isRunning();
00475     if (newstatus != mRunning)
00476     {
00477         mRunning = newstatus;
00478         int status = mRunning  &&  !mCalendarDisabled;
00479         emit mInstance->daemonRunning(status);
00480         mStatusTimer->changeInterval(mStatusTimerInterval * 1000);   // exit from fast checking
00481         mStatusTimerCount = 0;
00482         if (mRunning)
00483         {
00484             // The alarm daemon has started up
00485             if (mEnableCalPending)
00486                 enableCalendar(true);  // tell it to monitor the calendar, if appropriate
00487         }
00488     }
00489     return mRunning;
00490 }
00491 
00492 /******************************************************************************
00493 * Starts checking at a faster rate whether the daemon is running.
00494 */
00495 void Daemon::setFastCheck()
00496 {
00497     mStatusTimer->start(500);    // check new status every half second
00498     mStatusTimerCount = 20;      // don't check at this rate for more than 10 seconds
00499 }
00500 
00501 /******************************************************************************
00502 * Called when a program setting has changed.
00503 * If the system tray icon update interval has changed, reset the timer.
00504 */
00505 void Daemon::slotPreferencesChanged()
00506 {
00507     int newInterval = Preferences::daemonTrayCheckInterval();
00508     if (newInterval != mStatusTimerInterval)
00509     {
00510         // Daemon check interval has changed
00511         mStatusTimerInterval = newInterval;
00512         if (mStatusTimerCount <= 0)   // don't change if on fast rate
00513             mStatusTimer->changeInterval(mStatusTimerInterval * 1000);
00514     }
00515 }
00516 
00517 /******************************************************************************
00518 * Create an "Alarms Enabled/Enable Alarms" action.
00519 */
00520 AlarmEnableAction* Daemon::createAlarmEnableAction(KActionCollection* actions, const char* name)
00521 {
00522     AlarmEnableAction* a = new AlarmEnableAction(Qt::CTRL+Qt::Key_A, actions, name);
00523     connect(a, SIGNAL(userClicked(bool)), mInstance, SLOT(setAlarmsEnabled(bool)));
00524     connect(mInstance, SIGNAL(daemonRunning(bool)), a, SLOT(setCheckedActual(bool)));
00525     return a;
00526 }
00527 
00528 /******************************************************************************
00529 * Called when a calendar has been saved.
00530 * If it's the active alarm calendar, notify the alarm daemon.
00531 */
00532 void Daemon::slotCalendarSaved(AlarmCalendar* cal)
00533 {
00534     if (cal == AlarmCalendar::activeCalendar())
00535         reload();
00536 }
00537 
00538 /******************************************************************************
00539 * Return the maximum time (in seconds) elapsed since the last time the alarm
00540 * daemon must have checked alarms.
00541 */
00542 int Daemon::maxTimeSinceCheck()
00543 {
00544     return DAEMON_CHECK_INTERVAL;
00545 }
00546 
00547 
00548 /*=============================================================================
00549 =  Class: NotificationHandler
00550 =============================================================================*/
00551 
00552 NotificationHandler::NotificationHandler()
00553     : DCOPObject(NOTIFY_DCOP_OBJECT), 
00554       QObject()
00555 {
00556     kdDebug(5950) << "NotificationHandler::NotificationHandler()\n";
00557 }
00558 
00559 /******************************************************************************
00560  * DCOP call from the alarm daemon to notify a change.
00561  * The daemon notifies calendar statuses when we first register as a GUI, and whenever
00562  * a calendar status changes. So we don't need to read its config files.
00563  */
00564 void NotificationHandler::alarmDaemonUpdate(int calendarStatus, const QString& calendarURL)
00565 {
00566     kdDebug(5950) << "NotificationHandler::alarmDaemonUpdate(" << calendarStatus << ")\n";
00567     KAlarmd::CalendarStatus status = KAlarmd::CalendarStatus(calendarStatus);
00568     if (expandURL(calendarURL) != AlarmCalendar::activeCalendar()->urlString())
00569         return;     // it's not a notification about KAlarm's calendar
00570     bool enabled = false;
00571     switch (status)
00572     {
00573         case KAlarmd::CALENDAR_UNAVAILABLE:
00574             // Calendar is not available for monitoring
00575             kdDebug(5950) << "NotificationHandler::alarmDaemonUpdate(CALENDAR_UNAVAILABLE)\n";
00576             break;
00577         case KAlarmd::CALENDAR_DISABLED:
00578             // Calendar is available for monitoring but is not currently being monitored
00579             kdDebug(5950) << "NotificationHandler::alarmDaemonUpdate(DISABLE_CALENDAR)\n";
00580             break;
00581         case KAlarmd::CALENDAR_ENABLED:
00582             // Calendar is currently being monitored
00583             kdDebug(5950) << "NotificationHandler::alarmDaemonUpdate(ENABLE_CALENDAR)\n";
00584             enabled = true;
00585             break;
00586         default:
00587             return;
00588     }
00589     Daemon::calendarIsEnabled(enabled);
00590 }
00591 
00592 /******************************************************************************
00593  * DCOP call from the alarm daemon to notify that an alarm is due.
00594  */
00595 void NotificationHandler::handleEvent(const QString& url, const QString& eventId)
00596 {
00597     theApp()->handleEvent(url, eventId);
00598 }
00599 
00600 /******************************************************************************
00601  * DCOP call from the alarm daemon to notify the success or failure of a
00602  * registration request from KAlarm.
00603  */
00604 void NotificationHandler::registered(bool reregister, int result)
00605 {
00606     Daemon::registrationResult(reregister, result);
00607 }
00608 
00609 
00610 /*=============================================================================
00611 =  Class: AlarmEnableAction
00612 =============================================================================*/
00613 
00614 AlarmEnableAction::AlarmEnableAction(int accel, QObject* parent, const char* name)
00615     : KToggleAction(QString::null, accel, parent, name),
00616       mInitialised(false)
00617 {
00618     setCheckedActual(false);    // set the correct text
00619     mInitialised = true;
00620 }
00621 
00622 /******************************************************************************
00623 *  Set the checked status and the correct text for the Alarms Enabled action.
00624 */
00625 void AlarmEnableAction::setCheckedActual(bool running)
00626 {
00627     kdDebug(5950) << "AlarmEnableAction::setCheckedActual(" << running << ")\n";
00628     if (running != isChecked()  ||  !mInitialised)
00629     {
00630         setText(running ? i18n("&Alarms Enabled") : i18n("Enable &Alarms"));
00631         KToggleAction::setChecked(running);
00632         emit switched(running);
00633     }
00634 }
00635 
00636 /******************************************************************************
00637 *  Request a change in the checked status.
00638 *  The status is only actually changed when the alarm daemon run state changes.
00639 */
00640 void AlarmEnableAction::setChecked(bool check)
00641 {
00642     kdDebug(5950) << "AlarmEnableAction::setChecked(" << check << ")\n";
00643     if (check != isChecked())
00644     {
00645         if (check)
00646             Daemon::allowRegisterFailMsg();
00647         emit userClicked(check);
00648     }
00649 }
00650 
00651 
00652 /******************************************************************************
00653  * Expand a DCOP call parameter URL to a full URL.
00654  * (We must store full URLs in the calendar data since otherwise later calls to
00655  *  reload or remove calendars won't necessarily find a match.)
00656  */
00657 QString expandURL(const QString& urlString)
00658 {
00659     if (urlString.isEmpty())
00660         return QString();
00661     return KURL(urlString).url();
00662 }
KDE Home | KDE Accessibility Home | Description of Access Keys