00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kalarm.h"
00022
00023 #include <qiconset.h>
00024 #include <qdragobject.h>
00025 #include <qheader.h>
00026
00027 #include <kmenubar.h>
00028 #include <ktoolbar.h>
00029 #include <kpopupmenu.h>
00030 #include <kaccel.h>
00031 #include <kaction.h>
00032 #include <kactionclasses.h>
00033 #include <kstdaction.h>
00034 #include <kiconloader.h>
00035 #include <kmessagebox.h>
00036 #include <kurldrag.h>
00037 #include <klocale.h>
00038 #include <kglobalsettings.h>
00039 #include <kconfig.h>
00040 #include <kkeydialog.h>
00041 #include <kedittoolbar.h>
00042 #include <kaboutdata.h>
00043 #include <dcopclient.h>
00044 #include <kdebug.h>
00045
00046 #include <libkdepim/maillistdrag.h>
00047 #include <libkmime/kmime_content.h>
00048 #include <libkcal/calendarlocal.h>
00049 #include <libkcal/icaldrag.h>
00050
00051 #include "alarmcalendar.h"
00052 #include "alarmevent.h"
00053 #include "alarmlistview.h"
00054 #include "alarmtext.h"
00055 #include "birthdaydlg.h"
00056 #include "daemon.h"
00057 #include "editdlg.h"
00058 #include "functions.h"
00059 #include "kalarmapp.h"
00060 #include "kamail.h"
00061 #include "prefdlg.h"
00062 #include "preferences.h"
00063 #include "synchtimer.h"
00064 #include "templatepickdlg.h"
00065 #include "templatedlg.h"
00066 #include "traywindow.h"
00067 #include "mainwindow.moc"
00068
00069 using namespace KCal;
00070
00071 static const char* UI_FILE = "kalarmui.rc";
00072 static const char* WINDOW_NAME = "MainWindow";
00073
00074 static QString undoText;
00075 static QString undoTextStripped;
00076 static QString undoIcon;
00077 static KShortcut undoShortcut;
00078 static QString redoText;
00079 static QString redoTextStripped;
00080 static QString redoIcon;
00081 static KShortcut redoShortcut;
00082
00083
00084
00085
00086
00087
00088 MainWindow::WindowList MainWindow::mWindowList;
00089 TemplateDlg* MainWindow::mTemplateDlg = 0;
00090
00091
00092
00093 QString MainWindow::i18n_a_ShowAlarmTimes() { return i18n("Show &Alarm Times"); }
00094 QString MainWindow::i18n_t_ShowAlarmTime() { return i18n("Show alarm &time"); }
00095 QString MainWindow::i18n_m_ShowAlarmTime() { return i18n("Show alarm ti&me"); }
00096 QString MainWindow::i18n_o_ShowTimeToAlarms() { return i18n("Show Time t&o Alarms"); }
00097 QString MainWindow::i18n_n_ShowTimeToAlarm() { return i18n("Show time u&ntil alarm"); }
00098 QString MainWindow::i18n_l_ShowTimeToAlarm() { return i18n("Show time unti&l alarm"); }
00099 QString MainWindow::i18n_ShowExpiredAlarms() { return i18n("Show Expired Alarms"); }
00100 QString MainWindow::i18n_e_ShowExpiredAlarms() { return i18n("Show &Expired Alarms"); }
00101 QString MainWindow::i18n_HideExpiredAlarms() { return i18n("Hide Expired Alarms"); }
00102 QString MainWindow::i18n_e_HideExpiredAlarms() { return i18n("Hide &Expired Alarms"); }
00103
00104
00105
00106
00107
00108
00109
00110 MainWindow* MainWindow::create(bool restored)
00111 {
00112 theApp()->checkCalendarDaemon();
00113 return new MainWindow(restored);
00114 }
00115
00116 MainWindow::MainWindow(bool restored)
00117 : MainWindowBase(0, "MainWin", WGroupLeader | WStyle_ContextHelp | WDestructiveClose),
00118 mMinuteTimerActive(false),
00119 mHiddenTrayParent(false),
00120 mShowExpired(Preferences::showExpiredAlarms()),
00121 mShowTime(Preferences::showAlarmTime()),
00122 mShowTimeTo(Preferences::showTimeToAlarm())
00123 {
00124 kdDebug(5950) << "MainWindow::MainWindow()\n";
00125 setAutoSaveSettings(QString::fromLatin1(WINDOW_NAME));
00126 setPlainCaption(kapp->aboutData()->programName());
00127 if (!restored)
00128 {
00129 QSize s;
00130 if (KAlarm::readConfigWindowSize(WINDOW_NAME, s))
00131 resize(s);
00132 }
00133 KConfig* config = KGlobal::config();
00134 config->setGroup(QString::fromLatin1(WINDOW_NAME));
00135 QValueList<int> order = config->readIntListEntry(QString::fromLatin1("ColumnOrder"));
00136
00137 setAcceptDrops(true);
00138 if (!mShowTimeTo)
00139 mShowTime = true;
00140 mListView = new AlarmListView(order, this, "listView");
00141 mListView->selectTimeColumns(mShowTime, mShowTimeTo);
00142 mListView->showExpired(mShowExpired);
00143 setCentralWidget(mListView);
00144 mListView->refresh();
00145 mListView->clearSelection();
00146
00147 connect(mListView, SIGNAL(itemDeleted()), SLOT(slotDeletion()));
00148 connect(mListView, SIGNAL(selectionChanged()), SLOT(slotSelection()));
00149 connect(mListView, SIGNAL(mouseButtonClicked(int, QListViewItem*, const QPoint&, int)),
00150 SLOT(slotMouseClicked(int, QListViewItem*, const QPoint&, int)));
00151 connect(mListView, SIGNAL(executed(QListViewItem*)), SLOT(slotDoubleClicked(QListViewItem*)));
00152 connect(mListView->header(), SIGNAL(indexChange(int, int, int)), SLOT(columnsReordered()));
00153 initActions();
00154
00155 mWindowList.append(this);
00156 if (mWindowList.count() == 1 && Daemon::isDcopHandlerReady())
00157 {
00158
00159 if (theApp()->wantRunInSystemTray())
00160 theApp()->displayTrayIcon(true, this);
00161 else if (theApp()->trayWindow())
00162 theApp()->trayWindow()->setAssocMainWindow(this);
00163 }
00164 setUpdateTimer();
00165 }
00166
00167 MainWindow::~MainWindow()
00168 {
00169 kdDebug(5950) << "MainWindow::~MainWindow()\n";
00170 mWindowList.remove(this);
00171 if (theApp()->trayWindow())
00172 {
00173 if (isTrayParent())
00174 delete theApp()->trayWindow();
00175 else
00176 theApp()->trayWindow()->removeWindow(this);
00177 }
00178 MinuteTimer::disconnect(this);
00179 mMinuteTimerActive = false;
00180 setUpdateTimer();
00181 MainWindow* main = mainMainWindow();
00182 if (main)
00183 KAlarm::writeConfigWindowSize(WINDOW_NAME, main->size());
00184 KToolBar* tb = toolBar();
00185 if (tb)
00186 tb->saveSettings(KGlobal::config(), "Toolbars");
00187 KGlobal::config()->sync();
00188 theApp()->quitIf();
00189 }
00190
00191
00192
00193
00194
00195 void MainWindow::saveProperties(KConfig* config)
00196 {
00197 config->writeEntry(QString::fromLatin1("HiddenTrayParent"), isTrayParent() && isHidden());
00198 config->writeEntry(QString::fromLatin1("ShowExpired"), mShowExpired);
00199 config->writeEntry(QString::fromLatin1("ShowTime"), mShowTime);
00200 config->writeEntry(QString::fromLatin1("ShowTimeTo"), mShowTimeTo);
00201 }
00202
00203
00204
00205
00206
00207
00208 void MainWindow::readProperties(KConfig* config)
00209 {
00210 mHiddenTrayParent = config->readBoolEntry(QString::fromLatin1("HiddenTrayParent"));
00211 mShowExpired = config->readBoolEntry(QString::fromLatin1("ShowExpired"));
00212 mShowTime = config->readBoolEntry(QString::fromLatin1("ShowTime"));
00213 mShowTimeTo = config->readBoolEntry(QString::fromLatin1("ShowTimeTo"));
00214 }
00215
00216
00217
00218
00219
00220
00221 MainWindow* MainWindow::mainMainWindow()
00222 {
00223 MainWindow* tray = theApp()->trayWindow() ? theApp()->trayWindow()->assocMainWindow() : 0;
00224 if (tray && tray->isVisible())
00225 return tray;
00226 for (WindowList::Iterator it = mWindowList.begin(); it != mWindowList.end(); ++it)
00227 if ((*it)->isVisible())
00228 return *it;
00229 if (tray)
00230 return tray;
00231 if (mWindowList.isEmpty())
00232 return 0;
00233 return mWindowList.first();
00234 }
00235
00236
00237
00238
00239 bool MainWindow::isTrayParent() const
00240 {
00241 return theApp()->wantRunInSystemTray() && theApp()->trayMainWindow() == this;
00242 }
00243
00244
00245
00246
00247 void MainWindow::closeAll()
00248 {
00249 while (mWindowList.first())
00250 delete mWindowList.first();
00251 }
00252
00253
00254
00255
00256
00257
00258
00259 void MainWindow::resizeEvent(QResizeEvent* re)
00260 {
00261
00262 if (mainMainWindow() == this)
00263 KAlarm::writeConfigWindowSize(WINDOW_NAME, re->size());
00264 MainWindowBase::resizeEvent(re);
00265 }
00266
00267
00268
00269
00270
00271
00272 void MainWindow::showEvent(QShowEvent* se)
00273 {
00274 setUpdateTimer();
00275 slotUpdateTimeTo();
00276 MainWindowBase::showEvent(se);
00277 }
00278
00279
00280
00281
00282 void MainWindow::show()
00283 {
00284 MainWindowBase::show();
00285 if (mMenuError)
00286 {
00287
00288
00289
00290 KMessageBox::error(this, i18n("Failure to create menus\n(perhaps %1 missing or corrupted)").arg(QString::fromLatin1(UI_FILE)));
00291 mMenuError = false;
00292 }
00293 }
00294
00295
00296
00297
00298 void MainWindow::hideEvent(QHideEvent* he)
00299 {
00300 setUpdateTimer();
00301 MainWindowBase::hideEvent(he);
00302 }
00303
00304
00305
00306
00307
00308 void MainWindow::columnsReordered()
00309 {
00310 KConfig* config = KGlobal::config();
00311 config->setGroup(QString::fromLatin1(WINDOW_NAME));
00312 config->writeEntry(QString::fromLatin1("ColumnOrder"), mListView->columnOrder());
00313 config->sync();
00314 }
00315
00316
00317
00318
00319 void MainWindow::initActions()
00320 {
00321 KActionCollection* actions = actionCollection();
00322 mActionTemplates = new KAction(i18n("&Templates..."), 0, this, SLOT(slotTemplates()), actions, "templates");
00323 mActionNew = KAlarm::createNewAlarmAction(i18n("&New..."), this, SLOT(slotNew()), actions, "new");
00324 mActionNewFromTemplate = KAlarm::createNewFromTemplateAction(i18n("New &From Template"), this, SLOT(slotNewFromTemplate(const KAEvent&)), actions, "newFromTempl");
00325 mActionCreateTemplate = new KAction(i18n("Create Tem&plate..."), 0, this, SLOT(slotNewTemplate()), actions, "createTemplate");
00326 mActionCopy = new KAction(i18n("&Copy..."), "editcopy", Qt::SHIFT+Qt::Key_Insert, this, SLOT(slotCopy()), actions, "copy");
00327 mActionModify = new KAction(i18n("&Edit..."), "edit", Qt::CTRL+Qt::Key_E, this, SLOT(slotModify()), actions, "modify");
00328 mActionDelete = new KAction(i18n("&Delete"), "editdelete", Qt::Key_Delete, this, SLOT(slotDelete()), actions, "delete");
00329 mActionReactivate = new KAction(i18n("Reac&tivate"), 0, Qt::CTRL+Qt::Key_R, this, SLOT(slotReactivate()), actions, "undelete");
00330 mActionEnable = new KAction(QString::null, 0, Qt::CTRL+Qt::Key_B, this, SLOT(slotEnable()), actions, "disable");
00331 mActionView = new KAction(i18n("&View"), "viewmag", Qt::CTRL+Qt::Key_W, this, SLOT(slotView()), actions, "view");
00332 mActionShowTime = new KToggleAction(i18n_a_ShowAlarmTimes(), Qt::CTRL+Qt::Key_M, this, SLOT(slotShowTime()), actions, "showAlarmTimes");
00333 mActionShowTime->setCheckedState(i18n("Hide &Alarm Times"));
00334 mActionShowTimeTo = new KToggleAction(i18n_o_ShowTimeToAlarms(), Qt::CTRL+Qt::Key_I, this, SLOT(slotShowTimeTo()), actions, "showTimeToAlarms");
00335 mActionShowTimeTo->setCheckedState(i18n("Hide Time t&o Alarms"));
00336 mActionShowExpired = new KToggleAction(i18n_e_ShowExpiredAlarms(), "history", Qt::CTRL+Qt::Key_P, this, SLOT(slotShowExpired()), actions, "showExpiredAlarms");
00337 mActionShowExpired->setCheckedState(i18n_e_HideExpiredAlarms());
00338 mActionToggleTrayIcon = new KToggleAction(i18n("Show in System &Tray"), 0, this, SLOT(slotToggleTrayIcon()), actions, "showInSystemTray");
00339 mActionToggleTrayIcon->setCheckedState(i18n("Hide From System &Tray"));
00340 new KAction(i18n("Import &Alarms..."), 0, this, SLOT(slotImportAlarms()), actions, "importAlarms");
00341 new KAction(i18n("Import &Birthdays..."), 0, this, SLOT(slotBirthdays()), actions, "importBirthdays");
00342 new KAction(i18n("&Refresh Alarms"), "reload", 0, this, SLOT(slotResetDaemon()), actions, "refreshAlarms");
00343 Daemon::createAlarmEnableAction(actions, "alarmEnable");
00344 if (undoText.isNull())
00345 {
00346
00347 KAction* act = KStdAction::undo(this, 0, actions);
00348 undoIcon = act->icon();
00349 undoShortcut = act->shortcut();
00350 undoText = act->text();
00351 undoTextStripped = KAlarm::stripAccel(undoText);
00352 delete act;
00353 act = KStdAction::redo(this, 0, actions);
00354 redoIcon = act->icon();
00355 redoShortcut = act->shortcut();
00356 redoText = act->text();
00357 redoTextStripped = KAlarm::stripAccel(redoText);
00358 delete act;
00359 }
00360 mActionUndo = new KToolBarPopupAction(undoText, undoIcon, undoShortcut, this, SLOT(slotUndo()), actions, "edit_undo");
00361 mActionRedo = new KToolBarPopupAction(redoText, redoIcon, redoShortcut, this, SLOT(slotRedo()), actions, "edit_redo");
00362 KStdAction::find(mListView, SLOT(slotFind()), actions);
00363 mActionFindNext = KStdAction::findNext(mListView, SLOT(slotFindNext()), actions);
00364 mActionFindPrev = KStdAction::findPrev(mListView, SLOT(slotFindPrev()), actions);
00365 KStdAction::selectAll(mListView, SLOT(slotSelectAll()), actions);
00366 KStdAction::deselect(mListView, SLOT(slotDeselect()), actions);
00367 KStdAction::quit(this, SLOT(slotQuit()), actions);
00368 KStdAction::keyBindings(this, SLOT(slotConfigureKeys()), actions);
00369 KStdAction::configureToolbars(this, SLOT(slotConfigureToolbar()), actions);
00370 KStdAction::preferences(this, SLOT(slotPreferences()), actions);
00371 setStandardToolBarMenuEnabled(true);
00372 createGUI(UI_FILE);
00373
00374 mContextMenu = static_cast<KPopupMenu*>(factory()->container("listContext", this));
00375 mActionsMenu = static_cast<KPopupMenu*>(factory()->container("actions", this));
00376 mMenuError = (!mContextMenu || !mActionsMenu);
00377 connect(mActionsMenu, SIGNAL(aboutToShow()), SLOT(updateActionsMenu()));
00378 connect(mActionUndo->popupMenu(), SIGNAL(aboutToShow()), SLOT(slotInitUndoMenu()));
00379 connect(mActionUndo->popupMenu(), SIGNAL(activated(int)), SLOT(slotUndoItem(int)));
00380 connect(mActionRedo->popupMenu(), SIGNAL(aboutToShow()), SLOT(slotInitRedoMenu()));
00381 connect(mActionRedo->popupMenu(), SIGNAL(activated(int)), SLOT(slotRedoItem(int)));
00382 connect(Undo::instance(), SIGNAL(changed(const QString&, const QString&)), SLOT(slotUndoStatus(const QString&, const QString&)));
00383 connect(mListView, SIGNAL(findActive(bool)), SLOT(slotFindActive(bool)));
00384 Preferences::connect(SIGNAL(preferencesChanged()), this, SLOT(slotPrefsChanged()));
00385 connect(theApp(), SIGNAL(trayIconToggled()), SLOT(updateTrayIconAction()));
00386
00387
00388 setEnableText(true);
00389 mActionShowTime->setChecked(mShowTime);
00390 mActionShowTimeTo->setChecked(mShowTimeTo);
00391 mActionShowExpired->setChecked(mShowExpired);
00392 slotPrefsChanged();
00393 mActionUndo->setEnabled(Undo::haveUndo());
00394 mActionRedo->setEnabled(Undo::haveRedo());
00395 mActionFindNext->setEnabled(false);
00396 mActionFindPrev->setEnabled(false);
00397
00398 mActionCopy->setEnabled(false);
00399 mActionModify->setEnabled(false);
00400 mActionDelete->setEnabled(false);
00401 mActionReactivate->setEnabled(false);
00402 mActionView->setEnabled(false);
00403 mActionEnable->setEnabled(false);
00404 mActionCreateTemplate->setEnabled(false);
00405
00406 KToolBar* tb = toolBar();
00407 if (tb)
00408 tb->applySettings(KGlobal::config(), "Toolbars");
00409
00410 Undo::emitChanged();
00411 Daemon::checkStatus();
00412 Daemon::monitoringAlarms();
00413 }
00414
00415
00416
00417
00418 void MainWindow::enableTemplateMenuItem(bool enable)
00419 {
00420 for (WindowList::Iterator it = mWindowList.begin(); it != mWindowList.end(); ++it)
00421 (*it)->mActionTemplates->setEnabled(enable);
00422 }
00423
00424
00425
00426
00427 void MainWindow::refresh()
00428 {
00429 kdDebug(5950) << "MainWindow::refresh()\n";
00430 for (WindowList::Iterator it = mWindowList.begin(); it != mWindowList.end(); ++it)
00431 (*it)->mListView->refresh();
00432 }
00433
00434
00435
00436
00437
00438
00439 void MainWindow::updateExpired()
00440 {
00441 kdDebug(5950) << "MainWindow::updateExpired()\n";
00442 bool enableShowExpired = Preferences::expiredKeepDays();
00443 for (WindowList::Iterator it = mWindowList.begin(); it != mWindowList.end(); ++it)
00444 {
00445 MainWindow* w = *it;
00446 if (w->mShowExpired)
00447 {
00448 if (!enableShowExpired)
00449 w->slotShowExpired();
00450 else
00451 w->mListView->refresh();
00452 }
00453 w->mActionShowExpired->setEnabled(enableShowExpired);
00454 }
00455 }
00456
00457
00458
00459
00460
00461
00462
00463 void MainWindow::updateTimeColumns(bool oldTime, bool oldTimeTo)
00464 {
00465 kdDebug(5950) << "MainWindow::updateShowAlarmTimes()\n";
00466 bool newTime = Preferences::showAlarmTime();
00467 bool newTimeTo = Preferences::showTimeToAlarm();
00468 if (!newTime && !newTimeTo)
00469 newTime = true;
00470 if (!oldTime && !oldTimeTo)
00471 oldTime = true;
00472 if (newTime != oldTime || newTimeTo != oldTimeTo)
00473 {
00474 for (WindowList::Iterator it = mWindowList.begin(); it != mWindowList.end(); ++it)
00475 {
00476 MainWindow* w = *it;
00477 if (w->mShowTime == oldTime
00478 && w->mShowTimeTo == oldTimeTo)
00479 {
00480 w->mShowTime = newTime;
00481 w->mShowTimeTo = newTimeTo;
00482 w->mActionShowTime->setChecked(newTime);
00483 w->mActionShowTimeTo->setChecked(newTimeTo);
00484 w->mListView->selectTimeColumns(newTime, newTimeTo);
00485 }
00486 }
00487 setUpdateTimer();
00488 }
00489 }
00490
00491
00492
00493
00494
00495
00496 void MainWindow::setUpdateTimer()
00497 {
00498
00499 MainWindow* needTimer = 0;
00500 MainWindow* timerWindow = 0;
00501 for (WindowList::Iterator it = mWindowList.begin(); it != mWindowList.end(); ++it)
00502 {
00503 MainWindow* w = *it;
00504 if (w->isVisible() && w->mListView->showingTimeTo())
00505 needTimer = w;
00506 if (w->mMinuteTimerActive)
00507 timerWindow = w;
00508 }
00509
00510
00511 if (needTimer && !timerWindow)
00512 {
00513
00514 needTimer->mMinuteTimerActive = true;
00515 MinuteTimer::connect(needTimer, SLOT(slotUpdateTimeTo()));
00516 kdDebug(5950) << "MainWindow::setUpdateTimer(): started timer" << endl;
00517 }
00518 else if (!needTimer && timerWindow)
00519 {
00520 timerWindow->mMinuteTimerActive = false;
00521 MinuteTimer::disconnect(timerWindow);
00522 kdDebug(5950) << "MainWindow::setUpdateTimer(): stopped timer" << endl;
00523 }
00524 }
00525
00526
00527
00528 void MainWindow::slotUpdateTimeTo()
00529 {
00530 kdDebug(5950) << "MainWindow::slotUpdateTimeTo()" << endl;
00531 for (WindowList::Iterator it = mWindowList.begin(); it != mWindowList.end(); ++it)
00532 {
00533 MainWindow* w = *it;
00534 if (w->isVisible() && w->mListView->showingTimeTo())
00535 w->mListView->updateTimeToAlarms();
00536 }
00537 }
00538
00539
00540
00541
00542 void MainWindow::selectEvent(const QString& eventID)
00543 {
00544 mListView->clearSelection();
00545 AlarmListViewItem* item = mListView->getEntry(eventID);
00546 if (item)
00547 {
00548 mListView->setSelected(item, true);
00549 mListView->setCurrentItem(item);
00550 mListView->ensureItemVisible(item);
00551 }
00552 }
00553
00554
00555
00556
00557 void MainWindow::slotNew()
00558 {
00559 executeNew(this);
00560 }
00561
00562
00563
00564
00565
00566 void MainWindow::executeNew(MainWindow* win, const KAEvent* evnt, KAEvent::Action action, const AlarmText& text)
00567 {
00568 EditAlarmDlg editDlg(false, i18n("New Alarm"), win, 0, evnt);
00569 if (!text.isEmpty())
00570 editDlg.setAction(action, text);
00571 if (editDlg.exec() == QDialog::Accepted)
00572 {
00573 KAEvent event;
00574 editDlg.getEvent(event);
00575
00576
00577 if (KAlarm::addEvent(event, (win ? win->mListView : 0), &editDlg) == KAlarm::UPDATE_KORG_ERR)
00578 KAlarm::displayKOrgUpdateError(&editDlg, KAlarm::KORG_ERR_ADD, 1);
00579 Undo::saveAdd(event);
00580
00581 KAlarm::outputAlarmWarnings(&editDlg, &event);
00582 }
00583 }
00584
00585
00586
00587
00588
00589 void MainWindow::slotNewFromTemplate(const KAEvent& tmplate)
00590 {
00591 executeNew(this, &tmplate);
00592 }
00593
00594
00595
00596
00597
00598 void MainWindow::slotNewTemplate()
00599 {
00600 AlarmListViewItem* item = mListView->selectedItem();
00601 if (item)
00602 {
00603 KAEvent event = item->event();
00604 TemplateDlg::createTemplate(&event, this);
00605 }
00606 }
00607
00608
00609
00610
00611
00612 void MainWindow::slotCopy()
00613 {
00614 AlarmListViewItem* item = mListView->selectedItem();
00615 if (item)
00616 executeNew(this, &item->event());
00617 }
00618
00619
00620
00621
00622
00623 void MainWindow::slotModify()
00624 {
00625 AlarmListViewItem* item = mListView->selectedItem();
00626 if (item)
00627 {
00628 KAEvent event = item->event();
00629 executeEdit(event, this);
00630 }
00631 }
00632
00633
00634
00635
00636 void MainWindow::executeEdit(KAEvent& event, MainWindow* win)
00637 {
00638 EditAlarmDlg editDlg(false, i18n("Edit Alarm"), win, 0, &event);
00639 if (editDlg.exec() == QDialog::Accepted)
00640 {
00641 KAEvent newEvent;
00642 bool changeDeferral = !editDlg.getEvent(newEvent);
00643
00644
00645 AlarmListView* view = win ? win->mListView : 0;
00646 if (changeDeferral)
00647 {
00648
00649 if (KAlarm::updateEvent(newEvent, view, &editDlg, true, false) != KAlarm::UPDATE_OK)
00650 return;
00651 }
00652 else
00653 {
00654 if (KAlarm::modifyEvent(event, newEvent, view, &editDlg) == KAlarm::UPDATE_KORG_ERR)
00655 KAlarm::displayKOrgUpdateError(&editDlg, KAlarm::KORG_ERR_MODIFY, 1);
00656 }
00657 Undo::saveEdit(event, newEvent);
00658
00659 KAlarm::outputAlarmWarnings(&editDlg, &newEvent);
00660 }
00661 }
00662
00663
00664
00665
00666
00667 void MainWindow::slotView()
00668 {
00669 AlarmListViewItem* item = mListView->selectedItem();
00670 if (item)
00671 {
00672 KAEvent event = item->event();
00673 EditAlarmDlg editDlg(false, (event.expired() ? i18n("Expired Alarm") + " [" + i18n("read-only") + ']'
00674 : i18n("View Alarm")),
00675 this, 0, &event, true);
00676 editDlg.exec();
00677 }
00678 }
00679
00680
00681
00682
00683
00684 void MainWindow::slotDelete()
00685 {
00686 QValueList<EventListViewItemBase*> items = mListView->selectedItems();
00687
00688
00689 QValueList<KAEvent> events;
00690 QValueList<KAEvent> origEvents;
00691 for (QValueList<EventListViewItemBase*>::Iterator iit = items.begin(); iit != items.end(); ++iit)
00692 {
00693 AlarmListViewItem* item = (AlarmListViewItem*)(*iit);
00694 events.append(item->event());
00695 origEvents.append(item->event());
00696 }
00697 if (Preferences::confirmAlarmDeletion())
00698 {
00699 int n = items.count();
00700 if (KMessageBox::warningContinueCancel(this, i18n("Do you really want to delete the selected alarm?",
00701 "Do you really want to delete the %n selected alarms?", n),
00702 i18n("Delete Alarm", "Delete Alarms", n),
00703 KGuiItem(i18n("&Delete"), "editdelete"),
00704 Preferences::CONFIRM_ALARM_DELETION)
00705 != KMessageBox::Continue)
00706 return;
00707 }
00708
00709 int warnErr = 0;
00710 int warnKOrg = 0;
00711 AlarmCalendar::activeCalendar()->startUpdate();
00712 AlarmCalendar::expiredCalendar()->startUpdate();
00713 for (QValueList<KAEvent>::Iterator it = events.begin(); it != events.end(); ++it)
00714 {
00715
00716 switch (KAlarm::deleteEvent(*it))
00717 {
00718 case KAlarm::UPDATE_ERROR:
00719 case KAlarm::UPDATE_FAILED:
00720 case KAlarm::SAVE_FAILED:
00721 ++warnErr;
00722 break;
00723 case KAlarm::UPDATE_KORG_ERR:
00724 ++warnKOrg;
00725 break;
00726 default:
00727 break;
00728 }
00729 }
00730 if (!AlarmCalendar::activeCalendar()->endUpdate())
00731 warnErr = events.count();
00732 AlarmCalendar::expiredCalendar()->endUpdate();
00733 Undo::saveDeletes(origEvents);
00734
00735 if (warnErr)
00736 KAlarm::displayUpdateError(this, KAlarm::UPDATE_FAILED, KAlarm::ERR_DELETE, warnErr);
00737 else if (warnKOrg)
00738 KAlarm::displayKOrgUpdateError(this, KAlarm::KORG_ERR_DELETE, warnKOrg);
00739 }
00740
00741
00742
00743
00744
00745 void MainWindow::slotReactivate()
00746 {
00747 int warnErr = 0;
00748 int warnKOrg = 0;
00749 QValueList<KAEvent> events;
00750 QValueList<EventListViewItemBase*> items = mListView->selectedItems();
00751 mListView->clearSelection();
00752 AlarmCalendar::activeCalendar()->startUpdate();
00753 AlarmCalendar::expiredCalendar()->startUpdate();
00754 for (QValueList<EventListViewItemBase*>::Iterator it = items.begin(); it != items.end(); ++it)
00755 {
00756
00757 AlarmListViewItem* item = (AlarmListViewItem*)(*it);
00758 KAEvent event = item->event();
00759 events.append(event);
00760 switch (KAlarm::reactivateEvent(event, mListView, true))
00761 {
00762 case KAlarm::UPDATE_ERROR:
00763 case KAlarm::UPDATE_FAILED:
00764 case KAlarm::SAVE_FAILED:
00765 ++warnErr;
00766 break;
00767 case KAlarm::UPDATE_KORG_ERR:
00768 ++warnKOrg;
00769 break;
00770 default:
00771 break;
00772 }
00773 }
00774 if (!AlarmCalendar::activeCalendar()->endUpdate())
00775 warnErr = items.count();
00776 AlarmCalendar::expiredCalendar()->endUpdate();
00777 Undo::saveReactivates(events);
00778
00779 if (warnErr)
00780 KAlarm::displayUpdateError(this, KAlarm::UPDATE_FAILED, KAlarm::ERR_REACTIVATE, warnErr);
00781 else if (warnKOrg)
00782 KAlarm::displayKOrgUpdateError(this, KAlarm::KORG_ERR_ADD, warnKOrg);
00783 }
00784
00785
00786
00787
00788
00789 void MainWindow::slotEnable()
00790 {
00791 bool enable = mActionEnableEnable;
00792 int warnErr = 0;
00793 QValueList<EventListViewItemBase*> items = mListView->selectedItems();
00794 AlarmCalendar::activeCalendar()->startUpdate();
00795 for (QValueList<EventListViewItemBase*>::Iterator it = items.begin(); it != items.end(); ++it)
00796 {
00797 AlarmListViewItem* item = (AlarmListViewItem*)(*it);
00798 KAEvent event = item->event();
00799
00800
00801 if (KAlarm::enableEvent(event, mListView, enable) != KAlarm::UPDATE_OK)
00802 ++warnErr;
00803 }
00804 if (!AlarmCalendar::activeCalendar()->endUpdate())
00805 warnErr = items.count();
00806 if (warnErr)
00807 KAlarm::displayUpdateError(this, KAlarm::UPDATE_FAILED, KAlarm::ERR_ADD, warnErr);
00808 }
00809
00810
00811
00812
00813 void MainWindow::slotShowTime()
00814 {
00815 mShowTime = !mShowTime;
00816 mActionShowTime->setChecked(mShowTime);
00817 if (!mShowTime && !mShowTimeTo)
00818 slotShowTimeTo();
00819 else
00820 mListView->selectTimeColumns(mShowTime, mShowTimeTo);
00821 }
00822
00823
00824
00825
00826 void MainWindow::slotShowTimeTo()
00827 {
00828 mShowTimeTo = !mShowTimeTo;
00829 mActionShowTimeTo->setChecked(mShowTimeTo);
00830 if (!mShowTimeTo && !mShowTime)
00831 slotShowTime();
00832 else
00833 mListView->selectTimeColumns(mShowTime, mShowTimeTo);
00834 setUpdateTimer();
00835 }
00836
00837
00838
00839
00840 void MainWindow::slotShowExpired()
00841 {
00842 mShowExpired = !mShowExpired;
00843 mActionShowExpired->setChecked(mShowExpired);
00844 mActionShowExpired->setToolTip(mShowExpired ? i18n_HideExpiredAlarms() : i18n_ShowExpiredAlarms());
00845 mListView->showExpired(mShowExpired);
00846 mListView->refresh();
00847 }
00848
00849
00850
00851
00852
00853 void MainWindow::slotImportAlarms()
00854 {
00855 if (AlarmCalendar::importAlarms(this))
00856 mListView->refresh();
00857 }
00858
00859
00860
00861
00862
00863 void MainWindow::slotBirthdays()
00864 {
00865 BirthdayDlg dlg(this);
00866 if (dlg.exec() == QDialog::Accepted)
00867 {
00868 QValueList<KAEvent> events = dlg.events();
00869 if (events.count())
00870 {
00871 mListView->clearSelection();
00872 int warnErr = 0;
00873 int warnKOrg = 0;
00874 for (QValueList<KAEvent>::Iterator ev = events.begin(); ev != events.end(); ++ev)
00875 {
00876
00877 switch (KAlarm::addEvent(*ev, mListView))
00878 {
00879 case KAlarm::UPDATE_ERROR:
00880 case KAlarm::UPDATE_FAILED:
00881 case KAlarm::SAVE_FAILED:
00882 ++warnErr;
00883 break;
00884 case KAlarm::UPDATE_KORG_ERR:
00885 ++warnKOrg;
00886 break;
00887 default:
00888 break;
00889 }
00890 }
00891 if (warnErr)
00892 KAlarm::displayUpdateError(this, KAlarm::UPDATE_FAILED, KAlarm::ERR_ADD, warnErr);
00893 else if (warnKOrg)
00894 KAlarm::displayKOrgUpdateError(this, KAlarm::KORG_ERR_ADD, warnKOrg);
00895 KAlarm::outputAlarmWarnings(&dlg);
00896 }
00897 }
00898 }
00899
00900
00901
00902
00903
00904 void MainWindow::slotTemplates()
00905 {
00906 if (!mTemplateDlg)
00907 {
00908 mTemplateDlg = TemplateDlg::create(this);
00909 enableTemplateMenuItem(false);
00910 connect(mTemplateDlg, SIGNAL(finished()), SLOT(slotTemplatesEnd()));
00911 mTemplateDlg->show();
00912 }
00913 }
00914
00915
00916
00917
00918 void MainWindow::slotTemplatesEnd()
00919 {
00920 if (mTemplateDlg)
00921 {
00922 mTemplateDlg->delayedDestruct();
00923 mTemplateDlg = 0;
00924 enableTemplateMenuItem(true);
00925 }
00926 }
00927
00928
00929
00930
00931 void MainWindow::slotToggleTrayIcon()
00932 {
00933 theApp()->displayTrayIcon(!theApp()->trayIconDisplayed(), this);
00934 }
00935
00936
00937
00938
00939 void MainWindow::slotPrefsChanged()
00940 {
00941 mActionShowExpired->setEnabled(Preferences::expiredKeepDays());
00942 updateTrayIconAction();
00943 }
00944
00945
00946
00947
00948
00949
00950 void MainWindow::updateTrayIconAction()
00951 {
00952 mActionToggleTrayIcon->setEnabled(theApp()->haveSystemTray() && !theApp()->wantRunInSystemTray());
00953 mActionToggleTrayIcon->setChecked(theApp()->trayIconDisplayed());
00954 }
00955
00956
00957
00958
00959
00960 void MainWindow::updateActionsMenu()
00961 {
00962 Daemon::checkStatus();
00963 }
00964
00965
00966
00967
00968 void MainWindow::slotFindActive(bool active)
00969 {
00970 mActionFindNext->setEnabled(active);
00971 mActionFindPrev->setEnabled(active);
00972 }
00973
00974
00975
00976
00977 void MainWindow::slotUndo()
00978 {
00979 Undo::undo(this, KAlarm::stripAccel(mActionUndo->text()));
00980 }
00981
00982
00983
00984
00985 void MainWindow::slotRedo()
00986 {
00987 Undo::redo(this, KAlarm::stripAccel(mActionRedo->text()));
00988 }
00989
00990
00991
00992
00993 void MainWindow::slotUndoItem(int id)
00994 {
00995 Undo::undo(id, this, Undo::actionText(Undo::UNDO, id));
00996 }
00997
00998
00999
01000
01001 void MainWindow::slotRedoItem(int id)
01002 {
01003 Undo::redo(id, this, Undo::actionText(Undo::REDO, id));
01004 }
01005
01006
01007
01008
01009
01010 void MainWindow::slotInitUndoMenu()
01011 {
01012 initUndoMenu(mActionUndo->popupMenu(), Undo::UNDO);
01013 }
01014
01015
01016
01017
01018
01019 void MainWindow::slotInitRedoMenu()
01020 {
01021 initUndoMenu(mActionRedo->popupMenu(), Undo::REDO);
01022 }
01023
01024
01025
01026
01027 void MainWindow::initUndoMenu(KPopupMenu* menu, Undo::Type type)
01028 {
01029 menu->clear();
01030 const QString& action = (type == Undo::UNDO) ? undoTextStripped : redoTextStripped;
01031 QValueList<int> ids = Undo::ids(type);
01032 for (QValueList<int>::ConstIterator it = ids.begin(); it != ids.end(); ++it)
01033 {
01034 int id = *it;
01035 menu->insertItem(i18n("Undo [action]: message", "%1 %2: %3")
01036 .arg(action).arg(Undo::actionText(type, id)).arg(Undo::description(type, id)), id);
01037 }
01038 }
01039
01040
01041
01042
01043
01044 void MainWindow::slotUndoStatus(const QString& undo, const QString& redo)
01045 {
01046 if (undo.isNull())
01047 {
01048 mActionUndo->setEnabled(false);
01049 mActionUndo->setText(undoText);
01050 }
01051 else
01052 {
01053 mActionUndo->setEnabled(true);
01054 mActionUndo->setText(QString("%1 %2").arg(undoText).arg(undo));
01055 }
01056 if (redo.isNull())
01057 {
01058 mActionRedo->setEnabled(false);
01059 mActionRedo->setText(redoText);
01060 }
01061 else
01062 {
01063 mActionRedo->setEnabled(true);
01064 mActionRedo->setText(QString("%1 %2").arg(redoText).arg(redo));
01065 }
01066 }
01067
01068
01069
01070
01071 void MainWindow::slotResetDaemon()
01072 {
01073 KAlarm::resetDaemon();
01074 }
01075
01076
01077
01078
01079 void MainWindow::slotPreferences()
01080 {
01081 KAlarmPrefDlg::display();
01082 }
01083
01084
01085
01086
01087 void MainWindow::slotConfigureKeys()
01088 {
01089 KKeyDialog::configure(actionCollection(), this);
01090 }
01091
01092
01093
01094
01095 void MainWindow::slotConfigureToolbar()
01096 {
01097 saveMainWindowSettings(KGlobal::config(), WINDOW_NAME);
01098 KEditToolbar dlg(factory());
01099 connect(&dlg, SIGNAL(newToolbarConfig()), this, SLOT(slotNewToolbarConfig()));
01100 dlg.exec();
01101 }
01102
01103
01104
01105
01106
01107 void MainWindow::slotNewToolbarConfig()
01108 {
01109 createGUI(UI_FILE);
01110 applyMainWindowSettings(KGlobal::config(), WINDOW_NAME);
01111 }
01112
01113
01114
01115
01116 void MainWindow::slotQuit()
01117 {
01118 theApp()->doQuit(this);
01119 }
01120
01121
01122
01123
01124 void MainWindow::closeEvent(QCloseEvent* ce)
01125 {
01126 if (!theApp()->sessionClosingDown() && isTrayParent())
01127 {
01128
01129
01130
01131 hide();
01132 theApp()->quitIf();
01133 ce->ignore();
01134 }
01135 else
01136 ce->accept();
01137 }
01138
01139
01140
01141
01142
01143 void MainWindow::slotDeletion()
01144 {
01145 if (!mListView->selectedCount())
01146 {
01147 kdDebug(5950) << "MainWindow::slotDeletion(true)\n";
01148 mActionCreateTemplate->setEnabled(false);
01149 mActionCopy->setEnabled(false);
01150 mActionModify->setEnabled(false);
01151 mActionView->setEnabled(false);
01152 mActionDelete->setEnabled(false);
01153 mActionReactivate->setEnabled(false);
01154 mActionEnable->setEnabled(false);
01155 }
01156 }
01157
01158
01159
01160
01161 void MainWindow::dragEnterEvent(QDragEnterEvent* e)
01162 {
01163 executeDragEnterEvent(e);
01164 }
01165
01166
01167
01168
01169
01170 void MainWindow::executeDragEnterEvent(QDragEnterEvent* e)
01171 {
01172 if (KCal::ICalDrag::canDecode(e))
01173 e->accept(!AlarmListView::dragging());
01174 else
01175 e->accept(QTextDrag::canDecode(e)
01176 || KURLDrag::canDecode(e)
01177 || KPIM::MailListDrag::canDecode(e));
01178 }
01179
01180
01181
01182
01183
01184 void MainWindow::dropEvent(QDropEvent* e)
01185 {
01186 executeDropEvent(this, e);
01187 }
01188
01189 static QString getMailHeader(const char* header, KMime::Content& content)
01190 {
01191 KMime::Headers::Base* hd = content.getHeaderByType(header);
01192 return hd ? hd->asUnicodeString() : QString::null;
01193 }
01194
01195
01196
01197
01198
01199 void MainWindow::executeDropEvent(MainWindow* win, QDropEvent* e)
01200 {
01201 KAEvent::Action action = KAEvent::MESSAGE;
01202 QString text;
01203 QByteArray bytes;
01204 AlarmText alarmText;
01205 KPIM::MailList mailList;
01206 KURL::List files;
01207 KCal::CalendarLocal calendar(QString::fromLatin1("UTC"));
01208 calendar.setLocalTime();
01209 #ifndef NDEBUG
01210 QCString fmts;
01211 for (int idbg = 0; e->format(idbg); ++idbg)
01212 {
01213 if (idbg) fmts += ", ";
01214 fmts += e->format(idbg);
01215 }
01216 kdDebug(5950) << "MainWindow::executeDropEvent(): " << fmts << endl;
01217 #endif
01218
01219
01220
01221
01222
01223 if (e->provides("message/rfc822")
01224 && !(bytes = e->encodedData("message/rfc822")).isEmpty())
01225 {
01226
01227 kdDebug(5950) << "MainWindow::executeDropEvent(email)" << endl;
01228 QCString mails(bytes.data(), bytes.size());
01229 KMime::Content content;
01230 content.setContent(mails);
01231 content.parse();
01232 QString body;
01233 if (content.textContent())
01234 content.textContent()->decodedText(body, true, true);
01235 unsigned long sernum = 0;
01236 if (e->provides(KPIM::MailListDrag::format())
01237 && KPIM::MailListDrag::decode(e, mailList)
01238 && mailList.count())
01239 {
01240
01241
01242 sernum = mailList.first().serialNumber();
01243 }
01244 alarmText.setEmail(getMailHeader("To", content),
01245 getMailHeader("From", content),
01246 getMailHeader("Cc", content),
01247 getMailHeader("Date", content),
01248 getMailHeader("Subject", content),
01249 body, sernum);
01250 }
01251 else if (KURLDrag::decode(e, files) && files.count())
01252 {
01253 kdDebug(5950) << "MainWindow::executeDropEvent(URL)" << endl;
01254 action = KAEvent::FILE;
01255 alarmText.setText(files.first().prettyURL());
01256 }
01257 else if (e->provides(KPIM::MailListDrag::format())
01258 && KPIM::MailListDrag::decode(e, mailList))
01259 {
01260
01261 kdDebug(5950) << "MainWindow::executeDropEvent(KMail_list)" << endl;
01262 if (!mailList.count())
01263 return;
01264 KPIM::MailSummary& summary = mailList.first();
01265 QDateTime dt;
01266 dt.setTime_t(summary.date());
01267 QString body = KAMail::getMailBody(summary.serialNumber());
01268 alarmText.setEmail(summary.to(), summary.from(), QString::null,
01269 KGlobal::locale()->formatDateTime(dt), summary.subject(),
01270 body, summary.serialNumber());
01271 }
01272 else if (KCal::ICalDrag::decode(e, &calendar))
01273 {
01274
01275 kdDebug(5950) << "MainWindow::executeDropEvent(iCalendar)" << endl;
01276 KCal::Event::List events = calendar.rawEvents();
01277 if (!events.isEmpty())
01278 {
01279 KAEvent ev(*events.first());
01280 executeNew(win, &ev);
01281 }
01282 return;
01283 }
01284 else if (QTextDrag::decode(e, text))
01285 {
01286 kdDebug(5950) << "MainWindow::executeDropEvent(text)" << endl;
01287 alarmText.setText(text);
01288 }
01289 else
01290 return;
01291
01292 if (!alarmText.isEmpty())
01293 executeNew(win, 0, action, alarmText);
01294 }
01295
01296
01297
01298
01299
01300 void MainWindow::slotSelection()
01301 {
01302
01303 QValueList<EventListViewItemBase*> items = mListView->selectedItems();
01304 int count = items.count();
01305 AlarmListViewItem* item = (AlarmListViewItem*)((count == 1) ? items.first() : 0);
01306 bool enableReactivate = true;
01307 bool enableEnableDisable = true;
01308 bool enableEnable = false;
01309 bool enableDisable = false;
01310 QDateTime now = QDateTime::currentDateTime();
01311 for (QValueList<EventListViewItemBase*>::Iterator it = items.begin(); it != items.end(); ++it)
01312 {
01313 const KAEvent& event = ((AlarmListViewItem*)(*it))->event();
01314 if (enableReactivate
01315 && (!event.expired() || !event.occursAfter(now, true)))
01316 enableReactivate = false;
01317 if (enableEnableDisable)
01318 {
01319 if (event.expired())
01320 enableEnableDisable = enableEnable = enableDisable = false;
01321 else
01322 {
01323 if (!enableEnable && !event.enabled())
01324 enableEnable = true;
01325 if (!enableDisable && event.enabled())
01326 enableDisable = true;
01327 }
01328 }
01329 }
01330
01331 kdDebug(5950) << "MainWindow::slotSelection(true)\n";
01332 mActionCreateTemplate->setEnabled(count == 1);
01333 mActionCopy->setEnabled(count == 1);
01334 mActionModify->setEnabled(item && !mListView->expired(item));
01335 mActionView->setEnabled(count == 1);
01336 mActionDelete->setEnabled(count);
01337 mActionReactivate->setEnabled(count && enableReactivate);
01338 mActionEnable->setEnabled(enableEnable || enableDisable);
01339 if (enableEnable || enableDisable)
01340 setEnableText(enableEnable);
01341 }
01342
01343
01344
01345
01346
01347
01348 void MainWindow::slotMouseClicked(int button, QListViewItem* item, const QPoint& pt, int)
01349 {
01350 if (button == Qt::RightButton)
01351 {
01352 kdDebug(5950) << "MainWindow::slotMouseClicked(right)\n";
01353 if (mContextMenu)
01354 mContextMenu->popup(pt);
01355 }
01356 else if (!item)
01357 {
01358 kdDebug(5950) << "MainWindow::slotMouseClicked(left)\n";
01359 mListView->clearSelection();
01360 mActionCreateTemplate->setEnabled(false);
01361 mActionCopy->setEnabled(false);
01362 mActionModify->setEnabled(false);
01363 mActionView->setEnabled(false);
01364 mActionDelete->setEnabled(false);
01365 mActionReactivate->setEnabled(false);
01366 mActionEnable->setEnabled(false);
01367 }
01368 }
01369
01370
01371
01372
01373
01374 void MainWindow::slotDoubleClicked(QListViewItem* item)
01375 {
01376 kdDebug(5950) << "MainWindow::slotDoubleClicked()\n";
01377 if (item)
01378 {
01379 if (mListView->expired((AlarmListViewItem*)item))
01380 slotView();
01381 else
01382 slotModify();
01383 }
01384 else
01385 slotNew();
01386 }
01387
01388
01389
01390
01391 void MainWindow::setEnableText(bool enable)
01392 {
01393 mActionEnableEnable = enable;
01394 mActionEnable->setText(enable ? i18n("Ena&ble") : i18n("Disa&ble"));
01395 }
01396
01397
01398
01399
01400
01401 MainWindow* MainWindow::toggleWindow(MainWindow* win)
01402 {
01403 if (win && mWindowList.find(win) != mWindowList.end())
01404 {
01405
01406 if (win->isVisible())
01407 {
01408
01409 win->close();
01410 return 0;
01411 }
01412 else
01413 {
01414
01415 win->hide();
01416 win->showNormal();
01417 win->raise();
01418 win->setActiveWindow();
01419 return win;
01420 }
01421 }
01422
01423
01424 win = create();
01425 win->show();
01426 return win;
01427 }