• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kalarm

  • sources
  • kde-4.12
  • kdepim
  • kalarm
editdlg.cpp
Go to the documentation of this file.
1 /*
2  * editdlg.cpp - dialog to create or modify an alarm or alarm template
3  * Program: kalarm
4  * Copyright © 2001-2012 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 
21 #include "kalarm.h"
22 #include "editdlg.moc"
23 #include "editdlg_p.moc"
24 #include "editdlgtypes.h"
25 
26 #include "alarmcalendar.h"
27 #ifdef USE_AKONADI
28 #include "collectionmodel.h"
29 #else
30 #include "alarmresources.h"
31 #endif
32 #include "alarmtimewidget.h"
33 #include "autoqpointer.h"
34 #include "buttongroup.h"
35 #include "checkbox.h"
36 #include "deferdlg.h"
37 #include "functions.h"
38 #include "kalarmapp.h"
39 #include "latecancel.h"
40 #include "lineedit.h"
41 #include "mainwindow.h"
42 #include "messagebox.h"
43 #include "packedlayout.h"
44 #include "preferences.h"
45 #include "radiobutton.h"
46 #include "recurrenceedit.h"
47 #include "reminder.h"
48 #include "shellprocess.h"
49 #include "spinbox.h"
50 #include "stackedwidgets.h"
51 #include "templatepickdlg.h"
52 #include "timeedit.h"
53 #include "timespinbox.h"
54 
55 #include <libkdepim/misc/maillistdrag.h>
56 
57 #include <kglobal.h>
58 #include <klocale.h>
59 #include <kconfig.h>
60 #include <kfiledialog.h>
61 #include <kpushbutton.h>
62 #include <khbox.h>
63 #include <kvbox.h>
64 #include <kwindowsystem.h>
65 #include <kdebug.h>
66 
67 #include <QLabel>
68 #include <QDir>
69 #include <QStyle>
70 #include <QGroupBox>
71 #include <QPushButton>
72 #include <QGridLayout>
73 #include <QHBoxLayout>
74 #include <QVBoxLayout>
75 #include <QDragEnterEvent>
76 #include <QResizeEvent>
77 #include <QShowEvent>
78 #include <QStackedWidget>
79 #include <QScrollBar>
80 #include <QTimer>
81 
82 using namespace KCal;
83 using namespace KAlarmCal;
84 
85 static const char EDIT_DIALOG_NAME[] = "EditDialog";
86 static const char TEMPLATE_DIALOG_NAME[] = "EditTemplateDialog";
87 static const char EDIT_MORE_GROUP[] = "ShowOpts";
88 static const char EDIT_MORE_KEY[] = "EditMore";
89 static const int maxDelayTime = 99*60 + 59; // < 100 hours
90 
91 inline QString recurText(const KAEvent& event)
92 {
93  QString r;
94  if (event.repetition())
95  r = QString::fromLatin1("%1 / %2").arg(event.recurrenceText()).arg(event.repetitionText());
96  else
97  r = event.recurrenceText();
98  return i18nc("@title:tab", "Recurrence - [%1]", r);
99 }
100 
101 // Collect these widget labels together to ensure consistent wording and
102 // translations across different modules.
103 QString EditAlarmDlg::i18n_chk_ShowInKOrganizer() { return i18nc("@option:check", "Show in KOrganizer"); }
104 
105 
106 EditAlarmDlg* EditAlarmDlg::create(bool Template, Type type, QWidget* parent, GetResourceType getResource)
107 {
108  kDebug();
109  switch (type)
110  {
111  case DISPLAY: return new EditDisplayAlarmDlg(Template, parent, getResource);
112  case COMMAND: return new EditCommandAlarmDlg(Template, parent, getResource);
113  case EMAIL: return new EditEmailAlarmDlg(Template, parent, getResource);
114  case AUDIO: return new EditAudioAlarmDlg(Template, parent, getResource);
115  default: break;
116  }
117  return 0;
118 }
119 
120 EditAlarmDlg* EditAlarmDlg::create(bool Template, const KAEvent* event, bool newAlarm, QWidget* parent,
121  GetResourceType getResource, bool readOnly)
122 {
123  switch (event->actionTypes())
124  {
125  case KAEvent::ACT_COMMAND: return new EditCommandAlarmDlg(Template, event, newAlarm, parent, getResource, readOnly);
126  case KAEvent::ACT_DISPLAY_COMMAND:
127  case KAEvent::ACT_DISPLAY: return new EditDisplayAlarmDlg(Template, event, newAlarm, parent, getResource, readOnly);
128  case KAEvent::ACT_EMAIL: return new EditEmailAlarmDlg(Template, event, newAlarm, parent, getResource, readOnly);
129  case KAEvent::ACT_AUDIO: return new EditAudioAlarmDlg(Template, event, newAlarm, parent, getResource, readOnly);
130  default:
131  break;
132  }
133  return 0;
134 }
135 
136 
137 /******************************************************************************
138 * Constructor.
139 * Parameters:
140 * Template = true to edit/create an alarm template
141 * = false to edit/create an alarm.
142 * event != to initialise the dialog to show the specified event's data.
143 */
144 EditAlarmDlg::EditAlarmDlg(bool Template, KAEvent::SubAction action, QWidget* parent, GetResourceType getResource)
145  : KDialog(parent),
146  mAlarmType(action),
147  mMainPageShown(false),
148  mRecurPageShown(false),
149  mRecurSetDefaultEndDate(true),
150  mTemplateName(0),
151  mDeferGroup(0),
152  mDeferChangeButton(0),
153  mTimeWidget(0),
154  mShowInKorganizer(0),
155 #ifndef USE_AKONADI
156  mResource(0),
157 #endif
158  mDeferGroupHeight(0),
159  mTemplate(Template),
160  mNewAlarm(true),
161  mDesiredReadOnly(false),
162  mReadOnly(false),
163  mShowingMore(true),
164  mSavedEvent(0)
165 {
166  init(0, getResource);
167 }
168 
169 EditAlarmDlg::EditAlarmDlg(bool Template, const KAEvent* event, bool newAlarm, QWidget* parent,
170  GetResourceType getResource, bool readOnly)
171  : KDialog(parent),
172  mAlarmType(event->actionSubType()),
173  mMainPageShown(false),
174  mRecurPageShown(false),
175  mRecurSetDefaultEndDate(true),
176  mTemplateName(0),
177  mDeferGroup(0),
178  mDeferChangeButton(0),
179  mTimeWidget(0),
180  mShowInKorganizer(0),
181 #ifndef USE_AKONADI
182  mResource(0),
183 #endif
184  mDeferGroupHeight(0),
185  mEventId(newAlarm ? QString() : event->id()),
186  mTemplate(Template),
187  mNewAlarm(newAlarm),
188  mDesiredReadOnly(readOnly),
189  mReadOnly(readOnly),
190  mShowingMore(true),
191  mSavedEvent(0)
192 {
193  init(event, getResource);
194 }
195 
196 void EditAlarmDlg::init(const KAEvent* event, GetResourceType getResource)
197 {
198  switch (getResource)
199  {
200 #ifdef USE_AKONADI
201  case RES_USE_EVENT_ID:
202  if (event)
203  {
204  mCollectionItemId = event->itemId();
205  break;
206  }
207  // fall through to RES_PROMPT
208  case RES_PROMPT:
209  mCollectionItemId = -1;
210  break;
211  case RES_IGNORE:
212  default:
213  mCollectionItemId = -2;
214  break;
215 #else
216  case RES_USE_EVENT_ID:
217  if (event)
218  {
219  mResourceEventId = event->id();
220  break;
221  }
222  // fall through to RES_PROMPT
223  case RES_PROMPT:
224  mResourceEventId = QString(""); // empty but non-null
225  break;
226  case RES_IGNORE:
227  default:
228  mResourceEventId.clear(); // null
229  break;
230 #endif
231  }
232 }
233 
234 void EditAlarmDlg::init(const KAEvent* event)
235 {
236  setObjectName(mTemplate ? QLatin1String("TemplEditDlg") : QLatin1String("EditDlg")); // used by LikeBack
237  QString caption;
238  if (mReadOnly)
239  caption = mTemplate ? i18nc("@title:window", "Alarm Template [read-only]")
240  : event->expired() ? i18nc("@title:window", "Archived Alarm [read-only]")
241  : i18nc("@title:window", "Alarm [read-only]");
242  else
243  caption = type_caption();
244  setCaption(caption);
245  setButtons((mReadOnly ? Cancel|Try|Default : mTemplate ? Ok|Cancel|Try|Default : Ok|Cancel|Try|Help|Default));
246  setDefaultButton(mReadOnly ? Cancel : Ok);
247  setButtonText(Help, i18nc("@action:button", "Load Template..."));
248  setButtonIcon(Help, KIcon());
249  setButtonIcon(Default, KIcon());
250  connect(this, SIGNAL(tryClicked()), SLOT(slotTry()));
251  connect(this, SIGNAL(defaultClicked()), SLOT(slotDefault())); // More/Less Options button
252  connect(this, SIGNAL(helpClicked()), SLOT(slotHelp())); // Load Template button
253  KVBox* mainWidget = new KVBox(this);
254  mainWidget->setMargin(0);
255  setMainWidget(mainWidget);
256  if (mTemplate)
257  {
258  KHBox* box = new KHBox(mainWidget);
259  box->setMargin(0);
260  box->setSpacing(spacingHint());
261  QLabel* label = new QLabel(i18nc("@label:textbox", "Template name:"), box);
262  label->setFixedSize(label->sizeHint());
263  mTemplateName = new KLineEdit(box);
264  mTemplateName->setReadOnly(mReadOnly);
265  connect(mTemplateName, SIGNAL(userTextChanged(QString)), SLOT(contentsChanged()));
266  label->setBuddy(mTemplateName);
267  box->setWhatsThis(i18nc("@info:whatsthis", "Enter the name of the alarm template"));
268  box->setFixedHeight(box->sizeHint().height());
269  }
270  mTabs = new KTabWidget(mainWidget);
271  mTabScrollGroup = new StackedScrollGroup(this, mTabs);
272 
273  StackedScrollWidget* mainScroll = new StackedScrollWidget(mTabScrollGroup);
274  mTabs->addTab(mainScroll, i18nc("@title:tab", "Alarm"));
275  mMainPageIndex = 0;
276  PageFrame* mainPage = new PageFrame(mainScroll);
277  mainScroll->setWidget(mainPage); // mainPage becomes the child of mainScroll
278  connect(mainPage, SIGNAL(shown()), SLOT(slotShowMainPage()));
279  QVBoxLayout* topLayout = new QVBoxLayout(mainPage);
280  topLayout->setMargin(marginHint());
281  topLayout->setSpacing(spacingHint());
282 
283  // Recurrence tab
284  StackedScrollWidget* recurScroll = new StackedScrollWidget(mTabScrollGroup);
285  mTabs->addTab(recurScroll, QString());
286  mRecurPageIndex = 1;
287  KVBox* recurTab = new KVBox();
288  recurTab->setMargin(marginHint());
289  recurScroll->setWidget(recurTab); // recurTab becomes the child of recurScroll
290  mRecurrenceEdit = new RecurrenceEdit(mReadOnly, recurTab);
291  connect(mRecurrenceEdit, SIGNAL(shown()), SLOT(slotShowRecurrenceEdit()));
292  connect(mRecurrenceEdit, SIGNAL(typeChanged(int)), SLOT(slotRecurTypeChange(int)));
293  connect(mRecurrenceEdit, SIGNAL(frequencyChanged()), SLOT(slotRecurFrequencyChange()));
294  connect(mRecurrenceEdit, SIGNAL(repeatNeedsInitialisation()), SLOT(slotSetSubRepetition()));
295  connect(mRecurrenceEdit, SIGNAL(contentsChanged()), SLOT(contentsChanged()));
296 
297  // Controls specific to the alarm type
298  QGroupBox* actionBox = new QGroupBox(i18nc("@title:group", "Action"), mainPage);
299  topLayout->addWidget(actionBox, 1);
300  QVBoxLayout* layout = new QVBoxLayout(actionBox);
301  layout->setMargin(marginHint());
302  layout->setSpacing(spacingHint());
303 
304  type_init(actionBox, layout);
305 
306  if (!mTemplate)
307  {
308  // Deferred date/time: visible only for a deferred recurring event.
309  mDeferGroup = new QGroupBox(i18nc("@title:group", "Deferred Alarm"), mainPage);
310  topLayout->addWidget(mDeferGroup);
311  QHBoxLayout* hlayout = new QHBoxLayout(mDeferGroup);
312  hlayout->setMargin(marginHint());
313  hlayout->setSpacing(spacingHint());
314  QLabel* label = new QLabel(i18nc("@label", "Deferred to:"), mDeferGroup);
315  label->setFixedSize(label->sizeHint());
316  hlayout->addWidget(label);
317  mDeferTimeLabel = new QLabel(mDeferGroup);
318  hlayout->addWidget(mDeferTimeLabel);
319 
320  mDeferChangeButton = new QPushButton(i18nc("@action:button", "Change..."), mDeferGroup);
321  mDeferChangeButton->setFixedSize(mDeferChangeButton->sizeHint());
322  connect(mDeferChangeButton, SIGNAL(clicked()), SLOT(slotEditDeferral()));
323  mDeferChangeButton->setWhatsThis(i18nc("@info:whatsthis", "Change the alarm's deferred time, or cancel the deferral"));
324  hlayout->addWidget(mDeferChangeButton);
325 //?? mDeferGroup->addSpace(0);
326  }
327 
328  QHBoxLayout* hlayout = new QHBoxLayout();
329  hlayout->setMargin(0);
330  topLayout->addLayout(hlayout);
331 
332  // Date and time entry
333  if (mTemplate)
334  {
335  QGroupBox* templateTimeBox = new QGroupBox(i18nc("@title:group", "Time"), mainPage);
336  hlayout->addWidget(templateTimeBox);
337  QGridLayout* grid = new QGridLayout(templateTimeBox);
338  grid->setMargin(marginHint());
339  grid->setSpacing(spacingHint());
340  mTemplateTimeGroup = new ButtonGroup(templateTimeBox);
341  connect(mTemplateTimeGroup, SIGNAL(buttonSet(QAbstractButton*)), SLOT(slotTemplateTimeType(QAbstractButton*)));
342  connect(mTemplateTimeGroup, SIGNAL(buttonSet(QAbstractButton*)), SLOT(contentsChanged()));
343 
344  mTemplateDefaultTime = new RadioButton(i18nc("@option:radio", "Default time"), templateTimeBox);
345  mTemplateDefaultTime->setFixedSize(mTemplateDefaultTime->sizeHint());
346  mTemplateDefaultTime->setReadOnly(mReadOnly);
347  mTemplateDefaultTime->setWhatsThis(i18nc("@info:whatsthis", "Do not specify a start time for alarms based on this template. "
348  "The normal default start time will be used."));
349  mTemplateTimeGroup->addButton(mTemplateDefaultTime);
350  grid->addWidget(mTemplateDefaultTime, 0, 0, Qt::AlignLeft);
351 
352  KHBox* box = new KHBox(templateTimeBox);
353  box->setMargin(0);
354  box->setSpacing(spacingHint());
355  mTemplateUseTime = new RadioButton(i18nc("@option:radio", "Time:"), box);
356  mTemplateUseTime->setFixedSize(mTemplateUseTime->sizeHint());
357  mTemplateUseTime->setReadOnly(mReadOnly);
358  mTemplateUseTime->setWhatsThis(i18nc("@info:whatsthis", "Specify a start time for alarms based on this template."));
359  mTemplateTimeGroup->addButton(mTemplateUseTime);
360  mTemplateTime = new TimeEdit(box);
361  mTemplateTime->setFixedSize(mTemplateTime->sizeHint());
362  mTemplateTime->setReadOnly(mReadOnly);
363  mTemplateTime->setWhatsThis(i18nc("@info:whatsthis",
364  "<para>Enter the start time for alarms based on this template.</para><para>%1</para>",
365  TimeSpinBox::shiftWhatsThis()));
366  connect(mTemplateTime, SIGNAL(valueChanged(int)), SLOT(contentsChanged()));
367  box->setStretchFactor(new QWidget(box), 1); // left adjust the controls
368  box->setFixedHeight(box->sizeHint().height());
369  grid->addWidget(box, 0, 1, Qt::AlignLeft);
370 
371  mTemplateAnyTime = new RadioButton(i18nc("@option:radio", "Date only"), templateTimeBox);
372  mTemplateAnyTime->setFixedSize(mTemplateAnyTime->sizeHint());
373  mTemplateAnyTime->setReadOnly(mReadOnly);
374  mTemplateAnyTime->setWhatsThis(i18nc("@info:whatsthis", "Set the <interface>Any time</interface> option for alarms based on this template."));
375  mTemplateTimeGroup->addButton(mTemplateAnyTime);
376  grid->addWidget(mTemplateAnyTime, 1, 0, Qt::AlignLeft);
377 
378  box = new KHBox(templateTimeBox);
379  box->setMargin(0);
380  box->setSpacing(spacingHint());
381  mTemplateUseTimeAfter = new RadioButton(i18nc("@option:radio", "Time from now:"), box);
382  mTemplateUseTimeAfter->setFixedSize(mTemplateUseTimeAfter->sizeHint());
383  mTemplateUseTimeAfter->setReadOnly(mReadOnly);
384  mTemplateUseTimeAfter->setWhatsThis(i18nc("@info:whatsthis",
385  "Set alarms based on this template to start after the specified time "
386  "interval from when the alarm is created."));
387  mTemplateTimeGroup->addButton(mTemplateUseTimeAfter);
388  mTemplateTimeAfter = new TimeSpinBox(1, maxDelayTime, box);
389  mTemplateTimeAfter->setValue(1439);
390  mTemplateTimeAfter->setFixedSize(mTemplateTimeAfter->sizeHint());
391  mTemplateTimeAfter->setReadOnly(mReadOnly);
392  connect(mTemplateTimeAfter, SIGNAL(valueChanged(int)), SLOT(contentsChanged()));
393  mTemplateTimeAfter->setWhatsThis(i18nc("@info:whatsthis", "<para>%1</para><para>%2</para>",
394  AlarmTimeWidget::i18n_TimeAfterPeriod(), TimeSpinBox::shiftWhatsThis()));
395  box->setFixedHeight(box->sizeHint().height());
396  grid->addWidget(box, 1, 1, Qt::AlignLeft);
397 
398  hlayout->addStretch();
399  }
400  else
401  {
402  mTimeWidget = new AlarmTimeWidget(i18nc("@title:group", "Time"), AlarmTimeWidget::AT_TIME, mainPage);
403  connect(mTimeWidget, SIGNAL(dateOnlyToggled(bool)), SLOT(slotAnyTimeToggled(bool)));
404  connect(mTimeWidget, SIGNAL(changed(KDateTime)), SLOT(contentsChanged()));
405  topLayout->addWidget(mTimeWidget);
406  }
407 
408  // Optional controls depending on More/Less Options button
409  mMoreOptions = new QFrame(mainPage);
410  mMoreOptions->setFrameStyle(QFrame::NoFrame);
411  topLayout->addWidget(mMoreOptions);
412  QVBoxLayout* moreLayout = new QVBoxLayout(mMoreOptions);
413  moreLayout->setMargin(0);
414  moreLayout->setSpacing(spacingHint());
415 
416  // Reminder
417  mReminder = createReminder(mMoreOptions);
418  if (mReminder)
419  {
420  mReminder->setFixedSize(mReminder->sizeHint());
421  connect(mReminder, SIGNAL(changed()), SLOT(contentsChanged()));
422  moreLayout->addWidget(mReminder, 0, Qt::AlignLeft);
423  if (mTimeWidget)
424  connect(mTimeWidget, SIGNAL(changed(KDateTime)), mReminder, SLOT(setDefaultUnits(KDateTime)));
425  }
426 
427  // Late cancel selector - default = allow late display
428  mLateCancel = new LateCancelSelector(true, mMoreOptions);
429  connect(mLateCancel, SIGNAL(changed()), SLOT(contentsChanged()));
430  moreLayout->addWidget(mLateCancel, 0, Qt::AlignLeft);
431 
432  PackedLayout* playout = new PackedLayout(Qt::AlignJustify);
433  playout->setSpacing(2*spacingHint());
434  moreLayout->addLayout(playout);
435 
436  // Acknowledgement confirmation required - default = no confirmation
437  CheckBox* confirmAck = type_createConfirmAckCheckbox(mMoreOptions);
438  if (confirmAck)
439  {
440  confirmAck->setFixedSize(confirmAck->sizeHint());
441  connect(confirmAck, SIGNAL(toggled(bool)), SLOT(contentsChanged()));
442  playout->addWidget(confirmAck);
443  }
444 
445  if (theApp()->korganizerEnabled())
446  {
447  // Show in KOrganizer checkbox
448  mShowInKorganizer = new CheckBox(i18n_chk_ShowInKOrganizer(), mMoreOptions);
449  mShowInKorganizer->setFixedSize(mShowInKorganizer->sizeHint());
450  connect(mShowInKorganizer, SIGNAL(toggled(bool)), SLOT(contentsChanged()));
451  mShowInKorganizer->setWhatsThis(i18nc("@info:whatsthis", "Check to copy the alarm into KOrganizer's calendar"));
452  playout->addWidget(mShowInKorganizer);
453  }
454 
455  setButtonWhatsThis(Ok, i18nc("@info:whatsthis", "Schedule the alarm at the specified time."));
456 
457  // Hide optional controls
458  KConfigGroup config(KGlobal::config(), EDIT_MORE_GROUP);
459  showOptions(config.readEntry(EDIT_MORE_KEY, false));
460 
461  // Initialise the state of all controls according to the specified event, if any
462  initValues(event);
463  if (mTemplateName)
464  mTemplateName->setFocus();
465 
466  if (!mNewAlarm)
467  {
468  // Save the initial state of all controls so that we can later tell if they have changed
469  saveState((event && (mTemplate || !event->isTemplate())) ? event : 0);
470  contentsChanged(); // enable/disable OK button
471  }
472 
473  // Note the current desktop so that the dialog can be shown on it.
474  // If a main window is visible, the dialog will by KDE default always appear on its
475  // desktop. If the user invokes the dialog via the system tray on a different desktop,
476  // that can cause confusion.
477  mDesktop = KWindowSystem::currentDesktop();
478 }
479 
480 EditAlarmDlg::~EditAlarmDlg()
481 {
482  delete mSavedEvent;
483 }
484 
485 /******************************************************************************
486 * Initialise the dialog controls from the specified event.
487 */
488 void EditAlarmDlg::initValues(const KAEvent* event)
489 {
490  setReadOnly(mDesiredReadOnly);
491 
492  mChanged = false;
493  mOnlyDeferred = false;
494  mExpiredRecurrence = false;
495  mLateCancel->showAutoClose(false);
496  bool deferGroupVisible = false;
497  if (event)
498  {
499  // Set the values to those for the specified event
500  if (mTemplate)
501  mTemplateName->setText(event->templateName());
502  bool recurs = event->recurs();
503  if ((recurs || event->repetition()) && !mTemplate && event->deferred())
504  {
505  deferGroupVisible = true;
506  mDeferDateTime = event->deferDateTime();
507  mDeferTimeLabel->setText(mDeferDateTime.formatLocale());
508  mDeferGroup->show();
509  }
510  if (mTemplate)
511  {
512  // Editing a template
513  int afterTime = event->isTemplate() ? event->templateAfterTime() : -1;
514  bool noTime = !afterTime;
515  bool useTime = !event->mainDateTime().isDateOnly();
516  RadioButton* button = noTime ? mTemplateDefaultTime :
517  (afterTime > 0) ? mTemplateUseTimeAfter :
518  useTime ? mTemplateUseTime : mTemplateAnyTime;
519  button->setChecked(true);
520  mTemplateTimeAfter->setValue(afterTime > 0 ? afterTime : 1);
521  if (!noTime && useTime)
522  mTemplateTime->setValue(event->mainDateTime().kDateTime().time());
523  else
524  mTemplateTime->setValue(0);
525  }
526  else
527  {
528  if (event->isTemplate())
529  {
530  // Initialising from an alarm template: use current date
531  KDateTime now = KDateTime::currentDateTime(Preferences::timeZone());
532  int afterTime = event->templateAfterTime();
533  if (afterTime >= 0)
534  {
535  mTimeWidget->setDateTime(now.addSecs(afterTime * 60));
536  mTimeWidget->selectTimeFromNow();
537  }
538  else
539  {
540  KDateTime dt = event->startDateTime().kDateTime();
541  dt.setTimeSpec(Preferences::timeZone());
542  QDate d = now.date();
543  if (!dt.isDateOnly() && now.time() >= dt.time())
544  d = d.addDays(1); // alarm time has already passed, so use tomorrow
545  dt.setDate(d);
546  mTimeWidget->setDateTime(dt);
547  }
548  }
549  else
550  {
551  mExpiredRecurrence = recurs && event->mainExpired();
552  mTimeWidget->setDateTime(recurs || event->category() == CalEvent::ARCHIVED ? event->startDateTime()
553  : event->mainExpired() ? event->deferDateTime() : event->mainDateTime());
554  }
555  }
556 
557  KAEvent::SubAction action = event->actionSubType();
558  AlarmText altext;
559  if (event->commandScript())
560  altext.setScript(event->cleanText());
561  else
562  altext.setText(event->cleanText());
563  setAction(action, altext);
564 
565  mLateCancel->setMinutes(event->lateCancel(), event->startDateTime().isDateOnly(),
566  TimePeriod::HoursMinutes);
567  if (mShowInKorganizer)
568  mShowInKorganizer->setChecked(event->copyToKOrganizer());
569  type_initValues(event);
570  mRecurrenceEdit->set(*event); // must be called after mTimeWidget is set up, to ensure correct date-only enabling
571  mTabs->setTabText(mRecurPageIndex, recurText(*event));
572  }
573  else
574  {
575  // Set the values to their defaults
576  KDateTime defaultTime = KDateTime::currentUtcDateTime().addSecs(60).toTimeSpec(Preferences::timeZone());
577  if (mTemplate)
578  {
579  mTemplateDefaultTime->setChecked(true);
580  mTemplateTime->setValue(0);
581  mTemplateTimeAfter->setValue(1);
582  }
583  else
584  mTimeWidget->setDateTime(defaultTime);
585  mLateCancel->setMinutes((Preferences::defaultLateCancel() ? 1 : 0), false, TimePeriod::HoursMinutes);
586  if (mShowInKorganizer)
587  mShowInKorganizer->setChecked(Preferences::defaultCopyToKOrganizer());
588  type_initValues(0);
589  mRecurrenceEdit->setDefaults(defaultTime); // must be called after mTimeWidget is set up, to ensure correct date-only enabling
590  slotRecurFrequencyChange(); // update the Recurrence text
591  }
592  if (mReminder && mTimeWidget)
593  mReminder->setDefaultUnits(mTimeWidget->getDateTime(0, false, false));
594 
595  if (!deferGroupVisible && mDeferGroup)
596  mDeferGroup->hide();
597 
598  bool empty = AlarmCalendar::resources()->events(CalEvent::TEMPLATE).isEmpty();
599  enableButton(Help, !empty); // Load Templates button
600 }
601 
602 /******************************************************************************
603 * Initialise various values in the New Alarm dialogue.
604 */
605 void EditAlarmDlg::setTime(const DateTime& start)
606 {
607  mTimeWidget->setDateTime(start);
608 }
609 void EditAlarmDlg::setRecurrence(const KARecurrence& recur, int subRepeatInterval, int subRepeatCount)
610 {
611  KAEvent event;
612  event.setTime(mTimeWidget->getDateTime(0, false, false));
613  event.setRecurrence(recur);
614  event.setRepetition(Repetition(subRepeatInterval, subRepeatCount - 1));
615  mRecurrenceEdit->set(event);
616 }
617 void EditAlarmDlg::setRepeatAtLogin()
618 {
619  mRecurrenceEdit->setRepeatAtLogin();
620 }
621 void EditAlarmDlg::setLateCancel(int minutes)
622 {
623  mLateCancel->setMinutes(minutes, mTimeWidget->getDateTime(0, false, false).isDateOnly(),
624  TimePeriod::HoursMinutes);
625 }
626 void EditAlarmDlg::setShowInKOrganizer(bool show)
627 {
628  mShowInKorganizer->setChecked(show);
629 }
630 
631 /******************************************************************************
632 * Set the read-only status of all non-template controls.
633 */
634 void EditAlarmDlg::setReadOnly(bool readOnly)
635 {
636  mReadOnly = readOnly;
637 
638  if (mTimeWidget)
639  mTimeWidget->setReadOnly(readOnly);
640  mLateCancel->setReadOnly(readOnly);
641  if (mDeferChangeButton)
642  {
643  if (readOnly)
644  mDeferChangeButton->hide();
645  else
646  mDeferChangeButton->show();
647  }
648  if (mShowInKorganizer)
649  mShowInKorganizer->setReadOnly(readOnly);
650 }
651 
652 /******************************************************************************
653 * Save the state of all controls.
654 */
655 void EditAlarmDlg::saveState(const KAEvent* event)
656 {
657  delete mSavedEvent;
658  mSavedEvent = 0;
659  if (event)
660  mSavedEvent = new KAEvent(*event);
661  if (mTemplate)
662  {
663  mSavedTemplateName = mTemplateName->text();
664  mSavedTemplateTimeType = mTemplateTimeGroup->checkedButton();
665  mSavedTemplateTime = mTemplateTime->time();
666  mSavedTemplateAfterTime = mTemplateTimeAfter->value();
667  }
668  checkText(mSavedTextFileCommandMessage, false);
669  if (mTimeWidget)
670  mSavedDateTime = mTimeWidget->getDateTime(0, false, false);
671  mSavedLateCancel = mLateCancel->minutes();
672  if (mShowInKorganizer)
673  mSavedShowInKorganizer = mShowInKorganizer->isChecked();
674  mSavedRecurrenceType = mRecurrenceEdit->repeatType();
675  mSavedDeferTime = mDeferDateTime.kDateTime();
676 }
677 
678 /******************************************************************************
679 * Check whether any of the controls has changed state since the dialog was
680 * first displayed.
681 * Reply = true if any non-deferral controls have changed, or if it's a new event.
682 * = false if no non-deferral controls have changed. In this case,
683 * mOnlyDeferred indicates whether deferral controls may have changed.
684 */
685 bool EditAlarmDlg::stateChanged() const
686 {
687  mChanged = true;
688  mOnlyDeferred = false;
689  if (!mSavedEvent)
690  return true;
691  QString textFileCommandMessage;
692  checkText(textFileCommandMessage, false);
693  if (mTemplate)
694  {
695  if (mSavedTemplateName != mTemplateName->text()
696  || mSavedTemplateTimeType != mTemplateTimeGroup->checkedButton()
697  || (mTemplateUseTime->isChecked() && mSavedTemplateTime != mTemplateTime->time())
698  || (mTemplateUseTimeAfter->isChecked() && mSavedTemplateAfterTime != mTemplateTimeAfter->value()))
699  return true;
700  }
701  else
702  {
703  KDateTime dt = mTimeWidget->getDateTime(0, false, false);
704  if (mSavedDateTime.timeSpec() != dt.timeSpec() || mSavedDateTime != dt)
705  return true;
706  }
707  if (mSavedLateCancel != mLateCancel->minutes()
708  || (mShowInKorganizer && mSavedShowInKorganizer != mShowInKorganizer->isChecked())
709  || textFileCommandMessage != mSavedTextFileCommandMessage
710  || mSavedRecurrenceType != mRecurrenceEdit->repeatType())
711  return true;
712  if (type_stateChanged())
713  return true;
714  if (mRecurrenceEdit->stateChanged())
715  return true;
716  if (mSavedEvent && mSavedEvent->deferred())
717  mOnlyDeferred = true;
718  mChanged = false;
719  return false;
720 }
721 
722 /******************************************************************************
723 * Called whenever any of the controls changes state.
724 * Enable or disable the OK button depending on whether any controls have a
725 * different state from their initial state.
726 */
727 void EditAlarmDlg::contentsChanged()
728 {
729  // Don't do anything if it's a new alarm or we're still initialising
730  // (i.e. mSavedEvent null).
731  if (mSavedEvent && button(Ok))
732  button(Ok)->setEnabled(stateChanged() || mDeferDateTime.kDateTime() != mSavedDeferTime);
733 }
734 
735 /******************************************************************************
736 * Get the currently entered dialog data.
737 * The data is returned in the supplied KAEvent instance.
738 * Reply = false if the only change has been to an existing deferral.
739 */
740 #ifdef USE_AKONADI
741 bool EditAlarmDlg::getEvent(KAEvent& event, Akonadi::Collection& collection)
742 #else
743 bool EditAlarmDlg::getEvent(KAEvent& event, AlarmResource*& resource)
744 #endif
745 {
746 #ifdef USE_AKONADI
747  collection = mCollection;
748 #else
749  resource = mResource;
750 #endif
751  if (mChanged)
752  {
753  // It's a new event, or the edit controls have changed
754  setEvent(event, mAlarmMessage, false);
755  return true;
756  }
757 
758  // Only the deferral time may have changed
759  event = *mSavedEvent;
760  if (mOnlyDeferred)
761  {
762  // Just modify the original event, to avoid expired recurring events
763  // being returned as rubbish.
764  if (mDeferDateTime.isValid())
765  event.defer(mDeferDateTime, event.reminderDeferral(), false);
766  else
767  event.cancelDefer();
768  }
769  return false;
770 }
771 
772 /******************************************************************************
773 * Extract the data in the dialog and set up a KAEvent from it.
774 * If 'trial' is true, the event is set up for a simple one-off test, ignoring
775 * recurrence, reminder, template etc. data.
776 */
777 void EditAlarmDlg::setEvent(KAEvent& event, const QString& text, bool trial)
778 {
779  KDateTime dt;
780  if (!trial)
781  {
782  if (!mTemplate)
783  dt = mAlarmDateTime.effectiveKDateTime();
784  else if (mTemplateUseTime->isChecked())
785  dt = KDateTime(QDate(2000,1,1), mTemplateTime->time());
786  }
787 
788  int lateCancel = (trial || !mLateCancel->isEnabled()) ? 0 : mLateCancel->minutes();
789  type_setEvent(event, dt, text, lateCancel, trial);
790 
791  if (!trial)
792  {
793  if (mRecurrenceEdit->repeatType() != RecurrenceEdit::NO_RECUR)
794  {
795  mRecurrenceEdit->updateEvent(event, !mTemplate);
796  KDateTime now = KDateTime::currentDateTime(mAlarmDateTime.timeSpec());
797  bool dateOnly = mAlarmDateTime.isDateOnly();
798  if ((dateOnly && mAlarmDateTime.date() < now.date())
799  || (!dateOnly && mAlarmDateTime.kDateTime() < now))
800  {
801  // A timed recurrence has an entered start date which has
802  // already expired, so we must adjust the next repetition.
803  event.setNextOccurrence(now);
804  }
805  mAlarmDateTime = event.startDateTime();
806  if (mDeferDateTime.isValid() && mDeferDateTime < mAlarmDateTime)
807  {
808  bool deferral = true;
809  bool deferReminder = false;
810  int reminder = mReminder ? mReminder->minutes() : 0;
811  if (reminder)
812  {
813  DateTime remindTime = mAlarmDateTime.addMins(-reminder);
814  if (mDeferDateTime >= remindTime)
815  {
816  if (remindTime > KDateTime::currentUtcDateTime())
817  deferral = false; // ignore deferral if it's after next reminder
818  else if (mDeferDateTime > remindTime)
819  deferReminder = true; // it's the reminder which is being deferred
820  }
821  }
822  if (deferral)
823  event.defer(mDeferDateTime, deferReminder, false);
824  }
825  }
826  if (mTemplate)
827  {
828  int afterTime = mTemplateDefaultTime->isChecked() ? 0
829  : mTemplateUseTimeAfter->isChecked() ? mTemplateTimeAfter->value() : -1;
830  event.setTemplate(mTemplateName->text(), afterTime);
831  }
832  }
833 }
834 
835 /******************************************************************************
836 * Get the currently specified alarm flag bits.
837 */
838 KAEvent::Flags EditAlarmDlg::getAlarmFlags() const
839 {
840  KAEvent::Flags flags(0);
841  if (mShowInKorganizer && mShowInKorganizer->isEnabled() && mShowInKorganizer->isChecked())
842  flags |= KAEvent::COPY_KORGANIZER;
843  if (mRecurrenceEdit->repeatType() == RecurrenceEdit::AT_LOGIN)
844  flags |= KAEvent::REPEAT_AT_LOGIN;
845  if (mTemplate ? mTemplateAnyTime->isChecked() : mAlarmDateTime.isDateOnly())
846  flags |= KAEvent::ANY_TIME;
847  return flags;
848 }
849 
850 /******************************************************************************
851 * Called when the dialog is displayed.
852 * The first time through, sets the size to the same as the last time it was
853 * displayed.
854 */
855 void EditAlarmDlg::showEvent(QShowEvent* se)
856 {
857  KDialog::showEvent(se);
858  if (!mDeferGroupHeight)
859  {
860  if (mDeferGroup)
861  mDeferGroupHeight = mDeferGroup->height() + spacingHint();
862  QSize s;
863  if (KAlarm::readConfigWindowSize(mTemplate ? TEMPLATE_DIALOG_NAME : EDIT_DIALOG_NAME, s))
864  {
865  bool defer = mDeferGroup && !mDeferGroup->isHidden();
866  s.setHeight(s.height() + (defer ? mDeferGroupHeight : 0));
867  if (!defer)
868  mTabScrollGroup->setSized();
869  resize(s);
870  }
871  }
872  slotResize();
873  KWindowSystem::setOnDesktop(winId(), mDesktop); // ensure it displays on the desktop expected by the user
874 }
875 
876 /******************************************************************************
877 * Called when the dialog is closed.
878 */
879 void EditAlarmDlg::closeEvent(QCloseEvent* ce)
880 {
881  emit rejected();
882  KDialog::closeEvent(ce);
883 }
884 
885 /******************************************************************************
886 * Update the tab sizes (again) and if the resized dialog height is greater
887 * than the minimum, resize it again. This is necessary because (a) resizing
888 * tabs doesn't always work properly the first time, and (b) resizing to the
889 * minimum size hint doesn't always work either.
890 */
891 void EditAlarmDlg::slotResize()
892 {
893  QSize s = mTabScrollGroup->adjustSize(true);
894  s = minimumSizeHint();
895  if (height() > s.height())
896  {
897  // Resize to slightly greater than the minimum height.
898  // This is for some unknown reason necessary, since
899  // sometimes resizing to the minimum height fails.
900  resize(s.width(), s.height() + 2);
901  }
902 }
903 
904 /******************************************************************************
905 * Called when the dialog's size has changed.
906 * Records the new size (adjusted to ignore the optional height of the deferred
907 * time edit widget) in the config file.
908 */
909 void EditAlarmDlg::resizeEvent(QResizeEvent* re)
910 {
911  if (isVisible() && mDeferGroupHeight)
912  {
913  QSize s = re->size();
914  s.setHeight(s.height() - (!mDeferGroup || mDeferGroup->isHidden() ? 0 : mDeferGroupHeight));
915  KAlarm::writeConfigWindowSize(mTemplate ? TEMPLATE_DIALOG_NAME : EDIT_DIALOG_NAME, s);
916  }
917  KDialog::resizeEvent(re);
918 }
919 
920 /******************************************************************************
921 * Called when any button is clicked.
922 */
923 void EditAlarmDlg::slotButtonClicked(int button)
924 {
925  if (button == Ok)
926  {
927  if (validate())
928  accept();
929  }
930  else
931  KDialog::slotButtonClicked(button);
932 }
933 
934 /******************************************************************************
935 * Called when the OK button is clicked.
936 * Validate the input data.
937 */
938 bool EditAlarmDlg::validate()
939 {
940  if (!stateChanged())
941  {
942  // No changes have been made except possibly to an existing deferral
943  if (!mOnlyDeferred)
944  reject();
945  return mOnlyDeferred;
946  }
947  RecurrenceEdit::RepeatType recurType = mRecurrenceEdit->repeatType();
948  if (mTimeWidget
949  && mTabs->currentIndex() == mRecurPageIndex && recurType == RecurrenceEdit::AT_LOGIN)
950  mTimeWidget->setDateTime(mRecurrenceEdit->endDateTime());
951  bool timedRecurrence = mRecurrenceEdit->isTimedRepeatType(); // does it recur other than at login?
952  if (mTemplate)
953  {
954  // Check that the template name is not blank and is unique
955  QString errmsg;
956  QString name = mTemplateName->text();
957  if (name.isEmpty())
958  errmsg = i18nc("@info", "You must enter a name for the alarm template");
959  else if (name != mSavedTemplateName)
960  {
961  if (AlarmCalendar::resources()->templateEvent(name))
962  errmsg = i18nc("@info", "Template name is already in use");
963  }
964  if (!errmsg.isEmpty())
965  {
966  mTemplateName->setFocus();
967  KAMessageBox::sorry(this, errmsg);
968  return false;
969  }
970  }
971  else if (mTimeWidget)
972  {
973  QWidget* errWidget;
974  mAlarmDateTime = mTimeWidget->getDateTime(0, !timedRecurrence, false, &errWidget);
975  if (errWidget)
976  {
977  // It's more than just an existing deferral being changed, so the time matters
978  mTabs->setCurrentIndex(mMainPageIndex);
979  errWidget->setFocus();
980  mTimeWidget->getDateTime(); // display the error message now
981  return false;
982  }
983  }
984  if (!type_validate(false))
985  return false;
986 
987  if (!mTemplate)
988  {
989  if (mChanged && mRecurrenceEdit->repeatType() != RecurrenceEdit::NO_RECUR)
990  {
991  // Check whether the start date/time must be adjusted
992  // to match the recurrence specification.
993  DateTime dt = mAlarmDateTime; // setEvent() changes mAlarmDateTime
994  KAEvent event;
995  setEvent(event, mAlarmMessage, false);
996  mAlarmDateTime = dt; // restore
997  KDateTime pre = dt.effectiveKDateTime();
998  bool dateOnly = dt.isDateOnly();
999  if (dateOnly)
1000  pre = pre.addDays(-1);
1001  else
1002  pre = pre.addSecs(-1);
1003  DateTime next;
1004  event.nextOccurrence(pre, next, KAEvent::IGNORE_REPETITION);
1005  if (next != dt)
1006  {
1007  QString prompt = dateOnly ? i18nc("@info The parameter is a date value",
1008  "The start date does not match the alarm's recurrence pattern, "
1009  "so it will be adjusted to the date of the next recurrence (%1).",
1010  KGlobal::locale()->formatDate(next.date(), KLocale::ShortDate))
1011  : i18nc("@info The parameter is a date/time value",
1012  "The start date/time does not match the alarm's recurrence pattern, "
1013  "so it will be adjusted to the date/time of the next recurrence (%1).",
1014  KGlobal::locale()->formatDateTime(next.kDateTime(), KLocale::ShortDate));
1015  if (KAMessageBox::warningContinueCancel(this, prompt) != KMessageBox::Continue)
1016  return false;
1017  }
1018  }
1019 
1020  if (timedRecurrence)
1021  {
1022  KAEvent event;
1023 #ifdef USE_AKONADI
1024  Akonadi::Collection c;
1025  getEvent(event, c); // this may adjust mAlarmDateTime
1026 #else
1027  AlarmResource* r;
1028  getEvent(event, r); // this may adjust mAlarmDateTime
1029 #endif
1030  KDateTime now = KDateTime::currentDateTime(mAlarmDateTime.timeSpec());
1031  bool dateOnly = mAlarmDateTime.isDateOnly();
1032  if ((dateOnly && mAlarmDateTime.date() < now.date())
1033  || (!dateOnly && mAlarmDateTime.kDateTime() < now))
1034  {
1035  // A timed recurrence has an entered start date which
1036  // has already expired, so we must adjust it.
1037  if (event.nextOccurrence(now, mAlarmDateTime, KAEvent::ALLOW_FOR_REPETITION) == KAEvent::NO_OCCURRENCE)
1038  {
1039  KAMessageBox::sorry(this, i18nc("@info", "Recurrence has already expired"));
1040  return false;
1041  }
1042  if (event.workTimeOnly() && !event.nextTrigger(KAEvent::DISPLAY_TRIGGER).isValid())
1043  {
1044  if (KAMessageBox::warningContinueCancel(this, i18nc("@info", "The alarm will never occur during working hours"))
1045  != KMessageBox::Continue)
1046  return false;
1047  }
1048  }
1049  }
1050  QString errmsg;
1051  QWidget* errWidget = mRecurrenceEdit->checkData(mAlarmDateTime.effectiveKDateTime(), errmsg);
1052  if (errWidget)
1053  {
1054  mTabs->setCurrentIndex(mRecurPageIndex);
1055  errWidget->setFocus();
1056  KAMessageBox::sorry(this, errmsg);
1057  return false;
1058  }
1059  }
1060  if (recurType != RecurrenceEdit::NO_RECUR)
1061  {
1062  KAEvent recurEvent;
1063  int longestRecurMinutes = -1;
1064  int reminder = mReminder ? mReminder->minutes() : 0;
1065  if (reminder && !mReminder->isOnceOnly())
1066  {
1067  mRecurrenceEdit->updateEvent(recurEvent, false);
1068  longestRecurMinutes = recurEvent.longestRecurrenceInterval().asSeconds() / 60;
1069  if (longestRecurMinutes && reminder >= longestRecurMinutes)
1070  {
1071  mTabs->setCurrentIndex(mMainPageIndex);
1072  mReminder->setFocusOnCount();
1073  KAMessageBox::sorry(this, i18nc("@info", "Reminder period must be less than the recurrence interval, unless <interface>%1</interface> is checked.",
1074  Reminder::i18n_chk_FirstRecurrenceOnly()));
1075  return false;
1076  }
1077  }
1078  if (mRecurrenceEdit->subRepetition())
1079  {
1080  if (longestRecurMinutes < 0)
1081  {
1082  mRecurrenceEdit->updateEvent(recurEvent, false);
1083  longestRecurMinutes = recurEvent.longestRecurrenceInterval().asSeconds() / 60;
1084  }
1085  if (longestRecurMinutes > 0
1086  && recurEvent.repetition().intervalMinutes() * recurEvent.repetition().count() >= longestRecurMinutes - reminder)
1087  {
1088  KAMessageBox::sorry(this, i18nc("@info", "The duration of a repetition within the recurrence must be less than the recurrence interval minus any reminder period"));
1089  mRecurrenceEdit->activateSubRepetition(); // display the alarm repetition dialog again
1090  return false;
1091  }
1092  if (!recurEvent.repetition().isDaily()
1093  && ((mTemplate && mTemplateAnyTime->isChecked()) || (!mTemplate && mAlarmDateTime.isDateOnly())))
1094  {
1095  KAMessageBox::sorry(this, i18nc("@info", "For a repetition within the recurrence, its period must be in units of days or weeks for a date-only alarm"));
1096  mRecurrenceEdit->activateSubRepetition(); // display the alarm repetition dialog again
1097  return false;
1098  }
1099  }
1100  }
1101  if (!checkText(mAlarmMessage))
1102  return false;
1103 
1104 #ifdef USE_AKONADI
1105  mCollection = Akonadi::Collection();
1106  // An item ID = -2 indicates that the caller already
1107  // knows which collection to use.
1108  if (mCollectionItemId >= -1)
1109  {
1110  if (mCollectionItemId >= 0)
1111  {
1112  mCollection = AlarmCalendar::resources()->collectionForEvent(mCollectionItemId);
1113  if (mCollection.isValid())
1114  {
1115  CalEvent::Type type = mTemplate ? CalEvent::TEMPLATE : CalEvent::ACTIVE;
1116  if (!(AkonadiModel::instance()->types(mCollection) & type))
1117  mCollection = Akonadi::Collection(); // event may have expired while dialog was open
1118  }
1119  }
1120  bool cancelled = false;
1121  CalEvent::Type type = mTemplate ? CalEvent::TEMPLATE : CalEvent::ACTIVE;
1122  if (CollectionControlModel::isWritableEnabled(mCollection, type) <= 0)
1123  mCollection = CollectionControlModel::destination(type, this, false, &cancelled);
1124  if (!mCollection.isValid())
1125  {
1126  if (!cancelled)
1127  KAMessageBox::sorry(this, i18nc("@info", "You must select a calendar to save the alarm in"));
1128  return false;
1129  }
1130  }
1131 #else
1132  mResource = 0;
1133  // A null resource event ID indicates that the caller already
1134  // knows which resource to use.
1135  if (!mResourceEventId.isNull())
1136  {
1137  if (!mResourceEventId.isEmpty())
1138  {
1139  mResource = AlarmCalendar::resources()->resourceForEvent(mResourceEventId);
1140  if (mResource)
1141  {
1142  CalEvent::Type type = mTemplate ? CalEvent::TEMPLATE : CalEvent::ACTIVE;
1143  if (mResource->alarmType() != type)
1144  mResource = 0; // event may have expired while dialog was open
1145  }
1146  }
1147  bool cancelled = false;
1148  if (!mResource || !mResource->writable())
1149  {
1150  CalEvent::Type type = mTemplate ? CalEvent::TEMPLATE : CalEvent::ACTIVE;
1151  mResource = AlarmResources::instance()->destination(type, this, false, &cancelled);
1152  }
1153  if (!mResource)
1154  {
1155  if (!cancelled)
1156  KAMessageBox::sorry(this, i18nc("@info", "You must select a calendar to save the alarm in"));
1157  return false;
1158  }
1159  }
1160 #endif
1161  return true;
1162 }
1163 
1164 /******************************************************************************
1165 * Called when the Try button is clicked.
1166 * Display/execute the alarm immediately for the user to check its configuration.
1167 */
1168 void EditAlarmDlg::slotTry()
1169 {
1170  QString text;
1171  if (checkText(text))
1172  {
1173  if (!type_validate(true))
1174  return;
1175  KAEvent event;
1176  setEvent(event, text, true);
1177  if (!mNewAlarm && !stateChanged())
1178  {
1179  // It's an existing alarm which hasn't been changed yet:
1180  // enable KALARM_UID environment variable to be set.
1181  event.setEventId(mEventId);
1182  }
1183  type_aboutToTry();
1184  void* result = theApp()->execAlarm(event, event.firstAlarm(), false, false);
1185  type_executedTry(text, result);
1186  }
1187 }
1188 
1189 /******************************************************************************
1190 * Called when the Load Template button is clicked.
1191 * Prompt to select a template and initialise the dialog with its contents.
1192 */
1193 void EditAlarmDlg::slotHelp()
1194 {
1195  KAEvent::Actions type;
1196  switch (mAlarmType)
1197  {
1198  case KAEvent::FILE:
1199  case KAEvent::MESSAGE: type = KAEvent::ACT_DISPLAY; break;
1200  case KAEvent::COMMAND: type = KAEvent::ACT_COMMAND; break;
1201  case KAEvent::EMAIL: type = KAEvent::ACT_EMAIL; break;
1202  case KAEvent::AUDIO: type = KAEvent::ACT_AUDIO; break;
1203  default:
1204  return;
1205  }
1206  // Use AutoQPointer to guard against crash on application exit while
1207  // the dialogue is still open. It prevents double deletion (both on
1208  // deletion of EditAlarmDlg, and on return from this function).
1209  AutoQPointer<TemplatePickDlg> dlg = new TemplatePickDlg(type, this);
1210  if (dlg->exec() == QDialog::Accepted)
1211 #ifdef USE_AKONADI
1212  {
1213  KAEvent event = dlg->selectedTemplate();
1214  initValues(&event);
1215  }
1216 #else
1217  initValues(dlg->selectedTemplate());
1218 #endif
1219 }
1220 
1221 /******************************************************************************
1222 * Called when the More Options or Less Options buttons are clicked.
1223 * Show/hide the optional options and swap the More/Less buttons, and save the
1224 * new setting as the default from now on.
1225 */
1226 void EditAlarmDlg::slotDefault()
1227 {
1228  showOptions(!mShowingMore);
1229  KConfigGroup config(KGlobal::config(), EDIT_MORE_GROUP);
1230  config.writeEntry(EDIT_MORE_KEY, mShowingMore);
1231 }
1232 
1233 /******************************************************************************
1234 * Show/hide the optional options and swap the More/Less buttons.
1235 */
1236 void EditAlarmDlg::showOptions(bool more)
1237 {
1238  kDebug() << (more ? "More" : "Less");
1239  if (more)
1240  {
1241  mMoreOptions->show();
1242  setButtonText(Default, i18nc("@action:button", "Less Options <<"));
1243  }
1244  else
1245  {
1246  mMoreOptions->hide();
1247  setButtonText(Default, i18nc("@action:button", "More Options >>"));
1248  }
1249  if (mTimeWidget)
1250  mTimeWidget->showMoreOptions(more);
1251  type_showOptions(more);
1252  mRecurrenceEdit->showMoreOptions(more);
1253  mShowingMore = more;
1254  QTimer::singleShot(0, this, SLOT(slotResize()));
1255 }
1256 
1257 /******************************************************************************
1258 * Called when the Change deferral button is clicked.
1259 */
1260 void EditAlarmDlg::slotEditDeferral()
1261 {
1262  if (!mTimeWidget)
1263  return;
1264  bool limit = true;
1265  Repetition repetition = mRecurrenceEdit->subRepetition();
1266  DateTime start = mSavedEvent->recurs() ? (mExpiredRecurrence ? DateTime() : mSavedEvent->mainDateTime())
1267  : mTimeWidget->getDateTime(0, !repetition, !mExpiredRecurrence);
1268  if (!start.isValid())
1269  {
1270  if (!mExpiredRecurrence)
1271  return;
1272  limit = false;
1273  }
1274  KDateTime now = KDateTime::currentUtcDateTime();
1275  if (limit)
1276  {
1277  if (repetition && start < now)
1278  {
1279  // Sub-repetition - find the time of the next one
1280  int repeatNum = repetition.isDaily()
1281  ? (start.daysTo(now) + repetition.intervalDays() - 1) / repetition.intervalDays()
1282  : (start.secsTo(now) + repetition.intervalSeconds() - 1) / repetition.intervalSeconds();
1283  if (repeatNum > repetition.count())
1284  {
1285  mTimeWidget->getDateTime(); // output the appropriate error message
1286  return;
1287  }
1288  start = repetition.duration(repeatNum).end(start.kDateTime());
1289  }
1290  }
1291 
1292  bool deferred = mDeferDateTime.isValid();
1293  // Use AutoQPointer to guard against crash on application exit while
1294  // the dialogue is still open. It prevents double deletion (both on
1295  // deletion of EditAlarmDlg, and on return from this function).
1296  AutoQPointer<DeferAlarmDlg> deferDlg = new DeferAlarmDlg((deferred ? mDeferDateTime : DateTime(now.addSecs(60).toTimeSpec(start.timeSpec()))),
1297  start.isDateOnly(), deferred, this);
1298  deferDlg->setObjectName(QLatin1String("EditDeferDlg")); // used by LikeBack
1299  if (limit)
1300  {
1301  // Don't allow deferral past the next recurrence
1302  int reminder = mReminder ? mReminder->minutes() : 0;
1303  if (reminder)
1304  {
1305  DateTime remindTime = start.addMins(-reminder);
1306  if (KDateTime::currentUtcDateTime() < remindTime)
1307  start = remindTime;
1308  }
1309  deferDlg->setLimit(start.addSecs(-60));
1310  }
1311  if (deferDlg->exec() == QDialog::Accepted)
1312  {
1313  mDeferDateTime = deferDlg->getDateTime();
1314  mDeferTimeLabel->setText(mDeferDateTime.isValid() ? mDeferDateTime.formatLocale() : QString());
1315  contentsChanged();
1316  }
1317 }
1318 
1319 /******************************************************************************
1320 * Called when the main page is shown.
1321 * Sets the focus widget to the first edit field.
1322 */
1323 void EditAlarmDlg::slotShowMainPage()
1324 {
1325  if (!mMainPageShown)
1326  {
1327  if (mTemplateName)
1328  mTemplateName->setFocus();
1329  mMainPageShown = true;
1330  }
1331  else
1332  {
1333  // Set scroll position to top, since it otherwise jumps randomly
1334  StackedScrollWidget* main = static_cast<StackedScrollWidget*>(mTabs->widget(0));
1335  main->verticalScrollBar()->setValue(0);
1336  }
1337  if (mTimeWidget)
1338  {
1339  if (!mReadOnly && mRecurPageShown && mRecurrenceEdit->repeatType() == RecurrenceEdit::AT_LOGIN)
1340  mTimeWidget->setDateTime(mRecurrenceEdit->endDateTime());
1341  if (mReadOnly || mRecurrenceEdit->isTimedRepeatType())
1342  mTimeWidget->setMinDateTime(); // don't set a minimum date/time
1343  else
1344  mTimeWidget->setMinDateTimeIsCurrent(); // set the minimum date/time to track the clock
1345  }
1346 }
1347 
1348 /******************************************************************************
1349 * Called when the recurrence edit page is shown.
1350 * The recurrence defaults are set to correspond to the start date.
1351 * The first time, for a new alarm, the recurrence end date is set according to
1352 * the alarm start time.
1353 */
1354 void EditAlarmDlg::slotShowRecurrenceEdit()
1355 {
1356  mRecurPageIndex = mTabs->currentIndex();
1357  if (!mReadOnly && !mTemplate)
1358  {
1359  mAlarmDateTime = mTimeWidget->getDateTime(0, false, false);
1360  KDateTime now = KDateTime::currentDateTime(mAlarmDateTime.timeSpec());
1361  bool expired = (mAlarmDateTime.effectiveKDateTime() < now);
1362  if (mRecurSetDefaultEndDate)
1363  {
1364  mRecurrenceEdit->setDefaultEndDate(expired ? now.date() : mAlarmDateTime.date());
1365  mRecurSetDefaultEndDate = false;
1366  }
1367  mRecurrenceEdit->setStartDate(mAlarmDateTime.date(), now.date());
1368  if (mRecurrenceEdit->repeatType() == RecurrenceEdit::AT_LOGIN)
1369  mRecurrenceEdit->setEndDateTime(expired ? now : mAlarmDateTime.kDateTime());
1370  }
1371  mRecurPageShown = true;
1372 }
1373 
1374 /******************************************************************************
1375 * Called when the recurrence type selection changes.
1376 * Enables/disables date-only alarms as appropriate.
1377 * Enables/disables controls depending on at-login setting.
1378 */
1379 void EditAlarmDlg::slotRecurTypeChange(int repeatType)
1380 {
1381  bool atLogin = (mRecurrenceEdit->repeatType() == RecurrenceEdit::AT_LOGIN);
1382  if (!mTemplate)
1383  {
1384  bool recurs = (mRecurrenceEdit->repeatType() != RecurrenceEdit::NO_RECUR);
1385  if (mDeferGroup)
1386  mDeferGroup->setEnabled(recurs);
1387  mTimeWidget->enableAnyTime(!recurs || repeatType != RecurrenceEdit::SUBDAILY);
1388  if (atLogin)
1389  {
1390  mAlarmDateTime = mTimeWidget->getDateTime(0, false, false);
1391  mRecurrenceEdit->setEndDateTime(mAlarmDateTime.kDateTime());
1392  }
1393  if (mReminder)
1394  mReminder->enableOnceOnly(recurs && !atLogin);
1395  }
1396  if (mReminder)
1397  mReminder->setAfterOnly(atLogin);
1398  mLateCancel->setEnabled(!atLogin);
1399  if (mShowInKorganizer)
1400  mShowInKorganizer->setEnabled(!atLogin);
1401  slotRecurFrequencyChange();
1402 }
1403 
1404 /******************************************************************************
1405 * Called when the recurrence frequency selection changes, or the sub-
1406 * repetition interval changes.
1407 * Updates the recurrence frequency text.
1408 */
1409 void EditAlarmDlg::slotRecurFrequencyChange()
1410 {
1411  slotSetSubRepetition();
1412  KAEvent event;
1413  mRecurrenceEdit->updateEvent(event, false);
1414  mTabs->setTabText(mRecurPageIndex, recurText(event));
1415 }
1416 
1417 /******************************************************************************
1418 * Called when the Repetition within Recurrence button has been pressed to
1419 * display the sub-repetition dialog.
1420 * Alarm repetition has the following restrictions:
1421 * 1) Not allowed for a repeat-at-login alarm
1422 * 2) For a date-only alarm, the repeat interval must be a whole number of days.
1423 * 3) The overall repeat duration must be less than the recurrence interval.
1424 */
1425 void EditAlarmDlg::slotSetSubRepetition()
1426 {
1427  bool dateOnly = mTemplate ? mTemplateAnyTime->isChecked() : mTimeWidget->anyTime();
1428  mRecurrenceEdit->setSubRepetition((mReminder ? mReminder->minutes() : 0), dateOnly);
1429 }
1430 
1431 /******************************************************************************
1432 * Called when one of the template time radio buttons is clicked,
1433 * to enable or disable the template time entry spin boxes.
1434 */
1435 void EditAlarmDlg::slotTemplateTimeType(QAbstractButton*)
1436 {
1437  mTemplateTime->setEnabled(mTemplateUseTime->isChecked());
1438  mTemplateTimeAfter->setEnabled(mTemplateUseTimeAfter->isChecked());
1439 }
1440 
1441 /******************************************************************************
1442 * Called when the "Any time" checkbox is toggled in the date/time widget.
1443 * Sets the advance reminder and late cancel units to days if any time is checked.
1444 */
1445 void EditAlarmDlg::slotAnyTimeToggled(bool anyTime)
1446 {
1447  if (mReminder && mReminder->isReminder())
1448  mReminder->setDateOnly(anyTime);
1449  mLateCancel->setDateOnly(anyTime);
1450 }
1451 
1452 bool EditAlarmDlg::dateOnly() const
1453 {
1454  return mTimeWidget ? mTimeWidget->anyTime() : mTemplateAnyTime->isChecked();
1455 }
1456 
1457 bool EditAlarmDlg::isTimedRecurrence() const
1458 {
1459  return mRecurrenceEdit->isTimedRepeatType();
1460 }
1461 
1462 void EditAlarmDlg::showMainPage()
1463 {
1464  mTabs->setCurrentIndex(mMainPageIndex);
1465 }
1466 
1467 // vim: et sw=4:
EditAlarmDlg::closeEvent
virtual void closeEvent(QCloseEvent *)
Definition: editdlg.cpp:879
CheckBox::setReadOnly
virtual void setReadOnly(bool readOnly)
EditAlarmDlg::mAlarmType
KAEvent::SubAction mAlarmType
Definition: editdlg.h:159
SpinBox2::setEnabled
virtual void setEnabled(bool enabled)
AlarmTimeWidget::setMinDateTimeIsCurrent
void setMinDateTimeIsCurrent()
Definition: alarmtimewidget.cpp:396
AlarmTimeWidget::i18n_TimeAfterPeriod
static QString i18n_TimeAfterPeriod()
Definition: alarmtimewidget.cpp:50
buttongroup.h
PreferencesBase::defaultCopyToKOrganizer
static bool defaultCopyToKOrganizer()
Get Show in KOrganizer.
Definition: kalarmconfig.h:1093
EDIT_MORE_KEY
static const char EDIT_MORE_KEY[]
Definition: editdlg.cpp:88
Reminder::setAfterOnly
void setAfterOnly(bool after)
Definition: reminder.cpp:102
EditCommandAlarmDlg
Definition: editdlgtypes.h:147
KVBox
EditAlarmDlg::RES_PROMPT
Definition: editdlg.h:67
EditAlarmDlg::lateCancel
LateCancelSelector * lateCancel() const
Definition: editdlg.h:129
EditAlarmDlg::slotTry
virtual void slotTry()
Definition: editdlg.cpp:1168
EditAlarmDlg::setTime
void setTime(const DateTime &)
Definition: editdlg.cpp:605
alarmtimewidget.h
TimeSpinBox
CollectionControlModel::isWritableEnabled
static int isWritableEnabled(const Akonadi::Collection &, CalEvent::Type)
Return whether a collection is both enabled and fully writable for a given alarm type, i.e.
Definition: collectionmodel.cpp:966
StackedScrollGroup::adjustSize
QSize adjustSize(bool force=false)
EditAlarmDlg::showEvent
virtual void showEvent(QShowEvent *)
Definition: editdlg.cpp:855
TimeEdit::setReadOnly
virtual void setReadOnly(bool readOnly)
EditAlarmDlg::type_createConfirmAckCheckbox
virtual CheckBox * type_createConfirmAckCheckbox(QWidget *parent)
Definition: editdlg.h:119
RecurrenceEdit::NO_RECUR
Definition: recurrenceedit.h:64
Reminder::i18n_chk_FirstRecurrenceOnly
static QString i18n_chk_FirstRecurrenceOnly()
Definition: reminder.cpp:49
RecurrenceEdit::updateEvent
void updateEvent(KAEvent &, bool adjustStart)
Write recurrence settings into an event.
Definition: recurrenceedit.cpp:944
text
virtual QByteArray text(quint32 serialNumber) const =0
PageFrame
Definition: editdlg_p.h:33
RadioButton
EditAlarmDlg::checkText
virtual bool checkText(QString &result, bool showErrorMessage=true) const =0
EditAlarmDlg::setLateCancel
void setLateCancel(int minutes)
Definition: editdlg.cpp:621
deferdlg.h
RecurrenceEdit::setStartDate
void setStartDate(const QDate &, const QDate &today)
Definition: recurrenceedit.cpp:686
AlarmCalendar::resources
static AlarmCalendar * resources()
Definition: alarmcalendar.h:130
LateCancelSelector::showAutoClose
void showAutoClose(bool show)
Definition: latecancel.cpp:147
QWidget
TimePeriod::HoursMinutes
EditAlarmDlg::~EditAlarmDlg
virtual ~EditAlarmDlg()
Definition: editdlg.cpp:480
QPushButton
latecancel.h
lineedit.h
AlarmTimeWidget::AT_TIME
Definition: alarmtimewidget.h:46
AlarmTimeWidget::enableAnyTime
void enableAnyTime(bool enable)
Definition: alarmtimewidget.cpp:502
alarmcalendar.h
AlarmTimeWidget
Definition: alarmtimewidget.h:41
KDialog
AlarmCalendar::resourceForEvent
AlarmResource * resourceForEvent(const QString &eventID) const
Definition: alarmcalendar.cpp:2120
DeferAlarmDlg
Definition: deferdlg.h:38
checkbox.h
AlarmTimeWidget::setMinDateTime
void setMinDateTime(const KDateTime &=KDateTime())
Definition: alarmtimewidget.cpp:409
AlarmCalendar::templateEvent
KAEvent * templateEvent(const QString &templateName)
Definition: alarmcalendar.cpp:1871
StackedScrollGroup
AlarmTimeWidget::setDateTime
void setDateTime(const DateTime &)
Definition: alarmtimewidget.cpp:358
RecurrenceEdit::endDateTime
KDateTime endDateTime() const
Definition: recurrenceedit.cpp:725
TemplatePickDlg
Definition: templatepickdlg.h:38
EditAlarmDlg::showMainPage
void showMainPage()
Definition: editdlg.cpp:1462
Reminder::setDateOnly
void setDateOnly(bool dateOnly)
Definition: reminder.cpp:192
EditAlarmDlg::type_executedTry
virtual void type_executedTry(const QString &text, void *obj)
Definition: editdlg.h:117
TimeEdit
kalarmapp.h
the KAlarm application object
EditAlarmDlg::EditAlarmDlg
EditAlarmDlg(bool Template, KAEvent::SubAction, QWidget *parent=0, GetResourceType=RES_PROMPT)
Definition: editdlg.cpp:144
EditAlarmDlg::contentsChanged
void contentsChanged()
Definition: editdlg.cpp:727
Reminder::setFocusOnCount
void setFocusOnCount()
Definition: reminder.cpp:200
templatepickdlg.h
TimeSpinBox::sizeHint
virtual QSize sizeHint() const
packedlayout.h
CheckBox
RecurrenceEdit::showMoreOptions
void showMoreOptions(bool)
Definition: recurrenceedit.cpp:397
autoqpointer.h
StackedScrollGroup::setSized
void setSized()
EditAlarmDlg::setRepeatAtLogin
void setRepeatAtLogin()
Definition: editdlg.cpp:617
EditAlarmDlg::slotButtonClicked
virtual void slotButtonClicked(int button)
Definition: editdlg.cpp:923
Preferences::timeZone
static KTimeZone timeZone(bool reload=false)
Definition: preferences.cpp:122
SpinBox2::setReadOnly
virtual void setReadOnly(bool readOnly)
maillistdrag.h
CollectionControlModel::destination
static Akonadi::Collection destination(CalEvent::Type, QWidget *promptParent=0, bool noPrompt=false, bool *cancelled=0)
Find the collection to be used to store an event of a given type.
Definition: collectionmodel.cpp:1178
Reminder::setDefaultUnits
void setDefaultUnits(const KDateTime &)
Definition: reminder.cpp:219
EditAlarmDlg::getAlarmFlags
virtual KAEvent::Flags getAlarmFlags() const
Definition: editdlg.cpp:838
RecurrenceEdit::repeatType
RepeatType repeatType() const
Definition: recurrenceedit.h:78
AkonadiModel::instance
static AkonadiModel * instance()
Definition: akonadimodel.cpp:83
EditAlarmDlg::setAction
virtual void setAction(KAEvent::SubAction, const AlarmText &=AlarmText())=0
mainwindow.h
main application window
RecurrenceEdit::subRepetition
Repetition subRepetition() const
Definition: recurrenceedit.cpp:544
EditAlarmDlg::type_aboutToTry
virtual void type_aboutToTry()
Definition: editdlg.h:116
EditAlarmDlg::setShowInKOrganizer
void setShowInKOrganizer(bool)
Definition: editdlg.cpp:626
QGroupBox
EditAlarmDlg::create
static EditAlarmDlg * create(bool Template, Type, QWidget *parent=0, GetResourceType=RES_PROMPT)
Definition: editdlg.cpp:106
PackedLayout
EditAlarmDlg::getEvent
bool getEvent(KAEvent &, AlarmResource *&)
Definition: editdlg.cpp:743
ButtonGroup::addButton
void addButton(QAbstractButton *button)
messagebox.h
RecurrenceEdit::isTimedRepeatType
bool isTimedRepeatType() const
Definition: recurrenceedit.h:79
EditAlarmDlg::dateOnly
bool dateOnly() const
Definition: editdlg.cpp:1452
LateCancelSelector
Definition: latecancel.h:33
theApp
KAlarmApp * theApp()
Definition: kalarmapp.h:259
RecurrenceEdit::stateChanged
bool stateChanged() const
Definition: recurrenceedit.cpp:1070
Reminder::isReminder
bool isReminder() const
Definition: reminder.cpp:124
maxDelayTime
static const int maxDelayTime
Definition: editdlg.cpp:89
RecurrenceEdit
Definition: recurrenceedit.h:59
reminder.h
SpinBox2::value
int value() const
AutoQPointer
editdlgtypes.h
preferences.h
EditAlarmDlg::type_stateChanged
virtual bool type_stateChanged() const =0
RecurrenceEdit::SUBDAILY
Definition: recurrenceedit.h:64
TimeSpinBox::setValue
virtual void setValue(int minutes)
StackedScrollWidget
EditAlarmDlg::setReadOnly
virtual void setReadOnly(bool readOnly)=0
Definition: editdlg.cpp:634
AlarmTimeWidget::getDateTime
KDateTime getDateTime(int *minsFromNow=0, bool checkExpired=true, bool showErrorMessage=true, QWidget **errorWidget=0) const
Definition: alarmtimewidget.cpp:280
LateCancelSelector::setReadOnly
void setReadOnly(bool)
Definition: latecancel.cpp:110
PreferencesBase::defaultLateCancel
static int defaultLateCancel()
Get Cancel if late (minutes)
Definition: kalarmconfig.h:1012
LateCancelSelector::setDateOnly
void setDateOnly(bool dateOnly)
Definition: latecancel.cpp:137
EditEmailAlarmDlg
Definition: editdlgtypes.h:199
EditAlarmDlg::isTimedRecurrence
bool isTimedRecurrence() const
Definition: editdlg.cpp:1457
EditAlarmDlg::init
void init(const KAEvent *event)
Definition: editdlg.cpp:234
collectionmodel.h
RadioButton::setReadOnly
virtual void setReadOnly(bool readOnly)
KAMessageBox::warningContinueCancel
static int warningContinueCancel(QWidget *parent, ButtonCode defaultButton, const QString &text, const QString &caption=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const QString &dontAskAgainName=QString())
EditAlarmDlg::type_showOptions
virtual void type_showOptions(bool more)=0
KLineEdit
RecurrenceEdit::setDefaults
void setDefaults(const KDateTime &from)
Set widgets to default values.
Definition: recurrenceedit.cpp:735
LateCancelSelector::minutes
int minutes() const
Definition: latecancel.cpp:121
RecurrenceEdit::activateSubRepetition
void activateSubRepetition()
Definition: recurrenceedit.cpp:581
EditAlarmDlg::setRecurrence
void setRecurrence(const KARecurrence &, int subRepeatInterval, int subRepeatCount)
Definition: editdlg.cpp:609
EditAlarmDlg::slotDefault
virtual void slotDefault()
Definition: editdlg.cpp:1226
EditAlarmDlg::Type
Type
Definition: editdlg.h:65
functions.h
miscellaneous functions
KAMessageBox::sorry
static void sorry(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Options(Notify|WindowModal))
EditAlarmDlg
Definition: editdlg.h:61
TimeEdit::setValue
virtual void setValue(int minutes)
EditAlarmDlg::type_caption
virtual QString type_caption() const =0
Reminder::isOnceOnly
bool isOnceOnly() const
Definition: reminder.cpp:129
EditAlarmDlg::RES_USE_EVENT_ID
Definition: editdlg.h:68
RecurrenceEdit::setRepeatAtLogin
void setRepeatAtLogin()
Initialise with repeat-at-login selected, instead of calling set().
Definition: recurrenceedit.cpp:797
kalarm.h
EditAlarmDlg::type_initValues
virtual void type_initValues(const KAEvent *)=0
QLabel
EditAlarmDlg::reminder
Reminder * reminder() const
Definition: editdlg.h:128
RecurrenceEdit::AT_LOGIN
Definition: recurrenceedit.h:64
EditDisplayAlarmDlg
Definition: editdlgtypes.h:57
EditAlarmDlg::type_setEvent
virtual void type_setEvent(KAEvent &, const KDateTime &, const QString &text, int lateCancel, bool trial)=0
KAlarmApp::execAlarm
void * execAlarm(KAEvent &, const KAAlarm &, bool reschedule, bool allowDefer=true, bool noPreAction=false)
Definition: kalarmapp.cpp:1838
AlarmCalendar::events
KAEvent::List events(CalEvent::Types s=CalEvent::EMPTY) const
Definition: alarmcalendar.h:96
Reminder::minutes
int minutes() const
Definition: reminder.cpp:164
RecurrenceEdit::checkData
QWidget * checkData(const KDateTime &startDateTime, QString &errorMessage) const
Definition: recurrenceedit.cpp:410
KHBox
Reminder::enableOnceOnly
void enableOnceOnly(bool enable)
Definition: reminder.cpp:143
shellprocess.h
EditAlarmDlg::slotHelp
virtual void slotHelp()
Definition: editdlg.cpp:1193
EditAlarmDlg::type_init
virtual void type_init(QWidget *parent, QVBoxLayout *frameLayout)=0
EditAlarmDlg::resizeEvent
virtual void resizeEvent(QResizeEvent *)
Definition: editdlg.cpp:909
EditAlarmDlg::saveState
virtual void saveState(const KAEvent *)=0
Definition: editdlg.cpp:655
EditAlarmDlg::i18n_chk_ShowInKOrganizer
static QString i18n_chk_ShowInKOrganizer()
Definition: editdlg.cpp:103
RecurrenceEdit::setDefaultEndDate
void setDefaultEndDate(const QDate &)
Definition: recurrenceedit.cpp:710
TimeSpinBox::shiftWhatsThis
static QString shiftWhatsThis()
LateCancelSelector::setMinutes
void setMinutes(int Minutes, bool dateOnly, TimePeriod::Units defaultUnits)
Definition: latecancel.cpp:126
EditAlarmDlg::RES_IGNORE
Definition: editdlg.h:69
AlarmTimeWidget::setReadOnly
void setReadOnly(bool)
Definition: alarmtimewidget.cpp:245
main
int main(int argc, char *argv[])
Definition: main.cpp:37
AlarmTimeWidget::anyTime
bool anyTime() const
Definition: alarmtimewidget.h:60
QFrame
TimeEdit::time
QTime time() const
stackedwidgets.h
spinbox.h
EditAlarmDlg::GetResourceType
GetResourceType
Definition: editdlg.h:66
timeedit.h
timespinbox.h
AlarmTimeWidget::showMoreOptions
void showMoreOptions(bool)
Definition: alarmtimewidget.cpp:643
EDIT_MORE_GROUP
static const char EDIT_MORE_GROUP[]
Definition: editdlg.cpp:87
EDIT_DIALOG_NAME
static const char EDIT_DIALOG_NAME[]
Definition: editdlg.cpp:85
recurText
QString recurText(const KAEvent &event)
Definition: editdlg.cpp:91
radiobutton.h
EditAlarmDlg::type_validate
virtual bool type_validate(bool trial)=0
RecurrenceEdit::set
void set(const KAEvent &)
Initialise according to a specified event.
Definition: recurrenceedit.cpp:806
EditAudioAlarmDlg
Definition: editdlgtypes.h:274
RecurrenceEdit::RepeatType
RepeatType
Definition: recurrenceedit.h:64
AlarmTimeWidget::selectTimeFromNow
void selectTimeFromNow(int minutes=0)
Definition: alarmtimewidget.cpp:264
EditAlarmDlg::createReminder
virtual Reminder * createReminder(QWidget *parent)
Definition: editdlg.h:118
RecurrenceEdit::setSubRepetition
void setSubRepetition(int reminderMinutes, bool dateOnly)
Definition: recurrenceedit.cpp:557
RecurrenceEdit::setEndDateTime
void setEndDateTime(const KDateTime &)
Definition: recurrenceedit.cpp:716
recurrenceedit.h
ButtonGroup
TEMPLATE_DIALOG_NAME
static const char TEMPLATE_DIALOG_NAME[]
Definition: editdlg.cpp:86
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:59:10 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kalarm

Skip menu "kalarm"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal