00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kalarm.h"
00022
00023 #include "alarmcalendar.h"
00024 #include "alarmresources.h"
00025 #include "alarmtimewidget.h"
00026 #include "buttongroup.h"
00027 #include "checkbox.h"
00028 #include "deferdlg.h"
00029 #include "dialogscroll.h"
00030 #include "functions.h"
00031 #include "kalarmapp.h"
00032 #include "latecancel.h"
00033 #include "lineedit.h"
00034 #include "mainwindow.h"
00035 #include "packedlayout.h"
00036 #include "preferences.h"
00037 #include "radiobutton.h"
00038 #include "recurrenceedit.h"
00039 #include "reminder.h"
00040 #include "shellprocess.h"
00041 #include "spinbox.h"
00042 #include "templatepickdlg.h"
00043 #include "timeedit.h"
00044 #include "timespinbox.h"
00045 #include "editdlg.moc"
00046 #include "editdlgprivate.moc"
00047 #include "editdlgtypes.h"
00048
00049 #include <QLabel>
00050 #include <QDir>
00051 #include <QStyle>
00052 #include <QGroupBox>
00053 #include <QPushButton>
00054 #include <QGridLayout>
00055 #include <QHBoxLayout>
00056 #include <QVBoxLayout>
00057 #include <QDragEnterEvent>
00058 #include <QResizeEvent>
00059 #include <QShowEvent>
00060
00061 #include <kglobal.h>
00062 #include <klocale.h>
00063 #include <kconfig.h>
00064 #include <kfiledialog.h>
00065 #include <kmessagebox.h>
00066 #include <ktabwidget.h>
00067 #include <khbox.h>
00068 #include <kvbox.h>
00069 #include <kwindowsystem.h>
00070 #include <kdebug.h>
00071
00072 #include <libkdepim/maillistdrag.h>
00073 #include <libkdepim/kvcarddrag.h>
00074 #include <kcal/icaldrag.h>
00075
00076 using namespace KCal;
00077
00078 static const char EDIT_DIALOG_NAME[] = "EditDialog";
00079 static const char TEMPLATE_DIALOG_NAME[] = "EditTemplateDialog";
00080 static const int maxDelayTime = 99*60 + 59;
00081
00082 inline QString recurText(const KAEvent& event)
00083 {
00084 QString r;
00085 if (event.repeatCount())
00086 r = QString::fromLatin1("%1 / %2").arg(event.recurrenceText()).arg(event.repetitionText());
00087 else
00088 r = event.recurrenceText();
00089 return i18nc("@title:tab", "Recurrence - [%1]", r);
00090 }
00091
00092
00093
00094 QString EditAlarmDlg::i18n_chk_ShowInKOrganizer() { return i18nc("@option:check", "Show in KOrganizer"); }
00095
00096
00097 EditAlarmDlg* EditAlarmDlg::create(bool Template, Type type, bool newAlarm, QWidget* parent, GetResourceType getResource)
00098 {
00099 kDebug();
00100 switch (type)
00101 {
00102 case DISPLAY: return new EditDisplayAlarmDlg(Template, newAlarm, parent, getResource);
00103 case COMMAND: return new EditCommandAlarmDlg(Template, newAlarm, parent, getResource);
00104 case EMAIL: return new EditEmailAlarmDlg(Template, newAlarm, parent, getResource);
00105 }
00106 return 0;
00107 }
00108
00109 EditAlarmDlg* EditAlarmDlg::create(bool Template, const KAEvent* event, bool newAlarm, QWidget* parent,
00110 GetResourceType getResource, bool readOnly)
00111 {
00112 switch (event->action())
00113 {
00114 case KAEvent::COMMAND:
00115 if (!event->commandDisplay())
00116 return new EditCommandAlarmDlg(Template, event, newAlarm, parent, getResource, readOnly);
00117
00118 case KAEvent::MESSAGE:
00119 case KAEvent::FILE: return new EditDisplayAlarmDlg(Template, event, newAlarm, parent, getResource, readOnly);
00120 case KAEvent::EMAIL: return new EditEmailAlarmDlg(Template, event, newAlarm, parent, getResource, readOnly);
00121 }
00122 return 0;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 EditAlarmDlg::EditAlarmDlg(bool Template, KAEvent::Action action, QWidget* parent, GetResourceType getResource)
00134 : KDialog(parent),
00135 mAlarmType(action),
00136 mMainPageShown(false),
00137 mRecurPageShown(false),
00138 mRecurSetDefaultEndDate(true),
00139 mTemplateName(0),
00140 mDeferGroup(0),
00141 mDeferChangeButton(0),
00142 mTimeWidget(0),
00143 mShowInKorganizer(0),
00144 mResource(0),
00145 mDeferGroupHeight(0),
00146 mTemplate(Template),
00147 mDesiredReadOnly(false),
00148 mReadOnly(false),
00149 mSavedEvent(0)
00150 {
00151 init(0, getResource);
00152 }
00153
00154 EditAlarmDlg::EditAlarmDlg(bool Template, const KAEvent* event, QWidget* parent,
00155 GetResourceType getResource, bool readOnly)
00156 : KDialog(parent),
00157 mAlarmType(event->action()),
00158 mMainPageShown(false),
00159 mRecurPageShown(false),
00160 mRecurSetDefaultEndDate(true),
00161 mTemplateName(0),
00162 mDeferGroup(0),
00163 mDeferChangeButton(0),
00164 mTimeWidget(0),
00165 mShowInKorganizer(0),
00166 mResource(0),
00167 mDeferGroupHeight(0),
00168 mTemplate(Template),
00169 mDesiredReadOnly(readOnly),
00170 mReadOnly(readOnly),
00171 mSavedEvent(0)
00172 {
00173 init(event, getResource);
00174 }
00175
00176 void EditAlarmDlg::init(const KAEvent* event, GetResourceType getResource)
00177 {
00178 switch (getResource)
00179 {
00180 case RES_USE_EVENT_ID:
00181 if (event)
00182 {
00183 mResourceEventId = event->id();
00184 break;
00185 }
00186
00187 case RES_PROMPT:
00188 mResourceEventId = QString("");
00189 break;
00190 case RES_IGNORE:
00191 default:
00192 mResourceEventId.clear();
00193 break;
00194 }
00195 }
00196
00197 void EditAlarmDlg::init(const KAEvent* event, bool newAlarm)
00198 {
00199 setObjectName(mTemplate ? "TemplEditDlg" : "EditDlg");
00200 QString caption;
00201 if (mReadOnly)
00202 caption = mTemplate ? i18nc("@title:window", "Alarm Template [read-only]")
00203 : event->expired() ? i18nc("@title:window", "Archived Alarm [read-only]")
00204 : i18nc("@title:window", "Alarm [read-only]");
00205 else
00206 caption = type_caption(newAlarm);
00207 setCaption(caption);
00208 setButtons((mReadOnly ? Cancel|Try : mTemplate ? Ok|Cancel|Try : Ok|Cancel|Try|Default));
00209 setDefaultButton(mReadOnly ? Cancel : Ok);
00210 setButtonText(Default, i18nc("@action:button", "Load Template..."));
00211 connect(this, SIGNAL(tryClicked()), SLOT(slotTry()));
00212 connect(this, SIGNAL(defaultClicked()), SLOT(slotDefault()));
00213 KVBox* mainWidget = new KVBox(this);
00214 mainWidget->setMargin(0);
00215 setMainWidget(mainWidget);
00216 if (mTemplate)
00217 {
00218 KHBox* box = new KHBox(mainWidget);
00219 box->setMargin(0);
00220 box->setSpacing(spacingHint());
00221 QLabel* label = new QLabel(i18nc("@label:textbox", "Template name:"), box);
00222 label->setFixedSize(label->sizeHint());
00223 mTemplateName = new KLineEdit(box);
00224 mTemplateName->setReadOnly(mReadOnly);
00225 label->setBuddy(mTemplateName);
00226 box->setWhatsThis(i18nc("@info:whatsthis", "Enter the name of the alarm template"));
00227 box->setFixedHeight(box->sizeHint().height());
00228 }
00229 mTabs = new KTabWidget(mainWidget);
00230
00231 DialogScroll<EditAlarmDlg>* mainScroll = new DialogScroll<EditAlarmDlg>();
00232 mTabs->addTab(mainScroll, i18nc("@title:tab", "Alarm"));
00233 mMainPageIndex = 0;
00234 PageFrame* mainPage = new PageFrame(mainScroll);
00235 mainScroll->setWidget(mainPage);
00236 connect(mainPage, SIGNAL(shown()), SLOT(slotShowMainPage()));
00237 QVBoxLayout* topLayout = new QVBoxLayout(mainPage);
00238 topLayout->setMargin(marginHint());
00239 topLayout->setSpacing(spacingHint());
00240
00241
00242 DialogScroll<EditAlarmDlg>* recurScroll = new DialogScroll<EditAlarmDlg>();
00243 mTabs->addTab(recurScroll, QString());
00244 mRecurPageIndex = 1;
00245 KVBox* recurTab = new KVBox();
00246 recurTab->setMargin(marginHint());
00247 recurScroll->setWidget(recurTab);
00248 mRecurrenceEdit = new RecurrenceEdit(mReadOnly, recurTab);
00249 connect(mRecurrenceEdit, SIGNAL(shown()), SLOT(slotShowRecurrenceEdit()));
00250 connect(mRecurrenceEdit, SIGNAL(typeChanged(int)), SLOT(slotRecurTypeChange(int)));
00251 connect(mRecurrenceEdit, SIGNAL(frequencyChanged()), SLOT(slotRecurFrequencyChange()));
00252 connect(mRecurrenceEdit, SIGNAL(repeatNeedsInitialisation()), SLOT(slotSetSubRepetition()));
00253
00254
00255 QGroupBox* actionBox = new QGroupBox(i18nc("@title:group", "Action"), mainPage);
00256 topLayout->addWidget(actionBox, 1);
00257 QVBoxLayout* layout = new QVBoxLayout(actionBox);
00258 layout->setMargin(marginHint());
00259 layout->setSpacing(spacingHint());
00260
00261 type_init(actionBox, layout);
00262
00263 if (!mTemplate)
00264 {
00265
00266 mDeferGroup = new QGroupBox(i18nc("@title:group", "Deferred Alarm"), mainPage);
00267 topLayout->addWidget(mDeferGroup);
00268 QHBoxLayout* hlayout = new QHBoxLayout(mDeferGroup);
00269 hlayout->setMargin(marginHint());
00270 hlayout->setSpacing(spacingHint());
00271 QLabel* label = new QLabel(i18nc("@label", "Deferred to:"), mDeferGroup);
00272 label->setFixedSize(label->sizeHint());
00273 hlayout->addWidget(label);
00274 mDeferTimeLabel = new QLabel(mDeferGroup);
00275 hlayout->addWidget(mDeferTimeLabel);
00276
00277 mDeferChangeButton = new QPushButton(i18nc("@action:button", "Change..."), mDeferGroup);
00278 mDeferChangeButton->setFixedSize(mDeferChangeButton->sizeHint());
00279 connect(mDeferChangeButton, SIGNAL(clicked()), SLOT(slotEditDeferral()));
00280 mDeferChangeButton->setWhatsThis(i18nc("@info:whatsthis", "Change the alarm's deferred time, or cancel the deferral"));
00281 hlayout->addWidget(mDeferChangeButton);
00282
00283 }
00284
00285 QHBoxLayout* hlayout = new QHBoxLayout();
00286 hlayout->setMargin(0);
00287 topLayout->addLayout(hlayout);
00288
00289
00290 if (mTemplate)
00291 {
00292 QGroupBox* templateTimeBox = new QGroupBox(i18nc("@title:group", "Time"), mainPage);
00293 hlayout->addWidget(templateTimeBox);
00294 QGridLayout* grid = new QGridLayout(templateTimeBox);
00295 grid->setMargin(marginHint());
00296 grid->setSpacing(spacingHint());
00297 mTemplateTimeGroup = new ButtonGroup(templateTimeBox);
00298 connect(mTemplateTimeGroup, SIGNAL(buttonSet(QAbstractButton*)), SLOT(slotTemplateTimeType(QAbstractButton*)));
00299
00300 mTemplateDefaultTime = new RadioButton(i18nc("@option:radio", "Default time"), templateTimeBox);
00301 mTemplateDefaultTime->setFixedSize(mTemplateDefaultTime->sizeHint());
00302 mTemplateDefaultTime->setReadOnly(mReadOnly);
00303 mTemplateDefaultTime->setWhatsThis(i18nc("@info:whatsthis", "Do not specify a start time for alarms based on this template. "
00304 "The normal default start time will be used."));
00305 mTemplateTimeGroup->addButton(mTemplateDefaultTime);
00306 grid->addWidget(mTemplateDefaultTime, 0, 0, Qt::AlignLeft);
00307
00308 KHBox* box = new KHBox(templateTimeBox);
00309 box->setMargin(0);
00310 box->setSpacing(spacingHint());
00311 mTemplateUseTime = new RadioButton(i18nc("@option:radio", "Time:"), box);
00312 mTemplateUseTime->setFixedSize(mTemplateUseTime->sizeHint());
00313 mTemplateUseTime->setReadOnly(mReadOnly);
00314 mTemplateUseTime->setWhatsThis(i18nc("@info:whatsthis", "Specify a start time for alarms based on this template."));
00315 mTemplateTimeGroup->addButton(mTemplateUseTime);
00316 mTemplateTime = new TimeEdit(box);
00317 mTemplateTime->setFixedSize(mTemplateTime->sizeHint());
00318 mTemplateTime->setReadOnly(mReadOnly);
00319 mTemplateTime->setWhatsThis(i18nc("@info:whatsthis",
00320 "<para>Enter the start time for alarms based on this template.</para><para>%1</para>",
00321 TimeSpinBox::shiftWhatsThis()));
00322 box->setStretchFactor(new QWidget(box), 1);
00323 box->setFixedHeight(box->sizeHint().height());
00324 grid->addWidget(box, 0, 1, Qt::AlignLeft);
00325
00326 mTemplateAnyTime = new RadioButton(i18nc("@option:radio", "Date only"), templateTimeBox);
00327 mTemplateAnyTime->setFixedSize(mTemplateAnyTime->sizeHint());
00328 mTemplateAnyTime->setReadOnly(mReadOnly);
00329 mTemplateAnyTime->setWhatsThis(i18nc("@info:whatsthis", "Set the <interface>Date</interface> option for alarms based on this template."));
00330 mTemplateTimeGroup->addButton(mTemplateAnyTime);
00331 grid->addWidget(mTemplateAnyTime, 1, 0, Qt::AlignLeft);
00332
00333 box = new KHBox(templateTimeBox);
00334 box->setMargin(0);
00335 box->setSpacing(spacingHint());
00336 mTemplateUseTimeAfter = new RadioButton(i18nc("@option:radio", "Time from now:"), box);
00337 mTemplateUseTimeAfter->setFixedSize(mTemplateUseTimeAfter->sizeHint());
00338 mTemplateUseTimeAfter->setReadOnly(mReadOnly);
00339 mTemplateUseTimeAfter->setWhatsThis(i18nc("@info:whatsthis",
00340 "Set alarms based on this template to start after the specified time "
00341 "interval from when the alarm is created."));
00342 mTemplateTimeGroup->addButton(mTemplateUseTimeAfter);
00343 mTemplateTimeAfter = new TimeSpinBox(1, maxDelayTime, box);
00344 mTemplateTimeAfter->setValue(1439);
00345 mTemplateTimeAfter->setFixedSize(mTemplateTimeAfter->sizeHint());
00346 mTemplateTimeAfter->setReadOnly(mReadOnly);
00347 mTemplateTimeAfter->setWhatsThis(i18nc("@info:whatsthis", "<para>%1</para><para>%2</para>",
00348 AlarmTimeWidget::i18n_TimeAfterPeriod(), TimeSpinBox::shiftWhatsThis()));
00349 box->setFixedHeight(box->sizeHint().height());
00350 grid->addWidget(box, 1, 1, Qt::AlignLeft);
00351
00352 hlayout->addStretch();
00353 }
00354 else
00355 {
00356 mTimeWidget = new AlarmTimeWidget(i18nc("@title:group", "Time"), AlarmTimeWidget::AT_TIME, mainPage);
00357 connect(mTimeWidget, SIGNAL(dateOnlyToggled(bool)), SLOT(slotAnyTimeToggled(bool)));
00358 topLayout->addWidget(mTimeWidget);
00359 }
00360
00361
00362 mReminder = createReminder(mainPage);
00363 if (mReminder)
00364 {
00365 mReminder->setFixedSize(mReminder->sizeHint());
00366 topLayout->addWidget(mReminder, 0, Qt::AlignLeft);
00367 }
00368
00369
00370 mLateCancel = new LateCancelSelector(true, mainPage);
00371 topLayout->addWidget(mLateCancel, 0, Qt::AlignLeft);
00372
00373 PackedLayout* playout = new PackedLayout(Qt::AlignJustify);
00374 playout->setSpacing(2*spacingHint());
00375 topLayout->addLayout(playout);
00376
00377
00378 CheckBox* confirmAck = type_createConfirmAckCheckbox(mainPage);
00379 if (confirmAck)
00380 {
00381 confirmAck->setFixedSize(confirmAck->sizeHint());
00382 playout->addWidget(confirmAck);
00383 }
00384
00385 if (theApp()->korganizerEnabled())
00386 {
00387
00388 mShowInKorganizer = new CheckBox(i18n_chk_ShowInKOrganizer(), mainPage);
00389 mShowInKorganizer->setFixedSize(mShowInKorganizer->sizeHint());
00390 mShowInKorganizer->setWhatsThis(i18nc("@info:whatsthis", "Check to copy the alarm into KOrganizer's calendar"));
00391 playout->addWidget(mShowInKorganizer);
00392 }
00393
00394 setButtonWhatsThis(Ok, i18nc("@info:whatsthis", "Schedule the alarm at the specified time."));
00395
00396
00397 initValues(event);
00398 if (mTemplateName)
00399 mTemplateName->setFocus();
00400
00401
00402 saveState((event && (mTemplate || !event->isTemplate())) ? event : 0);
00403
00404
00405
00406
00407
00408 mDesktop = KWindowSystem::currentDesktop();
00409 }
00410
00411 EditAlarmDlg::~EditAlarmDlg()
00412 {
00413 delete mSavedEvent;
00414 }
00415
00416
00417
00418
00419 void EditAlarmDlg::initValues(const KAEvent* event)
00420 {
00421 setReadOnly(mDesiredReadOnly);
00422
00423 mChanged = false;
00424 mOnlyDeferred = false;
00425 mExpiredRecurrence = false;
00426 mLateCancel->showAutoClose(false);
00427 bool deferGroupVisible = false;
00428 if (event)
00429 {
00430
00431 if (mTemplate)
00432 mTemplateName->setText(event->templateName());
00433 bool recurs = event->recurs();
00434 if ((recurs || event->repeatCount()) && !mTemplate && event->deferred())
00435 {
00436 deferGroupVisible = true;
00437 mDeferDateTime = event->deferDateTime();
00438 mDeferTimeLabel->setText(mDeferDateTime.formatLocale());
00439 mDeferGroup->show();
00440 }
00441 if (mTemplate)
00442 {
00443
00444 int afterTime = event->isTemplate() ? event->templateAfterTime() : -1;
00445 bool noTime = !afterTime;
00446 bool useTime = !event->mainDateTime().isDateOnly();
00447 RadioButton* button = noTime ? mTemplateDefaultTime :
00448 (afterTime > 0) ? mTemplateUseTimeAfter :
00449 useTime ? mTemplateUseTime : mTemplateAnyTime;
00450 button->setChecked(true);
00451 mTemplateTimeAfter->setValue(afterTime > 0 ? afterTime : 1);
00452 if (!noTime && useTime)
00453 mTemplateTime->setValue(event->mainDateTime().kDateTime().time());
00454 else
00455 mTemplateTime->setValue(0);
00456 }
00457 else
00458 {
00459 if (event->isTemplate())
00460 {
00461
00462 KDateTime now = KDateTime::currentDateTime(Preferences::timeZone());
00463 int afterTime = event->templateAfterTime();
00464 if (afterTime >= 0)
00465 {
00466 mTimeWidget->setDateTime(now.addSecs(afterTime * 60));
00467 mTimeWidget->selectTimeFromNow();
00468 }
00469 else
00470 {
00471 KDateTime dt = event->startDateTime().kDateTime();
00472 dt.setTimeSpec(Preferences::timeZone());
00473 QDate d = now.date();
00474 if (!dt.isDateOnly() && now.time() >= dt.time())
00475 d = d.addDays(1);
00476 dt.setDate(d);
00477 mTimeWidget->setDateTime(dt);
00478 }
00479 }
00480 else
00481 {
00482 mExpiredRecurrence = recurs && event->mainExpired();
00483 mTimeWidget->setDateTime(recurs || event->category() == KCalEvent::ARCHIVED ? event->startDateTime()
00484 : event->mainExpired() ? event->deferDateTime() : event->mainDateTime());
00485 }
00486 }
00487
00488 KAEvent::Action action = event->action();
00489 AlarmText altext;
00490 if (event->commandScript())
00491 altext.setScript(event->cleanText());
00492 else
00493 altext.setText(event->cleanText());
00494 setAction(action, altext);
00495
00496 mLateCancel->setMinutes(event->lateCancel(), event->startDateTime().isDateOnly(),
00497 TimePeriod::HoursMinutes);
00498 if (mShowInKorganizer)
00499 mShowInKorganizer->setChecked(event->copyToKOrganizer());
00500 type_initValues(event);
00501 mRecurrenceEdit->set(*event, (mTemplate || event->isTemplate()));
00502 mTabs->setTabText(mRecurPageIndex, recurText(*event));
00503 }
00504 else
00505 {
00506
00507 KDateTime defaultTime = KDateTime::currentUtcDateTime().addSecs(60).toTimeSpec(Preferences::timeZone());
00508 if (mTemplate)
00509 {
00510 mTemplateDefaultTime->setChecked(true);
00511 mTemplateTime->setValue(0);
00512 mTemplateTimeAfter->setValue(1);
00513 }
00514 else
00515 mTimeWidget->setDateTime(defaultTime);
00516 mLateCancel->setMinutes((Preferences::defaultLateCancel() ? 1 : 0), false, TimePeriod::HoursMinutes);
00517 if (mShowInKorganizer)
00518 mShowInKorganizer->setChecked(Preferences::defaultCopyToKOrganizer());
00519 type_initValues(0);
00520 mRecurrenceEdit->setDefaults(defaultTime);
00521 slotRecurFrequencyChange();
00522 }
00523
00524 if (!deferGroupVisible && mDeferGroup)
00525 mDeferGroup->hide();
00526
00527 bool empty = AlarmCalendar::resources()->events(KCalEvent::TEMPLATE).isEmpty();
00528 enableButton(Default, !empty);
00529 }
00530
00531
00532
00533
00534 void EditAlarmDlg::setReadOnly(bool readOnly)
00535 {
00536 mReadOnly = readOnly;
00537
00538 if (mTimeWidget)
00539 mTimeWidget->setReadOnly(readOnly);
00540 mLateCancel->setReadOnly(readOnly);
00541 if (mDeferChangeButton)
00542 {
00543 if (readOnly)
00544 mDeferChangeButton->hide();
00545 else
00546 mDeferChangeButton->show();
00547 }
00548 if (mShowInKorganizer)
00549 mShowInKorganizer->setReadOnly(readOnly);
00550 }
00551
00552
00553
00554
00555 void EditAlarmDlg::saveState(const KAEvent* event)
00556 {
00557 delete mSavedEvent;
00558 mSavedEvent = 0;
00559 if (event)
00560 mSavedEvent = new KAEvent(*event);
00561 if (mTemplate)
00562 {
00563 mSavedTemplateName = mTemplateName->text();
00564 mSavedTemplateTimeType = mTemplateTimeGroup->checkedButton();
00565 mSavedTemplateTime = mTemplateTime->time();
00566 mSavedTemplateAfterTime = mTemplateTimeAfter->value();
00567 }
00568 checkText(mSavedTextFileCommandMessage, false);
00569 if (mTimeWidget)
00570 mSavedDateTime = mTimeWidget->getDateTime(0, false, false);
00571 mSavedLateCancel = mLateCancel->minutes();
00572 if (mShowInKorganizer)
00573 mSavedShowInKorganizer = mShowInKorganizer->isChecked();
00574 mSavedRecurrenceType = mRecurrenceEdit->repeatType();
00575 }
00576
00577
00578
00579
00580
00581
00582
00583
00584 bool EditAlarmDlg::stateChanged() const
00585 {
00586 mChanged = true;
00587 mOnlyDeferred = false;
00588 if (!mSavedEvent)
00589 return true;
00590 QString textFileCommandMessage;
00591 checkText(textFileCommandMessage, false);
00592 if (mTemplate)
00593 {
00594 if (mSavedTemplateName != mTemplateName->text()
00595 || mSavedTemplateTimeType != mTemplateTimeGroup->checkedButton()
00596 || (mTemplateUseTime->isChecked() && mSavedTemplateTime != mTemplateTime->time())
00597 || (mTemplateUseTimeAfter->isChecked() && mSavedTemplateAfterTime != mTemplateTimeAfter->value()))
00598 return true;
00599 }
00600 else
00601 {
00602 KDateTime dt = mTimeWidget->getDateTime(0, false, false);
00603 if (mSavedDateTime.timeSpec() != dt.timeSpec() || mSavedDateTime != dt)
00604 return true;
00605 }
00606 if (mSavedLateCancel != mLateCancel->minutes()
00607 || (mShowInKorganizer && mSavedShowInKorganizer != mShowInKorganizer->isChecked())
00608 || textFileCommandMessage != mSavedTextFileCommandMessage
00609 || mSavedRecurrenceType != mRecurrenceEdit->repeatType())
00610 return true;
00611 if (type_stateChanged())
00612 return true;
00613 if (mRecurrenceEdit->stateChanged())
00614 return true;
00615 if (mSavedEvent && mSavedEvent->deferred())
00616 mOnlyDeferred = true;
00617 mChanged = false;
00618 return false;
00619 }
00620
00621
00622
00623
00624
00625
00626 bool EditAlarmDlg::getEvent(KAEvent& event, AlarmResource*& resource)
00627 {
00628 resource = mResource;
00629 if (mChanged)
00630 {
00631
00632 setEvent(event, mAlarmMessage, false);
00633 return true;
00634 }
00635
00636
00637 event = *mSavedEvent;
00638 if (mOnlyDeferred)
00639 {
00640
00641
00642 if (mDeferDateTime.isValid())
00643 event.defer(mDeferDateTime, event.reminderDeferral(), false);
00644 else
00645 event.cancelDefer();
00646 }
00647 return false;
00648 }
00649
00650
00651
00652
00653
00654
00655 void EditAlarmDlg::setEvent(KAEvent& event, const QString& text, bool trial)
00656 {
00657 KDateTime dt;
00658 if (!trial)
00659 {
00660 if (!mTemplate)
00661 dt = mAlarmDateTime.effectiveKDateTime();
00662 else if (mTemplateUseTime->isChecked())
00663 dt = KDateTime(QDate(2000,1,1), mTemplateTime->time());
00664 }
00665
00666 type_setEvent(event, dt, text, (trial ? 0 : mLateCancel->minutes()), trial);
00667
00668 if (!trial)
00669 {
00670 if (mRecurrenceEdit->repeatType() != RecurrenceEdit::NO_RECUR)
00671 {
00672 mRecurrenceEdit->updateEvent(event, !mTemplate);
00673 KDateTime now = KDateTime::currentDateTime(mAlarmDateTime.timeSpec());
00674 bool dateOnly = mAlarmDateTime.isDateOnly();
00675 if ((dateOnly && mAlarmDateTime.date() < now.date())
00676 || (!dateOnly && mAlarmDateTime.kDateTime() < now))
00677 {
00678
00679
00680 event.setNextOccurrence(now);
00681 }
00682 mAlarmDateTime = event.startDateTime();
00683 if (mDeferDateTime.isValid() && mDeferDateTime < mAlarmDateTime)
00684 {
00685 bool deferral = true;
00686 bool deferReminder = false;
00687 int reminder = mReminder ? mReminder->minutes() : 0;
00688 if (reminder)
00689 {
00690 DateTime remindTime = mAlarmDateTime.addMins(-reminder);
00691 if (mDeferDateTime >= remindTime)
00692 {
00693 if (remindTime > KDateTime::currentUtcDateTime())
00694 deferral = false;
00695 else if (mDeferDateTime > remindTime)
00696 deferReminder = true;
00697 }
00698 }
00699 if (deferral)
00700 event.defer(mDeferDateTime, deferReminder, false);
00701 }
00702 }
00703 if (mTemplate)
00704 {
00705 int afterTime = mTemplateDefaultTime->isChecked() ? 0
00706 : mTemplateUseTimeAfter->isChecked() ? mTemplateTimeAfter->value() : -1;
00707 event.setTemplate(mTemplateName->text(), afterTime);
00708 }
00709 }
00710 }
00711
00712
00713
00714
00715 int EditAlarmDlg::getAlarmFlags() const
00716 {
00717 return (mShowInKorganizer && mShowInKorganizer->isChecked() ? KAEvent::COPY_KORGANIZER : 0)
00718 | (mRecurrenceEdit->repeatType() == RecurrenceEdit::AT_LOGIN ? KAEvent::REPEAT_AT_LOGIN : 0)
00719 | ((mTemplate ? mTemplateAnyTime->isChecked() : mAlarmDateTime.isDateOnly()) ? KAEvent::ANY_TIME : 0);
00720 }
00721
00722
00723
00724
00725
00726
00727 void EditAlarmDlg::showEvent(QShowEvent* se)
00728 {
00729 KDialog::showEvent(se);
00730 if (!mDeferGroupHeight)
00731 {
00732 if (mDeferGroup)
00733 mDeferGroupHeight = mDeferGroup->height() + spacingHint();
00734 QSize s;
00735 if (KAlarm::readConfigWindowSize(mTemplate ? TEMPLATE_DIALOG_NAME : EDIT_DIALOG_NAME, s))
00736 {
00737 bool defer = mDeferGroup && !mDeferGroup->isHidden();
00738 s.setHeight(s.height() + (defer ? mDeferGroupHeight : 0));
00739 if (!defer)
00740 DialogScroll<EditAlarmDlg>::setSized();
00741 resize(s);
00742 }
00743 }
00744 KWindowSystem::setOnDesktop(winId(), mDesktop);
00745 }
00746
00747
00748
00749
00750
00751
00752 QSize EditAlarmDlg::minimumSizeHint() const
00753 {
00754 QSize s = DialogScroll<EditAlarmDlg>::initMinimumHeight(const_cast<EditAlarmDlg*>(this));
00755 if (s.isValid())
00756 return s;
00757 return KDialog::minimumSizeHint();
00758 }
00759
00760
00761
00762
00763
00764
00765 void EditAlarmDlg::resizeEvent(QResizeEvent* re)
00766 {
00767 if (isVisible())
00768 {
00769 QSize s = re->size();
00770 s.setHeight(s.height() - (!mDeferGroup || mDeferGroup->isHidden() ? 0 : mDeferGroupHeight));
00771 KAlarm::writeConfigWindowSize(mTemplate ? TEMPLATE_DIALOG_NAME : EDIT_DIALOG_NAME, s);
00772 }
00773 KDialog::resizeEvent(re);
00774 }
00775
00776
00777
00778
00779 void EditAlarmDlg::slotButtonClicked(int button)
00780 {
00781 if (button == Ok)
00782 {
00783 if (validate())
00784 accept();
00785 }
00786 else
00787 KDialog::slotButtonClicked(button);
00788 }
00789
00790
00791
00792
00793
00794 bool EditAlarmDlg::validate()
00795 {
00796 if (!stateChanged())
00797 {
00798
00799 if (!mOnlyDeferred)
00800 reject();
00801 return mOnlyDeferred;
00802 }
00803 RecurrenceEdit::RepeatType recurType = mRecurrenceEdit->repeatType();
00804 if (mTimeWidget
00805 && mTabs->currentIndex() == mRecurPageIndex && recurType == RecurrenceEdit::AT_LOGIN)
00806 mTimeWidget->setDateTime(mRecurrenceEdit->endDateTime());
00807 bool timedRecurrence = mRecurrenceEdit->isTimedRepeatType();
00808 if (mTemplate)
00809 {
00810
00811 QString errmsg;
00812 QString name = mTemplateName->text();
00813 if (name.isEmpty())
00814 errmsg = i18nc("@info", "You must enter a name for the alarm template");
00815 else if (name != mSavedTemplateName)
00816 {
00817 if (AlarmCalendar::resources()->templateEvent(name))
00818 errmsg = i18nc("@info", "Template name is already in use");
00819 }
00820 if (!errmsg.isEmpty())
00821 {
00822 mTemplateName->setFocus();
00823 KMessageBox::sorry(this, errmsg);
00824 return false;
00825 }
00826 }
00827 else if (mTimeWidget)
00828 {
00829 QWidget* errWidget;
00830 mAlarmDateTime = mTimeWidget->getDateTime(0, !timedRecurrence, false, &errWidget);
00831 if (errWidget)
00832 {
00833
00834 mTabs->setCurrentIndex(mMainPageIndex);
00835 errWidget->setFocus();
00836 mTimeWidget->getDateTime();
00837 return false;
00838 }
00839 }
00840 if (!type_validate(false))
00841 return false;
00842 if (!mTemplate)
00843 {
00844 if (timedRecurrence)
00845 {
00846 KAEvent event;
00847 AlarmResource* r;
00848 getEvent(event, r);
00849 KDateTime now = KDateTime::currentDateTime(mAlarmDateTime.timeSpec());
00850 bool dateOnly = mAlarmDateTime.isDateOnly();
00851 if ((dateOnly && mAlarmDateTime.date() < now.date())
00852 || (!dateOnly && mAlarmDateTime.kDateTime() < now))
00853 {
00854
00855
00856 if (event.nextOccurrence(now, mAlarmDateTime, KAEvent::ALLOW_FOR_REPETITION) == KAEvent::NO_OCCURRENCE)
00857 {
00858 KMessageBox::sorry(this, i18nc("@info", "Recurrence has already expired"));
00859 return false;
00860 }
00861 if (event.workTimeOnly() && !event.nextTrigger(KAEvent::DISPLAY_TRIGGER).isValid())
00862 {
00863 if (KMessageBox::warningContinueCancel(this, i18nc("@info", "The alarm will never occur during working hours"))
00864 != KMessageBox::Continue)
00865 return false;
00866 }
00867 }
00868 }
00869 QString errmsg;
00870 QWidget* errWidget = mRecurrenceEdit->checkData(mAlarmDateTime.effectiveKDateTime(), errmsg);
00871 if (errWidget)
00872 {
00873 mTabs->setCurrentIndex(mRecurPageIndex);
00874 errWidget->setFocus();
00875 KMessageBox::sorry(this, errmsg);
00876 return false;
00877 }
00878 }
00879 if (recurType != RecurrenceEdit::NO_RECUR)
00880 {
00881 KAEvent recurEvent;
00882 int longestRecurMinutes = -1;
00883 int reminder = mReminder ? mReminder->minutes() : 0;
00884 if (reminder && !mReminder->isOnceOnly())
00885 {
00886 mRecurrenceEdit->updateEvent(recurEvent, false);
00887 longestRecurMinutes = recurEvent.longestRecurrenceInterval().asSeconds() / 60;
00888 if (longestRecurMinutes && reminder >= longestRecurMinutes)
00889 {
00890 mTabs->setCurrentIndex(mMainPageIndex);
00891 mReminder->setFocusOnCount();
00892 KMessageBox::sorry(this, i18nc("@info", "Reminder period must be less than the recurrence interval, unless <interface>%1</interface> is checked."
00893 , Reminder::i18n_chk_FirstRecurrenceOnly()));
00894 return false;
00895 }
00896 }
00897 if (mRecurrenceEdit->subRepeatCount())
00898 {
00899 if (longestRecurMinutes < 0)
00900 {
00901 mRecurrenceEdit->updateEvent(recurEvent, false);
00902 longestRecurMinutes = recurEvent.longestRecurrenceInterval().asSeconds() / 60;
00903 }
00904 if (longestRecurMinutes > 0
00905 && recurEvent.repeatInterval().asSeconds()/60 * recurEvent.repeatCount() >= longestRecurMinutes - reminder)
00906 {
00907 KMessageBox::sorry(this, i18nc("@info", "The duration of a repetition within the recurrence must be less than the recurrence interval minus any reminder period"));
00908 mRecurrenceEdit->activateSubRepetition();
00909 return false;
00910 }
00911 if (!recurEvent.repeatInterval().isDaily()
00912 && ((mTemplate && mTemplateAnyTime->isChecked()) || (!mTemplate && mAlarmDateTime.isDateOnly())))
00913 {
00914 KMessageBox::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"));
00915 mRecurrenceEdit->activateSubRepetition();
00916 return false;
00917 }
00918 }
00919 }
00920 if (!checkText(mAlarmMessage))
00921 return false;
00922
00923 mResource = 0;
00924
00925
00926 if (!mResourceEventId.isNull())
00927 {
00928 if (!mResourceEventId.isEmpty())
00929 {
00930 mResource = AlarmCalendar::resources()->resourceForEvent(mResourceEventId);
00931 AlarmResource::Type type = mTemplate ? AlarmResource::TEMPLATE : AlarmResource::ACTIVE;
00932 if (mResource->alarmType() != type)
00933 mResource = 0;
00934 }
00935 bool cancelled = false;
00936 if (!mResource || !mResource->writable())
00937 {
00938 KCalEvent::Status type = mTemplate ? KCalEvent::TEMPLATE : KCalEvent::ACTIVE;
00939 mResource = AlarmResources::instance()->destination(type, this, false, &cancelled);
00940 }
00941 if (!mResource)
00942 {
00943 if (!cancelled)
00944 KMessageBox::sorry(this, i18nc("@info", "You must select a resource to save the alarm in"));
00945 return false;
00946 }
00947 }
00948 return true;
00949 }
00950
00951
00952
00953
00954
00955 void EditAlarmDlg::slotTry()
00956 {
00957 QString text;
00958 if (checkText(text))
00959 {
00960 if (!type_validate(true))
00961 return;
00962 KAEvent event;
00963 setEvent(event, text, true);
00964 connect(theApp(), SIGNAL(execAlarmSuccess()), SLOT(slotTrySuccess()));
00965 void* proc = theApp()->execAlarm(event, event.firstAlarm(), false, false);
00966 if (proc && proc != (void*)-1)
00967 type_trySuccessMessage((ShellProcess*)proc, text);
00968 }
00969 }
00970
00971
00972
00973
00974 void EditAlarmDlg::slotTrySuccess()
00975 {
00976 type_trySuccessMessage(0, QString());