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

kalarm

  • sources
  • kde-4.14
  • 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-2015 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.h"
23 #include "editdlg_p.h"
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 <QGroupBox>
69 #include <QPushButton>
70 #include <QGridLayout>
71 #include <QHBoxLayout>
72 #include <QVBoxLayout>
73 #include <QResizeEvent>
74 #include <QShowEvent>
75 #include <QScrollBar>
76 #include <QTimer>
77 
78 using namespace KCal;
79 using namespace KAlarmCal;
80 
81 static const char EDIT_DIALOG_NAME[] = "EditDialog";
82 static const char TEMPLATE_DIALOG_NAME[] = "EditTemplateDialog";
83 static const char EDIT_MORE_GROUP[] = "ShowOpts";
84 static const char EDIT_MORE_KEY[] = "EditMore";
85 static const int maxDelayTime = 99*60 + 59; // < 100 hours
86 
87 inline QString recurText(const KAEvent& event)
88 {
89  QString r;
90  if (event.repetition())
91  r = QString::fromLatin1("%1 / %2").arg(event.recurrenceText()).arg(event.repetitionText());
92  else
93  r = event.recurrenceText();
94  return i18nc("@title:tab", "Recurrence - [%1]", r);
95 }
96 
97 QList<EditAlarmDlg*> EditAlarmDlg::mWindowList;
98 
99 // Collect these widget labels together to ensure consistent wording and
100 // translations across different modules.
101 QString EditAlarmDlg::i18n_chk_ShowInKOrganizer() { return i18nc("@option:check", "Show in KOrganizer"); }
102 
103 
104 EditAlarmDlg* EditAlarmDlg::create(bool Template, Type type, QWidget* parent, GetResourceType getResource)
105 {
106  kDebug();
107  switch (type)
108  {
109  case DISPLAY: return new EditDisplayAlarmDlg(Template, parent, getResource);
110  case COMMAND: return new EditCommandAlarmDlg(Template, parent, getResource);
111  case EMAIL: return new EditEmailAlarmDlg(Template, parent, getResource);
112  case AUDIO: return new EditAudioAlarmDlg(Template, parent, getResource);
113  default: break;
114  }
115  return 0;
116 }
117 
118 EditAlarmDlg* EditAlarmDlg::create(bool Template, const KAEvent* event, bool newAlarm, QWidget* parent,
119  GetResourceType getResource, bool readOnly)
120 {
121  switch (event->actionTypes())
122  {
123  case KAEvent::ACT_COMMAND: return new EditCommandAlarmDlg(Template, event, newAlarm, parent, getResource, readOnly);
124  case KAEvent::ACT_DISPLAY_COMMAND:
125  case KAEvent::ACT_DISPLAY: return new EditDisplayAlarmDlg(Template, event, newAlarm, parent, getResource, readOnly);
126  case KAEvent::ACT_EMAIL: return new EditEmailAlarmDlg(Template, event, newAlarm, parent, getResource, readOnly);
127  case KAEvent::ACT_AUDIO: return new EditAudioAlarmDlg(Template, event, newAlarm, parent, getResource, readOnly);
128  default:
129  break;
130  }
131  return 0;
132 }
133 
134 
135 /******************************************************************************
136 * Constructor.
137 * Parameters:
138 * Template = true to edit/create an alarm template
139 * = false to edit/create an alarm.
140 * event != to initialise the dialog to show the specified event's data.
141 */
142 EditAlarmDlg::EditAlarmDlg(bool Template, KAEvent::SubAction action, QWidget* parent, GetResourceType getResource)
143  : KDialog(parent),
144  mAlarmType(action),
145  mMainPageShown(false),
146  mRecurPageShown(false),
147  mRecurSetDefaultEndDate(true),
148  mTemplateName(0),
149  mDeferGroup(0),
150  mDeferChangeButton(0),
151  mTimeWidget(0),
152  mShowInKorganizer(0),
153 #ifndef USE_AKONADI
154  mResource(0),
155 #endif
156  mDeferGroupHeight(0),
157  mTemplate(Template),
158  mNewAlarm(true),
159  mDesiredReadOnly(false),
160  mReadOnly(false),
161  mShowingMore(true),
162  mSavedEvent(0)
163 {
164  init(0, getResource);
165  mWindowList.append(this);
166 }
167 
168 EditAlarmDlg::EditAlarmDlg(bool Template, const KAEvent* event, bool newAlarm, QWidget* parent,
169  GetResourceType getResource, bool readOnly)
170  : KDialog(parent),
171  mAlarmType(event->actionSubType()),
172  mMainPageShown(false),
173  mRecurPageShown(false),
174  mRecurSetDefaultEndDate(true),
175  mTemplateName(0),
176  mDeferGroup(0),
177  mDeferChangeButton(0),
178  mTimeWidget(0),
179  mShowInKorganizer(0),
180 #ifndef USE_AKONADI
181  mResource(0),
182 #endif
183  mDeferGroupHeight(0),
184  mEventId(newAlarm ? QString() : event->id()),
185  mTemplate(Template),
186  mNewAlarm(newAlarm),
187  mDesiredReadOnly(readOnly),
188  mReadOnly(readOnly),
189  mShowingMore(true),
190  mSavedEvent(0)
191 {
192  init(event, getResource);
193  mWindowList.append(this);
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  if (theApp()->windowFocusBroken())
480  {
481  const QList<QWidget*> children = findChildren<QWidget*>();
482  foreach (QWidget* w, children)
483  w->installEventFilter(this);
484  }
485 }
486 
487 EditAlarmDlg::~EditAlarmDlg()
488 {
489  delete mSavedEvent;
490  mWindowList.removeAll(this);
491 }
492 
493 /******************************************************************************
494 * Return the number of instances.
495 */
496 int EditAlarmDlg::instanceCount()
497 {
498  return mWindowList.count();
499 }
500 
501 /******************************************************************************
502 * Initialise the dialog controls from the specified event.
503 */
504 void EditAlarmDlg::initValues(const KAEvent* event)
505 {
506  setReadOnly(mDesiredReadOnly);
507 
508  mChanged = false;
509  mOnlyDeferred = false;
510  mExpiredRecurrence = false;
511  mLateCancel->showAutoClose(false);
512  bool deferGroupVisible = false;
513  if (event)
514  {
515  // Set the values to those for the specified event
516  if (mTemplate)
517  mTemplateName->setText(event->templateName());
518  bool recurs = event->recurs();
519  if ((recurs || event->repetition()) && !mTemplate && event->deferred())
520  {
521  deferGroupVisible = true;
522  mDeferDateTime = event->deferDateTime();
523  mDeferTimeLabel->setText(mDeferDateTime.formatLocale());
524  mDeferGroup->show();
525  }
526  if (mTemplate)
527  {
528  // Editing a template
529  int afterTime = event->isTemplate() ? event->templateAfterTime() : -1;
530  bool noTime = !afterTime;
531  bool useTime = !event->mainDateTime().isDateOnly();
532  RadioButton* button = noTime ? mTemplateDefaultTime :
533  (afterTime > 0) ? mTemplateUseTimeAfter :
534  useTime ? mTemplateUseTime : mTemplateAnyTime;
535  button->setChecked(true);
536  mTemplateTimeAfter->setValue(afterTime > 0 ? afterTime : 1);
537  if (!noTime && useTime)
538  mTemplateTime->setValue(event->mainDateTime().kDateTime().time());
539  else
540  mTemplateTime->setValue(0);
541  }
542  else
543  {
544  if (event->isTemplate())
545  {
546  // Initialising from an alarm template: use current date
547  KDateTime now = KDateTime::currentDateTime(Preferences::timeZone());
548  int afterTime = event->templateAfterTime();
549  if (afterTime >= 0)
550  {
551  mTimeWidget->setDateTime(now.addSecs(afterTime * 60));
552  mTimeWidget->selectTimeFromNow();
553  }
554  else
555  {
556  KDateTime dt = event->startDateTime().kDateTime();
557  dt.setTimeSpec(Preferences::timeZone());
558  QDate d = now.date();
559  if (!dt.isDateOnly() && now.time() >= dt.time())
560  d = d.addDays(1); // alarm time has already passed, so use tomorrow
561  dt.setDate(d);
562  mTimeWidget->setDateTime(dt);
563  }
564  }
565  else
566  {
567  mExpiredRecurrence = recurs && event->mainExpired();
568  mTimeWidget->setDateTime(recurs || event->category() == CalEvent::ARCHIVED ? event->startDateTime()
569  : event->mainExpired() ? event->deferDateTime() : event->mainDateTime());
570  }
571  }
572 
573  KAEvent::SubAction action = event->actionSubType();
574  AlarmText altext;
575  if (event->commandScript())
576  altext.setScript(event->cleanText());
577  else
578  altext.setText(event->cleanText());
579  setAction(action, altext);
580 
581  mLateCancel->setMinutes(event->lateCancel(), event->startDateTime().isDateOnly(),
582  TimePeriod::HoursMinutes);
583  if (mShowInKorganizer)
584  mShowInKorganizer->setChecked(event->copyToKOrganizer());
585  type_initValues(event);
586  mRecurrenceEdit->set(*event); // must be called after mTimeWidget is set up, to ensure correct date-only enabling
587  mTabs->setTabText(mRecurPageIndex, recurText(*event));
588  }
589  else
590  {
591  // Set the values to their defaults
592  KDateTime defaultTime = KDateTime::currentUtcDateTime().addSecs(60).toTimeSpec(Preferences::timeZone());
593  if (mTemplate)
594  {
595  mTemplateDefaultTime->setChecked(true);
596  mTemplateTime->setValue(0);
597  mTemplateTimeAfter->setValue(1);
598  }
599  else
600  mTimeWidget->setDateTime(defaultTime);
601  mLateCancel->setMinutes((Preferences::defaultLateCancel() ? 1 : 0), false, TimePeriod::HoursMinutes);
602  if (mShowInKorganizer)
603  mShowInKorganizer->setChecked(Preferences::defaultCopyToKOrganizer());
604  type_initValues(0);
605  mRecurrenceEdit->setDefaults(defaultTime); // must be called after mTimeWidget is set up, to ensure correct date-only enabling
606  slotRecurFrequencyChange(); // update the Recurrence text
607  }
608  if (mReminder && mTimeWidget)
609  mReminder->setDefaultUnits(mTimeWidget->getDateTime(0, false, false));
610 
611  if (!deferGroupVisible && mDeferGroup)
612  mDeferGroup->hide();
613 
614  bool empty = AlarmCalendar::resources()->events(CalEvent::TEMPLATE).isEmpty();
615  enableButton(Help, !empty); // Load Templates button
616 }
617 
618 /******************************************************************************
619 * Initialise various values in the New Alarm dialogue.
620 */
621 void EditAlarmDlg::setTime(const DateTime& start)
622 {
623  mTimeWidget->setDateTime(start);
624 }
625 void EditAlarmDlg::setRecurrence(const KARecurrence& recur, int subRepeatInterval, int subRepeatCount)
626 {
627  KAEvent event;
628  event.setTime(mTimeWidget->getDateTime(0, false, false));
629  event.setRecurrence(recur);
630  event.setRepetition(Repetition(subRepeatInterval, subRepeatCount - 1));
631  mRecurrenceEdit->set(event);
632 }
633 void EditAlarmDlg::setRepeatAtLogin()
634 {
635  mRecurrenceEdit->setRepeatAtLogin();
636 }
637 void EditAlarmDlg::setLateCancel(int minutes)
638 {
639  mLateCancel->setMinutes(minutes, mTimeWidget->getDateTime(0, false, false).isDateOnly(),
640  TimePeriod::HoursMinutes);
641 }
642 void EditAlarmDlg::setShowInKOrganizer(bool show)
643 {
644  mShowInKorganizer->setChecked(show);
645 }
646 
647 /******************************************************************************
648 * Set the read-only status of all non-template controls.
649 */
650 void EditAlarmDlg::setReadOnly(bool readOnly)
651 {
652  mReadOnly = readOnly;
653 
654  if (mTimeWidget)
655  mTimeWidget->setReadOnly(readOnly);
656  mLateCancel->setReadOnly(readOnly);
657  if (mDeferChangeButton)
658  {
659  if (readOnly)
660  mDeferChangeButton->hide();
661  else
662  mDeferChangeButton->show();
663  }
664  if (mShowInKorganizer)
665  mShowInKorganizer->setReadOnly(readOnly);
666 }
667 
668 /******************************************************************************
669 * Save the state of all controls.
670 */
671 void EditAlarmDlg::saveState(const KAEvent* event)
672 {
673  delete mSavedEvent;
674  mSavedEvent = 0;
675  if (event)
676  mSavedEvent = new KAEvent(*event);
677  if (mTemplate)
678  {
679  mSavedTemplateName = mTemplateName->text();
680  mSavedTemplateTimeType = mTemplateTimeGroup->checkedButton();
681  mSavedTemplateTime = mTemplateTime->time();
682  mSavedTemplateAfterTime = mTemplateTimeAfter->value();
683  }
684  checkText(mSavedTextFileCommandMessage, false);
685  if (mTimeWidget)
686  mSavedDateTime = mTimeWidget->getDateTime(0, false, false);
687  mSavedLateCancel = mLateCancel->minutes();
688  if (mShowInKorganizer)
689  mSavedShowInKorganizer = mShowInKorganizer->isChecked();
690  mSavedRecurrenceType = mRecurrenceEdit->repeatType();
691  mSavedDeferTime = mDeferDateTime.kDateTime();
692 }
693 
694 /******************************************************************************
695 * Check whether any of the controls has changed state since the dialog was
696 * first displayed.
697 * Reply = true if any non-deferral controls have changed, or if it's a new event.
698 * = false if no non-deferral controls have changed. In this case,
699 * mOnlyDeferred indicates whether deferral controls may have changed.
700 */
701 bool EditAlarmDlg::stateChanged() const
702 {
703  mChanged = true;
704  mOnlyDeferred = false;
705  if (!mSavedEvent)
706  return true;
707  QString textFileCommandMessage;
708  checkText(textFileCommandMessage, false);
709  if (mTemplate)
710  {
711  if (mSavedTemplateName != mTemplateName->text()
712  || mSavedTemplateTimeType != mTemplateTimeGroup->checkedButton()
713  || (mTemplateUseTime->isChecked() && mSavedTemplateTime != mTemplateTime->time())
714  || (mTemplateUseTimeAfter->isChecked() && mSavedTemplateAfterTime != mTemplateTimeAfter->value()))
715  return true;
716  }
717  else
718  {
719  KDateTime dt = mTimeWidget->getDateTime(0, false, false);
720  if (mSavedDateTime.timeSpec() != dt.timeSpec() || mSavedDateTime != dt)
721  return true;
722  }
723  if (mSavedLateCancel != mLateCancel->minutes()
724  || (mShowInKorganizer && mSavedShowInKorganizer != mShowInKorganizer->isChecked())
725  || textFileCommandMessage != mSavedTextFileCommandMessage
726  || mSavedRecurrenceType != mRecurrenceEdit->repeatType())
727  return true;
728  if (type_stateChanged())
729  return true;
730  if (mRecurrenceEdit->stateChanged())
731  return true;
732  if (mSavedEvent && mSavedEvent->deferred())
733  mOnlyDeferred = true;
734  mChanged = false;
735  return false;
736 }
737 
738 /******************************************************************************
739 * Called whenever any of the controls changes state.
740 * Enable or disable the OK button depending on whether any controls have a
741 * different state from their initial state.
742 */
743 void EditAlarmDlg::contentsChanged()
744 {
745  // Don't do anything if it's a new alarm or we're still initialising
746  // (i.e. mSavedEvent null).
747  if (mSavedEvent && button(Ok))
748  button(Ok)->setEnabled(stateChanged() || mDeferDateTime.kDateTime() != mSavedDeferTime);
749 }
750 
751 /******************************************************************************
752 * Get the currently entered dialog data.
753 * The data is returned in the supplied KAEvent instance.
754 * Reply = false if the only change has been to an existing deferral.
755 */
756 #ifdef USE_AKONADI
757 bool EditAlarmDlg::getEvent(KAEvent& event, Akonadi::Collection& collection)
758 #else
759 bool EditAlarmDlg::getEvent(KAEvent& event, AlarmResource*& resource)
760 #endif
761 {
762 #ifdef USE_AKONADI
763  collection = mCollection;
764 #else
765  resource = mResource;
766 #endif
767  if (mChanged)
768  {
769  // It's a new event, or the edit controls have changed
770  setEvent(event, mAlarmMessage, false);
771  return true;
772  }
773 
774  // Only the deferral time may have changed
775  event = *mSavedEvent;
776  if (mOnlyDeferred)
777  {
778  // Just modify the original event, to avoid expired recurring events
779  // being returned as rubbish.
780  if (mDeferDateTime.isValid())
781  event.defer(mDeferDateTime, event.reminderDeferral(), false);
782  else
783  event.cancelDefer();
784  }
785  return false;
786 }
787 
788 /******************************************************************************
789 * Extract the data in the dialog and set up a KAEvent from it.
790 * If 'trial' is true, the event is set up for a simple one-off test, ignoring
791 * recurrence, reminder, template etc. data.
792 */
793 void EditAlarmDlg::setEvent(KAEvent& event, const QString& text, bool trial)
794 {
795  KDateTime dt;
796  if (!trial)
797  {
798  if (!mTemplate)
799  dt = mAlarmDateTime.effectiveKDateTime();
800  else if (mTemplateUseTime->isChecked())
801  dt = KDateTime(QDate(2000,1,1), mTemplateTime->time());
802  }
803 
804  int lateCancel = (trial || !mLateCancel->isEnabled()) ? 0 : mLateCancel->minutes();
805  type_setEvent(event, dt, text, lateCancel, trial);
806 
807  if (!trial)
808  {
809  if (mRecurrenceEdit->repeatType() != RecurrenceEdit::NO_RECUR)
810  {
811  mRecurrenceEdit->updateEvent(event, !mTemplate);
812  KDateTime now = KDateTime::currentDateTime(mAlarmDateTime.timeSpec());
813  bool dateOnly = mAlarmDateTime.isDateOnly();
814  if ((dateOnly && mAlarmDateTime.date() < now.date())
815  || (!dateOnly && mAlarmDateTime.kDateTime() < now))
816  {
817  // A timed recurrence has an entered start date which has
818  // already expired, so we must adjust the next repetition.
819  event.setNextOccurrence(now);
820  }
821  mAlarmDateTime = event.startDateTime();
822  if (mDeferDateTime.isValid() && mDeferDateTime < mAlarmDateTime)
823  {
824  bool deferral = true;
825  bool deferReminder = false;
826  int reminder = mReminder ? mReminder->minutes() : 0;
827  if (reminder)
828  {
829  DateTime remindTime = mAlarmDateTime.addMins(-reminder);
830  if (mDeferDateTime >= remindTime)
831  {
832  if (remindTime > KDateTime::currentUtcDateTime())
833  deferral = false; // ignore deferral if it's after next reminder
834  else if (mDeferDateTime > remindTime)
835  deferReminder = true; // it's the reminder which is being deferred
836  }
837  }
838  if (deferral)
839  event.defer(mDeferDateTime, deferReminder, false);
840  }
841  }
842  if (mTemplate)
843  {
844  int afterTime = mTemplateDefaultTime->isChecked() ? 0
845  : mTemplateUseTimeAfter->isChecked() ? mTemplateTimeAfter->value() : -1;
846  event.setTemplate(mTemplateName->text(), afterTime);
847  }
848  }
849 }
850 
851 /******************************************************************************
852 * Get the currently specified alarm flag bits.
853 */
854 KAEvent::Flags EditAlarmDlg::getAlarmFlags() const
855 {
856  KAEvent::Flags flags(0);
857  if (mShowInKorganizer && mShowInKorganizer->isEnabled() && mShowInKorganizer->isChecked())
858  flags |= KAEvent::COPY_KORGANIZER;
859  if (mRecurrenceEdit->repeatType() == RecurrenceEdit::AT_LOGIN)
860  flags |= KAEvent::REPEAT_AT_LOGIN;
861  if (mTemplate ? mTemplateAnyTime->isChecked() : mAlarmDateTime.isDateOnly())
862  flags |= KAEvent::ANY_TIME;
863  return flags;
864 }
865 
866 /******************************************************************************
867 * Called when the dialog is displayed.
868 * The first time through, sets the size to the same as the last time it was
869 * displayed.
870 */
871 void EditAlarmDlg::showEvent(QShowEvent* se)
872 {
873  KDialog::showEvent(se);
874  if (!mDeferGroupHeight)
875  {
876  if (mDeferGroup)
877  mDeferGroupHeight = mDeferGroup->height() + spacingHint();
878  QSize s;
879  if (KAlarm::readConfigWindowSize(mTemplate ? TEMPLATE_DIALOG_NAME : EDIT_DIALOG_NAME, s))
880  {
881  bool defer = mDeferGroup && !mDeferGroup->isHidden();
882  s.setHeight(s.height() + (defer ? mDeferGroupHeight : 0));
883  if (!defer)
884  mTabScrollGroup->setSized();
885  resize(s);
886  }
887  }
888  slotResize();
889  KWindowSystem::setOnDesktop(winId(), mDesktop); // ensure it displays on the desktop expected by the user
890 
891  if (theApp()->needWindowFocusFix())
892  {
893  QApplication::setActiveWindow(this);
894  QTimer::singleShot(0, this, SLOT(focusFixTimer()));
895  }
896 }
897 
898 /******************************************************************************
899 * Called when the window is first shown, to ensure that it initially becomes
900 * the active window.
901 * This is only required on Ubuntu's Unity desktop, which doesn't transfer
902 * keyboard focus properly between Edit Alarm Dialog windows and MessageWin
903 * windows.
904 */
905 void EditAlarmDlg::focusFixTimer()
906 {
907  if (theApp()->needWindowFocusFix()
908  && QApplication::focusWidget()->window() != this)
909  {
910  QApplication::setActiveWindow(this);
911  QTimer::singleShot(0, this, SLOT(focusFixTimer()));
912  }
913 }
914 
915 /******************************************************************************
916 * Called to detect when the mouse is pressed anywhere inside the window.
917 * Activates this window if a MessageWin window is also active.
918 * This is only required on Ubuntu's Unity desktop, which doesn't transfer
919 * keyboard focus properly between Edit Alarm Dialog windows and MessageWin
920 * windows.
921 */
922 bool EditAlarmDlg::eventFilter(QObject*, QEvent* e)
923 {
924  if (theApp()->needWindowFocusFix())
925  {
926  if (e->type() == QEvent::MouseButtonPress)
927  QApplication::setActiveWindow(this);
928  }
929  return false;
930 }
931 
932 /******************************************************************************
933 * Called when the dialog is closed.
934 */
935 void EditAlarmDlg::closeEvent(QCloseEvent* ce)
936 {
937  emit rejected();
938  KDialog::closeEvent(ce);
939 }
940 
941 /******************************************************************************
942 * Update the tab sizes (again) and if the resized dialog height is greater
943 * than the minimum, resize it again. This is necessary because (a) resizing
944 * tabs doesn't always work properly the first time, and (b) resizing to the
945 * minimum size hint doesn't always work either.
946 */
947 void EditAlarmDlg::slotResize()
948 {
949  QSize s = mTabScrollGroup->adjustSize(true);
950  s = minimumSizeHint();
951  if (height() > s.height())
952  {
953  // Resize to slightly greater than the minimum height.
954  // This is for some unknown reason necessary, since
955  // sometimes resizing to the minimum height fails.
956  resize(s.width(), s.height() + 2);
957  }
958 }
959 
960 /******************************************************************************
961 * Called when the dialog's size has changed.
962 * Records the new size (adjusted to ignore the optional height of the deferred
963 * time edit widget) in the config file.
964 */
965 void EditAlarmDlg::resizeEvent(QResizeEvent* re)
966 {
967  if (isVisible() && mDeferGroupHeight)
968  {
969  QSize s = re->size();
970  s.setHeight(s.height() - (!mDeferGroup || mDeferGroup->isHidden() ? 0 : mDeferGroupHeight));
971  KAlarm::writeConfigWindowSize(mTemplate ? TEMPLATE_DIALOG_NAME : EDIT_DIALOG_NAME, s);
972  }
973  KDialog::resizeEvent(re);
974 }
975 
976 /******************************************************************************
977 * Called when any button is clicked.
978 */
979 void EditAlarmDlg::slotButtonClicked(int button)
980 {
981  if (button == Ok)
982  {
983  if (validate())
984  accept();
985  }
986  else
987  KDialog::slotButtonClicked(button);
988 }
989 
990 /******************************************************************************
991 * Called when the OK button is clicked.
992 * Validate the input data.
993 */
994 bool EditAlarmDlg::validate()
995 {
996  if (!stateChanged())
997  {
998  // No changes have been made except possibly to an existing deferral
999  if (!mOnlyDeferred)
1000  reject();
1001  return mOnlyDeferred;
1002  }
1003  RecurrenceEdit::RepeatType recurType = mRecurrenceEdit->repeatType();
1004  if (mTimeWidget
1005  && mTabs->currentIndex() == mRecurPageIndex && recurType == RecurrenceEdit::AT_LOGIN)
1006  mTimeWidget->setDateTime(mRecurrenceEdit->endDateTime());
1007  bool timedRecurrence = mRecurrenceEdit->isTimedRepeatType(); // does it recur other than at login?
1008  if (mTemplate)
1009  {
1010  // Check that the template name is not blank and is unique
1011  QString errmsg;
1012  QString name = mTemplateName->text();
1013  if (name.isEmpty())
1014  errmsg = i18nc("@info", "You must enter a name for the alarm template");
1015  else if (name != mSavedTemplateName)
1016  {
1017  if (AlarmCalendar::resources()->templateEvent(name))
1018  errmsg = i18nc("@info", "Template name is already in use");
1019  }
1020  if (!errmsg.isEmpty())
1021  {
1022  mTemplateName->setFocus();
1023  KAMessageBox::sorry(this, errmsg);
1024  return false;
1025  }
1026  }
1027  else if (mTimeWidget)
1028  {
1029  QWidget* errWidget;
1030  mAlarmDateTime = mTimeWidget->getDateTime(0, !timedRecurrence, false, &errWidget);
1031  if (errWidget)
1032  {
1033  // It's more than just an existing deferral being changed, so the time matters
1034  mTabs->setCurrentIndex(mMainPageIndex);
1035  errWidget->setFocus();
1036  mTimeWidget->getDateTime(); // display the error message now
1037  return false;
1038  }
1039  }
1040  if (!type_validate(false))
1041  return false;
1042 
1043  if (!mTemplate)
1044  {
1045  if (mChanged && mRecurrenceEdit->repeatType() != RecurrenceEdit::NO_RECUR)
1046  {
1047  // Check whether the start date/time must be adjusted
1048  // to match the recurrence specification.
1049  DateTime dt = mAlarmDateTime; // setEvent() changes mAlarmDateTime
1050  KAEvent event;
1051  setEvent(event, mAlarmMessage, false);
1052  mAlarmDateTime = dt; // restore
1053  KDateTime pre = dt.effectiveKDateTime();
1054  bool dateOnly = dt.isDateOnly();
1055  if (dateOnly)
1056  pre = pre.addDays(-1);
1057  else
1058  pre = pre.addSecs(-1);
1059  DateTime next;
1060  event.nextOccurrence(pre, next, KAEvent::IGNORE_REPETITION);
1061  if (next != dt)
1062  {
1063  QString prompt = dateOnly ? i18nc("@info The parameter is a date value",
1064  "The start date does not match the alarm's recurrence pattern, "
1065  "so it will be adjusted to the date of the next recurrence (%1).",
1066  KGlobal::locale()->formatDate(next.date(), KLocale::ShortDate))
1067  : i18nc("@info The parameter is a date/time value",
1068  "The start date/time does not match the alarm's recurrence pattern, "
1069  "so it will be adjusted to the date/time of the next recurrence (%1).",
1070  KGlobal::locale()->formatDateTime(next.kDateTime(), KLocale::ShortDate));
1071  if (KAMessageBox::warningContinueCancel(this, prompt) != KMessageBox::Continue)
1072  return false;
1073  }
1074  }
1075 
1076  if (timedRecurrence)
1077  {
1078  KAEvent event;
1079 #ifdef USE_AKONADI
1080  Akonadi::Collection c;
1081  getEvent(event, c); // this may adjust mAlarmDateTime
1082 #else
1083  AlarmResource* r;
1084  getEvent(event, r); // this may adjust mAlarmDateTime
1085 #endif
1086  KDateTime now = KDateTime::currentDateTime(mAlarmDateTime.timeSpec());
1087  bool dateOnly = mAlarmDateTime.isDateOnly();
1088  if ((dateOnly && mAlarmDateTime.date() < now.date())
1089  || (!dateOnly && mAlarmDateTime.kDateTime() < now))
1090  {
1091  // A timed recurrence has an entered start date which
1092  // has already expired, so we must adjust it.
1093  if (event.nextOccurrence(now, mAlarmDateTime, KAEvent::ALLOW_FOR_REPETITION) == KAEvent::NO_OCCURRENCE)
1094  {
1095  KAMessageBox::sorry(this, i18nc("@info", "Recurrence has already expired"));
1096  return false;
1097  }
1098  if (event.workTimeOnly() && !event.nextTrigger(KAEvent::DISPLAY_TRIGGER).isValid())
1099  {
1100  if (KAMessageBox::warningContinueCancel(this, i18nc("@info", "The alarm will never occur during working hours"))
1101  != KMessageBox::Continue)
1102  return false;
1103  }
1104  }
1105  }
1106  QString errmsg;
1107  QWidget* errWidget = mRecurrenceEdit->checkData(mAlarmDateTime.effectiveKDateTime(), errmsg);
1108  if (errWidget)
1109  {
1110  mTabs->setCurrentIndex(mRecurPageIndex);
1111  errWidget->setFocus();
1112  KAMessageBox::sorry(this, errmsg);
1113  return false;
1114  }
1115  }
1116  if (recurType != RecurrenceEdit::NO_RECUR)
1117  {
1118  KAEvent recurEvent;
1119  int longestRecurMinutes = -1;
1120  int reminder = mReminder ? mReminder->minutes() : 0;
1121  if (reminder && !mReminder->isOnceOnly())
1122  {
1123  mRecurrenceEdit->updateEvent(recurEvent, false);
1124  longestRecurMinutes = recurEvent.longestRecurrenceInterval().asSeconds() / 60;
1125  if (longestRecurMinutes && reminder >= longestRecurMinutes)
1126  {
1127  mTabs->setCurrentIndex(mMainPageIndex);
1128  mReminder->setFocusOnCount();
1129  KAMessageBox::sorry(this, i18nc("@info", "Reminder period must be less than the recurrence interval, unless <interface>%1</interface> is checked.",
1130  Reminder::i18n_chk_FirstRecurrenceOnly()));
1131  return false;
1132  }
1133  }
1134  if (mRecurrenceEdit->subRepetition())
1135  {
1136  if (longestRecurMinutes < 0)
1137  {
1138  mRecurrenceEdit->updateEvent(recurEvent, false);
1139  longestRecurMinutes = recurEvent.longestRecurrenceInterval().asSeconds() / 60;
1140  }
1141  if (longestRecurMinutes > 0
1142  && recurEvent.repetition().intervalMinutes() * recurEvent.repetition().count() >= longestRecurMinutes - reminder)
1143  {
1144  KAMessageBox::sorry(this, i18nc("@info", "The duration of a repetition within the recurrence must be less than the recurrence interval minus any reminder period"));
1145  mRecurrenceEdit->activateSubRepetition(); // display the alarm repetition dialog again
1146  return false;
1147  }
1148  if (!recurEvent.repetition().isDaily()
1149  && ((mTemplate && mTemplateAnyTime->isChecked()) || (!mTemplate && mAlarmDateTime.isDateOnly())))
1150  {
1151  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"));
1152  mRecurrenceEdit->activateSubRepetition(); // display the alarm repetition dialog again
1153  return false;
1154  }
1155  }
1156  }
1157  if (!checkText(mAlarmMessage))
1158  return false;
1159 
1160 #ifdef USE_AKONADI
1161  mCollection = Akonadi::Collection();
1162  // An item ID = -2 indicates that the caller already
1163  // knows which collection to use.
1164  if (mCollectionItemId >= -1)
1165  {
1166  if (mCollectionItemId >= 0)
1167  {
1168  mCollection = AlarmCalendar::resources()->collectionForEvent(mCollectionItemId);
1169  if (mCollection.isValid())
1170  {
1171  CalEvent::Type type = mTemplate ? CalEvent::TEMPLATE : CalEvent::ACTIVE;
1172  if (!(AkonadiModel::instance()->types(mCollection) & type))
1173  mCollection = Akonadi::Collection(); // event may have expired while dialog was open
1174  }
1175  }
1176  bool cancelled = false;
1177  CalEvent::Type type = mTemplate ? CalEvent::TEMPLATE : CalEvent::ACTIVE;
1178  if (CollectionControlModel::isWritableEnabled(mCollection, type) <= 0)
1179  mCollection = CollectionControlModel::destination(type, this, false, &cancelled);
1180  if (!mCollection.isValid())
1181  {
1182  if (!cancelled)
1183  KAMessageBox::sorry(this, i18nc("@info", "You must select a calendar to save the alarm in"));
1184  return false;
1185  }
1186  }
1187 #else
1188  mResource = 0;
1189  // A null resource event ID indicates that the caller already
1190  // knows which resource to use.
1191  if (!mResourceEventId.isNull())
1192  {
1193  if (!mResourceEventId.isEmpty())
1194  {
1195  mResource = AlarmCalendar::resources()->resourceForEvent(mResourceEventId);
1196  if (mResource)
1197  {
1198  CalEvent::Type type = mTemplate ? CalEvent::TEMPLATE : CalEvent::ACTIVE;
1199  if (mResource->alarmType() != type)
1200  mResource = 0; // event may have expired while dialog was open
1201  }
1202  }
1203  bool cancelled = false;
1204  if (!mResource || !mResource->writable())
1205  {
1206  CalEvent::Type type = mTemplate ? CalEvent::TEMPLATE : CalEvent::ACTIVE;
1207  mResource = AlarmResources::instance()->destination(type, this, false, &cancelled);
1208  }
1209  if (!mResource)
1210  {
1211  if (!cancelled)
1212  KAMessageBox::sorry(this, i18nc("@info", "You must select a calendar to save the alarm in"));
1213  return false;
1214  }
1215  }
1216 #endif
1217  return true;
1218 }
1219 
1220 /******************************************************************************
1221 * Called when the Try button is clicked.
1222 * Display/execute the alarm immediately for the user to check its configuration.
1223 */
1224 void EditAlarmDlg::slotTry()
1225 {
1226  QString text;
1227  if (checkText(text))
1228  {
1229  if (!type_validate(true))
1230  return;
1231  KAEvent event;
1232  setEvent(event, text, true);
1233  if (!mNewAlarm && !stateChanged())
1234  {
1235  // It's an existing alarm which hasn't been changed yet:
1236  // enable KALARM_UID environment variable to be set.
1237  event.setEventId(mEventId);
1238  }
1239  type_aboutToTry();
1240  void* result = theApp()->execAlarm(event, event.firstAlarm(), false, false);
1241  type_executedTry(text, result);
1242  }
1243 }
1244 
1245 /******************************************************************************
1246 * Called when the Load Template button is clicked.
1247 * Prompt to select a template and initialise the dialog with its contents.
1248 */
1249 void EditAlarmDlg::slotHelp()
1250 {
1251  KAEvent::Actions type;
1252  switch (mAlarmType)
1253  {
1254  case KAEvent::FILE:
1255  case KAEvent::MESSAGE: type = KAEvent::ACT_DISPLAY; break;
1256  case KAEvent::COMMAND: type = KAEvent::ACT_COMMAND; break;
1257  case KAEvent::EMAIL: type = KAEvent::ACT_EMAIL; break;
1258  case KAEvent::AUDIO: type = KAEvent::ACT_AUDIO; break;
1259  default:
1260  return;
1261  }
1262  // Use AutoQPointer to guard against crash on application exit while
1263  // the dialogue is still open. It prevents double deletion (both on
1264  // deletion of EditAlarmDlg, and on return from this function).
1265  AutoQPointer<TemplatePickDlg> dlg = new TemplatePickDlg(type, this);
1266  if (dlg->exec() == QDialog::Accepted)
1267 #ifdef USE_AKONADI
1268  {
1269  KAEvent event = dlg->selectedTemplate();
1270  initValues(&event);
1271  }
1272 #else
1273  initValues(dlg->selectedTemplate());
1274 #endif
1275 }
1276 
1277 /******************************************************************************
1278 * Called when the More Options or Less Options buttons are clicked.
1279 * Show/hide the optional options and swap the More/Less buttons, and save the
1280 * new setting as the default from now on.
1281 */
1282 void EditAlarmDlg::slotDefault()
1283 {
1284  showOptions(!mShowingMore);
1285  KConfigGroup config(KGlobal::config(), EDIT_MORE_GROUP);
1286  config.writeEntry(EDIT_MORE_KEY, mShowingMore);
1287 }
1288 
1289 /******************************************************************************
1290 * Show/hide the optional options and swap the More/Less buttons.
1291 */
1292 void EditAlarmDlg::showOptions(bool more)
1293 {
1294  kDebug() << (more ? "More" : "Less");
1295  if (more)
1296  {
1297  mMoreOptions->show();
1298  setButtonText(Default, i18nc("@action:button", "Less Options <<"));
1299  }
1300  else
1301  {
1302  mMoreOptions->hide();
1303  setButtonText(Default, i18nc("@action:button", "More Options >>"));
1304  }
1305  if (mTimeWidget)
1306  mTimeWidget->showMoreOptions(more);
1307  type_showOptions(more);
1308  mRecurrenceEdit->showMoreOptions(more);
1309  mShowingMore = more;
1310  QTimer::singleShot(0, this, SLOT(slotResize()));
1311 }
1312 
1313 /******************************************************************************
1314 * Called when the Change deferral button is clicked.
1315 */
1316 void EditAlarmDlg::slotEditDeferral()
1317 {
1318  if (!mTimeWidget)
1319  return;
1320  bool limit = true;
1321  Repetition repetition = mRecurrenceEdit->subRepetition();
1322  DateTime start = mSavedEvent->recurs() ? (mExpiredRecurrence ? DateTime() : mSavedEvent->mainDateTime())
1323  : mTimeWidget->getDateTime(0, !repetition, !mExpiredRecurrence);
1324  if (!start.isValid())
1325  {
1326  if (!mExpiredRecurrence)
1327  return;
1328  limit = false;
1329  }
1330  KDateTime now = KDateTime::currentUtcDateTime();
1331  if (limit)
1332  {
1333  if (repetition && start < now)
1334  {
1335  // Sub-repetition - find the time of the next one
1336  int repeatNum = repetition.isDaily()
1337  ? (start.daysTo(now) + repetition.intervalDays() - 1) / repetition.intervalDays()
1338  : (start.secsTo(now) + repetition.intervalSeconds() - 1) / repetition.intervalSeconds();
1339  if (repeatNum > repetition.count())
1340  {
1341  mTimeWidget->getDateTime(); // output the appropriate error message
1342  return;
1343  }
1344  start = repetition.duration(repeatNum).end(start.kDateTime());
1345  }
1346  }
1347 
1348  bool deferred = mDeferDateTime.isValid();
1349  // Use AutoQPointer to guard against crash on application exit while
1350  // the dialogue is still open. It prevents double deletion (both on
1351  // deletion of EditAlarmDlg, and on return from this function).
1352  AutoQPointer<DeferAlarmDlg> deferDlg = new DeferAlarmDlg((deferred ? mDeferDateTime : DateTime(now.addSecs(60).toTimeSpec(start.timeSpec()))),
1353  start.isDateOnly(), deferred, this);
1354  deferDlg->setObjectName(QLatin1String("EditDeferDlg")); // used by LikeBack
1355  if (limit)
1356  {
1357  // Don't allow deferral past the next recurrence
1358  int reminder = mReminder ? mReminder->minutes() : 0;
1359  if (reminder)
1360  {
1361  DateTime remindTime = start.addMins(-reminder);
1362  if (KDateTime::currentUtcDateTime() < remindTime)
1363  start = remindTime;
1364  }
1365  deferDlg->setLimit(start.addSecs(-60));
1366  }
1367  if (deferDlg->exec() == QDialog::Accepted)
1368  {
1369  mDeferDateTime = deferDlg->getDateTime();
1370  mDeferTimeLabel->setText(mDeferDateTime.isValid() ? mDeferDateTime.formatLocale() : QString());
1371  contentsChanged();
1372  }
1373 }
1374 
1375 /******************************************************************************
1376 * Called when the main page is shown.
1377 * Sets the focus widget to the first edit field.
1378 */
1379 void EditAlarmDlg::slotShowMainPage()
1380 {
1381  if (!mMainPageShown)
1382  {
1383  if (mTemplateName)
1384  mTemplateName->setFocus();
1385  mMainPageShown = true;
1386  }
1387  else
1388  {
1389  // Set scroll position to top, since it otherwise jumps randomly
1390  StackedScrollWidget* main = static_cast<StackedScrollWidget*>(mTabs->widget(0));
1391  main->verticalScrollBar()->setValue(0);
1392  }
1393  if (mTimeWidget)
1394  {
1395  if (!mReadOnly && mRecurPageShown && mRecurrenceEdit->repeatType() == RecurrenceEdit::AT_LOGIN)
1396  mTimeWidget->setDateTime(mRecurrenceEdit->endDateTime());
1397  if (mReadOnly || mRecurrenceEdit->isTimedRepeatType())
1398  mTimeWidget->setMinDateTime(); // don't set a minimum date/time
1399  else
1400  mTimeWidget->setMinDateTimeIsCurrent(); // set the minimum date/time to track the clock
1401  }
1402 }
1403 
1404 /******************************************************************************
1405 * Called when the recurrence edit page is shown.
1406 * The recurrence defaults are set to correspond to the start date.
1407 * The first time, for a new alarm, the recurrence end date is set according to
1408 * the alarm start time.
1409 */
1410 void EditAlarmDlg::slotShowRecurrenceEdit()
1411 {
1412  mRecurPageIndex = mTabs->currentIndex();
1413  if (!mReadOnly && !mTemplate)
1414  {
1415  mAlarmDateTime = mTimeWidget->getDateTime(0, false, false);
1416  KDateTime now = KDateTime::currentDateTime(mAlarmDateTime.timeSpec());
1417  bool expired = (mAlarmDateTime.effectiveKDateTime() < now);
1418  if (mRecurSetDefaultEndDate)
1419  {
1420  mRecurrenceEdit->setDefaultEndDate(expired ? now.date() : mAlarmDateTime.date());
1421  mRecurSetDefaultEndDate = false;
1422  }
1423  mRecurrenceEdit->setStartDate(mAlarmDateTime.date(), now.date());
1424  if (mRecurrenceEdit->repeatType() == RecurrenceEdit::AT_LOGIN)
1425  mRecurrenceEdit->setEndDateTime(expired ? now : mAlarmDateTime.kDateTime());
1426  }
1427  mRecurPageShown = true;
1428 }
1429 
1430 /******************************************************************************
1431 * Called when the recurrence type selection changes.
1432 * Enables/disables date-only alarms as appropriate.
1433 * Enables/disables controls depending on at-login setting.
1434 */
1435 void EditAlarmDlg::slotRecurTypeChange(int repeatType)
1436 {
1437  bool atLogin = (mRecurrenceEdit->repeatType() == RecurrenceEdit::AT_LOGIN);
1438  if (!mTemplate)
1439  {
1440  bool recurs = (mRecurrenceEdit->repeatType() != RecurrenceEdit::NO_RECUR);
1441  if (mDeferGroup)
1442  mDeferGroup->setEnabled(recurs);
1443  mTimeWidget->enableAnyTime(!recurs || repeatType != RecurrenceEdit::SUBDAILY);
1444  if (atLogin)
1445  {
1446  mAlarmDateTime = mTimeWidget->getDateTime(0, false, false);
1447  mRecurrenceEdit->setEndDateTime(mAlarmDateTime.kDateTime());
1448  }
1449  if (mReminder)
1450  mReminder->enableOnceOnly(recurs && !atLogin);
1451  }
1452  if (mReminder)
1453  mReminder->setAfterOnly(atLogin);
1454  mLateCancel->setEnabled(!atLogin);
1455  if (mShowInKorganizer)
1456  mShowInKorganizer->setEnabled(!atLogin);
1457  slotRecurFrequencyChange();
1458 }
1459 
1460 /******************************************************************************
1461 * Called when the recurrence frequency selection changes, or the sub-
1462 * repetition interval changes.
1463 * Updates the recurrence frequency text.
1464 */
1465 void EditAlarmDlg::slotRecurFrequencyChange()
1466 {
1467  slotSetSubRepetition();
1468  KAEvent event;
1469  mRecurrenceEdit->updateEvent(event, false);
1470  mTabs->setTabText(mRecurPageIndex, recurText(event));
1471 }
1472 
1473 /******************************************************************************
1474 * Called when the Repetition within Recurrence button has been pressed to
1475 * display the sub-repetition dialog.
1476 * Alarm repetition has the following restrictions:
1477 * 1) Not allowed for a repeat-at-login alarm
1478 * 2) For a date-only alarm, the repeat interval must be a whole number of days.
1479 * 3) The overall repeat duration must be less than the recurrence interval.
1480 */
1481 void EditAlarmDlg::slotSetSubRepetition()
1482 {
1483  bool dateOnly = mTemplate ? mTemplateAnyTime->isChecked() : mTimeWidget->anyTime();
1484  mRecurrenceEdit->setSubRepetition((mReminder ? mReminder->minutes() : 0), dateOnly);
1485 }
1486 
1487 /******************************************************************************
1488 * Called when one of the template time radio buttons is clicked,
1489 * to enable or disable the template time entry spin boxes.
1490 */
1491 void EditAlarmDlg::slotTemplateTimeType(QAbstractButton*)
1492 {
1493  mTemplateTime->setEnabled(mTemplateUseTime->isChecked());
1494  mTemplateTimeAfter->setEnabled(mTemplateUseTimeAfter->isChecked());
1495 }
1496 
1497 /******************************************************************************
1498 * Called when the "Any time" checkbox is toggled in the date/time widget.
1499 * Sets the advance reminder and late cancel units to days if any time is checked.
1500 */
1501 void EditAlarmDlg::slotAnyTimeToggled(bool anyTime)
1502 {
1503  if (mReminder && mReminder->isReminder())
1504  mReminder->setDateOnly(anyTime);
1505  mLateCancel->setDateOnly(anyTime);
1506 }
1507 
1508 bool EditAlarmDlg::dateOnly() const
1509 {
1510  return mTimeWidget ? mTimeWidget->anyTime() : mTemplateAnyTime->isChecked();
1511 }
1512 
1513 bool EditAlarmDlg::isTimedRecurrence() const
1514 {
1515  return mRecurrenceEdit->isTimedRepeatType();
1516 }
1517 
1518 void EditAlarmDlg::showMainPage()
1519 {
1520  mTabs->setCurrentIndex(mMainPageIndex);
1521 }
1522 
1523 #include "moc_editdlg.cpp"
1524 #include "moc_editdlg_p.cpp"
1525 
1526 // vim: et sw=4:
EditAlarmDlg::closeEvent
virtual void closeEvent(QCloseEvent *)
Definition: editdlg.cpp:935
CheckBox::setReadOnly
virtual void setReadOnly(bool readOnly)
QEvent
QResizeEvent
QWidget
EditAlarmDlg::mAlarmType
KAEvent::SubAction mAlarmType
Definition: editdlg.h:161
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
QSize::setHeight
void setHeight(int height)
EDIT_MORE_KEY
static const char EDIT_MORE_KEY[]
Definition: editdlg.cpp:84
QScrollArea::setWidget
void setWidget(QWidget *widget)
QEvent::type
Type type() const
Reminder::setAfterOnly
void setAfterOnly(bool after)
Definition: reminder.cpp:102
EditCommandAlarmDlg
Definition: editdlgtypes.h:147
KVBox
EditAlarmDlg::RES_PROMPT
Definition: editdlg.h:66
QWidget::isHidden
bool isHidden() const
EditAlarmDlg::lateCancel
LateCancelSelector * lateCancel() const
Definition: editdlg.h:130
QSize::width
int width() const
EditAlarmDlg::slotTry
virtual void slotTry()
Definition: editdlg.cpp:1224
EditAlarmDlg::eventFilter
virtual bool eventFilter(QObject *, QEvent *)
Definition: editdlg.cpp:922
EditAlarmDlg::setTime
void setTime(const DateTime &)
Definition: editdlg.cpp:621
QPushButton::sizeHint
virtual QSize sizeHint() const
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:968
QGridLayout::addWidget
void addWidget(QWidget *widget, int row, int column, QFlags< Qt::AlignmentFlag > alignment)
StackedScrollGroup::adjustSize
QSize adjustSize(bool force=false)
EditAlarmDlg::showEvent
virtual void showEvent(QShowEvent *)
Definition: editdlg.cpp:871
TimeEdit::setReadOnly
virtual void setReadOnly(bool readOnly)
EditAlarmDlg::type_createConfirmAckCheckbox
virtual CheckBox * type_createConfirmAckCheckbox(QWidget *parent)
Definition: editdlg.h:120
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:637
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
TimePeriod::HoursMinutes
QCheckBox::sizeHint
virtual QSize sizeHint() const
EditAlarmDlg::~EditAlarmDlg
virtual ~EditAlarmDlg()
Definition: editdlg.cpp:487
latecancel.h
lineedit.h
QHBoxLayout
AlarmTimeWidget::AT_TIME
Definition: alarmtimewidget.h:46
AlarmTimeWidget::enableAnyTime
void enableAnyTime(bool enable)
Definition: alarmtimewidget.cpp:502
editdlg.h
alarmcalendar.h
QGridLayout
AlarmTimeWidget
Definition: alarmtimewidget.h:41
KDialog
AlarmCalendar::resourceForEvent
AlarmResource * resourceForEvent(const QString &eventID) const
Definition: alarmcalendar.cpp:2117
QFrame::setFrameStyle
void setFrameStyle(int style)
DeferAlarmDlg
Definition: deferdlg.h:38
checkbox.h
AlarmTimeWidget::setMinDateTime
void setMinDateTime(const KDateTime &=KDateTime())
Definition: alarmtimewidget.cpp:409
QFrame::sizeHint
virtual QSize sizeHint() const
AlarmCalendar::templateEvent
KAEvent * templateEvent(const QString &templateName)
Definition: alarmcalendar.cpp:1868
StackedScrollGroup
AlarmTimeWidget::setDateTime
void setDateTime(const DateTime &)
Definition: alarmtimewidget.cpp:358
RecurrenceEdit::endDateTime
KDateTime endDateTime() const
Definition: recurrenceedit.cpp:725
QGridLayout::setSpacing
void setSpacing(int spacing)
TemplatePickDlg
Definition: templatepickdlg.h:38
QString::isNull
bool isNull() const
EditAlarmDlg::showMainPage
void showMainPage()
Definition: editdlg.cpp:1518
QApplication::setActiveWindow
void setActiveWindow(QWidget *active)
QString::clear
void clear()
Reminder::setDateOnly
void setDateOnly(bool dateOnly)
Definition: reminder.cpp:192
QLabel::setBuddy
void setBuddy(QWidget *buddy)
EditAlarmDlg::type_executedTry
virtual void type_executedTry(const QString &text, void *obj)
Definition: editdlg.h:118
QCloseEvent
TimeEdit
kalarmapp.h
the KAlarm application object
EditAlarmDlg::EditAlarmDlg
EditAlarmDlg(bool Template, KAEvent::SubAction, QWidget *parent=0, GetResourceType=RES_PROMPT)
Definition: editdlg.cpp:142
EditAlarmDlg::contentsChanged
void contentsChanged()
Definition: editdlg.cpp:743
QWidget::setEnabled
void setEnabled(bool)
QBoxLayout::addWidget
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QList::count
int count(const T &value) const
QList::append
void append(const T &value)
Reminder::setFocusOnCount
void setFocusOnCount()
Definition: reminder.cpp:200
templatepickdlg.h
QObject::installEventFilter
void installEventFilter(QObject *filterObj)
TimeSpinBox::sizeHint
virtual QSize sizeHint() const
QGroupBox
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:633
EditAlarmDlg::slotButtonClicked
virtual void slotButtonClicked(int button)
Definition: editdlg.cpp:979
QShowEvent
Preferences::timeZone
static KTimeZone timeZone(bool reload=false)
Definition: preferences.cpp:199
QObject
SpinBox2::setReadOnly
virtual void setReadOnly(bool readOnly)
maillistdrag.h
QWidget::setFocus
void setFocus()
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:1180
Reminder::setDefaultUnits
void setDefaultUnits(const KDateTime &)
Definition: reminder.cpp:219
EditAlarmDlg::getAlarmFlags
virtual KAEvent::Flags getAlarmFlags() const
Definition: editdlg.cpp:854
RecurrenceEdit::repeatType
RepeatType repeatType() const
Definition: recurrenceedit.h:78
AkonadiModel::instance
static AkonadiModel * instance()
Definition: akonadimodel.cpp:83
QString::isEmpty
bool isEmpty() const
EditAlarmDlg::setAction
virtual void setAction(KAEvent::SubAction, const AlarmText &=AlarmText())=0
QApplication::focusWidget
QWidget * focusWidget()
QList::removeAll
int removeAll(const T &value)
mainwindow.h
main application window
RecurrenceEdit::subRepetition
Repetition subRepetition() const
Definition: recurrenceedit.cpp:544
EditAlarmDlg::type_aboutToTry
virtual void type_aboutToTry()
Definition: editdlg.h:117
EditAlarmDlg::setShowInKOrganizer
void setShowInKOrganizer(bool)
Definition: editdlg.cpp:642
QVBoxLayout
EditAlarmDlg::create
static EditAlarmDlg * create(bool Template, Type, QWidget *parent=0, GetResourceType=RES_PROMPT)
Definition: editdlg.cpp:104
PackedLayout
QDate
EditAlarmDlg::getEvent
bool getEvent(KAEvent &, AlarmResource *&)
Definition: editdlg.cpp:759
ButtonGroup::addButton
void addButton(QAbstractButton *button)
QLabel::setText
void setText(const QString &)
messagebox.h
QString
QList< EditAlarmDlg * >
QWidget::hide
void hide()
RecurrenceEdit::isTimedRepeatType
bool isTimedRepeatType() const
Definition: recurrenceedit.h:79
EditAlarmDlg::dateOnly
bool dateOnly() const
Definition: editdlg.cpp:1508
LateCancelSelector
Definition: latecancel.h:33
QAbstractScrollArea::verticalScrollBar
QScrollBar * verticalScrollBar() const
QLayout::setMargin
void setMargin(int margin)
QLayout::addWidget
void addWidget(QWidget *w)
theApp
KAlarmApp * theApp()
Definition: kalarmapp.h:263
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:85
RecurrenceEdit
Definition: recurrenceedit.h:59
EditAlarmDlg::instanceCount
static int instanceCount()
Definition: editdlg.cpp:496
reminder.h
SpinBox2::value
int value() const
QResizeEvent::size
const QSize & size() const
QSize
QWidget::setFixedSize
void setFixedSize(const QSize &s)
AutoQPointer
editdlgtypes.h
preferences.h
QAbstractSlider::setValue
void setValue(int)
EditAlarmDlg::type_stateChanged
virtual bool type_stateChanged() const =0
QFrame
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:650
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
LateCancelSelector::setDateOnly
void setDateOnly(bool dateOnly)
Definition: latecancel.cpp:137
QAbstractButton::setChecked
void setChecked(bool)
EditEmailAlarmDlg
Definition: editdlgtypes.h:199
EditAlarmDlg::isTimedRecurrence
bool isTimedRecurrence() const
Definition: editdlg.cpp:1513
QDate::setDate
bool setDate(int year, int month, int day)
EditAlarmDlg::init
void init(const KAEvent *event)
Definition: editdlg.cpp:234
collectionmodel.h
QAbstractButton
RadioButton::setReadOnly
virtual void setReadOnly(bool readOnly)
EditAlarmDlg::type_showOptions
virtual void type_showOptions(bool more)=0
KLineEdit
DeferAlarmDlg::getDateTime
const DateTime & getDateTime() const
Definition: deferdlg.h:45
RecurrenceEdit::setDefaults
void setDefaults(const KDateTime &from)
Set widgets to default values.
Definition: recurrenceedit.cpp:735
QWidget::setWhatsThis
void setWhatsThis(const QString &)
LateCancelSelector::minutes
int minutes() const
Definition: latecancel.cpp:121
TemplatePickDlg::selectedTemplate
const KAEvent * selectedTemplate() const
Definition: templatepickdlg.cpp:96
RecurrenceEdit::activateSubRepetition
void activateSubRepetition()
Definition: recurrenceedit.cpp:581
editdlg_p.h
EditAlarmDlg::setRecurrence
void setRecurrence(const KARecurrence &, int subRepeatInterval, int subRepeatCount)
Definition: editdlg.cpp:625
EditAlarmDlg::slotDefault
virtual void slotDefault()
Definition: editdlg.cpp:1282
EditAlarmDlg::Type
Type
Definition: editdlg.h:64
QLatin1String
functions.h
miscellaneous functions
QBoxLayout::addStretch
void addStretch(int stretch)
KAMessageBox::sorry
static void sorry(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Options(Notify|WindowModal))
EditAlarmDlg
Definition: editdlg.h:60
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
DeferAlarmDlg::setLimit
void setLimit(const DateTime &)
Definition: deferdlg.cpp:142
EditAlarmDlg::RES_USE_EVENT_ID
Definition: editdlg.h:67
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::sizeHint
virtual QSize sizeHint() const
QSize::height
int height() const
EditAlarmDlg::reminder
Reminder * reminder() const
Definition: editdlg.h:129
RecurrenceEdit::AT_LOGIN
Definition: recurrenceedit.h:64
EditDisplayAlarmDlg
Definition: editdlgtypes.h:57
KAMessageBox::warningContinueCancel
static int warningContinueCancel(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Options(Notify|WindowModal))
QString::fromLatin1
QString fromLatin1(const char *str, int size)
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:1884
QLayout::setSpacing
void setSpacing(int)
QPushButton
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
QWidget::show
void show()
Reminder::enableOnceOnly
void enableOnceOnly(bool enable)
Definition: reminder.cpp:143
shellprocess.h
EditAlarmDlg::slotHelp
virtual void slotHelp()
Definition: editdlg.cpp:1249
QDate::addDays
QDate addDays(int ndays) const
EditAlarmDlg::type_init
virtual void type_init(QWidget *parent, QVBoxLayout *frameLayout)=0
EditAlarmDlg::resizeEvent
virtual void resizeEvent(QResizeEvent *)
Definition: editdlg.cpp:965
EditAlarmDlg::saveState
virtual void saveState(const KAEvent *)=0
Definition: editdlg.cpp:671
EditAlarmDlg::i18n_chk_ShowInKOrganizer
static QString i18n_chk_ShowInKOrganizer()
Definition: editdlg.cpp:101
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:68
QRadioButton::sizeHint
virtual QSize sizeHint() const
AlarmTimeWidget::setReadOnly
void setReadOnly(bool)
Definition: alarmtimewidget.cpp:245
main
int main(int argc, char *argv[])
Definition: main.cpp:37
QLabel
AlarmTimeWidget::anyTime
bool anyTime() const
Definition: alarmtimewidget.h:60
TimeEdit::time
QTime time() const
stackedwidgets.h
spinbox.h
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QButtonGroup::checkedButton
QAbstractButton * checkedButton() const
EditAlarmDlg::GetResourceType
GetResourceType
Definition: editdlg.h:65
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:83
EDIT_DIALOG_NAME
static const char EDIT_DIALOG_NAME[]
Definition: editdlg.cpp:81
QBoxLayout::setSpacing
void setSpacing(int spacing)
QWidget::height
height
recurText
QString recurText(const KAEvent &event)
Definition: editdlg.cpp:87
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
QBoxLayout::addLayout
void addLayout(QLayout *layout, int stretch)
AlarmTimeWidget::selectTimeFromNow
void selectTimeFromNow(int minutes=0)
Definition: alarmtimewidget.cpp:264
EditAlarmDlg::createReminder
virtual Reminder * createReminder(QWidget *parent)
Definition: editdlg.h:119
RecurrenceEdit::setSubRepetition
void setSubRepetition(int reminderMinutes, bool dateOnly)
Definition: recurrenceedit.cpp:557
QTimer::singleShot
singleShot
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:82
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:34:51 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
  • pimprint

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