kalarm Library API Documentation

mainwindow.cpp

00001 /*
00002  *  mainwindow.cpp  -  main application window
00003  *  Program:  kalarm
00004  *  (C) 2001, 2002 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
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  *
00020  *  As a special exception, permission is given to link this program
00021  *  with any edition of Qt, and distribute the resulting executable,
00022  *  without including the source code for Qt in the source distribution.
00023  */
00024 
00025 #include "kalarm.h"
00026 
00027 #include <qiconset.h>
00028 
00029 #include <kmenubar.h>
00030 #include <ktoolbar.h>
00031 #include <kpopupmenu.h>
00032 #include <kaccel.h>
00033 #include <kaction.h>
00034 #include <kstdaction.h>
00035 #include <kiconloader.h>
00036 #include <kmessagebox.h>
00037 #include <klocale.h>
00038 #include <kconfig.h>
00039 #include <kaboutdata.h>
00040 #include <kdebug.h>
00041 
00042 #include "kalarmapp.h"
00043 #include "alarmcalendar.h"
00044 #include "daemongui.h"
00045 #include "traywindow.h"
00046 #include "editdlg.h"
00047 #include "prefdlg.h"
00048 #include "prefsettings.h"
00049 #include "alarmlistview.h"
00050 #include "mainwindow.moc"
00051 
00052 
00053 /*=============================================================================
00054 =  Class: KAlarmMainWindow
00055 =============================================================================*/
00056 
00057 QPtrList<KAlarmMainWindow> KAlarmMainWindow::windowList;
00058 
00059 
00060 KAlarmMainWindow::KAlarmMainWindow(bool restored)
00061         : MainWindowBase(0L, 0L, WGroupLeader | WStyle_ContextHelp | WDestructiveClose),
00062           mHiddenTrayParent(false)
00063 {
00064         kdDebug(5950) << "KAlarmMainWindow::KAlarmMainWindow()\n";
00065         setAutoSaveSettings(QString::fromLatin1("MainWindow"));    // save window sizes etc.
00066         setPlainCaption(kapp->aboutData()->programName());
00067         if (!restored)
00068                 resize(theApp()->readConfigWindowSize("MainWindow", size()));
00069 
00070         theApp()->checkCalendar();    // ensure calendar is open
00071         listView = new AlarmListView(this, "listView");
00072         setCentralWidget(listView);
00073         listView->refresh();          // populate the alarm list
00074         listView->clearSelection();
00075 
00076         initActions();
00077         connect(listView, SIGNAL(itemDeleted()), this, SLOT(slotDeletion()));
00078         connect(listView, SIGNAL(selectionChanged(QListViewItem*)), this, SLOT(slotSelection(QListViewItem*)));
00079         connect(listView, SIGNAL(mouseButtonClicked(int, QListViewItem*, const QPoint&, int)),
00080                 this, SLOT(slotMouseClicked(int, QListViewItem*, const QPoint&, int)));
00081         connect(listView, SIGNAL(executed(QListViewItem*)), this, SLOT(slotDoubleClicked(QListViewItem*)));
00082         windowList.append(this);
00083 
00084         if (windowList.count() == 1  &&  theApp()->daemonGuiHandler())
00085         {
00086                 // It's the first main window, and the DCOP handler is ready
00087                 if (theApp()->runInSystemTray())
00088                         theApp()->displayTrayIcon(true, this);     // create system tray icon for run-in-system-tray mode
00089                 else if (theApp()->trayWindow())
00090                         theApp()->trayWindow()->setAssocMainWindow(this);    // associate this window with the system tray icon
00091         }
00092 }
00093 
00094 KAlarmMainWindow::~KAlarmMainWindow()
00095 {
00096         kdDebug(5950) << "KAlarmMainWindow::~KAlarmMainWindow()\n";
00097         if (findWindow(this))
00098                 windowList.remove();
00099         if (theApp()->trayWindow())
00100         {
00101                 if (trayParent())
00102                         delete theApp()->trayWindow();
00103                 else
00104                         theApp()->trayWindow()->removeWindow(this);
00105         }
00106         KAlarmMainWindow* main = mainMainWindow();
00107         if (main)
00108                 theApp()->writeConfigWindowSize("MainWindow", main->size());
00109         KGlobal::config()->sync();    // save any new window size to disc
00110         theApp()->quitIf();
00111 }
00112 
00113 /******************************************************************************
00114 * Save settings to the session managed config file, for restoration
00115 * when the program is restored.
00116 */
00117 void KAlarmMainWindow::saveProperties(KConfig* config)
00118 {
00119         config->writeEntry(QString::fromLatin1("HiddenTrayParent"), trayParent() && isHidden());
00120 }
00121 
00122 /******************************************************************************
00123 * Read settings from the session managed config file.
00124 * This function is automatically called whenever the app is being
00125 * restored. Read in whatever was saved in saveProperties().
00126 */
00127 void KAlarmMainWindow::readProperties(KConfig* config)
00128 {
00129         mHiddenTrayParent = config->readBoolEntry(QString::fromLatin1("HiddenTrayParent"));
00130 }
00131 
00132 /******************************************************************************
00133 * Get the main main window, i.e. the parent of the system tray icon, or if
00134 * none, the first main window to be created. Visible windows take precedence
00135 * over hidden ones.
00136 */
00137 KAlarmMainWindow* KAlarmMainWindow::mainMainWindow()
00138 {
00139         KAlarmMainWindow* tray = theApp()->trayWindow() ? theApp()->trayWindow()->assocMainWindow() : 0L;
00140         if (tray  &&  tray->isVisible())
00141                 return tray;
00142         for (KAlarmMainWindow* w = windowList.first();  w;  w = windowList.next())
00143                 if (w->isVisible())
00144                                 return w;
00145         if (tray)
00146                 return tray;
00147         return windowList.first();
00148 }
00149 
00150 /******************************************************************************
00151 * Check whether this main window is the parent of the system tray icon.
00152 */
00153 bool KAlarmMainWindow::trayParent() const
00154 {
00155         return theApp()->runInSystemTray()  &&  theApp()->trayMainWindow() == this;
00156 }
00157 
00158 /******************************************************************************
00159 *  Close all main windows.
00160 */
00161 void KAlarmMainWindow::closeAll()
00162 {
00163         while (windowList.first())
00164                 delete windowList.first();
00165 }
00166 
00167 /******************************************************************************
00168 *  Called when the window's size has changed (before it is painted).
00169 *  Sets the last column in the list view to extend at least to the right hand
00170 *  edge of the list view.
00171 *  Records the new size in the config file.
00172 */
00173 void KAlarmMainWindow::resizeEvent(QResizeEvent* re)
00174 {
00175         listView->resizeLastColumn();
00176         // Save the window's new size only if it's the first main window
00177         if (mainMainWindow() == this)
00178                 theApp()->writeConfigWindowSize("MainWindow", re->size());
00179         MainWindowBase::resizeEvent(re);
00180 }
00181 
00182 /******************************************************************************
00183 *  Called when the window is first displayed.
00184 *  Sets the last column in the list view to extend at least to the right hand
00185 *  edge of the list view.
00186 */
00187 void KAlarmMainWindow::showEvent(QShowEvent* se)
00188 {
00189         listView->resizeLastColumn();
00190         MainWindowBase::showEvent(se);
00191 }
00192 
00193 /******************************************************************************
00194 *  Initialise the menu, toolbar and main window actions.
00195 */
00196 void KAlarmMainWindow::initActions()
00197 {
00198         KActionCollection* actions = actionCollection();
00199         actionQuit           = KStdAction::quit(this, SLOT(slotQuit()), actions);
00200         actionNew            = new KAction(i18n("&New..."), "eventnew", Qt::Key_Insert, this, SLOT(slotNew()), actions, "new");
00201         actionModify         = new KAction(i18n("&Modify..."), "pencil", Qt::CTRL+Qt::Key_M, this, SLOT(slotModify()), actions, "modify");
00202         actionDelete         = new KAction(i18n("&Delete"), "eventdelete", Qt::Key_Delete, this, SLOT(slotDelete()), actions, "delete");
00203         actionToggleTrayIcon = new KAction(QString(" "), "kalarm", Qt::CTRL+Qt::Key_T, this, SLOT(slotToggleTrayIcon()), actions, "tray");
00204         actionRefreshAlarms  = new KAction(i18n("&Refresh Alarms"), "reload", 0, this, SLOT(slotResetDaemon()), actions, "refresh");
00205 
00206         // Set up the menu bar
00207 
00208         KMenuBar* menu = menuBar();
00209         KPopupMenu* submenu = new KPopupMenu(this, "file");
00210         menu->insertItem(i18n("&File"), submenu);
00211         actionQuit->plug(submenu);
00212 
00213         mViewMenu = new KPopupMenu(this, "view");
00214         mViewMenuId = 0L;
00215         connect(theApp()->settings(), SIGNAL(settingsChanged()), this, SLOT(slotSettingsChanged()));
00216         actionToggleTrayIcon->plug(mViewMenu);
00217         connect(theApp(), SIGNAL(trayIconToggled()), this, SLOT(updateTrayIconAction()));
00218         updateTrayIconAction();         // set the correct text for this action
00219         slotSettingsChanged();          // display View menu if appropriate
00220 
00221         mActionsMenu = new KPopupMenu(this, "actions");
00222         menu->insertItem(i18n("&Actions"), mActionsMenu);
00223         actionNew->plug(mActionsMenu);
00224         actionModify->plug(mActionsMenu);
00225         actionDelete->plug(mActionsMenu);
00226         mActionsMenu->insertSeparator(3);
00227 
00228         ActionAlarmsEnabled* a = theApp()->actionAlarmEnable();
00229         mAlarmsEnabledId = a->itemId(a->plug(mActionsMenu));
00230         connect(a, SIGNAL(alarmsEnabledChange(bool)), this, SLOT(setAlarmEnabledStatus(bool)));
00231         DaemonGuiHandler* daemonGui = theApp()->daemonGuiHandler();
00232         if (daemonGui)
00233         {
00234                 daemonGui->checkStatus();
00235                 setAlarmEnabledStatus(daemonGui->monitoringAlarms());
00236         }
00237 
00238         actionRefreshAlarms->plug(mActionsMenu);
00239         connect(mActionsMenu, SIGNAL(aboutToShow()), this, SLOT(updateActionsMenu()));
00240 
00241         submenu = new KPopupMenu(this, "settings");
00242         menu->insertItem(i18n("&Settings"), submenu);
00243         theApp()->actionPreferences()->plug(submenu);
00244         theApp()->actionDaemonControl()->plug(submenu);
00245 
00246         menu->insertItem(i18n("&Help"), helpMenu());
00247 
00248         // Set up the toolbar
00249 
00250         KToolBar* toolbar = toolBar();
00251         actionNew->plug(toolbar);
00252         actionModify->plug(toolbar);
00253         actionDelete->plug(toolbar);
00254 
00255 
00256         actionModify->setEnabled(false);
00257         actionDelete->setEnabled(false);
00258         if (!theApp()->KDEDesktop())
00259                 actionToggleTrayIcon->setEnabled(false);
00260 }
00261 
00262 /******************************************************************************
00263 *  Called when KAlarm settings have changed.
00264 *  Show or hide the View menu in the menu bar.
00265 */
00266 void KAlarmMainWindow::slotSettingsChanged()
00267 {
00268         bool systray = theApp()->runInSystemTray();
00269         if (systray  &&  mViewMenuId
00270         ||  !systray  &&  !mViewMenuId)
00271         {
00272                 KMenuBar* menu = menuBar();
00273                 if (systray)
00274                 {
00275                         menu->removeItem(mViewMenuId);
00276                         mViewMenuId = 0;
00277                 }
00278                 else
00279                 {
00280                         mViewMenuId = menu->insertItem(i18n("&View"), mViewMenu, -1, 1);
00281                         updateTrayIconAction();
00282                 }
00283         }
00284 }
00285 
00286 /******************************************************************************
00287 * Refresh the alarm list in every main window instance.
00288 */
00289 void KAlarmMainWindow::refresh()
00290 {
00291         kdDebug(5950) << "KAlarmMainWindow::refresh()\n";
00292         for (KAlarmMainWindow* w = windowList.first();  w;  w = windowList.next())
00293                 w->listView->refresh();
00294 }
00295 
00296 /******************************************************************************
00297 * Add a new alarm to every main window instance.
00298 * 'win' = initiating main window instance (which has already been updated)
00299 */
00300 void KAlarmMainWindow::addEvent(const KAlarmEvent& event, KAlarmMainWindow* win)
00301 {
00302         kdDebug(5950) << "KAlarmMainWindow::addEvent(): " << event.id() << endl;
00303         for (KAlarmMainWindow* w = windowList.first();  w;  w = windowList.next())
00304                 if (w != win)
00305                         w->listView->addEntry(event, true);
00306 }
00307 
00308 /******************************************************************************
00309 * Modify an alarm in every main window instance.
00310 * 'win' = initiating main window instance (which has already been updated)
00311 */
00312 void KAlarmMainWindow::modifyEvent(const QString& oldEventID, const KAlarmEvent& newEvent, KAlarmMainWindow* win)
00313 {
00314         for (KAlarmMainWindow* w = windowList.first();  w;  w = windowList.next())
00315                 if (w != win)
00316                         w->modifyEvent(oldEventID, newEvent);
00317 }
00318 
00319 /******************************************************************************
00320 * Modify an alarm in the displayed list.
00321 */
00322 void KAlarmMainWindow::modifyEvent(const QString& oldEventID, const KAlarmEvent& newEvent)
00323 {
00324         AlarmListViewItem* item = listView->getEntry(oldEventID);
00325         if (item)
00326         {
00327                 listView->deleteEntry(item);
00328                 listView->addEntry(newEvent, true);
00329         }
00330         else
00331                 listView->refresh();
00332 }
00333 
00334 /******************************************************************************
00335 * Delete an alarm from every main window instance.
00336 * 'win' = initiating main window instance (which has already been updated)
00337 */
00338 void KAlarmMainWindow::deleteEvent(const KAlarmEvent& event, KAlarmMainWindow* win)
00339 {
00340         for (KAlarmMainWindow* w = windowList.first();  w;  w = windowList.next())
00341                 if (w != win)
00342                         w->deleteEvent(event);
00343 }
00344 
00345 /******************************************************************************
00346 * Delete an alarm from the displayed list.
00347 */
00348 void KAlarmMainWindow::deleteEvent(const KAlarmEvent& event)
00349 {
00350         AlarmListViewItem* item = listView->getEntry(event.id());
00351         if (item)
00352                 listView->deleteEntry(item, true);
00353         else
00354                 listView->refresh();
00355 }
00356 
00358 // SLOT IMPLEMENTATION
00360 
00361 /******************************************************************************
00362 *  Called when the New button is clicked to edit a new alarm to add to the list.
00363 */
00364 void KAlarmMainWindow::slotNew()
00365 {
00366         EditAlarmDlg* editDlg = new EditAlarmDlg(i18n("New Alarm"), this, "editDlg");
00367         if (editDlg->exec() == QDialog::Accepted)
00368         {
00369                 KAlarmEvent event;
00370                 editDlg->getEvent(event);
00371 
00372                 // Add the alarm to the displayed lists and to the calendar file
00373                 theApp()->addEvent(event, this);
00374                 AlarmListViewItem* item = listView->addEntry(event, true);
00375                 listView->setSelected(item, true);
00376         }
00377 }
00378 
00379 /******************************************************************************
00380 *  Called when the Modify button is clicked to edit the currently highlighted
00381 *  alarm in the list.
00382 */
00383 void KAlarmMainWindow::slotModify()
00384 {
00385         AlarmListViewItem* item = listView->selectedItem();
00386         if (item)
00387         {
00388                 KAlarmEvent event = listView->getEntry(item);
00389                 EditAlarmDlg* editDlg = new EditAlarmDlg(i18n("Edit Alarm"), this, "editDlg", &event);
00390                 if (editDlg->exec() == QDialog::Accepted)
00391                 {
00392                         KAlarmEvent newEvent;
00393                         editDlg->getEvent(newEvent);
00394 
00395                         // Update the event in the displays and in the calendar file
00396                         theApp()->modifyEvent(event.id(), newEvent, this);
00397                         item = listView->updateEntry(item, newEvent, true);
00398                         listView->setSelected(item, true);
00399                 }
00400         }
00401 }
00402 
00403 /******************************************************************************
00404 *  Called when the Delete button is clicked to delete the currently highlighted
00405 *  alarm in the list.
00406 */
00407 void KAlarmMainWindow::slotDelete()
00408 {
00409         AlarmListViewItem* item = listView->selectedItem();
00410         if (item)
00411         {
00412                 if (theApp()->settings()->confirmAlarmDeletion())
00413                 {
00414                         int n = 1;
00415                         if (KMessageBox::warningContinueCancel(this, i18n("Do you really want to delete the selected alarm?", "Do you really want to delete the %n selected alarms?", n),
00416                                                                i18n("Delete Alarm", "Delete Alarms", n), i18n("&Delete"))
00417                             != KMessageBox::Continue)
00418                                 return;
00419                 }
00420                 KAlarmEvent event = listView->getEntry(item);
00421 
00422                 // Delete the event from the displays
00423                 theApp()->deleteEvent(event, this);
00424                 listView->deleteEntry(item, true);
00425         }
00426 }
00427 
00428 /******************************************************************************
00429 *  Called when the Display System Tray Icon menu item is selected.
00430 */
00431 void KAlarmMainWindow::slotToggleTrayIcon()
00432 {
00433         theApp()->displayTrayIcon(!theApp()->trayIconDisplayed(), this);
00434 }
00435 
00436 /******************************************************************************
00437 * Called when the system tray icon is created or destroyed.
00438 * Set the system tray icon menu text according to whether or not the system
00439 * tray icon is currently visible.
00440 */
00441 void KAlarmMainWindow::updateTrayIconAction()
00442 {
00443         actionToggleTrayIcon->setEnabled(!theApp()->runInSystemTray());
00444         actionToggleTrayIcon->setText(theApp()->trayIconDisplayed() ? i18n("Hide from System &Tray") : i18n("Show in System &Tray"));
00445 }
00446 
00447 /******************************************************************************
00448 * Called when the Actions menu is about to be displayed.
00449 * Update the status of the Alarms Enabled menu item.
00450 */
00451 void KAlarmMainWindow::updateActionsMenu()
00452 {
00453         theApp()->daemonGuiHandler()->checkStatus();   // update the Alarms Enabled item status
00454 }
00455 
00456 /******************************************************************************
00457 *  Called when the Reset Daemon menu item is selected.
00458 */
00459 void KAlarmMainWindow::slotResetDaemon()
00460 {
00461         theApp()->resetDaemon();
00462 }
00463 
00464 /******************************************************************************
00465 *  Called when the Quit menu item is selected.
00466 */
00467 void KAlarmMainWindow::slotQuit()
00468 {
00469         if (trayParent())
00470                 hide();          // closing would also close the system tray icon
00471         else
00472                 close();
00473 }
00474 
00475 /******************************************************************************
00476 *  Called when the user or the session manager attempts to close the window.
00477 */
00478 void KAlarmMainWindow::closeEvent(QCloseEvent* ce)
00479 {
00480         if (!theApp()->sessionClosingDown()  &&  trayParent())
00481         {
00482                 // The user (not the session manager) wants to close the window.
00483                 // It's the parent window of the system tray icon, so just hide
00484                 // it to prevent the system tray icon closing.
00485                 hide();
00486                 ce->ignore();
00487         }
00488         else
00489                 ce->accept();
00490 }
00491 
00492 /******************************************************************************
00493 *  Called when an item is deleted from the ListView.
00494 *  Disables the actions if no item is still selected.
00495 */
00496 void KAlarmMainWindow::slotDeletion()
00497 {
00498         if (!listView->selectedItem())
00499         {
00500                 kdDebug(5950) << "KAlarmMainWindow::slotDeletion(true)\n";
00501                 actionModify->setEnabled(false);
00502                 actionDelete->setEnabled(false);
00503         }
00504 }
00505 
00506 /******************************************************************************
00507 *  Called when the selected item in the ListView changes.
00508 *  Selects the new current item, and enables the actions appropriately.
00509 */
00510 void KAlarmMainWindow::slotSelection(QListViewItem* item)
00511 {
00512         if (item)
00513         {
00514                 kdDebug(5950) << "KAlarmMainWindow::slotSelection(true)\n";
00515                 listView->setSelected(item, true);
00516                 actionModify->setEnabled(true);
00517                 actionDelete->setEnabled(true);
00518         }
00519 }
00520 
00521 /******************************************************************************
00522 *  Called when the mouse is clicked on the ListView.
00523 *  Deselects the current item and disables the actions if appropriate, or
00524 *  displays a context menu to modify or delete the selected item.
00525 */
00526 void KAlarmMainWindow::slotMouseClicked(int button, QListViewItem* item, const QPoint& pt, int)
00527 {
00528         if (!item)
00529         {
00530                 kdDebug(5950) << "KAlarmMainWindow::slotMouseClicked(left)\n";
00531                 listView->clearSelection();
00532                 actionModify->setEnabled(false);
00533                 actionDelete->setEnabled(false);
00534         }
00535         else if (button == Qt::RightButton)
00536         {
00537                 kdDebug(5950) << "KAlarmMainWindow::slotMouseClicked(right)\n";
00538                 QPopupMenu* menu = new QPopupMenu(this, "ListContextMenu");
00539                 actionModify->plug(menu);
00540                 actionDelete->plug(menu);
00541                 menu->exec(pt);
00542         }
00543 }
00544 
00545 /******************************************************************************
00546 *  Called when the mouse is double clicked on the ListView.
00547 *  If it is double clicked on an item, the modification dialog is displayed.
00548 */
00549 void KAlarmMainWindow::slotDoubleClicked(QListViewItem* item)
00550 {
00551         if (item)
00552         {
00553                 kdDebug(5950) << "KAlarmMainWindow::slotDoubleClicked()\n";
00554                 slotModify();
00555         }
00556 }
00557 
00558 /******************************************************************************
00559 * Called when the Alarms Enabled action status has changed.
00560 * Updates the alarms enabled menu item check state.
00561 */
00562 void KAlarmMainWindow::setAlarmEnabledStatus(bool status)
00563 {
00564         kdDebug(5950) << "KAlarmMainWindow::setAlarmEnabledStatus(" << (int)status << ")\n";
00565         mActionsMenu->setItemChecked(mAlarmsEnabledId, status);
00566 }
00567 
00568 /******************************************************************************
00569 *  Display or hide the specified main window.
00570 *  This should only be called when the application doesn't run in the system tray.
00571 */
00572 KAlarmMainWindow* KAlarmMainWindow::toggleWindow(KAlarmMainWindow* win)
00573 {
00574         if (win  &&  findWindow(win))
00575         {
00576                 // A window is specified (and it exists)
00577                 if (win->isVisible())
00578                 {
00579                         // The window is visible, so close it
00580                         win->close();
00581                         return 0L;
00582                 }
00583                 else
00584                 {
00585                         // The window is hidden, so display it
00586                         win->hide();        // in case it's on a different desktop
00587                         win->showNormal();
00588                         win->raise();
00589                         win->setActiveWindow();
00590                         return win;
00591                 }
00592         }
00593 
00594         // No window is specified, or the window doesn't exist. Open a new one.
00595         win = new KAlarmMainWindow;
00596         win->show();
00597         return win;
00598 }
00599 
00600 /******************************************************************************
00601 * Find the specified window in the main window list.
00602 */
00603 bool KAlarmMainWindow::findWindow(KAlarmMainWindow* win)
00604 {
00605         for (KAlarmMainWindow* w = windowList.first();  w;  w = windowList.next())
00606                 if (w == win)
00607                         return true;
00608         return false;
00609 }
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sat Oct 18 02:47:26 2003 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001