kalarmd Library API Documentation

alarmgui.cpp

00001 /*
00002     KDE Alarm Daemon GUI.
00003 
00004     This file is part of the GUI interface for the KDE alarm daemon.
00005     Copyright (c) 2001 David Jarvie <software@astrojar.org.uk>
00006     Based on the original, (c) 1998, 1999 Preston Brown
00007 
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     This program is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with this program; if not, write to the Free Software
00020     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021 
00022     As a special exception, permission is given to link this program
00023     with any edition of Qt, and distribute the resulting executable,
00024     without including the source code for Qt in the source distribution.
00025 */
00026 
00027 #include <kstddirs.h>
00028 #include <klocale.h>
00029 #include <ksimpleconfig.h>
00030 #include <kurl.h>
00031 #include <dcopclient.h>
00032 #include <knotifyclient.h>
00033 #include <kdebug.h>
00034 
00035 #include "dockwindow.h"
00036 #include "alarmdialog.h"
00037 #include "alarmdaemoniface_stub.h"
00038 
00039 #include "alarmgui.h"
00040 #include "alarmgui.moc"
00041 
00042 const int DAEMON_TIMER_INTERVAL = 5;    // seconds between checks on daemon status
00043 
00044 void ADConfigData::readDaemonData(bool& deletedClients, bool& deletedCalendars)
00045 {
00046   ADCalendarGuiFactory calFactory;
00047   readConfigData(false, deletedClients, deletedCalendars, &calFactory);
00048 }
00049 
00050 AlarmGui::AlarmGui(QObject *parent, const char *name)
00051   : QObject(parent, name),
00052     DCOPObject(name),
00053     mSuspendTimer(this),
00054     mDaemonStatusTimer(this),
00055     mDaemonStatusTimerCount(0),
00056     mRevisingAlarmDialog(false),
00057     mDrawAlarmDialog(false)
00058 {
00059   kdDebug(5900) << "AlarmGui::AlarmGui()" << endl;
00060 
00061   readDaemonConfig();
00062   bool deletedClients;
00063   bool deletedCalendars;
00064   readDaemonData(deletedClients, deletedCalendars);
00065   checkDefaultClient();
00066 
00067   mDocker = new AlarmDockWindow(this);
00068   mDocker->show();
00069 
00070   connect(&mDaemonStatusTimer, SIGNAL(timeout()), SLOT(checkDaemonRunning()));
00071   mDaemonStatusTimer.start(DAEMON_TIMER_INTERVAL*1000);     // check regularly if daemon is running
00072 
00073   mAlarmDialog = new AlarmDialog;
00074   connect(mAlarmDialog, SIGNAL(suspendSignal(int)), SLOT(suspend(int)));
00075 
00076   setToolTip();
00077 
00078   registerWithDaemon();
00079 }
00080 
00081 AlarmGui::~AlarmGui()
00082 {
00083   delete mDocker;
00084 }
00085 
00086 /*
00087  * DCOP call from the alarm daemon to notify a change.
00088  */
00089 void AlarmGui::alarmDaemonUpdate(int alarmGuiChangeType,
00090                                  const QString& calendarURL,
00091                                  const QCString& appName)
00092 {
00093   AlarmGuiChangeType changeType = AlarmGuiChangeType(alarmGuiChangeType);
00094   switch (changeType)
00095   {
00096     case CHANGE_STATUS:
00097       kdDebug(5900) << "AlarmGui::alarmDaemonUpdate(CHANGE_STATUS)\n";
00098       readDaemonConfig();
00099       mDocker->setDaemonAutostart(mAutostartDaemon);
00100       break;
00101     case CHANGE_CLIENT:
00102     {
00103       kdDebug(5900) << "AlarmGui::alarmDaemonUpdate(CHANGE_CLIENT)\n";
00104       bool deletedClients, deletedCalendars;
00105       readDaemonData(deletedClients, deletedCalendars);
00106       checkDefaultClient();
00107       mDocker->updateMenuClients();
00108       mDocker->updateMenuCalendars(true);
00109       setToolTip();
00110       break;
00111     }
00112     default:
00113     {
00114       // It must be a calendar-related change
00115       bool recreateMenu = false;
00116       ADCalendarBase* cal = getCalendar(expandURL(calendarURL));
00117       switch (changeType)
00118       {
00119         case ADD_CALENDAR:
00120           // Add a KOrganizer-type calendar
00121           kdDebug(5900) << "AlarmGui::alarmDaemonUpdate(ADD_CALENDAR)\n";
00122           if (cal)
00123           {
00124             if (cal->actionType() == ADCalendarBase::KORGANIZER)
00125             {
00126               removeDialogEvents(cal);
00127               cal->close();
00128               cal->loadFile();
00129             }
00130           }
00131           else
00132           {
00133             cal = new ADCalendarGui(calendarURL, appName, ADCalendarBase::KORGANIZER);
00134             mCalendars.append(cal);
00135             kdDebug(5900) << "AlarmGui::alarmDaemonUpdate(): KORGANIZER calendar added" << endl;
00136             recreateMenu = true;
00137           }
00138           break;
00139         case ADD_MSG_CALENDAR:
00140           // Add a KAlarm-type calendar
00141           kdDebug(5900) << "AlarmGui::alarmDaemonUpdate(ADD_MSG_CALENDAR)\n";
00142           if (cal)
00143           {
00144             if (cal->actionType() == ADCalendarBase::KORGANIZER)
00145               removeDialogEvents(cal);
00146             mCalendars.remove(cal);
00147           }
00148           cal = new ADCalendarGui(calendarURL, appName, ADCalendarBase::KALARM);
00149           mCalendars.append(cal);
00150           recreateMenu = true;
00151           break;
00152         default:
00153           if (!cal)
00154           {
00155             kdDebug(5900) << "AlarmGui::alarmDaemonUpdate(): unknown calendar: " << calendarURL << endl;
00156             return;
00157           }
00158           switch (changeType)
00159           {
00160             case DELETE_CALENDAR:
00161               kdDebug(5900) << "AlarmGui::alarmDaemonUpdate(DELETE_CALENDAR)\n";
00162               removeDialogEvents(cal);
00163               mCalendars.remove(cal);
00164               recreateMenu = true;
00165               break;
00166             case CALENDAR_UNAVAILABLE:
00167               // Calendar is not available for monitoring
00168               kdDebug(5900) << "AlarmGui::alarmDaemonUpdate(CALENDAR_UNAVAILABLE)\n";
00169               cal->setAvailable( false );
00170               cal->setEnabled( false );
00171               break;
00172             case DISABLE_CALENDAR:
00173               // Calendar is available for monitoring but is not currently being monitored
00174               kdDebug(5900) << "AlarmGui::alarmDaemonUpdate(DISABLE_CALENDAR)\n";
00175               cal->setAvailable( true );
00176               cal->setEnabled( false );
00177               break;
00178             case ENABLE_CALENDAR:
00179               // Calendar is currently being monitored
00180               kdDebug(5900) << "AlarmGui::alarmDaemonUpdate(ENABLE_CALENDAR)\n";
00181               cal->setAvailable( true );
00182               cal->setEnabled( true );
00183               break;
00184             default:
00185               kdDebug(5900) << "AlarmGui::alarmDaemonUpdate(): unknown change type: " << changeType << endl;
00186               return;
00187           }
00188           break;
00189       }
00190       mDocker->updateMenuCalendars(recreateMenu);
00191       setToolTip();
00192       break;
00193     }
00194   }
00195 }
00196 
00197 /*
00198  * DCOP call from the alarm daemon to notify an event becoming due.
00199  */
00200 void AlarmGui::handleEvent(const QString& calendarURL, const QString& eventID)
00201 {
00202   ADCalendarBase* cal = getCalendar(expandURL(calendarURL));
00203   Event* event = cal->getEvent(eventID);
00204   mAlarmDialog->appendEvent(cal, event);
00205 }
00206 
00207 void AlarmGui::registerWithDaemon()
00208 {
00209   kdDebug(5900) << "AlarmGui::registerWithDaemon()" << endl;
00210   AlarmDaemonIface_stub s( DAEMON_APP_NAME, DAEMON_DCOP_OBJECT );
00211   s.registerGui(kapp->aboutData()->appName(), DCOP_OBJECT_NAME);
00212 }
00213 
00214 // Read the Alarm Daemon's config file
00215 void AlarmGui::readDaemonConfig()
00216 {
00217   if (mDaemonDataFile.isEmpty())
00218     mDaemonDataFile = locate("config", QString("kalarmdrc"));
00219   KSimpleConfig kalarmdConfig(mDaemonDataFile, true);
00220   kalarmdConfig.setGroup("General");
00221   mAutostartDaemon = kalarmdConfig.readBoolEntry("Autostart", true);
00222   kdDebug(5900) << "AlarmGui::readDaemonConfig(): " << mDaemonDataFile
00223                 << " auto=" << (int)mAutostartDaemon << endl;
00224 }
00225 
00226 /*
00227  * Check that the default client is in the list of client applications.
00228  * If not, set it to the first client application and update the client data file.
00229  */
00230 void AlarmGui::checkDefaultClient()
00231 {
00232   // Read the default client application
00233   KConfig* config = kapp->config();
00234   config->setGroup("General");
00235   mDefaultClient = config->readEntry("Default Client");
00236 
00237   if (!getClientInfo(mDefaultClient).isValid())
00238   {
00239     // Default client isn't in the list of clients.
00240     // Replace it with the first client in the list.
00241     if ( mClients.count() > 0 ) {
00242       mDefaultClient = mClients[ 0 ].appName;
00243     } else {
00244       mDefaultClient = "";
00245     }
00246     config->writeEntry("Default Client", QString::fromLocal8Bit(mDefaultClient));
00247     config->sync();
00248   }
00249 }
00250 
00251 void AlarmGui::setDefaultClient(int menuIndex)
00252 {
00253   ClientList::ConstIterator client;
00254   for (client = mClients.begin();  client != mClients.end();  ++client)
00255   {
00256     if ((*client).menuIndex == menuIndex)
00257     {
00258       mDefaultClient = (*client).appName;
00259       KConfig* config = kapp->config();
00260       config->setGroup("General");
00261       config->writeEntry("Default Client",
00262                          QString::fromLocal8Bit(mDefaultClient));
00263       config->sync();
00264     }
00265   }
00266 }
00267 
00268 /* Check whether the alarm daemon is currently running */
00269 bool AlarmGui::isDaemonRunning(bool updateDockWindow)
00270 {
00271   bool newstatus = kapp->dcopClient()->isApplicationRegistered(static_cast<const char*>("kalarmd"));
00272   if (!updateDockWindow)
00273     return newstatus;
00274   if (newstatus != mDaemonRunning)
00275   {
00276 //kdDebug(5900) << "AlarmGui::isDaemonRunning(): "<<(int)mDaemonRunning<<"->"<<(int)newstatus<<endl;
00277     mDaemonRunning = newstatus;
00278     mDocker->setDaemonStatus(newstatus);
00279     mDaemonStatusTimer.changeInterval(DAEMON_TIMER_INTERVAL*1000);
00280     mDaemonStatusTimerCount = 0;
00281     if (newstatus)
00282       registerWithDaemon();   // the alarm daemon has started up, so register with it
00283   }
00284   return mDaemonRunning;
00285 }
00286 
00287 /*
00288  * Called by a timer to check whether the daemon is running.
00289  */
00290 void AlarmGui::checkDaemonRunning()
00291 {
00292   isDaemonRunning();
00293   if (mDaemonStatusTimerCount > 0  &&  --mDaemonStatusTimerCount <= 0)   // limit how long we check at fast rate
00294     mDaemonStatusTimer.changeInterval(DAEMON_TIMER_INTERVAL*1000);
00295 }
00296 
00297 /* Starts checking at a faster rate whether the daemon is running */
00298 void AlarmGui::setFastDaemonCheck()
00299 {
00300   mDaemonStatusTimer.start(500);     // check new status every half second
00301   mDaemonStatusTimerCount = 20;      // don't check at this rate for more than 10 seconds
00302 }
00303 
00304 /* Schedule the alarm dialog for redisplay after a specified number of minutes */
00305 void AlarmGui::suspend(int minutes)
00306 {
00307 //  kdDebug(5900) << "AlarmGui::suspend() " << minutes << " minutes" << endl;
00308   connect(&mSuspendTimer, SIGNAL(timeout()), SLOT(showAlarmDialog()));
00309   mSuspendTimer.start(1000*60*minutes, true);
00310 }
00311 
00312 /* Display the alarm dialog (showing KOrganiser-type events) */
00313 void AlarmGui::showAlarmDialog()
00314 {
00315   if (mRevisingAlarmDialog)
00316     mDrawAlarmDialog = true;
00317   else
00318   {
00319     KNotifyClient::beep();
00320     mAlarmDialog->show();
00321     mAlarmDialog->eventNotification();
00322     mDrawAlarmDialog = false;
00323   }
00324 }
00325 
00326 /* Remove all events belonging to the specified calendar from the alarm dialog */
00327 void AlarmGui::removeDialogEvents(const Calendar* calendar)
00328 {
00329   mRevisingAlarmDialog = true;   // prevent dialog being displayed while it's being changed
00330   if (mAlarmDialog->clearEvents(calendar) > 0)
00331   {
00332     // There are still some events left in the dialog, so display it
00333     // if the suspend time has expired
00334     mRevisingAlarmDialog = false;
00335     if (mDrawAlarmDialog)
00336       showAlarmDialog();
00337   }
00338   else
00339   {
00340     // The dialog is now empty, so tidy up
00341     mSuspendTimer.stop();
00342     mRevisingAlarmDialog = false;
00343     mDrawAlarmDialog = false;
00344   }
00345 }
00346 
00347 /*
00348  * Adds the appropriate calendar file name to the panel tool tip.
00349  */
00350 void AlarmGui::setToolTip()
00351 {
00352   // Count the number of currently loaded calendars whose names should be displayed
00353   int nAvailable = 0;
00354   int nForDisplay = 0;
00355   ADCalendarBase* firstForDisplay = 0L;
00356   for (ADCalendarBase* cal = mCalendars.first();  cal;  cal = mCalendars.next())
00357   {
00358     if (cal->available())
00359     {
00360       ClientInfo c = getClientInfo(cal->appName());
00361       if (c.isValid()  &&  c.displayCalName  &&  !nForDisplay++) {
00362         firstForDisplay = cal;
00363       }
00364       ++nAvailable;
00365     }
00366   }
00367 
00368   // Display the appropriate tooltip
00369   QString filename;
00370   if (nForDisplay == 1)
00371   {
00372     // Display the name of the one and only calendar whose name is to be displayed
00373     KURL url(firstForDisplay->urlString());
00374     if (url.isLocalFile())
00375       filename = KURL::decode_string(url.path());
00376     else
00377       filename = url.prettyURL();
00378   }
00379   else if (!nAvailable)
00380     filename = i18n("No calendar loaded.");
00381   mDocker->addToolTip(filename);
00382 }
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 15 11:40:55 2004 by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2001