TDE personal information management applications
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mainwindow.cpp 50KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424
  1. /*
  2. * mainwindow.cpp - main application window
  3. * Program: kalarm
  4. * Copyright © 2001-2007 by David Jarvie <djarvie@kde.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. #include "kalarm.h"
  21. #include <tqiconset.h>
  22. #include <tqdragobject.h>
  23. #include <tqheader.h>
  24. #include <kmenubar.h>
  25. #include <ktoolbar.h>
  26. #include <kpopupmenu.h>
  27. #include <kaccel.h>
  28. #include <kaction.h>
  29. #include <kactionclasses.h>
  30. #include <kstdaction.h>
  31. #include <kiconloader.h>
  32. #include <kmessagebox.h>
  33. #include <kurldrag.h>
  34. #include <klocale.h>
  35. #include <kglobalsettings.h>
  36. #include <kconfig.h>
  37. #include <kkeydialog.h>
  38. #include <kedittoolbar.h>
  39. #include <kaboutdata.h>
  40. #include <dcopclient.h>
  41. #include <kdebug.h>
  42. #include <libtdepim/maillistdrag.h>
  43. #include <libkmime/kmime_content.h>
  44. #include <libkcal/calendarlocal.h>
  45. #include <libkcal/icaldrag.h>
  46. #include "alarmcalendar.h"
  47. #include "alarmevent.h"
  48. #include "alarmlistview.h"
  49. #include "alarmtext.h"
  50. #include "birthdaydlg.h"
  51. #include "daemon.h"
  52. #include "editdlg.h"
  53. #include "functions.h"
  54. #include "kalarmapp.h"
  55. #include "kamail.h"
  56. #include "prefdlg.h"
  57. #include "preferences.h"
  58. #include "synchtimer.h"
  59. #include "templatepickdlg.h"
  60. #include "templatedlg.h"
  61. #include "traywindow.h"
  62. #include "mainwindow.moc"
  63. using namespace KCal;
  64. static const char* UI_FILE = "kalarmui.rc";
  65. static const char* WINDOW_NAME = "MainWindow";
  66. static const TQString VIEW_GROUP = TQString::tqfromLatin1("View");
  67. static const TQString SHOW_TIME_KEY = TQString::tqfromLatin1("ShowAlarmTime");
  68. static const TQString SHOW_TIME_TO_KEY = TQString::tqfromLatin1("ShowTimeToAlarm");
  69. static const TQString SHOW_ARCHIVED_KEY = TQString::tqfromLatin1("ShowArchivedAlarms");
  70. static const TQString SHOW_RESOURCES_KEY = TQString::tqfromLatin1("ShowResources");
  71. static TQString undoText;
  72. static TQString undoTextStripped;
  73. static TQString undoIcon;
  74. static KShortcut undoShortcut;
  75. static TQString redoText;
  76. static TQString redoTextStripped;
  77. static TQString redoIcon;
  78. static KShortcut redoShortcut;
  79. /*=============================================================================
  80. = Class: MainWindow
  81. =============================================================================*/
  82. MainWindow::WindowList MainWindow::mWindowList;
  83. TemplateDlg* MainWindow::mTemplateDlg = 0;
  84. // Collect these widget labels together to ensure consistent wording and
  85. // translations across different modules.
  86. TQString MainWindow::i18n_a_ShowAlarmTimes() { return i18n("Show &Alarm Times"); }
  87. TQString MainWindow::i18n_m_ShowAlarmTime() { return i18n("Show alarm ti&me"); }
  88. TQString MainWindow::i18n_o_ShowTimeToAlarms() { return i18n("Show Time t&o Alarms"); }
  89. TQString MainWindow::i18n_l_ShowTimeToAlarm() { return i18n("Show time unti&l alarm"); }
  90. TQString MainWindow::i18n_ShowExpiredAlarms() { return i18n("Show Expired Alarms"); }
  91. TQString MainWindow::i18n_e_ShowExpiredAlarms() { return i18n("Show &Expired Alarms"); }
  92. TQString MainWindow::i18n_HideExpiredAlarms() { return i18n("Hide Expired Alarms"); }
  93. TQString MainWindow::i18n_e_HideExpiredAlarms() { return i18n("Hide &Expired Alarms"); }
  94. /******************************************************************************
  95. * Construct an instance.
  96. * To avoid resize() events occurring while still opening the calendar (and
  97. * resultant crashes), the calendar is opened before constructing the instance.
  98. */
  99. MainWindow* MainWindow::create(bool restored)
  100. {
  101. theApp()->checkCalendarDaemon(); // ensure calendar is open and daemon started
  102. return new MainWindow(restored);
  103. }
  104. MainWindow::MainWindow(bool restored)
  105. : MainWindowBase(0, "MainWin", WGroupLeader | WStyle_ContextHelp | WDestructiveClose),
  106. mMinuteTimerActive(false),
  107. mHiddenTrayParent(false)
  108. {
  109. kdDebug(5950) << "MainWindow::MainWindow()\n";
  110. setAutoSaveSettings(TQString::tqfromLatin1(WINDOW_NAME)); // save window sizes etc.
  111. setPlainCaption(kapp->aboutData()->programName());
  112. KConfig* config = KGlobal::config();
  113. config->setGroup(VIEW_GROUP);
  114. mShowExpired = config->readBoolEntry(SHOW_ARCHIVED_KEY, false);
  115. mShowTime = config->readBoolEntry(SHOW_TIME_KEY, true);
  116. mShowTimeTo = config->readBoolEntry(SHOW_TIME_TO_KEY, false);
  117. if (!restored)
  118. {
  119. TQSize s;
  120. if (KAlarm::readConfigWindowSize(WINDOW_NAME, s))
  121. resize(s);
  122. }
  123. config->setGroup(TQString::tqfromLatin1(WINDOW_NAME));
  124. TQValueList<int> order = config->readIntListEntry(TQString::tqfromLatin1("ColumnOrder"));
  125. setAcceptDrops(true); // allow drag-and-drop onto this window
  126. if (!mShowTimeTo)
  127. mShowTime = true; // ensure at least one time column is visible
  128. mListView = new AlarmListView(order, this, "listView");
  129. mListView->selectTimeColumns(mShowTime, mShowTimeTo);
  130. mListView->showExpired(mShowExpired);
  131. setCentralWidget(mListView);
  132. mListView->refresh(); // populate the alarm list
  133. mListView->clearSelection();
  134. connect(mListView, TQT_SIGNAL(itemDeleted()), TQT_SLOT(slotDeletion()));
  135. connect(mListView, TQT_SIGNAL(selectionChanged()), TQT_SLOT(slotSelection()));
  136. connect(mListView, TQT_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint&, int)),
  137. TQT_SLOT(slotContextMenuRequested(TQListViewItem*, const TQPoint&, int)));
  138. connect(mListView, TQT_SIGNAL(mouseButtonClicked(int, TQListViewItem*, const TQPoint&, int)),
  139. TQT_SLOT(slotMouseClicked(int, TQListViewItem*, const TQPoint&, int)));
  140. connect(mListView, TQT_SIGNAL(executed(TQListViewItem*)), TQT_SLOT(slotDoubleClicked(TQListViewItem*)));
  141. connect(mListView->header(), TQT_SIGNAL(indexChange(int, int, int)), TQT_SLOT(columnsReordered()));
  142. initActions();
  143. mWindowList.append(this);
  144. if (mWindowList.count() == 1 && Daemon::isDcopHandlerReady())
  145. {
  146. // It's the first main window, and the DCOP handler is ready
  147. if (theApp()->wantRunInSystemTray())
  148. theApp()->displayTrayIcon(true, this); // create system tray icon for run-in-system-tray mode
  149. else if (theApp()->trayWindow())
  150. theApp()->trayWindow()->setAssocMainWindow(this); // associate this window with the system tray icon
  151. }
  152. setUpdateTimer();
  153. }
  154. MainWindow::~MainWindow()
  155. {
  156. kdDebug(5950) << "MainWindow::~MainWindow()\n";
  157. mWindowList.remove(this);
  158. if (theApp()->trayWindow())
  159. {
  160. if (isTrayParent())
  161. delete theApp()->trayWindow();
  162. else
  163. theApp()->trayWindow()->removeWindow(this);
  164. }
  165. MinuteTimer::disconnect(TQT_TQOBJECT(this));
  166. mMinuteTimerActive = false; // to ensure that setUpdateTimer() works correctly
  167. setUpdateTimer();
  168. MainWindow* main = mainMainWindow();
  169. if (main)
  170. KAlarm::writeConfigWindowSize(WINDOW_NAME, main->size());
  171. KToolBar* tb = toolBar();
  172. if (tb)
  173. tb->saveSettings(KGlobal::config(), "Toolbars");
  174. KGlobal::config()->sync(); // save any new window size to disc
  175. theApp()->quitIf();
  176. }
  177. /******************************************************************************
  178. * Save settings to the session managed config file, for restoration
  179. * when the program is restored.
  180. */
  181. void MainWindow::saveProperties(KConfig* config)
  182. {
  183. config->writeEntry(TQString::tqfromLatin1("HiddenTrayParent"), isTrayParent() && isHidden());
  184. config->writeEntry(TQString::tqfromLatin1("ShowExpired"), mShowExpired);
  185. config->writeEntry(TQString::tqfromLatin1("ShowTime"), mShowTime);
  186. config->writeEntry(TQString::tqfromLatin1("ShowTimeTo"), mShowTimeTo);
  187. }
  188. /******************************************************************************
  189. * Read settings from the session managed config file.
  190. * This function is automatically called whenever the app is being
  191. * restored. Read in whatever was saved in saveProperties().
  192. */
  193. void MainWindow::readProperties(KConfig* config)
  194. {
  195. mHiddenTrayParent = config->readBoolEntry(TQString::tqfromLatin1("HiddenTrayParent"));
  196. mShowExpired = config->readBoolEntry(TQString::tqfromLatin1("ShowExpired"));
  197. mShowTime = config->readBoolEntry(TQString::tqfromLatin1("ShowTime"));
  198. mShowTimeTo = config->readBoolEntry(TQString::tqfromLatin1("ShowTimeTo"));
  199. }
  200. /******************************************************************************
  201. * Get the main main window, i.e. the parent of the system tray icon, or if
  202. * none, the first main window to be created. Visible windows take precedence
  203. * over hidden ones.
  204. */
  205. MainWindow* MainWindow::mainMainWindow()
  206. {
  207. MainWindow* tray = theApp()->trayWindow() ? theApp()->trayWindow()->assocMainWindow() : 0;
  208. if (tray && tray->isVisible())
  209. return tray;
  210. for (WindowList::Iterator it = mWindowList.begin(); it != mWindowList.end(); ++it)
  211. if ((*it)->isVisible())
  212. return *it;
  213. if (tray)
  214. return tray;
  215. if (mWindowList.isEmpty())
  216. return 0;
  217. return mWindowList.first();
  218. }
  219. /******************************************************************************
  220. * Check whether this main window is the parent of the system tray icon.
  221. */
  222. bool MainWindow::isTrayParent() const
  223. {
  224. return theApp()->wantRunInSystemTray() && theApp()->trayMainWindow() == this;
  225. }
  226. /******************************************************************************
  227. * Close all main windows.
  228. */
  229. void MainWindow::closeAll()
  230. {
  231. while (!mWindowList.isEmpty())
  232. delete mWindowList.first(); // N.B. the destructor removes the window from the list
  233. }
  234. /******************************************************************************
  235. * Called when the window's size has changed (before it is painted).
  236. * Sets the last column in the list view to extend at least to the right hand
  237. * edge of the list view.
  238. * Records the new size in the config file.
  239. */
  240. void MainWindow::resizeEvent(TQResizeEvent* re)
  241. {
  242. // Save the window's new size only if it's the first main window
  243. if (mainMainWindow() == this)
  244. KAlarm::writeConfigWindowSize(WINDOW_NAME, re->size());
  245. MainWindowBase::resizeEvent(re);
  246. }
  247. /******************************************************************************
  248. * Called when the window is first displayed.
  249. * Sets the last column in the list view to extend at least to the right hand
  250. * edge of the list view.
  251. */
  252. void MainWindow::showEvent(TQShowEvent* se)
  253. {
  254. setUpdateTimer();
  255. slotUpdateTimeTo();
  256. MainWindowBase::showEvent(se);
  257. }
  258. /******************************************************************************
  259. * Display the window.
  260. */
  261. void MainWindow::show()
  262. {
  263. MainWindowBase::show();
  264. if (mMenuError)
  265. {
  266. // Show error message now that the main window has been displayed.
  267. // Waiting until now lets the user easily associate the message with
  268. // the main window which is faulty.
  269. KMessageBox::error(this, i18n("Failure to create menus\n(perhaps %1 missing or corrupted)").tqarg(TQString::tqfromLatin1(UI_FILE)));
  270. mMenuError = false;
  271. }
  272. }
  273. /******************************************************************************
  274. * Called after the window is hidden.
  275. */
  276. void MainWindow::hideEvent(TQHideEvent* he)
  277. {
  278. setUpdateTimer();
  279. MainWindowBase::hideEvent(he);
  280. }
  281. /******************************************************************************
  282. * Called when the list's column order is changed.
  283. * Save the new column order as the default the next time the program is run.
  284. */
  285. void MainWindow::columnsReordered()
  286. {
  287. KConfig* config = KGlobal::config();
  288. config->setGroup(TQString::tqfromLatin1(WINDOW_NAME));
  289. config->writeEntry(TQString::tqfromLatin1("ColumnOrder"), mListView->columnOrder());
  290. config->sync();
  291. }
  292. /******************************************************************************
  293. * Initialise the menu, toolbar and main window actions.
  294. */
  295. void MainWindow::initActions()
  296. {
  297. KActionCollection* actions = actionCollection();
  298. mActionTemplates = new KAction(i18n("&Templates..."), 0, TQT_TQOBJECT(this), TQT_SLOT(slotTemplates()), actions, "templates");
  299. mActionNew = KAlarm::createNewAlarmAction(i18n("&New..."), TQT_TQOBJECT(this), TQT_SLOT(slotNew()), actions, "new");
  300. mActionNewFromTemplate = KAlarm::createNewFromTemplateAction(i18n("New &From Template"), TQT_TQOBJECT(this), TQT_SLOT(slotNewFromTemplate(const KAEvent&)), actions, "newFromTempl");
  301. mActionCreateTemplate = new KAction(i18n("Create Tem&plate..."), 0, TQT_TQOBJECT(this), TQT_SLOT(slotNewTemplate()), actions, "createTemplate");
  302. mActionCopy = new KAction(i18n("&Copy..."), "editcopy", TQt::SHIFT+TQt::Key_Insert, TQT_TQOBJECT(this), TQT_SLOT(slotCopy()), actions, "copy");
  303. mActionModify = new KAction(i18n("&Edit..."), "edit", TQt::CTRL+TQt::Key_E, TQT_TQOBJECT(this), TQT_SLOT(slotModify()), actions, "modify");
  304. mActionDelete = new KAction(i18n("&Delete"), "editdelete", TQt::Key_Delete, TQT_TQOBJECT(this), TQT_SLOT(slotDelete()), actions, "delete");
  305. mActionReactivate = new KAction(i18n("Reac&tivate"), 0, TQt::CTRL+TQt::Key_R, TQT_TQOBJECT(this), TQT_SLOT(slotReactivate()), actions, "undelete");
  306. mActionEnable = new KAction(TQString(), 0, TQt::CTRL+TQt::Key_B, TQT_TQOBJECT(this), TQT_SLOT(slotEnable()), actions, "disable");
  307. mActionView = new KAction(i18n("&View"), "viewmag", TQt::CTRL+TQt::Key_W, TQT_TQOBJECT(this), TQT_SLOT(slotView()), actions, "view");
  308. mActionShowTime = new KToggleAction(i18n_a_ShowAlarmTimes(), TQt::CTRL+TQt::Key_M, TQT_TQOBJECT(this), TQT_SLOT(slotShowTime()), actions, "showAlarmTimes");
  309. mActionShowTime->setCheckedState(i18n("Hide &Alarm Times"));
  310. mActionShowTimeTo = new KToggleAction(i18n_o_ShowTimeToAlarms(), TQt::CTRL+TQt::Key_I, TQT_TQOBJECT(this), TQT_SLOT(slotShowTimeTo()), actions, "showTimeToAlarms");
  311. mActionShowTimeTo->setCheckedState(i18n("Hide Time t&o Alarms"));
  312. mActionShowExpired = new KToggleAction(i18n_e_ShowExpiredAlarms(), "history", TQt::CTRL+TQt::Key_P, TQT_TQOBJECT(this), TQT_SLOT(slotShowExpired()), actions, "showExpiredAlarms");
  313. mActionShowExpired->setCheckedState(i18n_e_HideExpiredAlarms());
  314. mActionToggleTrayIcon = new KToggleAction(i18n("Show in System &Tray"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotToggleTrayIcon()), actions, "showInSystemTray");
  315. mActionToggleTrayIcon->setCheckedState(i18n("Hide From System &Tray"));
  316. new KAction(i18n("Import &Alarms..."), 0, TQT_TQOBJECT(this), TQT_SLOT(slotImportAlarms()), actions, "importAlarms");
  317. new KAction(i18n("Import &Birthdays..."), 0, TQT_TQOBJECT(this), TQT_SLOT(slotBirthdays()), actions, "importBirthdays");
  318. new KAction(i18n("&Refresh Alarms"), "reload", 0, TQT_TQOBJECT(this), TQT_SLOT(slotResetDaemon()), actions, "refreshAlarms");
  319. Daemon::createAlarmEnableAction(actions, "alarmEnable");
  320. if (undoText.isNull())
  321. {
  322. // Get standard texts, etc., for Undo and Redo actions
  323. KAction* act = KStdAction::undo(TQT_TQOBJECT(this), 0, actions);
  324. undoIcon = act->icon();
  325. undoShortcut = act->shortcut();
  326. undoText = act->text();
  327. undoTextStripped = KAlarm::stripAccel(undoText);
  328. delete act;
  329. act = KStdAction::redo(TQT_TQOBJECT(this), 0, actions);
  330. redoIcon = act->icon();
  331. redoShortcut = act->shortcut();
  332. redoText = act->text();
  333. redoTextStripped = KAlarm::stripAccel(redoText);
  334. delete act;
  335. }
  336. mActionUndo = new KToolBarPopupAction(undoText, undoIcon, undoShortcut, TQT_TQOBJECT(this), TQT_SLOT(slotUndo()), actions, "edit_undo");
  337. mActionRedo = new KToolBarPopupAction(redoText, redoIcon, redoShortcut, TQT_TQOBJECT(this), TQT_SLOT(slotRedo()), actions, "edit_redo");
  338. KStdAction::find(TQT_TQOBJECT(mListView), TQT_SLOT(slotFind()), actions);
  339. mActionFindNext = KStdAction::findNext(TQT_TQOBJECT(mListView), TQT_SLOT(slotFindNext()), actions);
  340. mActionFindPrev = KStdAction::findPrev(TQT_TQOBJECT(mListView), TQT_SLOT(slotFindPrev()), actions);
  341. KStdAction::selectAll(TQT_TQOBJECT(mListView), TQT_SLOT(slotSelectAll()), actions);
  342. KStdAction::deselect(TQT_TQOBJECT(mListView), TQT_SLOT(slotDeselect()), actions);
  343. KStdAction::quit(TQT_TQOBJECT(this), TQT_SLOT(slotQuit()), actions);
  344. KStdAction::keyBindings(TQT_TQOBJECT(this), TQT_SLOT(slotConfigureKeys()), actions);
  345. KStdAction::configureToolbars(TQT_TQOBJECT(this), TQT_SLOT(slotConfigureToolbar()), actions);
  346. KStdAction::preferences(TQT_TQOBJECT(this), TQT_SLOT(slotPreferences()), actions);
  347. setStandardToolBarMenuEnabled(true);
  348. createGUI(UI_FILE);
  349. mContextMenu = static_cast<KPopupMenu*>(factory()->container("listContext", this));
  350. mActionsMenu = static_cast<KPopupMenu*>(factory()->container("actions", this));
  351. mMenuError = (!mContextMenu || !mActionsMenu);
  352. connect(mActionsMenu, TQT_SIGNAL(aboutToShow()), TQT_SLOT(updateActionsMenu()));
  353. connect(mActionUndo->popupMenu(), TQT_SIGNAL(aboutToShow()), TQT_SLOT(slotInitUndoMenu()));
  354. connect(mActionUndo->popupMenu(), TQT_SIGNAL(activated(int)), TQT_SLOT(slotUndoItem(int)));
  355. connect(mActionRedo->popupMenu(), TQT_SIGNAL(aboutToShow()), TQT_SLOT(slotInitRedoMenu()));
  356. connect(mActionRedo->popupMenu(), TQT_SIGNAL(activated(int)), TQT_SLOT(slotRedoItem(int)));
  357. connect(Undo::instance(), TQT_SIGNAL(changed(const TQString&, const TQString&)), TQT_SLOT(slotUndotqStatus(const TQString&, const TQString&)));
  358. connect(mListView, TQT_SIGNAL(findActive(bool)), TQT_SLOT(slotFindActive(bool)));
  359. Preferences::connect(TQT_SIGNAL(preferencesChanged()), TQT_TQOBJECT(this), TQT_SLOT(slotPrefsChanged()));
  360. connect(theApp(), TQT_SIGNAL(trayIconToggled()), TQT_SLOT(updateTrayIconAction()));
  361. // Set menu item states
  362. setEnableText(true);
  363. mActionShowTime->setChecked(mShowTime);
  364. mActionShowTimeTo->setChecked(mShowTimeTo);
  365. mActionShowExpired->setChecked(mShowExpired);
  366. slotPrefsChanged(); // set the correct text for this action
  367. mActionUndo->setEnabled(Undo::haveUndo());
  368. mActionRedo->setEnabled(Undo::haveRedo());
  369. mActionFindNext->setEnabled(false);
  370. mActionFindPrev->setEnabled(false);
  371. mActionCopy->setEnabled(false);
  372. mActionModify->setEnabled(false);
  373. mActionDelete->setEnabled(false);
  374. mActionReactivate->setEnabled(false);
  375. mActionView->setEnabled(false);
  376. mActionEnable->setEnabled(false);
  377. mActionCreateTemplate->setEnabled(false);
  378. KToolBar* tb = toolBar();
  379. if (tb)
  380. tb->applySettings(KGlobal::config(), "Toolbars");
  381. Undo::emitChanged(); // set the Undo/Redo menu texts
  382. Daemon::checktqStatus();
  383. Daemon::monitoringAlarms();
  384. }
  385. /******************************************************************************
  386. * Enable or disable the Templates menu item in every main window instance.
  387. */
  388. void MainWindow::enableTemplateMenuItem(bool enable)
  389. {
  390. for (WindowList::Iterator it = mWindowList.begin(); it != mWindowList.end(); ++it)
  391. (*it)->mActionTemplates->setEnabled(enable);
  392. }
  393. /******************************************************************************
  394. * Refresh the alarm list in every main window instance.
  395. */
  396. void MainWindow::refresh()
  397. {
  398. kdDebug(5950) << "MainWindow::refresh()\n";
  399. for (WindowList::Iterator it = mWindowList.begin(); it != mWindowList.end(); ++it)
  400. (*it)->mListView->refresh();
  401. }
  402. /******************************************************************************
  403. * Refresh the alarm list in every main window instance which is displaying
  404. * expired alarms.
  405. * Called when an expired alarm setting changes in the user preferences.
  406. */
  407. void MainWindow::updateExpired()
  408. {
  409. kdDebug(5950) << "MainWindow::updateExpired()\n";
  410. bool enableShowExpired = Preferences::expiredKeepDays();
  411. for (WindowList::Iterator it = mWindowList.begin(); it != mWindowList.end(); ++it)
  412. {
  413. MainWindow* w = *it;
  414. if (w->mShowExpired)
  415. {
  416. if (!enableShowExpired)
  417. w->slotShowExpired();
  418. else
  419. w->mListView->refresh();
  420. }
  421. w->mActionShowExpired->setEnabled(enableShowExpired);
  422. }
  423. }
  424. /******************************************************************************
  425. * Start or stop the timer which updates the time-to-alarm values every minute.
  426. * Should be called whenever a main window is created or destroyed, or shown or
  427. * hidden.
  428. */
  429. void MainWindow::setUpdateTimer()
  430. {
  431. // Check whether any windows need to be updated
  432. MainWindow* needTimer = 0;
  433. MainWindow* timerWindow = 0;
  434. for (WindowList::Iterator it = mWindowList.begin(); it != mWindowList.end(); ++it)
  435. {
  436. MainWindow* w = *it;
  437. if (w->isVisible() && w->mListView->showingTimeTo())
  438. needTimer = w;
  439. if (w->mMinuteTimerActive)
  440. timerWindow = w;
  441. }
  442. // Start or stop the update timer if necessary
  443. if (needTimer && !timerWindow)
  444. {
  445. // Timeout every minute.
  446. needTimer->mMinuteTimerActive = true;
  447. MinuteTimer::connect(TQT_TQOBJECT(needTimer), TQT_SLOT(slotUpdateTimeTo()));
  448. kdDebug(5950) << "MainWindow::setUpdateTimer(): started timer" << endl;
  449. }
  450. else if (!needTimer && timerWindow)
  451. {
  452. timerWindow->mMinuteTimerActive = false;
  453. MinuteTimer::disconnect(TQT_TQOBJECT(timerWindow));
  454. kdDebug(5950) << "MainWindow::setUpdateTimer(): stopped timer" << endl;
  455. }
  456. }
  457. /******************************************************************************
  458. * Update the time-to-alarm values for each main window which is displaying them.
  459. */
  460. void MainWindow::slotUpdateTimeTo()
  461. {
  462. kdDebug(5950) << "MainWindow::slotUpdateTimeTo()" << endl;
  463. for (WindowList::Iterator it = mWindowList.begin(); it != mWindowList.end(); ++it)
  464. {
  465. MainWindow* w = *it;
  466. if (w->isVisible() && w->mListView->showingTimeTo())
  467. w->mListView->updateTimeToAlarms();
  468. }
  469. }
  470. /******************************************************************************
  471. * Select an alarm in the displayed list.
  472. */
  473. void MainWindow::selectEvent(const TQString& eventID)
  474. {
  475. mListView->clearSelection();
  476. AlarmListViewItem* item = mListView->getEntry(eventID);
  477. if (item)
  478. {
  479. mListView->setSelected(item, true);
  480. mListView->setCurrentItem(item);
  481. mListView->ensureItemVisible(item);
  482. }
  483. }
  484. /******************************************************************************
  485. * Called when the New button is clicked to edit a new alarm to add to the list.
  486. */
  487. void MainWindow::slotNew()
  488. {
  489. executeNew(this);
  490. }
  491. /******************************************************************************
  492. * Execute a New Alarm dialog, optionally either presetting it to the supplied
  493. * event, or setting the action and text.
  494. */
  495. void MainWindow::executeNew(MainWindow* win, const KAEvent* evnt, KAEvent::Action action, const AlarmText& text)
  496. {
  497. EditAlarmDlg editDlg(false, i18n("New Alarm"), win, 0, evnt);
  498. if (!text.isEmpty())
  499. editDlg.setAction(action, text);
  500. if (editDlg.exec() == TQDialog::Accepted)
  501. {
  502. KAEvent event;
  503. editDlg.getEvent(event);
  504. // Add the alarm to the displayed lists and to the calendar file
  505. if (KAlarm::addEvent(event, (win ? win->mListView : 0), &editDlg) == KAlarm::UPDATE_KORG_ERR)
  506. KAlarm::displayKOrgUpdateError(&editDlg, KAlarm::KORG_ERR_ADD, 1);
  507. Undo::saveAdd(event);
  508. KAlarm::outputAlarmWarnings(&editDlg, &event);
  509. }
  510. }
  511. /******************************************************************************
  512. * Called when a template is selected from the New From Template popup menu.
  513. * Executes a New Alarm dialog, preset from the selected template.
  514. */
  515. void MainWindow::slotNewFromTemplate(const KAEvent& tmplate)
  516. {
  517. executeNew(this, &tmplate);
  518. }
  519. /******************************************************************************
  520. * Called when the New Template button is clicked to create a new template
  521. * based on the currently selected alarm.
  522. */
  523. void MainWindow::slotNewTemplate()
  524. {
  525. AlarmListViewItem* item = mListView->selectedItem();
  526. if (item)
  527. {
  528. KAEvent event = item->event();
  529. TemplateDlg::createTemplate(&event, this);
  530. }
  531. }
  532. /******************************************************************************
  533. * Called when the Copy button is clicked to edit a copy of an existing alarm,
  534. * to add to the list.
  535. */
  536. void MainWindow::slotCopy()
  537. {
  538. AlarmListViewItem* item = mListView->selectedItem();
  539. if (item)
  540. executeNew(this, &item->event());
  541. }
  542. /******************************************************************************
  543. * Called when the Modify button is clicked to edit the currently highlighted
  544. * alarm in the list.
  545. */
  546. void MainWindow::slotModify()
  547. {
  548. AlarmListViewItem* item = mListView->selectedItem();
  549. if (item)
  550. {
  551. KAEvent event = item->event();
  552. executeEdit(event, this);
  553. }
  554. }
  555. /******************************************************************************
  556. * Open the Edit Alarm dialogue to edit the specified alarm.
  557. */
  558. void MainWindow::executeEdit(KAEvent& event, MainWindow* win)
  559. {
  560. EditAlarmDlg editDlg(false, i18n("Edit Alarm"), win, 0, &event);
  561. if (editDlg.exec() == TQDialog::Accepted)
  562. {
  563. KAEvent newEvent;
  564. bool changeDeferral = !editDlg.getEvent(newEvent);
  565. // Update the event in the displays and in the calendar file
  566. AlarmListView* view = win ? win->mListView : 0;
  567. if (changeDeferral)
  568. {
  569. // The only change has been to an existing deferral
  570. if (KAlarm::updateEvent(newEvent, view, &editDlg, true, false) != KAlarm::UPDATE_OK) // keep the same event ID
  571. return; // failed to save event
  572. }
  573. else
  574. {
  575. if (KAlarm::modifyEvent(event, newEvent, view, &editDlg) == KAlarm::UPDATE_KORG_ERR)
  576. KAlarm::displayKOrgUpdateError(&editDlg, KAlarm::KORG_ERR_MODIFY, 1);
  577. }
  578. Undo::saveEdit(event, newEvent);
  579. KAlarm::outputAlarmWarnings(&editDlg, &newEvent);
  580. }
  581. }
  582. /******************************************************************************
  583. * Called when the View button is clicked to view the currently highlighted
  584. * alarm in the list.
  585. */
  586. void MainWindow::slotView()
  587. {
  588. AlarmListViewItem* item = mListView->selectedItem();
  589. if (item)
  590. {
  591. KAEvent event = item->event();
  592. EditAlarmDlg editDlg(false, (event.expired() ? i18n("Expired Alarm") + " [" + i18n("read-only") + ']'
  593. : i18n("View Alarm")),
  594. this, 0, &event, true);
  595. editDlg.exec();
  596. }
  597. }
  598. /******************************************************************************
  599. * Called when the Delete button is clicked to delete the currently highlighted
  600. * alarms in the list.
  601. */
  602. void MainWindow::slotDelete()
  603. {
  604. TQValueList<EventListViewItemBase*> items = mListView->selectedItems();
  605. // Copy the events to be deleted, in case any are deleted by being
  606. // triggered while the confirmation prompt is displayed.
  607. TQValueList<KAEvent> events;
  608. TQValueList<KAEvent> origEvents;
  609. for (TQValueList<EventListViewItemBase*>::Iterator iit = items.begin(); iit != items.end(); ++iit)
  610. {
  611. AlarmListViewItem* item = (AlarmListViewItem*)(*iit);
  612. events.append(item->event());
  613. origEvents.append(item->event());
  614. }
  615. if (Preferences::confirmAlarmDeletion())
  616. {
  617. int n = items.count();
  618. if (KMessageBox::warningContinueCancel(this, i18n("Do you really want to delete the selected alarm?",
  619. "Do you really want to delete the %n selected alarms?", n),
  620. i18n("Delete Alarm", "Delete Alarms", n),
  621. KGuiItem(i18n("&Delete"), "editdelete"),
  622. Preferences::CONFIRM_ALARM_DELETION)
  623. != KMessageBox::Continue)
  624. return;
  625. }
  626. int warnErr = 0;
  627. int warnKOrg = 0;
  628. AlarmCalendar::activeCalendar()->startUpdate(); // prevent multiple saves of the calendars until we're finished
  629. AlarmCalendar::expiredCalendar()->startUpdate();
  630. for (TQValueList<KAEvent>::Iterator it = events.begin(); it != events.end(); ++it)
  631. {
  632. // Delete the event from the calendar and displays
  633. switch (KAlarm::deleteEvent(*it))
  634. {
  635. case KAlarm::UPDATE_ERROR:
  636. case KAlarm::UPDATE_FAILED:
  637. case KAlarm::SAVE_FAILED:
  638. ++warnErr;
  639. break;
  640. case KAlarm::UPDATE_KORG_ERR:
  641. ++warnKOrg;
  642. break;
  643. default:
  644. break;
  645. }
  646. }
  647. if (!AlarmCalendar::activeCalendar()->endUpdate()) // save the calendars now
  648. warnErr = events.count();
  649. AlarmCalendar::expiredCalendar()->endUpdate();
  650. Undo::saveDeletes(origEvents);
  651. if (warnErr)
  652. KAlarm::displayUpdateError(this, KAlarm::UPDATE_FAILED, KAlarm::ERR_DELETE, warnErr);
  653. else if (warnKOrg)
  654. KAlarm::displayKOrgUpdateError(this, KAlarm::KORG_ERR_DELETE, warnKOrg);
  655. }
  656. /******************************************************************************
  657. * Called when the Reactivate button is clicked to reinstate the currently
  658. * highlighted expired alarms in the list.
  659. */
  660. void MainWindow::slotReactivate()
  661. {
  662. int warnErr = 0;
  663. int warnKOrg = 0;
  664. TQValueList<KAEvent> events;
  665. TQValueList<EventListViewItemBase*> items = mListView->selectedItems();
  666. mListView->clearSelection();
  667. AlarmCalendar::activeCalendar()->startUpdate(); // prevent multiple saves of the calendars until we're finished
  668. AlarmCalendar::expiredCalendar()->startUpdate();
  669. for (TQValueList<EventListViewItemBase*>::Iterator it = items.begin(); it != items.end(); ++it)
  670. {
  671. // Add the alarm to the displayed lists and to the calendar file
  672. AlarmListViewItem* item = (AlarmListViewItem*)(*it);
  673. KAEvent event = item->event();
  674. events.append(event);
  675. switch (KAlarm::reactivateEvent(event, mListView, true))
  676. {
  677. case KAlarm::UPDATE_ERROR:
  678. case KAlarm::UPDATE_FAILED:
  679. case KAlarm::SAVE_FAILED:
  680. ++warnErr;
  681. break;
  682. case KAlarm::UPDATE_KORG_ERR:
  683. ++warnKOrg;
  684. break;
  685. default:
  686. break;
  687. }
  688. }
  689. if (!AlarmCalendar::activeCalendar()->endUpdate()) // save the calendars now
  690. warnErr = items.count();
  691. AlarmCalendar::expiredCalendar()->endUpdate();
  692. Undo::saveReactivates(events);
  693. if (warnErr)
  694. KAlarm::displayUpdateError(this, KAlarm::UPDATE_FAILED, KAlarm::ERR_REACTIVATE, warnErr);
  695. else if (warnKOrg)
  696. KAlarm::displayKOrgUpdateError(this, KAlarm::KORG_ERR_ADD, warnKOrg);
  697. }
  698. /******************************************************************************
  699. * Called when the Enable/Disable button is clicked to enable or disable the
  700. * currently highlighted alarms in the list.
  701. */
  702. void MainWindow::slotEnable()
  703. {
  704. bool enable = mActionEnableEnable; // save since changed in response to KAlarm::enableEvent()
  705. int warnErr = 0;
  706. TQValueList<EventListViewItemBase*> items = mListView->selectedItems();
  707. AlarmCalendar::activeCalendar()->startUpdate(); // prevent multiple saves of the calendars until we're finished
  708. for (TQValueList<EventListViewItemBase*>::Iterator it = items.begin(); it != items.end(); ++it)
  709. {
  710. AlarmListViewItem* item = (AlarmListViewItem*)(*it);
  711. KAEvent event = item->event();
  712. // Enable the alarm in the displayed lists and in the calendar file
  713. if (KAlarm::enableEvent(event, mListView, enable) != KAlarm::UPDATE_OK)
  714. ++warnErr;
  715. }
  716. if (!AlarmCalendar::activeCalendar()->endUpdate()) // save the calendars now
  717. warnErr = items.count();
  718. if (warnErr)
  719. KAlarm::displayUpdateError(this, KAlarm::UPDATE_FAILED, KAlarm::ERR_ADD, warnErr);
  720. }
  721. /******************************************************************************
  722. * Called when the Show Alarm Times menu item is selected or deselected.
  723. */
  724. void MainWindow::slotShowTime()
  725. {
  726. mShowTime = !mShowTime;
  727. mActionShowTime->setChecked(mShowTime);
  728. if (!mShowTime && !mShowTimeTo)
  729. slotShowTimeTo(); // at least one time column must be displayed
  730. else
  731. {
  732. mListView->selectTimeColumns(mShowTime, mShowTimeTo);
  733. KConfig* config = KGlobal::config();
  734. config->setGroup(VIEW_GROUP);
  735. config->writeEntry(SHOW_TIME_KEY, mShowTime);
  736. config->writeEntry(SHOW_TIME_TO_KEY, mShowTimeTo);
  737. }
  738. }
  739. /******************************************************************************
  740. * Called when the Show Time To Alarms menu item is selected or deselected.
  741. */
  742. void MainWindow::slotShowTimeTo()
  743. {
  744. mShowTimeTo = !mShowTimeTo;
  745. mActionShowTimeTo->setChecked(mShowTimeTo);
  746. if (!mShowTimeTo && !mShowTime)
  747. slotShowTime(); // at least one time column must be displayed
  748. else
  749. {
  750. mListView->selectTimeColumns(mShowTime, mShowTimeTo);
  751. KConfig* config = KGlobal::config();
  752. config->setGroup(VIEW_GROUP);
  753. config->writeEntry(SHOW_TIME_KEY, mShowTime);
  754. config->writeEntry(SHOW_TIME_TO_KEY, mShowTimeTo);
  755. }
  756. setUpdateTimer();
  757. }
  758. /******************************************************************************
  759. * Called when the Show Expired Alarms menu item is selected or deselected.
  760. */
  761. void MainWindow::slotShowExpired()
  762. {
  763. mShowExpired = !mShowExpired;
  764. mActionShowExpired->setChecked(mShowExpired);
  765. mActionShowExpired->setToolTip(mShowExpired ? i18n_HideExpiredAlarms() : i18n_ShowExpiredAlarms());
  766. mListView->showExpired(mShowExpired);
  767. mListView->refresh();
  768. KConfig* config = KGlobal::config();
  769. config->setGroup(VIEW_GROUP);
  770. config->writeEntry(SHOW_ARCHIVED_KEY, mShowExpired);
  771. }
  772. /******************************************************************************
  773. * Called when the Import Alarms menu item is selected, to merge alarms from an
  774. * external calendar into the current calendars.
  775. */
  776. void MainWindow::slotImportAlarms()
  777. {
  778. if (AlarmCalendar::importAlarms(this))
  779. mListView->refresh();
  780. }
  781. /******************************************************************************
  782. * Called when the Import Birthdays menu item is selected, to display birthdays
  783. * from the address book for selection as alarms.
  784. */
  785. void MainWindow::slotBirthdays()
  786. {
  787. BirthdayDlg dlg(this);
  788. if (dlg.exec() == TQDialog::Accepted)
  789. {
  790. TQValueList<KAEvent> events = dlg.events();
  791. if (events.count())
  792. {
  793. mListView->clearSelection();
  794. int warnErr = 0;
  795. int warnKOrg = 0;
  796. for (TQValueList<KAEvent>::Iterator ev = events.begin(); ev != events.end(); ++ev)
  797. {
  798. // Add alarm to the displayed lists and to the calendar file
  799. switch (KAlarm::addEvent(*ev, mListView))
  800. {
  801. case KAlarm::UPDATE_ERROR:
  802. case KAlarm::UPDATE_FAILED:
  803. case KAlarm::SAVE_FAILED:
  804. ++warnErr;
  805. break;
  806. case KAlarm::UPDATE_KORG_ERR:
  807. ++warnKOrg;
  808. break;
  809. default:
  810. break;
  811. }
  812. }
  813. if (warnErr)
  814. KAlarm::displayUpdateError(this, KAlarm::UPDATE_FAILED, KAlarm::ERR_ADD, warnErr);
  815. else if (warnKOrg)
  816. KAlarm::displayKOrgUpdateError(this, KAlarm::KORG_ERR_ADD, warnKOrg);
  817. KAlarm::outputAlarmWarnings(&dlg);
  818. }
  819. }
  820. }
  821. /******************************************************************************
  822. * Called when the Templates menu item is selected, to display the alarm
  823. * template editing dialogue.
  824. */
  825. void MainWindow::slotTemplates()
  826. {
  827. if (!mTemplateDlg)
  828. {
  829. mTemplateDlg = TemplateDlg::create(this);
  830. enableTemplateMenuItem(false); // disable menu item in all windows
  831. connect(mTemplateDlg, TQT_SIGNAL(finished()), TQT_SLOT(slotTemplatesEnd()));
  832. mTemplateDlg->show();
  833. }
  834. }
  835. /******************************************************************************
  836. * Called when the alarm template editing dialogue has exited.
  837. */
  838. void MainWindow::slotTemplatesEnd()
  839. {
  840. if (mTemplateDlg)
  841. {
  842. mTemplateDlg->delayedDestruct(); // this deletes the dialogue once it is safe to do so
  843. mTemplateDlg = 0;
  844. enableTemplateMenuItem(true); // re-enable menu item in all windows
  845. }
  846. }
  847. /******************************************************************************
  848. * Called when the Display System Tray Icon menu item is selected.
  849. */
  850. void MainWindow::slotToggleTrayIcon()
  851. {
  852. theApp()->displayTrayIcon(!theApp()->trayIconDisplayed(), this);
  853. }
  854. /******************************************************************************
  855. * Called when the user preferences have changed.
  856. */
  857. void MainWindow::slotPrefsChanged()
  858. {
  859. mActionShowExpired->setEnabled(Preferences::expiredKeepDays());
  860. updateTrayIconAction();
  861. }
  862. /******************************************************************************
  863. * Called when the system tray icon is created or destroyed.
  864. * Set the system tray icon menu text according to whether or not the system
  865. * tray icon is currently visible.
  866. */
  867. void MainWindow::updateTrayIconAction()
  868. {
  869. mActionToggleTrayIcon->setEnabled(theApp()->haveSystemTray() && !theApp()->wantRunInSystemTray());
  870. mActionToggleTrayIcon->setChecked(theApp()->trayIconDisplayed());
  871. }
  872. /******************************************************************************
  873. * Called when the Actions menu is about to be displayed.
  874. * Update the status of the Alarms Enabled menu item.
  875. */
  876. void MainWindow::updateActionsMenu()
  877. {
  878. Daemon::checktqStatus(); // update the Alarms Enabled item status
  879. }
  880. /******************************************************************************
  881. * Called when the active status of Find changes.
  882. */
  883. void MainWindow::slotFindActive(bool active)
  884. {
  885. mActionFindNext->setEnabled(active);
  886. mActionFindPrev->setEnabled(active);
  887. }
  888. /******************************************************************************
  889. * Called when the Undo action is selected.
  890. */
  891. void MainWindow::slotUndo()
  892. {
  893. Undo::undo(this, KAlarm::stripAccel(mActionUndo->text()));
  894. }
  895. /******************************************************************************
  896. * Called when the Redo action is selected.
  897. */
  898. void MainWindow::slotRedo()
  899. {
  900. Undo::redo(this, KAlarm::stripAccel(mActionRedo->text()));
  901. }
  902. /******************************************************************************
  903. * Called when an Undo item is selected.
  904. */
  905. void MainWindow::slotUndoItem(int id)
  906. {
  907. Undo::undo(id, this, Undo::actionText(Undo::UNDO, id));
  908. }
  909. /******************************************************************************
  910. * Called when a Redo item is selected.
  911. */
  912. void MainWindow::slotRedoItem(int id)
  913. {
  914. Undo::redo(id, this, Undo::actionText(Undo::REDO, id));
  915. }
  916. /******************************************************************************
  917. * Called when the Undo menu is about to show.
  918. * Populates the menu.
  919. */
  920. void MainWindow::slotInitUndoMenu()
  921. {
  922. initUndoMenu(mActionUndo->popupMenu(), Undo::UNDO);
  923. }
  924. /******************************************************************************
  925. * Called when the Redo menu is about to show.
  926. * Populates the menu.
  927. */
  928. void MainWindow::slotInitRedoMenu()
  929. {
  930. initUndoMenu(mActionRedo->popupMenu(), Undo::REDO);
  931. }
  932. /******************************************************************************
  933. * Populate the undo or redo menu.
  934. */
  935. void MainWindow::initUndoMenu(KPopupMenu* menu, Undo::Type type)
  936. {
  937. menu->clear();
  938. const TQString& action = (type == Undo::UNDO) ? undoTextStripped : redoTextStripped;
  939. TQValueList<int> ids = Undo::ids(type);
  940. for (TQValueList<int>::ConstIterator it = ids.begin(); it != ids.end(); ++it)
  941. {
  942. int id = *it;
  943. TQString actText = Undo::actionText(type, id);
  944. TQString descrip = Undo::description(type, id);
  945. TQString text = descrip.isEmpty()
  946. ? i18n("Undo/Redo [action]", "%1 %2").tqarg(action).tqarg(actText)
  947. : i18n("Undo [action]: message", "%1 %2: %3").tqarg(action).tqarg(actText).tqarg(descrip);
  948. menu->insertItem(text, id);
  949. }
  950. }
  951. /******************************************************************************
  952. * Called when the status of the Undo or Redo list changes.
  953. * Change the Undo or Redo text to include the action which would be undone/redone.
  954. */
  955. void MainWindow::slotUndotqStatus(const TQString& undo, const TQString& redo)
  956. {
  957. if (undo.isNull())
  958. {
  959. mActionUndo->setEnabled(false);
  960. mActionUndo->setText(undoText);
  961. }
  962. else
  963. {
  964. mActionUndo->setEnabled(true);
  965. mActionUndo->setText(TQString("%1 %2").tqarg(undoText).tqarg(undo));
  966. }
  967. if (redo.isNull())
  968. {
  969. mActionRedo->setEnabled(false);
  970. mActionRedo->setText(redoText);
  971. }
  972. else
  973. {
  974. mActionRedo->setEnabled(true);
  975. mActionRedo->setText(TQString("%1 %2").tqarg(redoText).tqarg(redo));
  976. }
  977. }
  978. /******************************************************************************
  979. * Called when the Reset Daemon menu item is selected.
  980. */
  981. void MainWindow::slotResetDaemon()
  982. {
  983. KAlarm::resetDaemon();
  984. }
  985. /******************************************************************************
  986. * Called when the "Configure KAlarm" menu item is selected.
  987. */
  988. void MainWindow::slotPreferences()
  989. {
  990. KAlarmPrefDlg::display();
  991. }
  992. /******************************************************************************
  993. * Called when the Configure Keys menu item is selected.
  994. */
  995. void MainWindow::slotConfigureKeys()
  996. {
  997. KKeyDialog::configure(actionCollection(), this);
  998. }
  999. /******************************************************************************
  1000. * Called when the Configure Toolbars menu item is selected.
  1001. */
  1002. void MainWindow::slotConfigureToolbar()
  1003. {
  1004. saveMainWindowSettings(KGlobal::config(), WINDOW_NAME);
  1005. KEditToolbar dlg(factory());
  1006. connect(&dlg, TQT_SIGNAL(newToolbarConfig()), TQT_TQOBJECT(this), TQT_SLOT(slotNewToolbarConfig()));
  1007. dlg.exec();
  1008. }
  1009. /******************************************************************************
  1010. * Called when OK or Apply is clicked in the Configure Toolbars dialog, to save
  1011. * the new configuration.
  1012. */
  1013. void MainWindow::slotNewToolbarConfig()
  1014. {
  1015. createGUI(UI_FILE);
  1016. applyMainWindowSettings(KGlobal::config(), WINDOW_NAME);
  1017. }
  1018. /******************************************************************************
  1019. * Called when the Quit menu item is selected.
  1020. */
  1021. void MainWindow::slotQuit()
  1022. {
  1023. theApp()->doQuit(this);
  1024. }
  1025. /******************************************************************************
  1026. * Called when the user or the session manager attempts to close the window.
  1027. */
  1028. void MainWindow::closeEvent(TQCloseEvent* ce)
  1029. {
  1030. if (!theApp()->sessionClosingDown() && isTrayParent())
  1031. {
  1032. // The user (not the session manager) wants to close the window.
  1033. // It's the parent window of the system tray icon, so just hide
  1034. // it to prevent the system tray icon closing.
  1035. hide();
  1036. theApp()->quitIf();
  1037. ce->ignore();
  1038. }
  1039. else
  1040. ce->accept();
  1041. }
  1042. /******************************************************************************
  1043. * Called when an item is deleted from the ListView.
  1044. * Disables the actions if no item is still selected.
  1045. */
  1046. void MainWindow::slotDeletion()
  1047. {
  1048. if (!mListView->selectedCount())
  1049. {
  1050. kdDebug(5950) << "MainWindow::slotDeletion(true)\n";
  1051. mActionCreateTemplate->setEnabled(false);
  1052. mActionCopy->setEnabled(false);
  1053. mActionModify->setEnabled(false);
  1054. mActionView->setEnabled(false);
  1055. mActionDelete->setEnabled(false);
  1056. mActionReactivate->setEnabled(false);
  1057. mActionEnable->setEnabled(false);
  1058. }
  1059. }
  1060. /******************************************************************************
  1061. * Called when the drag cursor enters the window.
  1062. */
  1063. void MainWindow::dragEnterEvent(TQDragEnterEvent* e)
  1064. {
  1065. executeDragEnterEvent(e);
  1066. }
  1067. /******************************************************************************
  1068. * Called when the drag cursor enters a main or system tray window, to accept
  1069. * or reject the dragged object.
  1070. */
  1071. void MainWindow::executeDragEnterEvent(TQDragEnterEvent* e)
  1072. {
  1073. if (KCal::ICalDrag::canDecode(e))
  1074. e->accept(!AlarmListView::dragging()); // don't accept "text/calendar" objects from KAlarm
  1075. else
  1076. e->accept(TQTextDrag::canDecode(e)
  1077. || KURLDrag::canDecode(e)
  1078. || KPIM::MailListDrag::canDecode(e));
  1079. }
  1080. /******************************************************************************
  1081. * Called when an object is dropped on the window.
  1082. * If the object is recognised, the edit alarm dialog is opened appropriately.
  1083. */
  1084. void MainWindow::dropEvent(TQDropEvent* e)
  1085. {
  1086. executeDropEvent(this, e);
  1087. }
  1088. static TQString getMailHeader(const char* header, KMime::Content& content)
  1089. {
  1090. KMime::Headers::Base* hd = content.getHeaderByType(header);
  1091. return hd ? hd->asUnicodeString() : TQString();
  1092. }
  1093. /******************************************************************************
  1094. * Called when an object is dropped on a main or system tray window, to
  1095. * evaluate the action required and extract the text.
  1096. */
  1097. void MainWindow::executeDropEvent(MainWindow* win, TQDropEvent* e)
  1098. {
  1099. KAEvent::Action action = KAEvent::MESSAGE;
  1100. TQString text;
  1101. TQByteArray bytes;
  1102. AlarmText alarmText;
  1103. KPIM::MailList mailList;
  1104. KURL::List files;
  1105. KCal::CalendarLocal calendar(TQString::tqfromLatin1("UTC"));
  1106. calendar.setLocalTime(); // default to local time (i.e. no time zone)
  1107. #ifndef NDEBUG
  1108. TQCString fmts;
  1109. for (int idbg = 0; e->format(idbg); ++idbg)
  1110. {
  1111. if (idbg) fmts += ", ";
  1112. fmts += e->format(idbg);
  1113. }
  1114. kdDebug(5950) << "MainWindow::executeDropEvent(): " << fmts << endl;
  1115. #endif
  1116. /* The order of the tests below matters, since some dropped objects
  1117. * provide more than one mime type.
  1118. * Don't change them without careful thought !!
  1119. */
  1120. if (e->provides("message/rfc822")
  1121. && !(bytes = e->tqencodedData("message/rfc822")).isEmpty())
  1122. {
  1123. // Email message(s). Ignore all but the first.
  1124. kdDebug(5950) << "MainWindow::executeDropEvent(email)" << endl;
  1125. TQCString mails(bytes.data(), bytes.size());
  1126. KMime::Content content;
  1127. content.setContent(mails);
  1128. content.parse();
  1129. TQString body;
  1130. if (content.textContent())
  1131. content.textContent()->decodedText(body, true, true); // strip trailing newlines & spaces
  1132. unsigned long sernum = 0;
  1133. if (e->provides(KPIM::MailListDrag::format())
  1134. && KPIM::MailListDrag::decode(e, mailList)
  1135. && mailList.count())
  1136. {
  1137. // Get its KMail serial number to allow the KMail message
  1138. // to be called up from the alarm message window.
  1139. sernum = mailList.first().serialNumber();
  1140. }
  1141. alarmText.setEmail(getMailHeader("To", content),
  1142. getMailHeader("From", content),
  1143. getMailHeader("Cc", content),
  1144. getMailHeader("Date", content),
  1145. getMailHeader("Subject", content),
  1146. body, sernum);
  1147. }
  1148. else if (KURLDrag::decode(e, files) && files.count())
  1149. {
  1150. kdDebug(5950) << "MainWindow::executeDropEvent(URL)" << endl;
  1151. action = KAEvent::FILE;
  1152. alarmText.setText(files.first().prettyURL());
  1153. }
  1154. else if (e->provides(KPIM::MailListDrag::format())
  1155. && KPIM::MailListDrag::decode(e, mailList))
  1156. {
  1157. // KMail message(s). Ignore all but the first.
  1158. kdDebug(5950) << "MainWindow::executeDropEvent(KMail_list)" << endl;
  1159. if (!mailList.count())
  1160. return;
  1161. KPIM::MailSummary& summary = mailList.first();
  1162. TQDateTime dt;
  1163. dt.setTime_t(summary.date());
  1164. TQString body = KAMail::getMailBody(summary.serialNumber());
  1165. alarmText.setEmail(summary.to(), summary.from(), TQString(),
  1166. KGlobal::locale()->formatDateTime(dt), summary.subject(),
  1167. body, summary.serialNumber());
  1168. }
  1169. else if (KCal::ICalDrag::decode(e, &calendar))
  1170. {
  1171. // iCalendar - ignore all but the first event
  1172. kdDebug(5950) << "MainWindow::executeDropEvent(iCalendar)" << endl;
  1173. KCal::Event::List events = calendar.rawEvents();
  1174. if (!events.isEmpty())
  1175. {
  1176. KAEvent ev(*events.first());
  1177. executeNew(win, &ev);
  1178. }
  1179. return;
  1180. }
  1181. else if (TQTextDrag::decode(e, text))
  1182. {
  1183. kdDebug(5950) << "MainWindow::executeDropEvent(text)" << endl;
  1184. alarmText.setText(text);
  1185. }
  1186. else
  1187. return;
  1188. if (!alarmText.isEmpty())
  1189. executeNew(win, 0, action, alarmText);
  1190. }
  1191. /******************************************************************************
  1192. * Called when the selected items in the ListView changes.
  1193. * Selects the new current item, and enables the actions appropriately.
  1194. */
  1195. void MainWindow::slotSelection()
  1196. {
  1197. // Find which item has been selected, and whether more than one is selected
  1198. TQValueList<EventListViewItemBase*> items = mListView->selectedItems();
  1199. int count = items.count();
  1200. AlarmListViewItem* item = (AlarmListViewItem*)((count == 1) ? items.first() : 0);
  1201. bool enableReactivate = true;
  1202. bool enableEnableDisable = true;
  1203. bool enableEnable = false;
  1204. bool enableDisable = false;
  1205. TQDateTime now = TQDateTime::tqcurrentDateTime();
  1206. for (TQValueList<EventListViewItemBase*>::Iterator it = items.begin(); it != items.end(); ++it)
  1207. {
  1208. const KAEvent& event = ((AlarmListViewItem*)(*it))->event();
  1209. if (enableReactivate
  1210. && (!event.expired() || !event.occursAfter(now, true)))
  1211. enableReactivate = false;
  1212. if (enableEnableDisable)
  1213. {
  1214. if (event.expired())
  1215. enableEnableDisable = enableEnable = enableDisable = false;
  1216. else
  1217. {
  1218. if (!enableEnable && !event.enabled())
  1219. enableEnable = true;
  1220. if (!enableDisable && event.enabled())
  1221. enableDisable = true;
  1222. }
  1223. }
  1224. }
  1225. kdDebug(5950) << "MainWindow::slotSelection(true)\n";
  1226. mActionCreateTemplate->setEnabled(count == 1);
  1227. mActionCopy->setEnabled(count == 1);
  1228. mActionModify->setEnabled(item && !mListView->expired(item));
  1229. mActionView->setEnabled(count == 1);
  1230. mActionDelete->setEnabled(count);
  1231. mActionReactivate->setEnabled(count && enableReactivate);
  1232. mActionEnable->setEnabled(enableEnable || enableDisable);
  1233. if (enableEnable || enableDisable)
  1234. setEnableText(enableEnable);
  1235. }
  1236. /******************************************************************************
  1237. * Called when a context menu is requested either by a mouse click or by a
  1238. * key press.
  1239. */
  1240. void MainWindow::slotContextMenuRequested(TQListViewItem* item, const TQPoint& pt, int)
  1241. {
  1242. kdDebug(5950) << "MainWindow::slotContextMenuRequested()" << endl;
  1243. if (mContextMenu)
  1244. mContextMenu->popup(pt);
  1245. }
  1246. /******************************************************************************
  1247. * Called when the mouse is clicked on the ListView.
  1248. * Deselects the current item and disables the actions if appropriate.
  1249. * Note that if a right button click is handled by slotContextMenuRequested().
  1250. */
  1251. void MainWindow::slotMouseClicked(int button, TQListViewItem* item, const TQPoint& pt, int)
  1252. {
  1253. if (button != Qt::RightButton && !item)
  1254. {
  1255. kdDebug(5950) << "MainWindow::slotMouseClicked(left)" << endl;
  1256. mListView->clearSelection();
  1257. mActionCreateTemplate->setEnabled(false);
  1258. mActionCopy->setEnabled(false);
  1259. mActionModify->setEnabled(false);
  1260. mActionView->setEnabled(false);
  1261. mActionDelete->setEnabled(false);
  1262. mActionReactivate->setEnabled(false);
  1263. mActionEnable->setEnabled(false);
  1264. }
  1265. }
  1266. /******************************************************************************
  1267. * Called when the mouse is double clicked on the ListView.
  1268. * Displays the Edit Alarm dialog, for the clicked item if applicable.
  1269. */
  1270. void MainWindow::slotDoubleClicked(TQListViewItem* item)
  1271. {
  1272. kdDebug(5950) << "MainWindow::slotDoubleClicked()\n";
  1273. if (item)
  1274. {
  1275. if (mListView->expired((AlarmListViewItem*)item))
  1276. slotView();
  1277. else
  1278. slotModify();
  1279. }
  1280. else
  1281. slotNew();
  1282. }
  1283. /******************************************************************************
  1284. * Set the text of the Enable/Disable menu action.
  1285. */
  1286. void MainWindow::setEnableText(bool enable)
  1287. {
  1288. mActionEnableEnable = enable;
  1289. mActionEnable->setText(enable ? i18n("Ena&ble") : i18n("Disa&ble"));
  1290. }
  1291. /******************************************************************************
  1292. * Display or hide the specified main window.
  1293. * This should only be called when the application doesn't run in the system tray.
  1294. */
  1295. MainWindow* MainWindow::toggleWindow(MainWindow* win)
  1296. {
  1297. if (win && mWindowList.find(win) != mWindowList.end())
  1298. {
  1299. // A window is specified (and it exists)
  1300. if (win->isVisible())
  1301. {
  1302. // The window is visible, so close it
  1303. win->close();
  1304. return 0;
  1305. }
  1306. else
  1307. {
  1308. // The window is hidden, so display it
  1309. win->hide(); // in case it's on a different desktop
  1310. win->showNormal();
  1311. win->raise();
  1312. win->setActiveWindow();
  1313. return win;
  1314. }
  1315. }
  1316. // No window is specified, or the window doesn't exist. Open a new one.
  1317. win = create();
  1318. win->show();
  1319. return win;
  1320. }