kalarmd Library API Documentation

dockwindow.cpp

00001 /*
00002     KDE Panel docking window for 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 <stdlib.h>
00028 
00029 #include <qtooltip.h>
00030 #include <qfile.h>
00031 
00032 #include <kapplication.h>
00033 #include <kdebug.h>
00034 #include <klocale.h>
00035 #include <kiconloader.h>
00036 #include <kprocess.h>
00037 #include <kconfig.h>
00038 #include <kmessagebox.h>
00039 #include <kurl.h>
00040 #include <kstandarddirs.h>
00041 #include <dcopclient.h>
00042 
00043 #include "alarmgui.h"
00044 #include "alarmdaemoniface_stub.h"
00045 
00046 #include "dockwindow.h"
00047 #include "dockwindow.moc"
00048 
00049 
00050 AlarmDockWindow::AlarmDockWindow(AlarmGui *ag, QWidget *parent, const char *name)
00051   : KSystemTray(parent, name),
00052     mAlarmGui(ag),
00053     mNumClientIds(0L),
00054     mNumCalendarIds(0L),
00055     mSettingDaemonStatus(false)
00056 {
00057   // Set up GUI icons
00058   KGlobal::iconLoader()->addAppDir(kapp->aboutData()->appName());
00059   kdDebug() << "kalarmd, icon dir = " << kapp->aboutData()->appName() << endl;
00060   mPixmapEnabled  = KGlobal::iconLoader()->loadIcon("kalarmdgui", KIcon::Panel );
00061   mPixmapDisabled = KGlobal::iconLoader()->loadIcon("kalarmdgui_disabled", KIcon::Panel );
00062 
00063   if (mPixmapEnabled.isNull() || mPixmapDisabled.isNull())
00064     KMessageBox::sorry(this, i18n("Can't load docking tray icon!"),
00065                              i18n("%1 Error").arg(kapp->aboutData()->programName()));
00066 
00067   // Read the GUI autostart status from the config file
00068   KConfig* config = kapp->config();
00069   config->setGroup("General");
00070   bool mAutostartGui = config->readBoolEntry("Autostart", true);
00071 
00072   // Set up the context menu
00073   mAlarmsEnabledId = contextMenu()->insertItem(i18n("Alarms Enabled"),
00074                                               this, SLOT(toggleAlarmsEnabled()));
00075   mAutostartDaemonId = contextMenu()->insertItem(i18n("Start Alarm Daemon Automatically at Login"),
00076                                                 this, SLOT(toggleDaemonAutostart()));
00077   mAutostartGuiId = contextMenu()->insertItem(i18n("Display this Tray Icon at Login"),
00078                                                 this, SLOT(toggleGuiAutostart()));
00079   contextMenu()->setItemChecked(mAutostartDaemonId, mAlarmGui->autostartDaemon());
00080   contextMenu()->setItemChecked(mAutostartGuiId, mAutostartGui);
00081   setPixmap(mPixmapEnabled);
00082   contextMenu()->setItemChecked(mAlarmsEnabledId, true);
00083 
00084   mClientIndex = contextMenu()->count();
00085   updateMenuClients();
00086   updateMenuCalendars(true);
00087 
00088   setDaemonStatus(mAlarmGui->isDaemonRunning(false));
00089 
00090   addToolTip(QString());
00091 }
00092 
00093 AlarmDockWindow::~AlarmDockWindow()
00094 {
00095 }
00096 
00097 /*
00098  * Update the context menu to display the current client applications
00099  * (if more than one)
00100  */
00101 void AlarmDockWindow::updateMenuClients()
00102 {
00103   KPopupMenu* menu = contextMenu();
00104   if (mNumClientIds)
00105   {
00106     // Client applications are already on the menu, so delete them
00107     for ( ;  mNumClientIds > 0;  --mNumClientIds)
00108       menu->removeItemAt(mClientIndex);
00109   }
00110   if (mAlarmGui->clientCount() > 1)
00111   {
00112     // More than one client is installed, so provide a choice
00113     // as to which program to activate when the panel icon is clicked.
00114     int index = mClientIndex;
00115     menu->insertSeparator(index++);
00116     ClientList clients = mAlarmGui->clients();
00117     ClientList::Iterator client;
00118     for ( client = clients.begin();  client != clients.end();  ++client )
00119     {
00120       int id = menu->insertItem(i18n("Click Starts %1").arg((*client).title),
00121                                 this, SLOT(selectClient(int)), 0, -1, index);
00122       menu->setItemParameter(id, index);    // set parameter for selectClient()
00123       menu->setItemChecked(id, ((*client).appName == mAlarmGui->defaultClient()));
00124       (*client).menuIndex = index++;
00125     }
00126     mNumClientIds = index - mClientIndex;
00127   }
00128 }
00129 
00130 /*
00131  * Update the context menu to display the current calendar URLs.
00132  * If 'recreate' is true, the calendar menu items are recreated from scratch.
00133  * If 'recreate' is false, the existing menu items' statuses are simply updated.
00134  */
00135 void AlarmDockWindow::updateMenuCalendars(bool recreate)
00136 {
00137   bool enable = mAlarmGui->isDaemonRunning(false);
00138   KPopupMenu* menu = contextMenu();
00139   int calendarIndex = mClientIndex + mNumClientIds;   // index to separator before calendars
00140   if (recreate)
00141   {
00142     // Recreate the calendar menu items
00143     if (mNumCalendarIds)
00144     {
00145       // Client applications are already on the menu, so delete them
00146       for ( ;  mNumCalendarIds > 0;  --mNumCalendarIds)
00147         menu->removeItemAt(calendarIndex);
00148     }
00149     if (mAlarmGui->calendarCount() > 0)
00150     {
00151       int index = calendarIndex;
00152       menu->insertSeparator(index++);
00153       CalendarList calendars = mAlarmGui->calendars();
00154       ADCalendarBase *cal;
00155       for( cal = calendars.first(); cal; cal = calendars.next() )
00156       {
00157         int id = menu->insertItem(KURL(cal->urlString()).prettyURL(), this,
00158                                   SLOT(selectCal(int)), 0, -1, index);
00159         menu->setItemParameter(id, index++);    // set parameter for selectCal()
00160         menu->setItemEnabled(id, enable && cal->available());
00161         menu->setItemChecked(id, cal->enabled());
00162       }
00163       mNumCalendarIds = index - calendarIndex;
00164     }
00165   }
00166   else
00167   {
00168     // Update the state of the existing menu items
00169     int index = calendarIndex;
00170     CalendarList calendars = mAlarmGui->calendars();
00171     ADCalendarBase *cal;
00172     for( cal = calendars.first(); cal; cal = calendars.next() )
00173     {
00174       int id = menu->idAt(++index);
00175       menu->setItemEnabled(id, enable && cal->available());
00176       menu->setItemChecked(id, cal->enabled());
00177     }
00178   }
00179 }
00180 
00181 /*
00182  * Called when the Alarms Enabled context menu item is selected.
00183  * The alarm daemon is stopped or started as appropriate.
00184  */
00185 void AlarmDockWindow::toggleAlarmsEnabled()
00186 {
00187   bool newstate = !contextMenu()->isItemChecked(mAlarmsEnabledId);
00188   if (newstate)
00189   {
00190     // Start monitoring alarms - start the alarm daemon
00191     if (!mAlarmGui->isDaemonRunning())
00192     {
00193       // The daemon is not running
00194       QString execStr = locate("exe", DAEMON_APP_NAME);
00195       if (execStr.isEmpty())
00196       {
00197         KMessageBox::error(this, i18n("Alarm Daemon not found"), i18n("%1 Error").arg(kapp->aboutData()->programName()));
00198         kdError() << "AlarmDockWindow::toggleAlarmsEnabled(): kalarmd not found" << endl;
00199         return;
00200       }
00201       system(QFile::encodeName(execStr));
00202     }
00203   }
00204   else
00205   {
00206     AlarmDaemonIface_stub s( DAEMON_APP_NAME, DAEMON_DCOP_OBJECT );
00207     s.quit();
00208     if (!s.ok())
00209       kdDebug() << "AlarmDockWindow::toggleAlarmsEnabled(): quit dcop send failed\n";
00210   }
00211   mAlarmGui->setFastDaemonCheck();
00212 }
00213 
00214 /*
00215  * Called by a timer after the Alarms Enabled context menu item is selected,
00216  * to update the GUI status once the daemon has responded to the command.
00217  */
00218 void AlarmDockWindow::setDaemonStatus(bool newstatus)
00219 {
00220   bool oldstatus = contextMenu()->isItemChecked(mAlarmsEnabledId);
00221   kdDebug() << "AlarmDockWindow::setDaemonStatus(): "<<(int)oldstatus<<"->"<<(int)newstatus<<endl;
00222   if (newstatus != oldstatus)
00223   {
00224     setPixmap(newstatus ? mPixmapEnabled : mPixmapDisabled);
00225     contextMenu()->setItemChecked(mAlarmsEnabledId, newstatus);
00226     mSettingDaemonStatus = true;
00227     contextMenuAboutToShow(contextMenu());
00228     mSettingDaemonStatus = false;
00229   }
00230 }
00231 
00232 /*
00233  * Called when a client application is selected in the context menu.
00234  * The config file is updated with the new default client.
00235  */
00236 void AlarmDockWindow::selectClient(int menuIndex)
00237 {
00238   KPopupMenu* menu = contextMenu();
00239   kdDebug() << "AlarmDockWindow::selectClient(): " << menuIndex << endl;
00240   if (!menu->isItemChecked(menu->idAt(menuIndex)))
00241   {
00242     for (int i = mClientIndex;  i < mClientIndex + mNumClientIds;  ++i) {
00243       menu->setItemChecked(menu->idAt(i), (i == menuIndex));
00244     }
00245     mAlarmGui->setDefaultClient(menuIndex);
00246   }
00247 }
00248 
00249 /*
00250  * Called when a calendar is selected in the context menu.
00251  * The calendar's new enable state is sent to the daemon via DCOP.
00252  * The menu item's status is changed only when the daemon notifies
00253  * its new status.
00254  */
00255 void AlarmDockWindow::selectCal(int menuIndex)
00256 {
00257   KPopupMenu* menu = contextMenu();
00258   int id = menu->idAt(menuIndex);
00259   bool newstate = !menu->isItemChecked(id);
00260   kdDebug() << "AlarmDockWindow::selectCal(): "<< menuIndex << ": id=" << id << " newstate=" << (int)newstate << endl;
00261   int index = mClientIndex + mNumClientIds;
00262   CalendarList calendars = mAlarmGui->calendars();
00263   ADCalendarBase *cal;
00264   for( cal = calendars.first(); cal; cal = calendars.next() )
00265   {
00266     if (++index == menuIndex)
00267     {
00268       AlarmDaemonIface_stub s( DAEMON_APP_NAME, DAEMON_DCOP_OBJECT );
00269       s.enableCal( cal->urlString(), newstate );
00270       break;
00271     }
00272   }
00273 }
00274 
00275 /*
00276  * Set GUI autostart at login on or off, and set the context menu accordingly.
00277  */
00278 void AlarmDockWindow::setGuiAutostart(bool on)
00279 {
00280 kdDebug()<<"setGuiAutostart()="<<int(on)<<endl;
00281   KConfig* config = kapp->config();
00282   config->setGroup("General");
00283   config->writeEntry("Autostart", on);
00284   config->sync();
00285   contextMenu()->setItemChecked(mAutostartGuiId, on);
00286 }
00287 
00288 /*
00289  * Called when the daemon autostart menu option is selected, to toggle
00290  * the daemon's autostart state. This is done by sending a DCOP message
00291  * to the daemon. The menu item state is changed only when the daemon
00292  * notifies its new autostart status.
00293  */
00294 void AlarmDockWindow::toggleDaemonAutostart()
00295 {
00296   AlarmDaemonIface_stub s( DAEMON_APP_NAME, DAEMON_DCOP_OBJECT );
00297   s.enableAutoStart( !mAlarmGui->autostartDaemon() );
00298   if (!s.ok())
00299     kdDebug() << "AlarmDockWindow::toggleDaemonAutostart(): enableAutoStart dcop send failed\n";
00300   contextMenuAboutToShow(contextMenu());
00301 }
00302 
00303 /*
00304  * Called when the context menu is about to be displayed.
00305  * Enable or disable items which cause DCOP messages to be sent to the
00306  * alarm daemon, depending on whether the daemon is currently running.
00307  */
00308 void AlarmDockWindow::contextMenuAboutToShow(KPopupMenu* menu)
00309 {
00310   menu->setItemEnabled(mAutostartDaemonId, mAlarmGui->isDaemonRunning(!mSettingDaemonStatus));
00311   updateMenuCalendars(false);
00312 }
00313 
00314 /*
00315  * Called when the mouse is clicked over the panel icon.
00316  */
00317 void AlarmDockWindow::mousePressEvent(QMouseEvent* e)
00318 {
00319   if (e->button() == LeftButton)
00320   {
00321     // Left click: start up the default client application
00322     KProcess proc;
00323     proc << mAlarmGui->defaultClient();
00324     proc.start(KProcess::DontCare);
00325   }
00326   else
00327     KSystemTray::mousePressEvent(e);
00328 }
00329 
00330 void AlarmDockWindow::closeEvent(QCloseEvent*)
00331 {
00332   kapp->quit();
00333 }
00334 
00335 void AlarmDockWindow::addToolTip(const QString& filename)
00336 {
00337   QString apps;
00338   ClientList clients = mAlarmGui->clients();
00339   ClientList::ConstIterator client;
00340   for ( client = clients.begin();  client != clients.end();  ++client )
00341   {
00342     if (!apps.isEmpty())
00343       apps += '/';
00344     apps += (*client).title;
00345   }
00346   apps += i18n(" Alarm Monitor");
00347 
00348   if (!filename.isEmpty())
00349     apps += "\n" + filename;
00350   QToolTip::remove(this);
00351   QToolTip::add(this, apps);
00352 }
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