25 #include "alarmtext.h"
26 #include "identities.h"
29 #ifndef KALARMCAL_USE_KRESOURCES
32 #include <kcal/calendarlocal.h>
34 #include <kholidays/holidays.h>
35 using namespace KHolidays;
37 #include <ksystemtimezone.h>
39 #ifdef KALARMCAL_USE_KRESOURCES
41 #include <kconfiggroup.h>
45 #ifndef KALARMCAL_USE_KRESOURCES
46 using namespace KCalCore;
50 using namespace KHolidays;
55 #ifndef KALARMCAL_USE_KRESOURCES
57 class EmailAddressList :
public KCalCore::Person::List
59 typedef KCal::Person EmailAddress;
60 class EmailAddressList :
public QList<KCal::Person>
64 #ifndef KALARMCAL_USE_KRESOURCES
65 EmailAddressList() : KCalCore::
Person::List() { }
66 EmailAddressList(
const KCalCore::Person::List& list) { operator=(list); }
67 EmailAddressList& operator=(
const KCalCore::Person::List&);
69 EmailAddressList() : QList<KCal::
Person>() { }
70 EmailAddressList(
const QList<KCal::Person>& list) { operator=(list); }
71 EmailAddressList& operator=(
const QList<KCal::Person>&);
73 operator QStringList()
const;
74 QString join(
const QString& separator)
const;
75 QStringList pureAddresses()
const;
76 QString pureAddresses(
const QString& separator)
const;
78 QString address(
int index)
const;
82 class KAAlarm::Private
89 DateTime mNextMainDateTime;
90 Repetition mRepetition;
99 class KAEvent::Private :
public QSharedData
109 TIMED_FLAG = 0x400000,
110 DATE_DEFERRAL = DEFERRAL,
111 TIME_DEFERRAL = DEFERRAL | TIMED_FLAG,
112 DISPLAYING_ = 0x800000,
113 READ_ONLY_FLAGS = 0xF00000
134 REMINDER_ALARM = 0x02,
135 DEFERRED_ALARM = 0x04,
136 DEFERRED_REMINDER_ALARM = REMINDER_ALARM | DEFERRED_ALARM,
139 AT_LOGIN_ALARM = 0x10,
140 DISPLAYING_ALARM = 0x20,
143 PRE_ACTION_ALARM = 0x40,
144 POST_ACTION_ALARM = 0x50
149 #ifndef KALARMCAL_USE_KRESOURCES
157 QColor bgColour, fgColour;
161 int repeatSoundPause;
164 KAEvent::Private::AlarmType
type;
165 KAAlarm::Action action;
167 ExtraActionOptions extraActionOptions;
174 typedef QMap<AlarmType, AlarmData> AlarmMap;
177 Private(
const KDateTime&,
const QString& message,
const QColor& bg,
const QColor& fg,
178 const QFont& f, SubAction,
int lateCancel, Flags flags,
bool changesPending =
false);
179 #ifndef KALARMCAL_USE_KRESOURCES
182 explicit Private(
const KCal::Event*);
184 Private(
const Private&);
185 ~Private() {
delete mRecurrence; }
186 Private& operator=(
const Private& e) {
if (&e !=
this) copy(e);
return *
this; }
187 #ifndef KALARMCAL_USE_KRESOURCES
190 void set(
const KCal::Event*);
192 void set(
const KDateTime&,
const QString& message,
const QColor& bg,
const QColor& fg,
193 const QFont&, SubAction,
int lateCancel, Flags flags,
bool changesPending =
false);
194 void setAudioFile(
const QString& filename,
float volume,
float fadeVolume,
int fadeSeconds,
int repeatPause,
bool allowEmptyFile);
195 OccurType setNextOccurrence(
const KDateTime& preDateTime);
196 void setFirstRecurrence();
197 void setCategory(CalEvent::Type);
198 void setRepeatAtLogin(
bool);
199 void setRepeatAtLoginTrue(
bool clearReminder);
200 void setReminder(
int minutes,
bool onceOnly);
201 void activateReminderAfter(
const DateTime& mainAlarmTime);
202 void defer(
const DateTime&,
bool reminder,
bool adjustRecurrence =
false);
204 #ifndef KALARMCAL_USE_KRESOURCES
205 bool setDisplaying(
const Private&, KAAlarm::Type,
Akonadi::Collection::Id,
const KDateTime& dt,
bool showEdit,
bool showDefer);
208 bool setDisplaying(
const Private&, KAAlarm::Type,
const QString& resourceID,
const KDateTime& dt,
bool showEdit,
bool showDefer);
209 void reinstateFromDisplaying(
const KCal::Event*, QString& resourceID,
bool& showEdit,
bool& showDefer);
210 void setCommandError(
const QString& configString);
211 void setCommandError(CmdErrType,
bool writeConfig)
const;
213 void startChanges() { ++mChangeCount; }
215 void removeExpiredAlarm(KAAlarm::Type);
216 KAAlarm alarm(KAAlarm::Type)
const;
217 KAAlarm firstAlarm()
const;
218 KAAlarm nextAlarm(KAAlarm::Type)
const;
219 #ifndef KALARMCAL_USE_KRESOURCES
220 bool updateKCalEvent(
const KCalCore::Event::Ptr&, UidAction,
bool setCustomProperties =
true)
const;
222 bool updateKCalEvent(KCal::Event*, UidAction)
const;
224 DateTime mainDateTime(
bool withRepeats =
false)
const
225 {
return (withRepeats && mNextRepeat && mRepetition)
226 ? mRepetition.duration(mNextRepeat).end(mNextMainDateTime.kDateTime()) : mNextMainDateTime; }
227 DateTime mainEndRepeatTime()
const
228 {
return mRepetition ? mRepetition.duration().end(mNextMainDateTime.kDateTime()) : mNextMainDateTime; }
229 DateTime deferralLimit(DeferLimitType* = 0)
const;
231 bool isWorkingTime(
const KDateTime&)
const;
232 bool setRepetition(
const Repetition&);
233 bool occursAfter(
const KDateTime& preDateTime,
bool includeRepetitions)
const;
234 OccurType nextOccurrence(
const KDateTime& preDateTime, DateTime& result, OccurOption = IGNORE_REPETITION)
const;
235 OccurType previousOccurrence(
const KDateTime& afterDateTime, DateTime& result,
bool includeRepetitions =
false)
const;
236 void setRecurrence(
const KARecurrence&);
237 #ifndef KALARMCAL_USE_KRESOURCES
241 bool setRecur(KCal::RecurrenceRule::PeriodType,
int freq,
int count,
const QDate& end, KARecurrence::Feb29Type = KARecurrence::Feb29_None);
242 bool setRecur(KCal::RecurrenceRule::PeriodType,
int freq,
int count,
const KDateTime& end, KARecurrence::Feb29Type = KARecurrence::Feb29_None);
244 KARecurrence::Type checkRecur()
const;
246 void calcTriggerTimes()
const;
247 #ifdef KDE_NO_DEBUG_OUTPUT
248 void dumpDebug()
const { }
250 void dumpDebug()
const;
252 #ifndef KALARMCAL_USE_KRESOURCES
257 static void readAlarm(
const KCalCore::Alarm::Ptr&, AlarmData&,
bool audioMain,
bool cmdDisplay =
false);
259 static bool convertRepetition(KCal::Event*);
260 static bool convertStartOfDay(KCal::Event*);
261 static DateTime readDateTime(
const KCal::Event*,
bool dateOnly, DateTime& start);
262 static void readAlarms(
const KCal::Event*,
void* alarmMap,
bool cmdDisplay =
false);
263 static void readAlarm(
const KCal::Alarm*, AlarmData&,
bool audioMain,
bool cmdDisplay =
false);
267 void copy(
const Private&);
268 bool mayOccurDailyDuringWork(
const KDateTime&)
const;
269 int nextWorkRepetition(
const KDateTime& pre)
const;
270 void calcNextWorkingTime(
const DateTime& nextTrigger)
const;
271 DateTime nextWorkingTime()
const;
272 OccurType nextRecurrence(
const KDateTime& preDateTime, DateTime& result)
const;
273 #ifndef KALARMCAL_USE_KRESOURCES
278 void setAudioAlarm(KCal::Alarm*)
const;
279 KCal::Alarm* initKCalAlarm(KCal::Event*,
const DateTime&,
const QStringList& types, AlarmType = INVALID_ALARM)
const;
280 KCal::Alarm* initKCalAlarm(KCal::Event*,
int startOffsetSecs,
const QStringList& types, AlarmType = INVALID_ALARM)
const;
282 inline void set_deferral(DeferType);
283 inline void activate_reminder(
bool activate);
286 #ifdef KALARMCAL_USE_KRESOURCES
287 static QString mCmdErrConfigGroup;
289 static QFont mDefaultFont;
290 static const KHolidays::HolidayRegion* mHolidays;
291 static QBitArray mWorkDays;
292 static QTime mWorkDayStart;
293 static QTime mWorkDayEnd;
294 static int mWorkTimeIndex;
295 #ifdef KALARMCAL_USE_KRESOURCES
296 AlarmResource* mResource;
298 mutable DateTime mAllTrigger;
299 mutable DateTime mMainTrigger;
300 mutable DateTime mAllWorkTrigger;
301 mutable DateTime mMainWorkTrigger;
302 mutable CmdErrType mCommandError;
305 QString mTemplateName;
306 #ifndef KALARMCAL_USE_KRESOURCES
307 QMap<QByteArray, QString> mCustomProperties;
308 Akonadi::Item::Id mItemId;
312 QString mOriginalResourceId;
318 DateTime mStartDateTime;
319 KDateTime mCreatedDateTime;
320 DateTime mNextMainDateTime;
321 KDateTime mAtLoginDateTime;
322 DateTime mDeferralTime;
323 DateTime mDisplayingTime;
324 int mDisplayingFlags;
325 int mReminderMinutes;
326 DateTime mReminderAfterTime;
327 ReminderType mReminderActive;
328 int mDeferDefaultMinutes;
329 bool mDeferDefaultDateOnly;
331 KARecurrence* mRecurrence;
332 Repetition mRepetition;
336 unsigned long mKMailSerialNumber;
337 int mTemplateAfterTime;
341 uint mEmailFromIdentity;
342 EmailAddressList mEmailAddresses;
343 QString mEmailSubject;
344 QStringList mEmailAttachments;
345 mutable int mChangeCount;
346 mutable bool mTriggerChanged;
351 int mRepeatSoundPause;
353 mutable const KHolidays::HolidayRegion*
355 mutable int mWorkTimeOnly;
356 SubAction mActionSubType;
357 CalEvent::Type mCategory;
358 ExtraActionOptions mExtraActionOptions;
359 #ifndef KALARMCAL_USE_KRESOURCES
360 KACalendar::Compat mCompatibility;
364 bool mUseDefaultFont;
367 bool mCommandDisplay;
371 bool mCopyToKOrganizer;
372 bool mReminderOnceOnly;
376 bool mArchiveRepeatAtLogin;
379 bool mDisplayingDefer;
380 bool mDisplayingEdit;
384 static const QByteArray FLAGS_PROPERTY;
385 static const QString DATE_ONLY_FLAG;
386 static const QString EMAIL_BCC_FLAG;
387 static const QString CONFIRM_ACK_FLAG;
388 static const QString KORGANIZER_FLAG;
389 static const QString EXCLUDE_HOLIDAYS_FLAG;
390 static const QString WORK_TIME_ONLY_FLAG;
391 static const QString REMINDER_ONCE_FLAG;
392 static const QString DEFER_FLAG;
393 static const QString LATE_CANCEL_FLAG;
394 static const QString AUTO_CLOSE_FLAG;
395 static const QString TEMPL_AFTER_TIME_FLAG;
396 static const QString KMAIL_SERNUM_FLAG;
397 static const QString ARCHIVE_FLAG;
398 static const QByteArray NEXT_RECUR_PROPERTY;
399 static const QByteArray REPEAT_PROPERTY;
400 static const QByteArray LOG_PROPERTY;
401 static const QString xtermURL;
402 static const QString displayURL;
403 static const QByteArray TYPE_PROPERTY;
404 static const QString FILE_TYPE;
405 static const QString AT_LOGIN_TYPE;
406 static const QString REMINDER_TYPE;
407 static const QString REMINDER_ONCE_TYPE;
408 static const QString TIME_DEFERRAL_TYPE;
409 static const QString DATE_DEFERRAL_TYPE;
410 static const QString DISPLAYING_TYPE;
411 static const QString PRE_ACTION_TYPE;
412 static const QString POST_ACTION_TYPE;
413 static const QString SOUND_REPEAT_TYPE;
414 static const QByteArray NEXT_REPEAT_PROPERTY;
415 static const QString HIDDEN_REMINDER_FLAG;
416 static const QByteArray FONT_COLOUR_PROPERTY;
417 static const QByteArray VOLUME_PROPERTY;
418 static const QString EMAIL_ID_FLAG;
419 static const QString SPEAK_FLAG;
420 static const QString EXEC_ON_DEFERRAL_FLAG;
421 static const QString CANCEL_ON_ERROR_FLAG;
422 static const QString DONT_SHOW_ERROR_FLAG;
423 static const QString DISABLED_STATUS;
424 static const QString DISP_DEFER;
425 static const QString DISP_EDIT;
426 static const QString CMD_ERROR_VALUE;
427 static const QString CMD_ERROR_PRE_VALUE;
428 static const QString CMD_ERROR_POST_VALUE;
429 static const QString SC;
436 QByteArray KAEvent::currentCalendarVersionString() {
return QByteArray(
"2.7.0"); }
437 int KAEvent::currentCalendarVersion() {
return Version(2,7,0); }
443 const QByteArray KAEvent::Private::FLAGS_PROPERTY(
"FLAGS");
444 const QString KAEvent::Private::DATE_ONLY_FLAG = QLatin1String(
"DATE");
445 const QString KAEvent::Private::EMAIL_BCC_FLAG = QLatin1String(
"BCC");
446 const QString KAEvent::Private::CONFIRM_ACK_FLAG = QLatin1String(
"ACKCONF");
447 const QString KAEvent::Private::KORGANIZER_FLAG = QLatin1String(
"KORG");
448 const QString KAEvent::Private::EXCLUDE_HOLIDAYS_FLAG = QLatin1String(
"EXHOLIDAYS");
449 const QString KAEvent::Private::WORK_TIME_ONLY_FLAG = QLatin1String(
"WORKTIME");
450 const QString KAEvent::Private::REMINDER_ONCE_FLAG = QLatin1String(
"ONCE");
451 const QString KAEvent::Private::DEFER_FLAG = QLatin1String(
"DEFER");
452 const QString KAEvent::Private::LATE_CANCEL_FLAG = QLatin1String(
"LATECANCEL");
453 const QString KAEvent::Private::AUTO_CLOSE_FLAG = QLatin1String(
"LATECLOSE");
454 const QString KAEvent::Private::TEMPL_AFTER_TIME_FLAG = QLatin1String(
"TMPLAFTTIME");
455 const QString KAEvent::Private::KMAIL_SERNUM_FLAG = QLatin1String(
"KMAIL");
456 const QString KAEvent::Private::ARCHIVE_FLAG = QLatin1String(
"ARCHIVE");
458 const QByteArray KAEvent::Private::NEXT_RECUR_PROPERTY(
"NEXTRECUR");
459 const QByteArray KAEvent::Private::REPEAT_PROPERTY(
"REPEAT");
460 const QByteArray KAEvent::Private::LOG_PROPERTY(
"LOG");
461 const QString KAEvent::Private::xtermURL = QLatin1String(
"xterm:");
462 const QString KAEvent::Private::displayURL = QLatin1String(
"display:");
465 const QByteArray KAEvent::Private::TYPE_PROPERTY(
"TYPE");
466 const QString KAEvent::Private::FILE_TYPE = QLatin1String(
"FILE");
467 const QString KAEvent::Private::AT_LOGIN_TYPE = QLatin1String(
"LOGIN");
468 const QString KAEvent::Private::REMINDER_TYPE = QLatin1String(
"REMINDER");
469 const QString KAEvent::Private::TIME_DEFERRAL_TYPE = QLatin1String(
"DEFERRAL");
470 const QString KAEvent::Private::DATE_DEFERRAL_TYPE = QLatin1String(
"DATE_DEFERRAL");
471 const QString KAEvent::Private::DISPLAYING_TYPE = QLatin1String(
"DISPLAYING");
472 const QString KAEvent::Private::PRE_ACTION_TYPE = QLatin1String(
"PRE");
473 const QString KAEvent::Private::POST_ACTION_TYPE = QLatin1String(
"POST");
474 const QString KAEvent::Private::SOUND_REPEAT_TYPE = QLatin1String(
"SOUNDREPEAT");
475 const QByteArray KAEvent::Private::NEXT_REPEAT_PROPERTY(
"NEXTREPEAT");
476 const QString KAEvent::Private::HIDDEN_REMINDER_FLAG = QLatin1String(
"HIDE");
478 const QByteArray KAEvent::Private::FONT_COLOUR_PROPERTY(
"FONTCOLOR");
480 const QString KAEvent::Private::EMAIL_ID_FLAG = QLatin1String(
"EMAILID");
482 const QByteArray KAEvent::Private::VOLUME_PROPERTY(
"VOLUME");
483 const QString KAEvent::Private::SPEAK_FLAG = QLatin1String(
"SPEAK");
485 const QString KAEvent::Private::EXEC_ON_DEFERRAL_FLAG = QLatin1String(
"EXECDEFER");
486 const QString KAEvent::Private::CANCEL_ON_ERROR_FLAG = QLatin1String(
"ERRCANCEL");
487 const QString KAEvent::Private::DONT_SHOW_ERROR_FLAG = QLatin1String(
"ERRNOSHOW");
490 const QString KAEvent::Private::DISABLED_STATUS = QLatin1String(
"DISABLED");
493 const QString KAEvent::Private::DISP_DEFER = QLatin1String(
"DEFER");
494 const QString KAEvent::Private::DISP_EDIT = QLatin1String(
"EDIT");
497 #ifdef KALARMCAL_USE_KRESOURCES
498 QString KAEvent::Private::mCmdErrConfigGroup = QLatin1String(
"CommandErrors");
500 const QString KAEvent::Private::CMD_ERROR_VALUE = QLatin1String(
"MAIN");
501 const QString KAEvent::Private::CMD_ERROR_PRE_VALUE = QLatin1String(
"PRE");
502 const QString KAEvent::Private::CMD_ERROR_POST_VALUE = QLatin1String(
"POST");
504 const QString KAEvent::Private::SC = QLatin1String(
";");
506 QFont KAEvent::Private::mDefaultFont;
507 const KHolidays::HolidayRegion* KAEvent::Private::mHolidays = 0;
508 QBitArray KAEvent::Private::mWorkDays(7);
509 QTime KAEvent::Private::mWorkDayStart(9, 0, 0);
510 QTime KAEvent::Private::mWorkDayEnd(17, 0, 0);
511 int KAEvent::Private::mWorkTimeIndex = 1;
514 #ifndef KALARMCAL_USE_KRESOURCES
515 static void setProcedureAlarm(
const Alarm::Ptr&,
const QString& commandLine);
517 static void setProcedureAlarm(
Alarm*,
const QString& commandLine);
519 static QString reminderToString(
int minutes);
527 inline void KAEvent::Private::set_deferral(DeferType type)
531 if (mDeferral == NO_DEFERRAL)
536 if (mDeferral != NO_DEFERRAL)
542 inline void KAEvent::Private::activate_reminder(
bool activate)
544 if (activate && mReminderActive != ACTIVE_REMINDER && mReminderMinutes)
546 if (mReminderActive == NO_REMINDER)
548 mReminderActive = ACTIVE_REMINDER;
550 else if (!activate && mReminderActive != NO_REMINDER)
552 mReminderActive = NO_REMINDER;
553 mReminderAfterTime = DateTime();
562 KAEvent::Private::Private()
564 #ifdef KALARMCAL_USE_KRESOURCES
567 mCommandError(CMD_NO_ERROR),
568 #ifndef KALARMCAL_USE_KRESOURCES
573 mReminderActive(NO_REMINDER),
578 mDeferral(NO_DEFERRAL),
580 mTriggerChanged(false),
584 mCategory(CalEvent::EMPTY),
585 #ifndef KALARMCAL_USE_KRESOURCES
586 mCompatibility(KACalendar::Current),
593 mRepeatAtLogin(false),
597 KAEvent::KAEvent(
const KDateTime& dt,
const QString& message,
const QColor& bg,
const QColor& fg,
const QFont& f,
598 SubAction action,
int lateCancel, Flags flags,
bool changesPending)
599 : d(new Private(dt, message, bg, fg, f, action, lateCancel, flags, changesPending))
603 KAEvent::Private::Private(
const KDateTime& dt,
const QString& message,
const QColor& bg,
const QColor& fg,
const QFont& f,
604 SubAction action,
int lateCancel, Flags flags,
bool changesPending)
610 #ifndef KALARMCAL_USE_KRESOURCES
619 #ifndef KALARMCAL_USE_KRESOURCES
620 KAEvent::Private::Private(
const Event::Ptr& e)
622 KAEvent::Private::Private(
const Event* e)
629 KAEvent::Private::Private(
const KAEvent::Private& e)
643 KAEvent& KAEvent::operator=(
const KAEvent& other)
653 void KAEvent::Private::copy(
const KAEvent::Private& event)
655 #ifdef KALARMCAL_USE_KRESOURCES
656 mResource =
event.mResource;
658 mAllTrigger =
event.mAllTrigger;
659 mMainTrigger =
event.mMainTrigger;
660 mAllWorkTrigger =
event.mAllWorkTrigger;
661 mMainWorkTrigger =
event.mMainWorkTrigger;
662 mCommandError =
event.mCommandError;
663 mEventID =
event.mEventID;
664 mTemplateName =
event.mTemplateName;
665 #ifndef KALARMCAL_USE_KRESOURCES
666 mCustomProperties =
event.mCustomProperties;
667 mItemId =
event.mItemId;
668 mCollectionId =
event.mCollectionId;
670 mOriginalResourceId =
event.mOriginalResourceId;
673 mAudioFile =
event.mAudioFile;
674 mPreAction =
event.mPreAction;
675 mPostAction =
event.mPostAction;
676 mStartDateTime =
event.mStartDateTime;
677 mCreatedDateTime =
event.mCreatedDateTime;
678 mNextMainDateTime =
event.mNextMainDateTime;
679 mAtLoginDateTime =
event.mAtLoginDateTime;
680 mDeferralTime =
event.mDeferralTime;
681 mDisplayingTime =
event.mDisplayingTime;
682 mDisplayingFlags =
event.mDisplayingFlags;
683 mReminderMinutes =
event.mReminderMinutes;
684 mReminderAfterTime =
event.mReminderAfterTime;
685 mReminderActive =
event.mReminderActive;
686 mDeferDefaultMinutes =
event.mDeferDefaultMinutes;
687 mDeferDefaultDateOnly =
event.mDeferDefaultDateOnly;
688 mRevision =
event.mRevision;
689 mRepetition =
event.mRepetition;
690 mNextRepeat =
event.mNextRepeat;
691 mAlarmCount =
event.mAlarmCount;
692 mDeferral =
event.mDeferral;
693 mKMailSerialNumber =
event.mKMailSerialNumber;
694 mTemplateAfterTime =
event.mTemplateAfterTime;
695 mBgColour =
event.mBgColour;
696 mFgColour =
event.mFgColour;
698 mEmailFromIdentity =
event.mEmailFromIdentity;
699 mEmailAddresses =
event.mEmailAddresses;
700 mEmailSubject =
event.mEmailSubject;
701 mEmailAttachments =
event.mEmailAttachments;
702 mLogFile =
event.mLogFile;
703 mSoundVolume =
event.mSoundVolume;
704 mFadeVolume =
event.mFadeVolume;
705 mFadeSeconds =
event.mFadeSeconds;
706 mRepeatSoundPause =
event.mRepeatSoundPause;
707 mLateCancel =
event.mLateCancel;
708 mExcludeHolidays =
event.mExcludeHolidays;
709 mWorkTimeOnly =
event.mWorkTimeOnly;
710 mActionSubType =
event.mActionSubType;
711 mCategory =
event.mCategory;
712 mExtraActionOptions =
event.mExtraActionOptions;
713 #ifndef KALARMCAL_USE_KRESOURCES
714 mCompatibility =
event.mCompatibility;
715 mReadOnly =
event.mReadOnly;
717 mConfirmAck =
event.mConfirmAck;
718 mUseDefaultFont =
event.mUseDefaultFont;
719 mCommandScript =
event.mCommandScript;
720 mCommandXterm =
event.mCommandXterm;
721 mCommandDisplay =
event.mCommandDisplay;
722 mEmailBcc =
event.mEmailBcc;
724 mSpeak =
event.mSpeak;
725 mCopyToKOrganizer =
event.mCopyToKOrganizer;
726 mReminderOnceOnly =
event.mReminderOnceOnly;
727 mAutoClose =
event.mAutoClose;
728 mMainExpired =
event.mMainExpired;
729 mRepeatAtLogin =
event.mRepeatAtLogin;
730 mArchiveRepeatAtLogin =
event.mArchiveRepeatAtLogin;
731 mArchive =
event.mArchive;
732 mDisplaying =
event.mDisplaying;
733 mDisplayingDefer =
event.mDisplayingDefer;
734 mDisplayingEdit =
event.mDisplayingEdit;
735 mEnabled =
event.mEnabled;
737 mTriggerChanged =
event.mTriggerChanged;
739 if (event.mRecurrence)
740 mRecurrence =
new KARecurrence(*event.mRecurrence);
745 #ifndef KALARMCAL_USE_KRESOURCES
757 #ifndef KALARMCAL_USE_KRESOURCES
758 void KAEvent::Private::set(
const Event::Ptr& event)
760 void KAEvent::Private::set(
const Event* event)
765 mCommandError = CMD_NO_ERROR;
766 #ifdef KALARMCAL_USE_KRESOURCES
769 mEventID =
event->uid();
770 mRevision =
event->revision();
771 mTemplateName.clear();
773 #ifndef KALARMCAL_USE_KRESOURCES
777 mOriginalResourceId.clear();
779 mTemplateAfterTime = -1;
783 mCommandXterm =
false;
784 mCommandDisplay =
false;
785 mCopyToKOrganizer =
false;
788 mReminderOnceOnly =
false;
790 mArchiveRepeatAtLogin =
false;
791 mDisplayingDefer =
false;
792 mDisplayingEdit =
false;
793 mDeferDefaultDateOnly =
false;
794 mReminderActive = NO_REMINDER;
795 mReminderMinutes = 0;
796 mDeferDefaultMinutes = 0;
798 mKMailSerialNumber = 0;
799 mExcludeHolidays = 0;
802 mBgColour = QColor(255, 255, 255);
803 mFgColour = QColor(0, 0, 0);
804 #ifndef KALARMCAL_USE_KRESOURCES
806 mReadOnly =
event->isReadOnly();
808 mUseDefaultFont =
true;
813 mCategory = CalEvent::status(event, ¶m);
817 const QStringList params = param.split(SC, QString::KeepEmptyParts);
818 int n = params.count();
821 #ifndef KALARMCAL_USE_KRESOURCES
822 const qlonglong
id = params[0].toLongLong(&ok);
826 mOriginalResourceId = params[0];
828 for (
int i = 1; i < n; ++i)
830 if (params[i] == DISP_DEFER)
831 mDisplayingDefer =
true;
832 if (params[i] == DISP_EDIT)
833 mDisplayingEdit =
true;
837 #ifndef KALARMCAL_USE_KRESOURCES
840 mCustomProperties =
event->customProperties();
841 for (QMap<QByteArray, QString>::Iterator it = mCustomProperties.begin(); it != mCustomProperties.end(); )
843 if (it.key().startsWith(kalarmKey))
844 it = mCustomProperties.erase(it);
850 bool dateOnly =
false;
851 QStringList flags =
event->customProperty(
KACalendar::APPNAME, FLAGS_PROPERTY).split(SC, QString::SkipEmptyParts);
852 flags << QString() << QString();
853 for (
int i = 0, end = flags.count() - 1; i < end; ++i)
855 if (flags[i] == DATE_ONLY_FLAG)
857 else if (flags[i] == CONFIRM_ACK_FLAG)
859 else if (flags[i] == EMAIL_BCC_FLAG)
861 else if (flags[i] == KORGANIZER_FLAG)
862 mCopyToKOrganizer =
true;
863 else if (flags[i] == EXCLUDE_HOLIDAYS_FLAG)
864 mExcludeHolidays = mHolidays;
865 else if (flags[i] == WORK_TIME_ONLY_FLAG)
867 else if (flags[i]== KMAIL_SERNUM_FLAG)
869 const unsigned long n = flags[i + 1].toULong(&ok);
872 mKMailSerialNumber = n;
875 else if (flags[i] == Private::ARCHIVE_FLAG)
877 else if (flags[i] == Private::AT_LOGIN_TYPE)
878 mArchiveRepeatAtLogin =
true;
879 else if (flags[i] == Private::REMINDER_TYPE)
881 if (flags[++i] == Private::REMINDER_ONCE_FLAG)
883 mReminderOnceOnly =
true;
886 const int len = flags[i].length() - 1;
887 mReminderMinutes = -flags[i].left(len).toInt();
888 switch (flags[i].at(len).toLatin1())
891 case 'H': mReminderMinutes *= 60;
break;
892 case 'D': mReminderMinutes *= 1440;
break;
893 default: mReminderMinutes = 0;
break;
896 else if (flags[i] == DEFER_FLAG)
898 QString mins = flags[i + 1];
899 if (mins.endsWith(
'D'))
901 mDeferDefaultDateOnly =
true;
902 mins.truncate(mins.length() - 1);
904 const int n =
static_cast<int>(mins.toUInt(&ok));
907 mDeferDefaultMinutes = n;
910 else if (flags[i] == TEMPL_AFTER_TIME_FLAG)
912 const int n =
static_cast<int>(flags[i + 1].toUInt(&ok));
915 mTemplateAfterTime = n;
918 else if (flags[i] == LATE_CANCEL_FLAG)
920 mLateCancel =
static_cast<int>(flags[i + 1].toUInt(&ok));
923 if (!ok || !mLateCancel)
926 else if (flags[i] == AUTO_CLOSE_FLAG)
928 mLateCancel =
static_cast<int>(flags[i + 1].toUInt(&ok));
931 if (!ok || !mLateCancel)
940 if (prop == xtermURL)
941 mCommandXterm =
true;
942 else if (prop == displayURL)
943 mCommandDisplay =
true;
951 const QStringList list = prop.split(QLatin1Char(
':'));
952 if (list.count() >= 2)
954 const int interval =
static_cast<int>(list[0].toUInt());
955 const int count =
static_cast<int>(list[1].toUInt());
956 if (interval && count)
958 if (interval % (24*60))
959 mRepetition.set(
Duration(interval * 60, Duration::Seconds), count);
961 mRepetition.set(
Duration(interval / (24*60), Duration::Days), count);
965 mNextMainDateTime = readDateTime(event, dateOnly, mStartDateTime);
966 mCreatedDateTime =
event->created();
967 if (dateOnly && !mRepetition.isDaily())
968 mRepetition.set(
Duration(mRepetition.intervalDays(), Duration::Days));
970 mTemplateName =
event->summary();
971 #ifndef KALARMCAL_USE_KRESOURCES
974 if (event->statusStr() == DISABLED_STATUS)
980 mActionSubType = MESSAGE;
982 mRepeatAtLogin =
false;
984 mCommandScript =
false;
985 mExtraActionOptions = 0;
986 mDeferral = NO_DEFERRAL;
989 mRepeatSoundPause = -1;
991 mEmailFromIdentity = 0;
992 mReminderAfterTime = DateTime();
997 mEmailSubject.clear();
998 mEmailAddresses.clear();
999 mEmailAttachments.clear();
1003 readAlarms(event, &alarmMap, mCommandDisplay);
1009 bool isEmailText =
false;
1010 bool setDeferralTime =
false;
1012 for (AlarmMap::ConstIterator it = alarmMap.constBegin(); it != alarmMap.constEnd(); ++it)
1014 const AlarmData& data = it.
value();
1015 const DateTime dateTime = data.alarm->hasStartOffset() ? data.alarm->startOffset().end(mNextMainDateTime.effectiveKDateTime()) : data.alarm->time();
1019 mMainExpired =
false;
1021 alTime.setDateOnly(mStartDateTime.isDateOnly());
1022 if (data.alarm->repeatCount() && data.alarm->snoozeTime())
1024 mRepetition.set(data.alarm->snoozeTime(), data.alarm->repeatCount());
1025 mNextRepeat = data.nextRepeat;
1031 mAudioFile = data.cleanText;
1032 mSpeak = data.speak && mAudioFile.isEmpty();
1033 mBeep = !mSpeak && mAudioFile.isEmpty();
1034 mSoundVolume = (!mBeep && !mSpeak) ? data.soundVolume : -1;
1035 mFadeVolume = (mSoundVolume >= 0 && data.fadeSeconds > 0) ? data.fadeVolume : -1;
1036 mFadeSeconds = (mFadeVolume >= 0) ? data.fadeSeconds : 0;
1037 mRepeatSoundPause = (!mBeep && !mSpeak) ? data.repeatSoundPause : -1;
1039 case AT_LOGIN_ALARM:
1040 mRepeatAtLogin =
true;
1041 mAtLoginDateTime = dateTime.kDateTime();
1042 alTime = mAtLoginDateTime;
1044 case REMINDER_ALARM:
1046 if (data.alarm->startOffset().asSeconds() / 60)
1048 mReminderActive = ACTIVE_REMINDER;
1049 if (mReminderMinutes < 0)
1051 mReminderAfterTime = dateTime;
1052 mReminderAfterTime.setDateOnly(dateOnly);
1053 if (data.hiddenReminder)
1054 mReminderActive = HIDDEN_REMINDER;
1058 case DEFERRED_REMINDER_ALARM:
1059 case DEFERRED_ALARM:
1060 mDeferral = (data.type == DEFERRED_REMINDER_ALARM) ? REMINDER_DEFERRAL : NORMAL_DEFERRAL;
1061 mDeferralTime = dateTime;
1062 if (!data.timedDeferral)
1063 mDeferralTime.setDateOnly(
true);
1064 if (data.alarm->hasStartOffset())
1065 deferralOffset = data.alarm->startOffset();
1067 case DISPLAYING_ALARM:
1070 mDisplayingFlags = data.displayingFlags;
1071 const bool dateOnly = (mDisplayingFlags & DEFERRAL) ? !(mDisplayingFlags & TIMED_FLAG)
1072 : mStartDateTime.isDateOnly();
1073 mDisplayingTime = dateTime;
1074 mDisplayingTime.setDateOnly(dateOnly);
1075 alTime = mDisplayingTime;
1078 case PRE_ACTION_ALARM:
1079 mPreAction = data.cleanText;
1080 mExtraActionOptions = data.extraActionOptions;
1082 case POST_ACTION_ALARM:
1083 mPostAction = data.cleanText;
1090 bool noSetNextTime =
false;
1093 case DEFERRED_REMINDER_ALARM:
1094 case DEFERRED_ALARM:
1099 setDeferralTime =
true;
1100 noSetNextTime =
true;
1103 case REMINDER_ALARM:
1104 case AT_LOGIN_ALARM:
1105 case DISPLAYING_ALARM:
1106 if (!
set && !noSetNextTime)
1107 mNextMainDateTime = alTime;
1115 mText = (mActionSubType == COMMAND) ? data.cleanText.trimmed() : data.cleanText;
1116 switch (data.action)
1119 mCommandScript = data.commandScript;
1120 if (!mCommandDisplay)
1125 mUseDefaultFont = data.defaultFont;
1126 if (data.isEmailText)
1130 mBgColour = data.bgColour;
1131 mFgColour = data.fgColour;
1134 mEmailFromIdentity = data.emailFromId;
1135 mEmailAddresses = data.alarm->mailAddresses();
1136 mEmailSubject = data.alarm->mailSubject();
1137 mEmailAttachments = data.alarm->mailAttachments();
1141 mRepeatSoundPause = data.repeatSoundPause;
1148 if (data.action ==
KAAlarm::FILE && mActionSubType == MESSAGE)
1149 mActionSubType = FILE;
1153 case PRE_ACTION_ALARM:
1154 case POST_ACTION_ALARM:
1161 mKMailSerialNumber = 0;
1164 if (recur && recur->
recurs())
1166 const int nextRepeat = mNextRepeat;
1167 setRecurrence(*recur);
1168 if (nextRepeat <= mRepetition.count())
1169 mNextRepeat = nextRepeat;
1171 else if (mRepetition)
1174 if (mRepetition.isDaily())
1175 recur->
setDaily(mRepetition.intervalDays());
1177 recur->
setMinutely(mRepetition.intervalMinutes());
1179 mRepetition.set(0, 0);
1184 mArchiveRepeatAtLogin =
false;
1185 if (mReminderMinutes > 0)
1187 mReminderMinutes = 0;
1188 mReminderActive = NO_REMINDER;
1190 setRepeatAtLoginTrue(
false);
1197 DateTime dt = mRecurrence->getNextDateTime(mStartDateTime.addDays(-1).kDateTime());
1198 dt.setDateOnly(mStartDateTime.isDateOnly());
1199 if (mDeferralTime.isDateOnly())
1201 mDeferralTime = deferralOffset.
end(dt.kDateTime());
1202 mDeferralTime.setDateOnly(
true);
1205 mDeferralTime = deferralOffset.
end(dt.effectiveKDateTime());
1207 if (mDeferral != NO_DEFERRAL)
1209 if (setDeferralTime)
1210 mNextMainDateTime = mDeferralTime;
1212 mTriggerChanged =
true;
1216 void KAEvent::set(
const KDateTime& dt,
const QString& message,
const QColor& bg,
const QColor& fg,
1217 const QFont& f,
SubAction act,
int lateCancel, Flags flags,
bool changesPending)
1219 d->set(dt, message, bg, fg, f, act, lateCancel, flags, changesPending);
1225 void KAEvent::Private::set(
const KDateTime& dateTime,
const QString& text,
const QColor& bg,
const QColor& fg,
1226 const QFont& font, SubAction action,
int lateCancel, Flags flags,
bool changesPending)
1229 mStartDateTime = dateTime;
1230 mStartDateTime.setDateOnly(flags & ANY_TIME);
1231 mNextMainDateTime = mStartDateTime;
1242 mActionSubType = MESSAGE;
1246 mTemplateName.clear();
1247 #ifndef KALARMCAL_USE_KRESOURCES
1252 mOriginalResourceId.clear();
1255 mPostAction.clear();
1256 mText = (mActionSubType == COMMAND) ? text.trimmed()
1257 : (mActionSubType == AUDIO) ? QString() : text;
1259 mAudioFile = (mActionSubType == AUDIO) ? text : QString();
1262 mTemplateAfterTime = -1;
1268 mLateCancel = lateCancel;
1269 mDeferral = NO_DEFERRAL;
1271 mStartDateTime.setDateOnly(flags & ANY_TIME);
1272 set_deferral((flags & DEFERRAL) ? NORMAL_DEFERRAL : NO_DEFERRAL);
1273 mRepeatAtLogin = flags & REPEAT_AT_LOGIN;
1274 mConfirmAck = flags & CONFIRM_ACK;
1275 mUseDefaultFont = flags & DEFAULT_FONT;
1276 mCommandScript = flags & SCRIPT;
1277 mCommandXterm = flags & EXEC_IN_XTERM;
1278 mCommandDisplay = flags & DISPLAY_COMMAND;
1279 mCopyToKOrganizer = flags & COPY_KORGANIZER;
1280 mExcludeHolidays = (flags & EXCL_HOLIDAYS) ? mHolidays : 0;
1281 mWorkTimeOnly = flags & WORK_TIME_ONLY;
1282 mEmailBcc = flags & EMAIL_BCC;
1283 mEnabled = !(flags & DISABLED);
1284 mDisplaying = flags & DISPLAYING_;
1285 mReminderOnceOnly = flags & REMINDER_ONCE;
1286 mAutoClose = (flags & AUTO_CLOSE) && mLateCancel;
1287 mRepeatSoundPause = (flags & REPEAT_SOUND) ? 0 : -1;
1288 mSpeak = (flags & SPEAK) && action != AUDIO;
1289 mBeep = (flags & BEEP) && action != AUDIO && !mSpeak;
1293 setRepeatAtLoginTrue(
false);
1296 mKMailSerialNumber = 0;
1297 mReminderMinutes = 0;
1298 mDeferDefaultMinutes = 0;
1299 mDeferDefaultDateOnly =
false;
1300 mArchiveRepeatAtLogin =
false;
1301 mReminderActive = NO_REMINDER;
1302 mDisplaying =
false;
1303 mMainExpired =
false;
1304 mDisplayingDefer =
false;
1305 mDisplayingEdit =
false;
1307 mReminderAfterTime = DateTime();
1308 mExtraActionOptions = 0;
1309 #ifndef KALARMCAL_USE_KRESOURCES
1313 mCommandError = CMD_NO_ERROR;
1314 mChangeCount = changesPending ? 1 : 0;
1315 mTriggerChanged =
true;
1324 #ifndef KALARMCAL_USE_KRESOURCES
1327 return d->updateKCalEvent(e, u, setCustomProperties);
1333 return d->updateKCalEvent(e, u);
1337 #ifndef KALARMCAL_USE_KRESOURCES
1338 bool KAEvent::Private::updateKCalEvent(
const Event::Ptr& ev, UidAction uidact,
bool setCustomProperties)
const
1340 bool KAEvent::Private::updateKCalEvent(
Event* ev, UidAction uidact)
const
1348 || (uidact == UID_CHECK && !mEventID.isEmpty() && mEventID != ev->uid())
1349 || (!mAlarmCount && (!archived || !mMainExpired)))
1354 const bool readOnly = ev->isReadOnly();
1356 ev->setUid(mEventID);
1357 #ifndef KALARMCAL_USE_KRESOURCES
1358 ev->setReadOnly(mReadOnly);
1360 ev->setReadOnly(
false);
1362 ev->setTransparency(Event::Transparent);
1367 #ifndef KALARMCAL_USE_KRESOURCES
1368 if (setCustomProperties)
1369 ev->setCustomProperties(mCustomProperties);
1379 #ifndef KALARMCAL_USE_KRESOURCES
1380 param = QString::number(mCollectionId);
1382 param = mOriginalResourceId;
1384 if (mDisplayingDefer)
1385 param += SC + DISP_DEFER;
1386 if (mDisplayingEdit)
1387 param += SC + DISP_EDIT;
1389 #ifndef KALARMCAL_USE_KRESOURCES
1390 CalEvent::setStatus(ev, mCategory, param);
1392 CalEvent::setStatus(ev, mCategory, param);
1395 if (mStartDateTime.isDateOnly())
1396 flags += DATE_ONLY_FLAG;
1398 flags += CONFIRM_ACK_FLAG;
1400 flags += EMAIL_BCC_FLAG;
1401 if (mCopyToKOrganizer)
1402 flags += KORGANIZER_FLAG;
1403 if (mExcludeHolidays)
1404 flags += EXCLUDE_HOLIDAYS_FLAG;
1406 flags += WORK_TIME_ONLY_FLAG;
1408 (flags += (mAutoClose ? AUTO_CLOSE_FLAG : LATE_CANCEL_FLAG)) += QString::number(mLateCancel);
1409 if (mReminderMinutes)
1411 flags += REMINDER_TYPE;
1412 if (mReminderOnceOnly)
1413 flags += REMINDER_ONCE_FLAG;
1414 flags += reminderToString(-mReminderMinutes);
1416 if (mDeferDefaultMinutes)
1418 QString param = QString::number(mDeferDefaultMinutes);
1419 if (mDeferDefaultDateOnly)
1421 (flags += DEFER_FLAG) += param;
1423 if (!mTemplateName.isEmpty() && mTemplateAfterTime >= 0)
1424 (flags += TEMPL_AFTER_TIME_FLAG) += QString::number(mTemplateAfterTime);
1425 if (mKMailSerialNumber)
1426 (flags += KMAIL_SERNUM_FLAG) += QString::number(mKMailSerialNumber);
1427 if (mArchive && !archived)
1429 flags += ARCHIVE_FLAG;
1430 if (mArchiveRepeatAtLogin)
1431 flags += AT_LOGIN_TYPE;
1433 if (!flags.isEmpty())
1438 else if (mCommandDisplay)
1440 else if (!mLogFile.isEmpty())
1443 ev->setCustomStatus(mEnabled ? QString() : DISABLED_STATUS);
1444 ev->setRevision(mRevision);
1459 ev->setDtStart(mStartDateTime.calendarKDateTime());
1460 ev->setAllDay(
false);
1461 ev->setHasEndDate(
false);
1463 const DateTime dtMain = archived ? mStartDateTime : mNextMainDateTime;
1464 int ancillaryType = 0;
1465 DateTime ancillaryTime;
1466 int ancillaryOffset = 0;
1467 if (!mMainExpired || archived)
1476 QDateTime dt = mNextMainDateTime.kDateTime().toTimeSpec(mStartDateTime.timeSpec()).dateTime();
1478 dt.toString(mNextMainDateTime.isDateOnly() ?
"yyyyMMdd" :
"yyyyMMddThhmmss"));
1481 initKCalAlarm(ev, 0, QStringList(), MAIN_ALARM);
1482 ancillaryOffset = 0;
1483 ancillaryType = dtMain.isValid() ? 2 : 0;
1485 else if (mRepetition)
1489 const QString param = QString(
"%1:%2").arg(mRepetition.intervalMinutes()).arg(mRepetition.count());
1494 if (mRepeatAtLogin || (mArchiveRepeatAtLogin && archived))
1497 if (mArchiveRepeatAtLogin)
1498 dtl = mStartDateTime.calendarKDateTime().addDays(-1);
1499 else if (mAtLoginDateTime.isValid())
1500 dtl = mAtLoginDateTime;
1501 else if (mStartDateTime.isDateOnly())
1502 dtl = DateTime(KDateTime::currentLocalDate().addDays(-1), mStartDateTime.timeSpec());
1504 dtl = KDateTime::currentUtcDateTime();
1505 initKCalAlarm(ev, dtl, QStringList(AT_LOGIN_TYPE));
1506 if (!ancillaryType && dtl.isValid())
1508 ancillaryTime = dtl;
1514 DateTime nextDateTime = mNextMainDateTime;
1518 nextDateTime = mStartDateTime;
1526 KDateTime dt = mRecurrence->getNextDateTime(mStartDateTime.addDays(-1).kDateTime());
1527 dt.setDateOnly(mStartDateTime.isDateOnly());
1532 if (mReminderMinutes && (mReminderActive != NO_REMINDER || archived))
1535 if (mReminderMinutes < 0 && mReminderActive != NO_REMINDER)
1538 startOffset = nextDateTime.calendarKDateTime().secsTo(mReminderAfterTime.calendarKDateTime());
1543 startOffset = -mReminderMinutes * 60;
1545 initKCalAlarm(ev, startOffset, QStringList(REMINDER_TYPE));
1547 if (!ancillaryType && (mReminderActive == ACTIVE_REMINDER || archived))
1549 ancillaryOffset = startOffset;
1553 if (mDeferral != NO_DEFERRAL)
1557 if (mDeferralTime.isDateOnly())
1559 startOffset = nextDateTime.secsTo(mDeferralTime.calendarKDateTime());
1560 list += DATE_DEFERRAL_TYPE;
1564 startOffset = nextDateTime.calendarKDateTime().secsTo(mDeferralTime.calendarKDateTime());
1565 list += TIME_DEFERRAL_TYPE;
1567 if (mDeferral == REMINDER_DEFERRAL)
1568 list += REMINDER_TYPE;
1569 initKCalAlarm(ev, startOffset, list);
1570 if (!ancillaryType && mDeferralTime.isValid())
1572 ancillaryOffset = startOffset;
1576 if (!mTemplateName.isEmpty())
1577 ev->setSummary(mTemplateName);
1578 else if (mDisplaying)
1580 QStringList list(DISPLAYING_TYPE);
1581 if (mDisplayingFlags & REPEAT_AT_LOGIN)
1582 list += AT_LOGIN_TYPE;
1583 else if (mDisplayingFlags & DEFERRAL)
1585 if (mDisplayingFlags & TIMED_FLAG)
1586 list += TIME_DEFERRAL_TYPE;
1588 list += DATE_DEFERRAL_TYPE;
1590 if (mDisplayingFlags & REMINDER)
1591 list += REMINDER_TYPE;
1592 initKCalAlarm(ev, mDisplayingTime, list);
1593 if (!ancillaryType && mDisplayingTime.isValid())
1595 ancillaryTime = mDisplayingTime;
1599 if ((mBeep || mSpeak || !mAudioFile.isEmpty()) && mActionSubType != AUDIO)
1602 if (ancillaryType == 2)
1603 initKCalAlarm(ev, ancillaryOffset, QStringList(), AUDIO_ALARM);
1605 initKCalAlarm(ev, ancillaryTime, QStringList(), AUDIO_ALARM);
1607 if (!mPreAction.isEmpty())
1610 if (ancillaryType == 2)
1611 initKCalAlarm(ev, ancillaryOffset, QStringList(PRE_ACTION_TYPE), PRE_ACTION_ALARM);
1613 initKCalAlarm(ev, ancillaryTime, QStringList(PRE_ACTION_TYPE), PRE_ACTION_ALARM);
1615 if (!mPostAction.isEmpty())
1618 if (ancillaryType == 2)
1619 initKCalAlarm(ev, ancillaryOffset, QStringList(POST_ACTION_TYPE), POST_ACTION_ALARM);
1621 initKCalAlarm(ev, ancillaryTime, QStringList(POST_ACTION_TYPE), POST_ACTION_ALARM);
1625 mRecurrence->writeRecurrence(*ev->recurrence());
1627 ev->clearRecurrence();
1628 if (mCreatedDateTime.isValid())
1629 ev->setCreated(mCreatedDateTime);
1630 ev->setReadOnly(readOnly);
1642 #ifndef KALARMCAL_USE_KRESOURCES
1643 Alarm::Ptr KAEvent::Private::initKCalAlarm(
const Event::Ptr& event,
const DateTime& dt,
const QStringList& types, AlarmType type)
const
1645 Alarm* KAEvent::Private::initKCalAlarm(
Event* event,
const DateTime& dt,
const QStringList& types, AlarmType type)
const
1648 const int startOffset = dt.isDateOnly() ? mStartDateTime.secsTo(dt)
1649 : mStartDateTime.calendarKDateTime().secsTo(dt.calendarKDateTime());
1650 return initKCalAlarm(event, startOffset, types, type);
1653 #ifndef KALARMCAL_USE_KRESOURCES
1654 Alarm::Ptr KAEvent::Private::initKCalAlarm(
const Event::Ptr& event,
int startOffsetSecs,
const QStringList& types, AlarmType type)
const
1656 Alarm* KAEvent::Private::initKCalAlarm(
Event* event,
int startOffsetSecs,
const QStringList& types, AlarmType type)
const
1659 QStringList alltypes;
1661 #ifndef KALARMCAL_USE_KRESOURCES
1664 Alarm* alarm =
event->newAlarm();
1667 if (type != MAIN_ALARM)
1677 setAudioAlarm(alarm);
1679 flags << Private::SPEAK_FLAG;
1680 if (mRepeatSoundPause >= 0)
1688 case PRE_ACTION_ALARM:
1689 setProcedureAlarm(alarm, mPreAction);
1690 if (mExtraActionOptions & ExecPreActOnDeferral)
1691 flags << Private::EXEC_ON_DEFERRAL_FLAG;
1692 if (mExtraActionOptions & CancelOnPreActError)
1693 flags << Private::CANCEL_ON_ERROR_FLAG;
1694 if (mExtraActionOptions & DontShowPreActError)
1695 flags << Private::DONT_SHOW_ERROR_FLAG;
1697 case POST_ACTION_ALARM:
1698 setProcedureAlarm(alarm, mPostAction);
1705 QString::number(mNextRepeat));
1707 case REMINDER_ALARM:
1710 if (types == QStringList(REMINDER_TYPE)
1711 && mReminderMinutes < 0 && mReminderActive == HIDDEN_REMINDER)
1715 flags << HIDDEN_REMINDER_FLAG;
1717 bool display =
false;
1718 switch (mActionSubType)
1721 alltypes += FILE_TYPE;
1731 setProcedureAlarm(alarm, mText);
1732 display = mCommandDisplay;
1735 alarm->
setEmailAlarm(mEmailSubject, mText, mEmailAddresses, mEmailAttachments);
1736 if (mEmailFromIdentity)
1737 flags << Private::EMAIL_ID_FLAG << QString::number(mEmailFromIdentity);
1740 setAudioAlarm(alarm);
1741 if (mRepeatSoundPause >= 0)
1743 alltypes += SOUND_REPEAT_TYPE;
1744 if (type == MAIN_ALARM)
1745 alltypes += QString::number(mRepeatSoundPause);
1751 QString::fromLatin1(
"%1;%2;%3").arg(mBgColour.name())
1752 .arg(mFgColour.name())
1753 .arg(mUseDefaultFont ? QString() : mFont.toString()));
1756 case DEFERRED_ALARM:
1757 case DEFERRED_REMINDER_ALARM:
1758 case AT_LOGIN_ALARM:
1759 case DISPLAYING_ALARM:
1763 if (!alltypes.isEmpty())
1765 if (!flags.isEmpty())
1772 return d->mAlarmCount && (d->mAlarmCount != 1 || !d->mRepeatAtLogin);
1777 d->mEnabled = enable;
1785 #ifndef KALARMCAL_USE_KRESOURCES
1793 return d->mReadOnly;
1809 return d->mMainExpired;
1822 KAEvent::Flags KAEvent::Private::flags()
const
1825 if (mBeep) result |= BEEP;
1826 if (mRepeatSoundPause >= 0) result |= REPEAT_SOUND;
1827 if (mEmailBcc) result |= EMAIL_BCC;
1828 if (mStartDateTime.isDateOnly()) result |= ANY_TIME;
1829 if (mSpeak) result |= SPEAK;
1830 if (mRepeatAtLogin) result |= REPEAT_AT_LOGIN;
1831 if (mConfirmAck) result |= CONFIRM_ACK;
1832 if (mUseDefaultFont) result |= DEFAULT_FONT;
1833 if (mCommandScript) result |= SCRIPT;
1834 if (mCommandXterm) result |= EXEC_IN_XTERM;
1835 if (mCommandDisplay) result |= DISPLAY_COMMAND;
1836 if (mCopyToKOrganizer) result |= COPY_KORGANIZER;
1837 if (mExcludeHolidays) result |= EXCL_HOLIDAYS;
1838 if (mWorkTimeOnly) result |= WORK_TIME_ONLY;
1839 if (mReminderOnceOnly) result |= REMINDER_ONCE;
1840 if (mAutoClose) result |= AUTO_CLOSE;
1841 if (!mEnabled) result |= DISABLED;
1859 mEventID = CalEvent::uid(mEventID, s);
1861 mTriggerChanged =
true;
1866 return d->mCategory;
1886 return d->mRevision;
1889 #ifndef KALARMCAL_USE_KRESOURCES
1892 d->mCollectionId =
id;
1897 d->mCollectionId =
id;
1903 return d->mDisplaying ? -1 : d->mCollectionId;
1925 switch (d->mCategory)
1930 default: Q_ASSERT(0);
return false;
1932 if (!collectionMimeTypes.contains(mimetype))
1941 d->mCompatibility = c;
1946 return d->mCompatibility;
1951 return d->mCustomProperties;
1955 void KAEvent::setResource(AlarmResource* r)
1960 AlarmResource* KAEvent::resource()
const
1962 return d->mResource;
1968 return d->mActionSubType;
1973 switch (d->mActionSubType)
1986 if (d->mRepeatAtLogin)
1988 d->mLateCancel = minutes;
1990 d->mAutoClose =
false;
1995 return d->mLateCancel;
2005 return d->mAutoClose;
2008 void KAEvent::setKMailSerialNumber(
unsigned long n)
2010 d->mKMailSerialNumber = n;
2013 unsigned long KAEvent::kmailSerialNumber()
const
2015 return d->mKMailSerialNumber;
2025 return (d->mActionSubType ==
MESSAGE
2026 || d->mActionSubType ==
EMAIL) ? d->mText : QString();
2031 return (d->mActionSubType ==
MESSAGE) ? d->mText : QString();
2036 return (d->mActionSubType ==
FILE) ? d->mText : QString();
2041 return d->mBgColour;
2046 return d->mFgColour;
2051 Private::mDefaultFont = f;
2056 return d->mUseDefaultFont;
2061 return d->mUseDefaultFont ? Private::mDefaultFont : d->mFont;
2066 return (d->mActionSubType ==
COMMAND) ? d->mText : QString();
2071 return d->mCommandScript;
2076 return d->mCommandXterm;
2081 return d->mCommandDisplay;
2084 #ifndef KALARMCAL_USE_KRESOURCES
2087 d->mCommandError = t;
2097 d->setCommandError(t, writeConfig);
2100 void KAEvent::Private::setCommandError(CmdErrType error,
bool writeConfig)
const
2102 kDebug() << mEventID <<
"," << error;
2103 if (error == mCommandError)
2105 mCommandError = error;
2108 KConfigGroup config(KGlobal::config(), mCmdErrConfigGroup);
2109 if (mCommandError == CMD_NO_ERROR)
2110 config.deleteEntry(mEventID);
2114 switch (mCommandError)
2116 case CMD_ERROR: errtext = CMD_ERROR_VALUE;
break;
2117 case CMD_ERROR_PRE: errtext = CMD_ERROR_PRE_VALUE;
break;
2118 case CMD_ERROR_POST: errtext = CMD_ERROR_POST_VALUE;
break;
2119 case CMD_ERROR_PRE_POST:
2120 errtext = CMD_ERROR_PRE_VALUE +
',' + CMD_ERROR_POST_VALUE;
2125 config.writeEntry(mEventID, errtext);
2136 d->setCommandError(configString);
2139 void KAEvent::Private::setCommandError(
const QString& configString)
2141 mCommandError = CMD_NO_ERROR;
2142 const QStringList errs = configString.split(
',');
2143 if (errs.indexOf(CMD_ERROR_VALUE) >= 0)
2144 mCommandError = CMD_ERROR;
2147 if (errs.indexOf(CMD_ERROR_PRE_VALUE) >= 0)
2148 mCommandError = CMD_ERROR_PRE;
2149 if (errs.indexOf(CMD_ERROR_POST_VALUE) >= 0)
2150 mCommandError = static_cast<CmdErrType>(mCommandError | CMD_ERROR_POST);
2154 QString KAEvent::commandErrorConfigGroup()
2156 return Private::mCmdErrConfigGroup;
2162 return d->mCommandError;
2167 d->mLogFile = logfile;
2168 if (!logfile.isEmpty())
2169 d->mCommandDisplay = d->mCommandXterm =
false;
2179 return d->mConfirmAck;
2184 return d->mCopyToKOrganizer;
2187 #ifndef KALARMCAL_USE_KRESOURCES
2189 const QStringList& attachments)
2191 void KAEvent::setEmail(uint from,
const QList<KCal::Person>& addresses,
const QString& subject,
2192 const QStringList& attachments)
2195 d->mEmailFromIdentity = from;
2196 d->mEmailAddresses = addresses;
2197 d->mEmailSubject = subject;
2198 d->mEmailAttachments = attachments;
2203 return (d->mActionSubType ==
EMAIL) ? d->mText : QString();
2208 return d->mEmailFromIdentity;
2211 #ifndef KALARMCAL_USE_KRESOURCES
2217 return d->mEmailAddresses;
2222 return static_cast<QStringList
>(d->mEmailAddresses);
2227 return d->mEmailAddresses.join(sep);
2230 #ifndef KALARMCAL_USE_KRESOURCES
2236 return EmailAddressList(addresses).join(separator);
2241 return d->mEmailAddresses.pureAddresses();
2246 return d->mEmailAddresses.pureAddresses(sep);
2251 return d->mEmailSubject;
2256 return d->mEmailAttachments;
2261 return d->mEmailAttachments.join(sep);
2266 return d->mEmailBcc;
2269 void KAEvent::setAudioFile(
const QString& filename,
float volume,
float fadeVolume,
int fadeSeconds,
int repeatPause,
bool allowEmptyFile)
2271 d->setAudioFile(filename, volume, fadeVolume, fadeSeconds, repeatPause, allowEmptyFile);
2274 void KAEvent::Private::setAudioFile(
const QString& filename,
float volume,
float fadeVolume,
int fadeSeconds,
int repeatPause,
bool allowEmptyFile)
2276 mAudioFile = filename;
2277 mSoundVolume = (!allowEmptyFile && filename.isEmpty()) ? -1 : volume;
2278 if (mSoundVolume >= 0)
2280 mFadeVolume = (fadeSeconds > 0) ? fadeVolume : -1;
2281 mFadeSeconds = (mFadeVolume >= 0) ? fadeSeconds : 0;
2288 mRepeatSoundPause = repeatPause;
2293 return d->mAudioFile;
2298 return d->mSoundVolume;
2303 return d->mSoundVolume >= 0 && d->mFadeSeconds ? d->mFadeVolume : -1;
2308 return d->mSoundVolume >= 0 && d->mFadeVolume >= 0 ? d->mFadeSeconds : 0;
2313 return d->mRepeatSoundPause >= 0;
2318 return d->mRepeatSoundPause;
2328 return (d->mActionSubType ==
MESSAGE
2329 || (d->mActionSubType ==
COMMAND && d->mCommandDisplay))
2339 d->mTemplateName = name;
2340 d->mTemplateAfterTime = afterTime;
2341 d->mTriggerChanged =
true;
2346 return !d->mTemplateName.isEmpty();
2351 return d->mTemplateName;
2356 return d->mTemplateAfterTime == 0;
2361 return d->mTemplateAfterTime;
2366 d->mPreAction = pre;
2367 d->mPostAction = post;
2368 d->mExtraActionOptions = options;
2373 ExtraActionOptions opts(0);
2383 return d->mPreAction;
2388 return d->mPostAction;
2393 return d->mExtraActionOptions;
2412 d->setReminder(minutes, onceOnly);
2415 void KAEvent::Private::setReminder(
int minutes,
bool onceOnly)
2417 if (minutes > 0 && mRepeatAtLogin)
2419 if (minutes != mReminderMinutes || (minutes && mReminderActive != ACTIVE_REMINDER))
2421 if (minutes && mReminderActive == NO_REMINDER)
2423 else if (!minutes && mReminderActive != NO_REMINDER)
2425 mReminderMinutes = minutes;
2426 mReminderActive = minutes ? ACTIVE_REMINDER : NO_REMINDER;
2427 mReminderOnceOnly = onceOnly;
2429 mTriggerChanged =
true;
2439 d->activateReminderAfter(mainAlarmTime);
2442 void KAEvent::Private::activateReminderAfter(
const DateTime& mainAlarmTime)
2444 if (mReminderMinutes >= 0 || mReminderActive == ACTIVE_REMINDER || !mainAlarmTime.
isValid())
2454 || mainAlarmTime != next)
2457 else if (!mRepeatAtLogin)
2460 if (mainAlarmTime != mStartDateTime)
2464 const DateTime reminderTime = mainAlarmTime.
addMins(-mReminderMinutes);
2466 if (nextOccurrence(mainAlarmTime.
effectiveKDateTime(), next, RETURN_REPETITION) != NO_OCCURRENCE
2467 && reminderTime >= next)
2471 activate_reminder(
true);
2472 mReminderAfterTime = reminderTime;
2477 return d->mReminderMinutes;
2482 return d->mReminderActive == Private::ACTIVE_REMINDER;
2487 return d->mReminderOnceOnly;
2492 return d->mDeferral == Private::REMINDER_DEFERRAL;
2503 return d->defer(dt, reminder, adjustRecurrence);
2506 void KAEvent::Private::defer(
const DateTime& dateTime,
bool reminder,
bool adjustRecurrence)
2509 bool setNextRepetition =
false;
2510 bool checkRepetition =
false;
2511 bool checkReminderAfter =
false;
2515 if (mReminderMinutes)
2517 bool deferReminder =
false;
2518 if (mReminderMinutes > 0)
2522 deferReminder =
true;
2523 else if (mReminderActive == ACTIVE_REMINDER || mDeferral == REMINDER_DEFERRAL)
2526 set_deferral(NO_DEFERRAL);
2527 mTriggerChanged =
true;
2530 else if (mReminderMinutes < 0 && reminder)
2531 deferReminder =
true;
2534 set_deferral(REMINDER_DEFERRAL);
2535 mDeferralTime = dateTime;
2536 mTriggerChanged =
true;
2538 if (mReminderActive == ACTIVE_REMINDER)
2540 activate_reminder(
false);
2541 mTriggerChanged =
true;
2544 if (mDeferral != REMINDER_DEFERRAL)
2548 mNextMainDateTime = mDeferralTime = dateTime;
2549 set_deferral(NORMAL_DEFERRAL);
2550 mTriggerChanged =
true;
2551 checkReminderAfter =
true;
2555 mMainExpired =
true;
2560 mArchiveRepeatAtLogin =
true;
2561 mRepeatAtLogin =
false;
2574 set_deferral(NO_DEFERRAL);
2578 set_deferral(REMINDER_DEFERRAL);
2579 mDeferralTime = dateTime;
2580 checkRepetition =
true;
2582 mTriggerChanged =
true;
2587 mDeferralTime = dateTime;
2588 if (mDeferral == NO_DEFERRAL)
2589 set_deferral(NORMAL_DEFERRAL);
2590 mTriggerChanged =
true;
2591 checkReminderAfter =
true;
2592 if (adjustRecurrence)
2594 const KDateTime now = KDateTime::currentUtcDateTime();
2595 if (mainEndRepeatTime() < now)
2599 if (!mMainExpired && setNextOccurrence(now) == NO_OCCURRENCE)
2601 mMainExpired =
true;
2606 setNextRepetition = mRepetition;
2609 checkRepetition =
true;
2611 if (checkReminderAfter && mReminderMinutes < 0 && mReminderActive != NO_REMINDER)
2615 mReminderActive = (mDeferralTime < mReminderAfterTime) ? ACTIVE_REMINDER : HIDDEN_REMINDER;
2617 if (checkRepetition)
2618 setNextRepetition = (mRepetition && mDeferralTime < mainEndRepeatTime());
2619 if (setNextRepetition)
2623 if (mNextMainDateTime >= mDeferralTime)
2626 mNextRepeat = mRepetition.nextRepeatCount(mNextMainDateTime.kDateTime(), mDeferralTime.kDateTime());
2627 mTriggerChanged =
true;
2640 void KAEvent::Private::cancelDefer()
2642 if (mDeferral != NO_DEFERRAL)
2645 set_deferral(NO_DEFERRAL);
2646 mTriggerChanged =
true;
2652 d->mDeferDefaultMinutes = minutes;
2653 d->mDeferDefaultDateOnly = dateOnly;
2658 return d->mDeferral > 0;
2663 return d->mDeferralTime;
2671 return d->deferralLimit(limitType);
2674 DateTime KAEvent::Private::deferralLimit(DeferLimitType* limitType)
const
2676 DeferLimitType ltype = LIMIT_NONE;
2684 const KDateTime now = KDateTime::currentUtcDateTime();
2685 const OccurType type = nextOccurrence(now, endTime, RETURN_REPETITION);
2686 if (type & OCCURRENCE_REPEAT)
2687 ltype = LIMIT_REPETITION;
2688 else if (type == NO_OCCURRENCE)
2690 else if (mReminderActive == ACTIVE_REMINDER && mReminderMinutes > 0
2691 && (now < (reminderTime = endTime.
addMins(-mReminderMinutes))))
2693 endTime = reminderTime;
2694 ltype = LIMIT_REMINDER;
2697 ltype = LIMIT_RECURRENCE;
2699 else if (mReminderMinutes < 0)
2703 if (KDateTime::currentUtcDateTime() < mNextMainDateTime.effectiveKDateTime())
2705 endTime = mNextMainDateTime;
2709 else if (mReminderMinutes > 0
2710 && KDateTime::currentUtcDateTime() < mNextMainDateTime.effectiveKDateTime())
2714 endTime = mNextMainDateTime;
2717 if (ltype != LIMIT_NONE)
2718 endTime = endTime.
addMins(-1);
2726 return d->mDeferDefaultMinutes;
2731 return d->mDeferDefaultDateOnly;
2736 return d->mStartDateTime;
2741 d->mNextMainDateTime = dt;
2742 d->mTriggerChanged =
true;
2747 return d->mainDateTime(withRepeats);
2752 return d->mNextMainDateTime.effectiveTime();
2757 return d->mainEndRepeatTime();
2767 #warning Does this need all trigger times for date-only alarms to be recalculated?
2778 for (
int i = 0, end = events.count(); i < end; ++i)
2780 Private*
const p = events[i]->d;
2782 p->mRecurrence->setStartDateTime(p->mStartDateTime.effectiveKDateTime(),
true);
2788 d->calcTriggerTimes();
2797 const bool reminderAfter = d->mMainExpired && d->mReminderActive && d->mReminderMinutes < 0;
2799 ? (reminderAfter ? d->mAllWorkTrigger : d->mMainWorkTrigger)
2800 : (reminderAfter ? d->mAllTrigger : d->mMainTrigger);
2808 d->mCreatedDateTime = dt;
2813 return d->mCreatedDateTime;
2821 d->setRepeatAtLogin(rl);
2824 void KAEvent::Private::setRepeatAtLogin(
bool rl)
2826 if (rl && !mRepeatAtLogin)
2828 setRepeatAtLoginTrue(
true);
2831 else if (!rl && mRepeatAtLogin)
2833 mRepeatAtLogin = rl;
2834 mTriggerChanged =
true;
2840 void KAEvent::Private::setRepeatAtLoginTrue(
bool clearReminder)
2843 if (mReminderMinutes >= 0 && clearReminder)
2844 setReminder(0,
false);
2847 mCopyToKOrganizer =
false;
2852 return d->mRepeatAtLogin || (includeArchived && d->mArchiveRepeatAtLogin);
2857 d->mExcludeHolidays = ex ? Private::mHolidays : 0;
2864 return d->mExcludeHolidays;
2876 Private::mHolidays = &h;
2881 d->mWorkTimeOnly = wto;
2888 return d->mWorkTimeOnly;
2897 return d->isWorkingTime(dt);
2900 bool KAEvent::Private::isWorkingTime(
const KDateTime& dt)
const
2902 if ((mWorkTimeOnly && !mWorkDays.testBit(dt.date().dayOfWeek() - 1))
2903 || (mExcludeHolidays && mHolidays && mHolidays->isHoliday(dt.date())))
2907 return dt.isDateOnly()
2908 || (dt.time() >= mWorkDayStart && dt.time() < mWorkDayEnd);
2918 if (days != Private::mWorkDays || start != Private::mWorkDayStart || end != Private::mWorkDayEnd)
2920 Private::mWorkDays = days;
2921 Private::mWorkDayStart = start;
2922 Private::mWorkDayEnd = end;
2923 if (!++Private::mWorkTimeIndex)
2924 ++Private::mWorkTimeIndex;
2936 void KAEvent::Private::clearRecur()
2938 if (mRecurrence || mRepetition)
2942 mRepetition.set(0, 0);
2943 mTriggerChanged =
true;
2954 d->setRecurrence(recurrence);
2957 void KAEvent::Private::setRecurrence(
const KARecurrence& recurrence)
2964 mRecurrence->setStartDateTime(mStartDateTime.effectiveKDateTime(), mStartDateTime.isDateOnly());
2965 mTriggerChanged =
true;
2970 mTriggerChanged =
true;
2975 setRepetition(mRepetition);
2992 const bool success = d->setRecur(RecurrenceRule::rMinutely, freq, count, end);
2993 d->mTriggerChanged =
true;
3010 const bool success = d->setRecur(RecurrenceRule::rDaily, freq, count, end);
3014 for (
int i = 0; i < 7; ++i)
3016 if (days.testBit(i))
3020 d->mRecurrence->addWeeklyDays(days);
3022 d->mTriggerChanged =
true;
3039 const bool success = d->setRecur(RecurrenceRule::rWeekly, freq, count, end);
3041 d->mRecurrence->addWeeklyDays(days);
3042 d->mTriggerChanged =
true;
3059 const bool success = d->setRecur(RecurrenceRule::rMonthly, freq, count, end);
3062 for (
int i = 0, end = days.count(); i < end; ++i)
3063 d->mRecurrence->addMonthlyDate(days[i]);
3065 d->mTriggerChanged =
true;
3083 const bool success = d->setRecur(RecurrenceRule::rMonthly, freq, count, end);
3086 for (
int i = 0, end = posns.count(); i < end; ++i)
3087 d->mRecurrence->addMonthlyPos(posns[i].weeknum, posns[i].days);
3089 d->mTriggerChanged =
true;
3109 const bool success = d->setRecur(RecurrenceRule::rYearly, freq, count, end, feb29);
3112 for (
int i = 0, end = months.count(); i < end; ++i)
3113 d->mRecurrence->addYearlyMonth(months[i]);
3115 d->mRecurrence->addMonthlyDate(day);
3117 d->mTriggerChanged =
true;
3136 const bool success = d->setRecur(RecurrenceRule::rYearly, freq, count, end);
3141 for (iend = months.count(); i < iend; ++i)
3142 d->mRecurrence->addYearlyMonth(months[i]);
3143 for (i = 0, iend = posns.count(); i < iend; ++i)
3144 d->mRecurrence->addYearlyPos(posns[i].weeknum, posns[i].days);
3146 d->mTriggerChanged =
true;
3162 KDateTime edt = mNextMainDateTime.kDateTime();
3164 return setRecur(recurType, freq, count, edt, feb29);
3168 if (count >= -1 && (count || end.date().isValid()))
3171 mRecurrence =
new KARecurrence;
3172 if (mRecurrence->init(recurType, freq, count, mNextMainDateTime.kDateTime(), end, feb29))
3186 return d->checkRecur();
3191 return d->mRecurrence;
3201 switch (d->mRecurrence->type())
3210 return d->mRecurrence->frequency();
3220 return d->mRecurrence ? d->mRecurrence->longestInterval() :
Duration(0);
3230 d->setFirstRecurrence();
3233 void KAEvent::Private::setFirstRecurrence()
3235 switch (checkRecur())
3242 if (mRecurrence->yearMonths().isEmpty())
3251 const KDateTime recurStart = mRecurrence->startDateTime();
3252 if (mRecurrence->recursOn(recurStart.date(), recurStart.timeSpec()))
3256 const int frequency = mRecurrence->frequency();
3257 mRecurrence->setFrequency(1);
3259 nextRecurrence(mNextMainDateTime.effectiveKDateTime(), next);
3260 if (!next.isValid())
3261 mRecurrence->setStartDateTime(recurStart, mStartDateTime.isDateOnly());
3264 mRecurrence->setStartDateTime(next.effectiveKDateTime(), next.isDateOnly());
3265 mStartDateTime = mNextMainDateTime = next;
3266 mTriggerChanged =
true;
3268 mRecurrence->setFrequency(frequency);
3276 if (d->mRepeatAtLogin)
3277 return brief ? i18nc(
"@info/plain Brief form of 'At Login'",
"Login") : i18nc(
"@info/plain",
"At login");
3280 const int frequency = d->mRecurrence->frequency();
3281 switch (d->mRecurrence->defaultRRuleConst()->recurrenceType())
3283 case RecurrenceRule::rMinutely:
3285 return i18ncp(
"@info/plain",
"1 Minute",
"%1 Minutes", frequency);
3286 else if (frequency % 60 == 0)
3287 return i18ncp(
"@info/plain",
"1 Hour",
"%1 Hours", frequency/60);
3291 return i18nc(
"@info/plain Hours and minutes",
"%1h %2m", frequency/60, mins.sprintf(
"%02d", frequency%60));
3293 case RecurrenceRule::rDaily:
3294 return i18ncp(
"@info/plain",
"1 Day",
"%1 Days", frequency);
3295 case RecurrenceRule::rWeekly:
3296 return i18ncp(
"@info/plain",
"1 Week",
"%1 Weeks", frequency);
3297 case RecurrenceRule::rMonthly:
3298 return i18ncp(
"@info/plain",
"1 Month",
"%1 Months", frequency);
3299 case RecurrenceRule::rYearly:
3300 return i18ncp(
"@info/plain",
"1 Year",
"%1 Years", frequency);
3301 case RecurrenceRule::rNone:
3306 return brief ? QString() : i18nc(
"@info/plain No recurrence",
"None");
3317 return d->setRepetition(r);
3320 bool KAEvent::Private::setRepetition(
const Repetition& repetition)
3325 if (repetition && !mRepeatAtLogin)
3328 if (!repetition.
isDaily() && mStartDateTime.isDateOnly())
3330 mRepetition.set(0, 0);
3333 Duration longestInterval = mRecurrence->longestInterval();
3334 if (repetition.
duration() >= longestInterval)
3336 const int count = mStartDateTime.isDateOnly()
3339 mRepetition.set(repetition.
interval(), count);
3342 mRepetition = repetition;
3343 mTriggerChanged =
true;
3345 else if (mRepetition)
3347 mRepetition.
set(0, 0);
3348 mTriggerChanged =
true;
3355 return d->mRepetition;
3360 return d->mNextRepeat;
3370 if (!d->mRepetition.isDaily())
3372 const int minutes = d->mRepetition.intervalMinutes();
3374 return i18ncp(
"@info/plain",
"1 Minute",
"%1 Minutes", minutes);
3375 if (minutes % 60 == 0)
3376 return i18ncp(
"@info/plain",
"1 Hour",
"%1 Hours", minutes/60);
3378 return i18nc(
"@info/plain Hours and minutes",
"%1h %2m", minutes/60, mins.sprintf(
"%02d", minutes%60));
3380 const int days = d->mRepetition.intervalDays();
3382 return i18ncp(
"@info/plain",
"1 Day",
"%1 Days", days);
3383 return i18ncp(
"@info/plain",
"1 Week",
"%1 Weeks", days / 7);
3385 return brief ? QString() : i18nc(
"@info/plain No repetition",
"None");
3395 return d->occursAfter(preDateTime, includeRepetitions);
3398 bool KAEvent::Private::occursAfter(
const KDateTime& preDateTime,
bool includeRepetitions)
const
3403 if (mRecurrence->duration() < 0)
3405 dt = mRecurrence->endDateTime();
3408 dt = mNextMainDateTime.effectiveKDateTime();
3409 if (mStartDateTime.isDateOnly())
3411 QDate pre = preDateTime.date();
3413 pre = pre.addDays(-1);
3414 if (pre < dt.date())
3417 else if (preDateTime < dt)
3420 if (includeRepetitions && mRepetition)
3422 if (preDateTime < mRepetition.duration().end(dt))
3438 return d->setNextOccurrence(preDateTime);
3443 if (preDateTime < mNextMainDateTime.effectiveKDateTime())
3444 return FIRST_OR_ONLY_OCCURRENCE;
3445 KDateTime pre = preDateTime;
3450 pre = mRepetition.duration(-mRepetition.count()).end(preDateTime);
3454 if (pre < mNextMainDateTime.effectiveKDateTime())
3456 afterPre = mNextMainDateTime;
3457 type = FIRST_OR_ONLY_OCCURRENCE;
3461 type = nextRecurrence(pre, afterPre);
3462 if (type == NO_OCCURRENCE)
3463 return NO_OCCURRENCE;
3464 if (type != FIRST_OR_ONLY_OCCURRENCE && afterPre != mNextMainDateTime)
3467 mNextMainDateTime = afterPre;
3468 if (mReminderMinutes > 0 && (mDeferral == REMINDER_DEFERRAL || mReminderActive != ACTIVE_REMINDER))
3472 activate_reminder(!mReminderOnceOnly);
3474 if (mDeferral == REMINDER_DEFERRAL)
3475 set_deferral(NO_DEFERRAL);
3476 mTriggerChanged =
true;
3480 return NO_OCCURRENCE;
3484 if (afterPre <= preDateTime)
3487 type =
static_cast<OccurType
>(type | OCCURRENCE_REPEAT);
3488 mNextRepeat = mRepetition.nextRepeatCount(afterPre.
effectiveKDateTime(), preDateTime);
3490 activate_reminder(
false);
3491 if (mDeferral == REMINDER_DEFERRAL)
3492 set_deferral(NO_DEFERRAL);
3493 mTriggerChanged =
true;
3495 else if (mNextRepeat)
3499 mTriggerChanged =
true;
3512 return d->nextOccurrence(preDateTime, result, o);
3516 OccurOption includeRepetitions)
const
3518 KDateTime pre = preDateTime;
3519 if (includeRepetitions != IGNORE_REPETITION)
3522 includeRepetitions = IGNORE_REPETITION;
3524 pre = mRepetition.duration(-mRepetition.count()).end(preDateTime);
3530 type = nextRecurrence(pre, result);
3531 else if (pre < mNextMainDateTime.effectiveKDateTime())
3533 result = mNextMainDateTime;
3534 type = FIRST_OR_ONLY_OCCURRENCE;
3538 result = DateTime();
3539 type = NO_OCCURRENCE;
3542 if (type != NO_OCCURRENCE && result <= preDateTime && includeRepetitions != IGNORE_REPETITION)
3546 const DateTime repeatDT = mRepetition.duration(repetition).end(result.
kDateTime());
3554 const OccurType newType = previousOccurrence(repeatDT.effectiveKDateTime(), dt,
false);
3559 if (includeRepetitions == RETURN_REPETITION && result <= preDateTime)
3562 repetition = mRepetition.nextRepeatCount(result.
kDateTime(), preDateTime);
3563 result = mRepetition.duration(repetition).end(result.
kDateTime());
3564 type =
static_cast<OccurType
>(type | OCCURRENCE_REPEAT);
3569 if (includeRepetitions == RETURN_REPETITION)
3573 type =
static_cast<OccurType
>(type | OCCURRENCE_REPEAT);
3588 return d->previousOccurrence(afterDateTime, result, includeRepetitions);
3592 bool includeRepetitions)
const
3594 Q_ASSERT(!afterDateTime.isDateOnly());
3595 if (mStartDateTime >= afterDateTime)
3597 result = KDateTime();
3598 return NO_OCCURRENCE;
3605 result = mStartDateTime;
3606 type = FIRST_OR_ONLY_OCCURRENCE;
3610 const KDateTime recurStart = mRecurrence->startDateTime();
3611 KDateTime after = afterDateTime.
toTimeSpec(mStartDateTime.timeSpec());
3614 const KDateTime dt = mRecurrence->getPreviousDateTime(after);
3618 return NO_OCCURRENCE;
3619 if (dt == recurStart)
3620 type = FIRST_OR_ONLY_OCCURRENCE;
3621 else if (mRecurrence->getNextDateTime(dt).isValid())
3622 type = result.
isDateOnly() ? RECURRENCE_DATE : RECURRENCE_DATE_TIME;
3624 type = LAST_RECURRENCE;
3627 if (includeRepetitions && mRepetition)
3630 const int repetition = mRepetition.previousRepeatCount(result.
effectiveKDateTime(), afterDateTime);
3633 result = mRepetition.duration(qMin(repetition, mRepetition.count())).end(result.
kDateTime());
3634 return static_cast<OccurType
>(type | OCCURRENCE_REPEAT);
3649 #ifndef KALARMCAL_USE_KRESOURCES
3655 return d->setDisplaying(*e.d, t,
id, dt, showEdit, showDefer);
3658 #ifndef KALARMCAL_USE_KRESOURCES
3660 const KDateTime& repeatAtLoginTime,
bool showEdit,
bool showDefer)
3662 bool KAEvent::Private::setDisplaying(
const KAEvent::Private& event,
KAAlarm::Type alarmType,
const QString& resourceID,
3663 const KDateTime& repeatAtLoginTime,
bool showEdit,
bool showDefer)
3674 KAAlarm al =
event.alarm(alarmType);
3680 #ifndef KALARMCAL_USE_KRESOURCES
3682 mCollectionId = collectionId;
3684 mOriginalResourceId = resourceID;
3686 mDisplayingDefer = showDefer;
3687 mDisplayingEdit = showEdit;
3696 default: mDisplayingFlags = 0;
break;
3708 #ifndef KALARMCAL_USE_KRESOURCES
3714 d->reinstateFromDisplaying(e,
id, showEdit, showDefer);
3717 #ifndef KALARMCAL_USE_KRESOURCES
3720 void KAEvent::Private::reinstateFromDisplaying(
const Event* kcalEvent, QString& resourceID,
bool& showEdit,
bool& showDefer)
3728 #ifndef KALARMCAL_USE_KRESOURCES
3729 collectionId = mCollectionId;
3732 resourceID = mOriginalResourceId;
3733 mOriginalResourceId.clear();
3735 showDefer = mDisplayingDefer;
3736 showEdit = mDisplayingEdit;
3737 mDisplaying =
false;
3751 KAAlarm::Private*
const al_d = al.d;
3752 const int displayingFlags = d->mDisplayingFlags;
3753 if (displayingFlags & REPEAT_AT_LOGIN)
3755 al_d->mRepeatAtLogin =
true;
3758 else if (displayingFlags & Private::DEFERRAL)
3760 al_d->mDeferred =
true;
3761 al_d->mTimedDeferral = (displayingFlags & Private::TIMED_FLAG);
3764 else if (displayingFlags & Private::REMINDER)
3773 return d->mDisplaying;
3788 KAAlarm::Private*
const al_d = al.d;
3792 al_d->mRepeatAtLogin =
false;
3793 al_d->mDeferred =
false;
3800 al_d->mNextMainDateTime = mNextMainDateTime;
3801 al_d->mRepetition = mRepetition;
3802 al_d->mNextRepeat = mNextRepeat;
3806 if (mReminderActive == ACTIVE_REMINDER)
3809 if (mReminderMinutes < 0)
3810 al_d->mNextMainDateTime = mReminderAfterTime;
3811 else if (mReminderOnceOnly)
3812 al_d->mNextMainDateTime = mStartDateTime.addMins(-mReminderMinutes);
3814 al_d->mNextMainDateTime = mNextMainDateTime.addMins(-mReminderMinutes);
3818 if (mDeferral != REMINDER_DEFERRAL)
3822 if (mDeferral != NO_DEFERRAL)
3825 al_d->mNextMainDateTime = mDeferralTime;
3826 al_d->mDeferred =
true;
3827 al_d->mTimedDeferral = !mDeferralTime.isDateOnly();
3834 al_d->mNextMainDateTime = mAtLoginDateTime;
3835 al_d->mRepeatAtLogin =
true;
3842 al_d->mNextMainDateTime = mDisplayingTime;
3862 return d->firstAlarm();
3865 KAAlarm KAEvent::Private::firstAlarm()
const
3883 return d->nextAlarm(previousAlarm.
type());
3888 return d->nextAlarm(previousType);
3893 switch (previousType)
3896 if (mReminderActive == ACTIVE_REMINDER)
3901 if (mDeferral == REMINDER_DEFERRAL)
3903 if (mDeferral == NORMAL_DEFERRAL)
3926 return d->mAlarmCount;
3936 d->removeExpiredAlarm(type);
3939 void KAEvent::Private::removeExpiredAlarm(
KAAlarm::Type type)
3941 const int count = mAlarmCount;
3945 if (!mReminderActive || mReminderMinutes > 0)
3952 mMainExpired =
true;
3954 set_deferral(NO_DEFERRAL);
3957 mDisplaying =
false;
3965 mArchiveRepeatAtLogin =
true;
3966 mRepeatAtLogin =
false;
3973 activate_reminder(
false);
3977 set_deferral(NO_DEFERRAL);
3982 mDisplaying =
false;
3990 if (mAlarmCount != count)
3991 mTriggerChanged =
true;
4008 void KAEvent::Private::endChanges()
4010 if (mChangeCount > 0)
4014 #ifndef KALARMCAL_USE_KRESOURCES
4021 for (
int i = 0, count = objList.count(); i < count; ++i)
4022 ptrs += &objList[i];
4029 #ifndef KDE_NO_DEBUG_OUTPUT
4034 #ifndef KDE_NO_DEBUG_OUTPUT
4035 void KAEvent::Private::dumpDebug()
const
4037 kDebug() <<
"KAEvent dump:";
4038 #ifdef KALARMCAL_USE_KRESOURCES
4039 if (mResource) { kDebug() <<
"-- mResource:" << (
void*)mResource; }
4041 kDebug() <<
"-- mEventID:" << mEventID;
4042 kDebug() <<
"-- mActionSubType:" << (mActionSubType == MESSAGE ?
"MESSAGE" : mActionSubType == FILE ?
"FILE" : mActionSubType == COMMAND ?
"COMMAND" : mActionSubType == EMAIL ?
"EMAIL" : mActionSubType == AUDIO ?
"AUDIO" :
"??");
4043 kDebug() <<
"-- mNextMainDateTime:" << mNextMainDateTime.toString();
4044 kDebug() <<
"-- mCommandError:" << mCommandError;
4045 kDebug() <<
"-- mAllTrigger:" << mAllTrigger.toString();
4046 kDebug() <<
"-- mMainTrigger:" << mMainTrigger.toString();
4047 kDebug() <<
"-- mAllWorkTrigger:" << mAllWorkTrigger.toString();
4048 kDebug() <<
"-- mMainWorkTrigger:" << mMainWorkTrigger.toString();
4049 kDebug() <<
"-- mCategory:" << mCategory;
4050 if (!mTemplateName.isEmpty())
4052 kDebug() <<
"-- mTemplateName:" << mTemplateName;
4053 kDebug() <<
"-- mTemplateAfterTime:" << mTemplateAfterTime;
4055 kDebug() <<
"-- mText:" << mText;
4056 if (mActionSubType == MESSAGE || mActionSubType == FILE)
4058 kDebug() <<
"-- mBgColour:" << mBgColour.name();
4059 kDebug() <<
"-- mFgColour:" << mFgColour.name();
4060 kDebug() <<
"-- mUseDefaultFont:" << mUseDefaultFont;
4061 if (!mUseDefaultFont)
4062 kDebug() <<
"-- mFont:" << mFont.toString();
4063 kDebug() <<
"-- mSpeak:" << mSpeak;
4064 kDebug() <<
"-- mAudioFile:" << mAudioFile;
4065 kDebug() <<
"-- mPreAction:" << mPreAction;
4066 kDebug() <<
"-- mExecPreActOnDeferral:" << (mExtraActionOptions & ExecPreActOnDeferral);
4067 kDebug() <<
"-- mCancelOnPreActErr:" << (mExtraActionOptions & CancelOnPreActError);
4068 kDebug() <<
"-- mDontShowPreActErr:" << (mExtraActionOptions & DontShowPreActError);
4069 kDebug() <<
"-- mPostAction:" << mPostAction;
4070 kDebug() <<
"-- mLateCancel:" << mLateCancel;
4071 kDebug() <<
"-- mAutoClose:" << mAutoClose;
4073 else if (mActionSubType == COMMAND)
4075 kDebug() <<
"-- mCommandScript:" << mCommandScript;
4076 kDebug() <<
"-- mCommandXterm:" << mCommandXterm;
4077 kDebug() <<
"-- mCommandDisplay:" << mCommandDisplay;
4078 kDebug() <<
"-- mLogFile:" << mLogFile;
4080 else if (mActionSubType == EMAIL)
4082 kDebug() <<
"-- mEmail: FromKMail:" << mEmailFromIdentity;
4083 kDebug() <<
"-- Addresses:" << mEmailAddresses.join(
",");
4084 kDebug() <<
"-- Subject:" << mEmailSubject;
4085 kDebug() <<
"-- Attachments:" << mEmailAttachments.join(
",");
4086 kDebug() <<
"-- Bcc:" << mEmailBcc;
4088 else if (mActionSubType == AUDIO)
4089 kDebug() <<
"-- mAudioFile:" << mAudioFile;
4090 kDebug() <<
"-- mBeep:" << mBeep;
4091 if (mActionSubType == AUDIO || !mAudioFile.isEmpty())
4093 if (mSoundVolume >= 0)
4095 kDebug() <<
"-- mSoundVolume:" << mSoundVolume;
4096 if (mFadeVolume >= 0)
4098 kDebug() <<
"-- mFadeVolume:" << mFadeVolume;
4099 kDebug() <<
"-- mFadeSeconds:" << mFadeSeconds;
4102 kDebug() <<
"-- mFadeVolume:-:";
4105 kDebug() <<
"-- mSoundVolume:-:";
4106 kDebug() <<
"-- mRepeatSoundPause:" << mRepeatSoundPause;
4108 kDebug() <<
"-- mKMailSerialNumber:" << mKMailSerialNumber;
4109 kDebug() <<
"-- mCopyToKOrganizer:" << mCopyToKOrganizer;
4110 kDebug() <<
"-- mExcludeHolidays:" << (bool)mExcludeHolidays;
4111 kDebug() <<
"-- mWorkTimeOnly:" << mWorkTimeOnly;
4112 kDebug() <<
"-- mStartDateTime:" << mStartDateTime.toString();
4113 kDebug() <<
"-- mCreatedDateTime:" << mCreatedDateTime;
4114 kDebug() <<
"-- mRepeatAtLogin:" << mRepeatAtLogin;
4116 kDebug() <<
"-- mAtLoginDateTime:" << mAtLoginDateTime;
4117 kDebug() <<
"-- mArchiveRepeatAtLogin:" << mArchiveRepeatAtLogin;
4118 kDebug() <<
"-- mConfirmAck:" << mConfirmAck;
4119 kDebug() <<
"-- mEnabled:" << mEnabled;
4120 #ifndef KALARMCAL_USE_KRESOURCES
4121 kDebug() <<
"-- mItemId:" << mItemId;
4122 kDebug() <<
"-- mCollectionId:" << mCollectionId;
4123 kDebug() <<
"-- mCompatibility:" << mCompatibility;
4124 kDebug() <<
"-- mReadOnly:" << mReadOnly;
4126 if (mReminderMinutes)
4128 kDebug() <<
"-- mReminderMinutes:" << mReminderMinutes;
4129 kDebug() <<
"-- mReminderActive:" << (mReminderActive == ACTIVE_REMINDER ?
"active" : mReminderActive == HIDDEN_REMINDER ?
"hidden" :
"no");
4130 kDebug() <<
"-- mReminderOnceOnly:" << mReminderOnceOnly;
4132 else if (mDeferral > 0)
4134 kDebug() <<
"-- mDeferral:" << (mDeferral == NORMAL_DEFERRAL ?
"normal" :
"reminder");
4135 kDebug() <<
"-- mDeferralTime:" << mDeferralTime.toString();
4137 kDebug() <<
"-- mDeferDefaultMinutes:" << mDeferDefaultMinutes;
4138 if (mDeferDefaultMinutes)
4139 kDebug() <<
"-- mDeferDefaultDateOnly:" << mDeferDefaultDateOnly;
4142 kDebug() <<
"-- mDisplayingTime:" << mDisplayingTime.toString();
4143 kDebug() <<
"-- mDisplayingFlags:" << mDisplayingFlags;
4144 kDebug() <<
"-- mDisplayingDefer:" << mDisplayingDefer;
4145 kDebug() <<
"-- mDisplayingEdit:" << mDisplayingEdit;
4147 kDebug() <<
"-- mRevision:" << mRevision;
4148 kDebug() <<
"-- mRecurrence:" << mRecurrence;
4150 kDebug() <<
"-- mRepetition: 0";
4151 else if (mRepetition.isDaily())
4152 kDebug() <<
"-- mRepetition: count:" << mRepetition.count() <<
", interval:" << mRepetition.intervalDays() <<
"days";
4154 kDebug() <<
"-- mRepetition: count:" << mRepetition.count() <<
", interval:" << mRepetition.intervalMinutes() <<
"minutes";
4155 kDebug() <<
"-- mNextRepeat:" << mNextRepeat;
4156 kDebug() <<
"-- mAlarmCount:" << mAlarmCount;
4157 kDebug() <<
"-- mMainExpired:" << mMainExpired;
4158 kDebug() <<
"-- mDisplaying:" << mDisplaying;
4159 kDebug() <<
"KAEvent dump end";
4168 #ifndef KALARMCAL_USE_KRESOURCES
4169 DateTime KAEvent::Private::readDateTime(
const Event::Ptr& event,
bool dateOnly, DateTime& start)
4171 DateTime KAEvent::Private::readDateTime(
const Event* event,
bool dateOnly, DateTime& start)
4174 start =
event->dtStart();
4179 start.setDateOnly(
true);
4181 DateTime next = start;
4183 if (prop.length() >= 8)
4186 const QDate d(prop.left(4).toInt(), prop.mid(4,2).toInt(), prop.mid(6,2).toInt());
4189 if (dateOnly && prop.length() == 8)
4191 else if (!dateOnly && prop.length() == 15 && prop[8] == QChar(
'T'))
4193 const QTime t(prop.mid(9,2).toInt(), prop.mid(11,2).toInt(), prop.mid(13,2).toInt());
4211 #ifndef KALARMCAL_USE_KRESOURCES
4212 void KAEvent::Private::readAlarms(
const Event::Ptr& event,
void* almap,
bool cmdDisplay)
4214 void KAEvent::Private::readAlarms(
const Event* event,
void* almap,
bool cmdDisplay)
4217 AlarmMap* alarmMap = (AlarmMap*)almap;
4221 bool audioOnly =
false;
4222 for (
int i = 0, end = alarms.count(); i < end; ++i)
4224 switch (alarms[i]->type())
4226 case Alarm::Display:
4227 case Alarm::Procedure:
4239 for (
int i = 0, end = alarms.count(); i < end; ++i)
4243 readAlarm(alarms[i], data, audioOnly, cmdDisplay);
4244 if (data.type != INVALID_ALARM)
4245 alarmMap->insert(data.type, data);
4254 #ifndef KALARMCAL_USE_KRESOURCES
4255 void KAEvent::Private::readAlarm(
const Alarm::Ptr& alarm, AlarmData& data,
bool audioMain,
bool cmdDisplay)
4257 void KAEvent::Private::readAlarm(
const Alarm* alarm, AlarmData& data,
bool audioMain,
bool cmdDisplay)
4262 data.displayingFlags = 0;
4263 data.isEmailText =
false;
4265 data.hiddenReminder =
false;
4266 data.timedDeferral =
false;
4267 data.nextRepeat = 0;
4268 data.repeatSoundPause = -1;
4273 int n =
static_cast<int>(
property.toUInt(&ok));
4275 data.nextRepeat = n;
4278 const QStringList flags =
property.split(Private::SC, QString::SkipEmptyParts);
4279 switch (alarm->
type())
4281 case Alarm::Procedure:
4284 data.commandScript = data.cleanText.isEmpty();
4287 if (!data.commandScript)
4288 data.cleanText +=
' ';
4291 data.extraActionOptions = 0;
4292 if (flags.contains(Private::EXEC_ON_DEFERRAL_FLAG))
4293 data.extraActionOptions |= ExecPreActOnDeferral;
4294 if (flags.contains(Private::CANCEL_ON_ERROR_FLAG))
4295 data.extraActionOptions |= CancelOnPreActError;
4296 if (flags.contains(Private::DONT_SHOW_ERROR_FLAG))
4297 data.extraActionOptions |= DontShowPreActError;
4301 case Alarm::Display:
4303 if (alarm->
type() == Alarm::Display)
4309 const QStringList list =
property.split(QLatin1Char(
';'), QString::KeepEmptyParts);
4310 data.bgColour = QColor(255, 255, 255);
4311 data.fgColour = QColor(0, 0, 0);
4312 const int n = list.count();
4315 if (!list[0].isEmpty())
4321 if (n > 1 && !list[1].isEmpty())
4328 data.defaultFont = (n <= 2 || list[2].isEmpty());
4329 if (!data.defaultFont)
4330 data.font.fromString(list[2]);
4336 data.cleanText = alarm->
mailText();
4337 const int i = flags.indexOf(Private::EMAIL_ID_FLAG);
4338 data.emailFromId = (i >= 0 && i + 1 < flags.count()) ? flags[i + 1].toUInt() : 0;
4347 data.soundVolume = -1;
4348 data.fadeVolume = -1;
4349 data.fadeSeconds = 0;
4351 if (!property.isEmpty())
4356 const QStringList list =
property.split(QLatin1Char(
';'), QString::KeepEmptyParts);
4357 data.soundVolume = list[0].toFloat(&ok);
4358 if (!ok || data.soundVolume > 1.0f)
4359 data.soundVolume = -1;
4360 if (data.soundVolume >= 0 && list.count() >= 3)
4362 fadeVolume = list[1].toFloat(&ok);
4364 fadeSecs =
static_cast<int>(list[2].toUInt(&ok));
4365 if (ok && fadeVolume >= 0 && fadeVolume <= 1.0f && fadeSecs > 0)
4367 data.fadeVolume = fadeVolume;
4368 data.fadeSeconds = fadeSecs;
4374 data.type = AUDIO_ALARM;
4375 data.speak = flags.contains(Private::SPEAK_FLAG);
4380 case Alarm::Invalid:
4381 data.type = INVALID_ALARM;
4385 bool atLogin =
false;
4386 bool reminder =
false;
4387 bool deferral =
false;
4388 bool dateDeferral =
false;
4389 bool repeatSound =
false;
4390 data.type = MAIN_ALARM;
4392 const QStringList
types =
property.split(QLatin1Char(
','), QString::SkipEmptyParts);
4393 for (
int i = 0, end = types.count(); i < end; ++i)
4395 const QString type = types[i];
4396 if (type == Private::AT_LOGIN_TYPE)
4400 else if (type == Private::REMINDER_TYPE)
4402 else if (type == Private::TIME_DEFERRAL_TYPE)
4404 else if (type == Private::DATE_DEFERRAL_TYPE)
4405 dateDeferral = deferral =
true;
4406 else if (type == Private::DISPLAYING_TYPE)
4407 data.type = DISPLAYING_ALARM;
4408 else if (type == Private::PRE_ACTION_TYPE && data.action ==
KAAlarm::COMMAND)
4409 data.type = PRE_ACTION_ALARM;
4410 else if (type == Private::POST_ACTION_TYPE && data.action ==
KAAlarm::COMMAND)
4411 data.type = POST_ACTION_ALARM;
4412 else if (type == Private::SOUND_REPEAT_TYPE && data.action ==
KAAlarm::AUDIO)
4418 uint n = types[i + 1].toUInt(&ok);
4421 data.repeatSoundPause = n;
4427 if (repeatSound && data.repeatSoundPause < 0)
4428 data.repeatSoundPause = 0;
4429 else if (!repeatSound)
4430 data.repeatSoundPause = -1;
4434 if (data.type == MAIN_ALARM)
4436 data.type = deferral ? DEFERRED_REMINDER_ALARM : REMINDER_ALARM;
4437 data.timedDeferral = (deferral && !dateDeferral);
4439 else if (data.type == DISPLAYING_ALARM)
4440 data.displayingFlags = dateDeferral ? REMINDER | DATE_DEFERRAL
4441 : deferral ? REMINDER | TIME_DEFERRAL : REMINDER;
4442 else if (data.type == REMINDER_ALARM
4443 && flags.contains(Private::HIDDEN_REMINDER_FLAG))
4444 data.hiddenReminder =
true;
4448 if (data.type == MAIN_ALARM)
4450 data.type = DEFERRED_ALARM;
4451 data.timedDeferral = !dateDeferral;
4453 else if (data.type == DISPLAYING_ALARM)
4454 data.displayingFlags = dateDeferral ? DATE_DEFERRAL : TIME_DEFERRAL;
4458 if (data.type == MAIN_ALARM)
4459 data.type = AT_LOGIN_ALARM;
4460 else if (data.type == DISPLAYING_ALARM)
4461 data.displayingFlags = REPEAT_AT_LOGIN;
4477 void KAEvent::Private::calcTriggerTimes()
const
4482 #warning May need to set date-only alarms to after start-of-day time in working-time checks
4485 if ((recurs && mWorkTimeOnly && mWorkTimeOnly != mWorkTimeIndex)
4486 || (recurs && mExcludeHolidays && mExcludeHolidays != mHolidays))
4490 mTriggerChanged =
true;
4492 else if (!mTriggerChanged)
4494 mTriggerChanged =
false;
4495 if (recurs && mWorkTimeOnly)
4496 mWorkTimeOnly = mWorkTimeIndex;
4497 if (recurs && mExcludeHolidays)
4498 mExcludeHolidays = mHolidays;
4503 mAllTrigger = mMainTrigger = mAllWorkTrigger = mMainWorkTrigger = KDateTime();
4505 else if (mDeferral == NORMAL_DEFERRAL)
4508 mAllTrigger = mMainTrigger = mAllWorkTrigger = mMainWorkTrigger = mDeferralTime;
4512 mMainTrigger = mainDateTime(
true);
4513 mAllTrigger = (mDeferral == REMINDER_DEFERRAL) ? mDeferralTime
4514 : (mReminderActive != ACTIVE_REMINDER) ? mMainTrigger
4515 : (mReminderMinutes < 0) ? mReminderAfterTime
4516 : mMainTrigger.addMins(-mReminderMinutes);
4520 if ((!mWorkTimeOnly && !mExcludeHolidays)
4522 || isWorkingTime(mMainTrigger.kDateTime()))
4526 mMainWorkTrigger = mMainTrigger;
4527 mAllWorkTrigger = mAllTrigger;
4529 else if (mWorkTimeOnly)
4535 if (!mExcludeHolidays)
4538 calcNextWorkingTime(mMainTrigger);
4543 DateTime nextTrigger = mMainTrigger;
4545 for (
int i = 0; i < 20; ++i)
4547 calcNextWorkingTime(nextTrigger);
4548 if (!mHolidays->isHoliday(mMainWorkTrigger.date()))
4550 kdt = mMainWorkTrigger.effectiveKDateTime();
4551 kdt.setTime(QTime(23,59,59));
4552 const OccurType type = nextOccurrence(kdt, nextTrigger, RETURN_REPETITION);
4553 if (!nextTrigger.isValid())
4555 if (isWorkingTime(nextTrigger.kDateTime()))
4557 const int reminder = (mReminderMinutes > 0) ? mReminderMinutes : 0;
4558 mMainWorkTrigger = nextTrigger;
4559 mAllWorkTrigger = (type & OCCURRENCE_REPEAT) ? mMainWorkTrigger : mMainWorkTrigger.addMins(-reminder);
4563 mMainWorkTrigger = mAllWorkTrigger = DateTime();
4566 else if (mExcludeHolidays && mHolidays)
4569 DateTime nextTrigger = mMainTrigger;
4571 for (
int i = 0; i < 20; ++i)
4573 kdt = nextTrigger.effectiveKDateTime();
4574 kdt.setTime(QTime(23,59,59));
4575 const OccurType type = nextOccurrence(kdt, nextTrigger, RETURN_REPETITION);
4576 if (!nextTrigger.isValid())
4578 if (!mHolidays->isHoliday(nextTrigger.date()))
4580 const int reminder = (mReminderMinutes > 0) ? mReminderMinutes : 0;
4581 mMainWorkTrigger = nextTrigger;
4582 mAllWorkTrigger = (type & OCCURRENCE_REPEAT) ? mMainWorkTrigger : mMainWorkTrigger.addMins(-reminder);
4586 mMainWorkTrigger = mAllWorkTrigger = DateTime();
4597 void KAEvent::Private::calcNextWorkingTime(
const DateTime& nextTrigger)
const
4599 kDebug() <<
"next=" << nextTrigger.kDateTime().dateTime();
4600 mMainWorkTrigger = mAllWorkTrigger = DateTime();
4602 for (
int i = 0; ; ++i)
4606 if (mWorkDays.testBit(i))
4610 KDateTime kdt = nextTrigger.effectiveKDateTime();
4611 const int reminder = (mReminderMinutes > 0) ? mReminderMinutes : 0;
4616 unsigned allDaysMask = 0x7F;
4617 bool noWorkPos =
false;
4618 const QList<RecurrenceRule::WDayPos> pos = rrule->byDays();
4619 const int nDayPos = pos.count();
4624 for (
int i = 0; i < nDayPos; ++i)
4626 const int day = pos[i].day() - 1;
4627 if (mWorkDays.testBit(day))
4629 allDaysMask |= 1 << day;
4631 if (noWorkPos && !mRepetition)
4636 if (mStartDateTime.isDateOnly())
4640 const int repeatFreq = mRepetition.intervalDays();
4641 const bool weeklyRepeat = mRepetition && !(repeatFreq % 7);
4642 const Duration interval = mRecurrence->regularInterval();
4643 if ((interval && !(interval.
asDays() % 7))
4647 if (!mRepetition || weeklyRepeat)
4653 KDateTime dt(nextTrigger.kDateTime().addDays(1));
4654 dt.setTime(QTime(0,0,0));
4655 previousOccurrence(dt, newdt,
false);
4656 if (!newdt.isValid())
4658 kdt = newdt.effectiveKDateTime();
4659 const int day = kdt.date().dayOfWeek() - 1;
4660 for (
int repeatNum = mNextRepeat + 1; ; ++repeatNum)
4662 if (repeatNum > mRepetition.count())
4664 if (repeatNum == mNextRepeat)
4668 nextOccurrence(newdt.kDateTime(), newdt, IGNORE_REPETITION);
4669 if (mWorkDays.testBit(day))
4671 mMainWorkTrigger = newdt;
4672 mAllWorkTrigger = mMainWorkTrigger.addMins(-reminder);
4675 kdt = newdt.effectiveKDateTime();
4679 const int inc = repeatFreq * repeatNum;
4680 if (mWorkDays.testBit((day + inc) % 7))
4682 kdt = kdt.addDays(inc);
4683 kdt.setDateOnly(
true);
4684 mMainWorkTrigger = mAllWorkTrigger = kdt;
4691 if (!mRepetition || weeklyRepeat)
4699 kdt.setTime(QTime(23,59,59));
4700 nextOccurrence(kdt, newdt, IGNORE_REPETITION);
4701 if (!newdt.isValid())
4703 kdt = newdt.effectiveKDateTime();
4704 const int day = kdt.date().dayOfWeek() - 1;
4705 if (mWorkDays.testBit(day))
4708 if ((days & allDaysMask) == allDaysMask)
4712 kdt.setDateOnly(
true);
4713 mMainWorkTrigger = kdt;
4714 mAllWorkTrigger = kdt.addSecs(-60 * reminder);
4721 unsigned days = 1 << (kdt.date().dayOfWeek() - 1);
4722 KDateTime dt(nextTrigger.kDateTime().addDays(1));
4723 dt.setTime(QTime(0,0,0));
4724 previousOccurrence(dt, newdt,
false);
4725 if (!newdt.isValid())
4727 kdt = newdt.effectiveKDateTime();
4728 int day = kdt.date().dayOfWeek() - 1;
4729 for (
int repeatNum = mNextRepeat; ; repeatNum = 0)
4731 while (++repeatNum <= mRepetition.count())
4733 const int inc = repeatFreq * repeatNum;
4734 if (mWorkDays.testBit((day + inc) % 7))
4736 kdt = kdt.addDays(inc);
4737 kdt.setDateOnly(
true);
4738 mMainWorkTrigger = mAllWorkTrigger = kdt;
4741 if ((days & allDaysMask) == allDaysMask)
4745 nextOccurrence(kdt, newdt, IGNORE_REPETITION);
4746 if (!newdt.isValid())
4748 kdt = newdt.effectiveKDateTime();
4749 day = kdt.date().dayOfWeek() - 1;
4750 if (mWorkDays.testBit(day))
4752 kdt.setDateOnly(
true);
4753 mMainWorkTrigger = kdt;
4754 mAllWorkTrigger = kdt.addSecs(-60 * reminder);
4757 if ((days & allDaysMask) == allDaysMask)
4775 const bool repeatTimeVaries = (mRepetition && !mRepetition.isDaily());
4777 if (!recurTimeVaries && !repeatTimeVaries)
4781 if (!mayOccurDailyDuringWork(kdt))
4785 bool repetition =
false;
4789 OccurType type = nextOccurrence(kdt, newdt, RETURN_REPETITION);
4790 if (!newdt.isValid())
4792 repetition = (type & OCCURRENCE_REPEAT);
4793 kdt = newdt.effectiveKDateTime();
4794 const int day = kdt.date().dayOfWeek() - 1;
4795 if (mWorkDays.testBit(day))
4800 if ((days & allDaysMask) == allDaysMask)
4805 mMainWorkTrigger = nextTrigger;
4806 mMainWorkTrigger.setDate(kdt.date());
4807 mAllWorkTrigger = repetition ? mMainWorkTrigger : mMainWorkTrigger.addMins(-reminder);
4814 KTimeZone tz = kdt.timeZone();
4815 if (tz.isValid() && tz.type() ==
"KSystemTimeZone")
4818 const KTimeZone ktz = KSystemTimeZones::readZone(tz.name());
4822 const QList<KTimeZone::Transition> tzTransitions = tz.transitions();
4824 if (recurTimeVaries)
4843 repeatFreq = mRepetition.intervalSeconds();
4844 previousOccurrence(kdt.addSecs(1), newdt,
false);
4845 if (!newdt.isValid())
4847 kdtRecur = newdt.effectiveKDateTime();
4848 repeatNum = kdtRecur.secsTo(kdt) / repeatFreq;
4849 kdt = kdtRecur.addSecs(repeatNum * repeatFreq);
4863 QTime firstTime = kdtRecur.time();
4864 int firstOffset = kdtRecur.utcOffset();
4865 int currentOffset = firstOffset;
4866 int dayRecur = kdtRecur.date().dayOfWeek() - 1;
4867 int firstDay = dayRecur;
4869 const bool subdaily = (repeatFreq < 24*3600);
4872 int transitionIndex = -1;
4873 for (
int n = 0; n < 7*24*60; ++n)
4881 const int inc = subdaily ? nextWorkRepetition(kdt) : 1;
4883 if (repeatNum > mRepetition.count())
4885 kdt = kdt.addSecs(inc * repeatFreq);
4886 const QTime t = kdt.time();
4887 if (t >= mWorkDayStart && t < mWorkDayEnd)
4889 if (mWorkDays.testBit(kdt.date().dayOfWeek() - 1))
4891 mMainWorkTrigger = mAllWorkTrigger = kdt;
4898 nextOccurrence(kdtRecur, newdt, IGNORE_REPETITION);
4899 if (!newdt.isValid())
4901 kdtRecur = newdt.effectiveKDateTime();
4902 dayRecur = kdtRecur.date().dayOfWeek() - 1;
4903 const QTime t = kdtRecur.time();
4904 if (t >= mWorkDayStart && t < mWorkDayEnd)
4906 if (mWorkDays.testBit(dayRecur))
4908 mMainWorkTrigger = kdtRecur;
4909 mAllWorkTrigger = kdtRecur.addSecs(-60 * reminder);
4913 if (kdtRecur.utcOffset() != currentOffset)
4914 currentOffset = kdtRecur.utcOffset();
4915 if (t == firstTime && dayRecur == firstDay && currentOffset == firstOffset)
4921 if (!finalDate.isValid())
4922 finalDate = kdtRecur.date();
4923 const int i = tz.transitionIndex(kdtRecur.toUtc().dateTime());
4926 if (i > transitionIndex)
4927 transitionIndex = i;
4928 if (++transitionIndex >= static_cast<int>(tzTransitions.count()))
4930 previousOccurrence(KDateTime(tzTransitions[transitionIndex].time(), KDateTime::UTC), newdt, IGNORE_REPETITION);
4931 kdtRecur = newdt.effectiveKDateTime();
4932 if (finalDate.daysTo(kdtRecur.date()) > 365)
4934 firstTime = kdtRecur.time();
4935 firstOffset = kdtRecur.utcOffset();
4936 currentOffset = firstOffset;
4937 firstDay = kdtRecur.date().dayOfWeek() - 1;
4945 if (repeatTimeVaries)
4954 const int repeatFreq = mRepetition.intervalSeconds();
4955 previousOccurrence(kdt.addSecs(1), newdt,
false);
4956 if (!newdt.isValid())
4958 KDateTime kdtRecur = newdt.effectiveKDateTime();
4959 const bool recurDuringWork = (kdtRecur.time() >= mWorkDayStart && kdtRecur.time() < mWorkDayEnd);
4963 const bool subdaily = (repeatFreq < 24*3600);
4965 bool checkTimeChangeOnly =
false;
4966 int transitionIndex = -1;
4967 for (
int limit = 10; --limit >= 0; )
4971 QDate dateRecur = kdtRecur.date();
4972 int dayRecur = dateRecur.dayOfWeek() - 1;
4973 int repeatNum = kdtRecur.secsTo(kdt) / repeatFreq;
4974 kdt = kdtRecur.addSecs(repeatNum * repeatFreq);
4981 nextOccurrence(kdtRecur, newdt, IGNORE_REPETITION);
4982 KDateTime kdtNextRecur = newdt.effectiveKDateTime();
4984 int repeatsToCheck = mRepetition.count();
4985 int repeatsDuringWork = 0;
4989 if (repeatsDuringWork >= 0)
4994 int inc = subdaily ? nextWorkRepetition(kdt) : 1;
4996 const bool pastEnd = (repeatNum > mRepetition.count());
4998 inc -= repeatNum - mRepetition.count();
4999 repeatsToCheck -= inc;
5000 kdt = kdt.addSecs(inc * repeatFreq);
5001 if (kdtNextRecur.isValid() && kdt >= kdtNextRecur)
5005 repeatsToCheck = mRepetition.count();
5010 const QTime t = kdt.time();
5011 if (t >= mWorkDayStart && t < mWorkDayEnd)
5013 if (mWorkDays.testBit(kdt.date().dayOfWeek() - 1))
5015 mMainWorkTrigger = mAllWorkTrigger = kdt;
5018 repeatsDuringWork = 1;
5020 else if (!repeatsDuringWork && repeatsToCheck <= 0)
5023 repeatsDuringWork = -1;
5029 if (repeatsDuringWork < 0 && !recurDuringWork)
5033 if (!kdtNextRecur.isValid())
5035 if (checkTimeChangeOnly || (days & allDaysMask) == allDaysMask)
5037 kdtRecur = kdtNextRecur;
5038 nextOccurrence(kdtRecur, newdt, IGNORE_REPETITION);
5039 kdtNextRecur = newdt.effectiveKDateTime();
5040 dateRecur = kdtRecur.date();
5041 dayRecur = dateRecur.dayOfWeek() - 1;
5042 if (recurDuringWork && mWorkDays.testBit(dayRecur))
5044 mMainWorkTrigger = kdtRecur;
5045 mAllWorkTrigger = kdtRecur.addSecs(-60 * reminder);
5048 days |= 1 << dayRecur;
5054 checkTimeChangeOnly =
true;
5055 const int i = tz.transitionIndex(kdtRecur.toUtc().dateTime());
5058 if (i > transitionIndex)
5059 transitionIndex = i;
5060 if (++transitionIndex >= static_cast<int>(tzTransitions.count()))
5062 kdt = KDateTime(tzTransitions[transitionIndex].time(), KDateTime::UTC);
5063 previousOccurrence(kdt, newdt, IGNORE_REPETITION);
5064 kdtRecur = newdt.effectiveKDateTime();
5075 int KAEvent::Private::nextWorkRepetition(
const KDateTime& pre)
const
5077 KDateTime nextWork(pre);
5078 if (pre.time() < mWorkDayStart)
5079 nextWork.setTime(mWorkDayStart);
5082 const int preDay = pre.date().dayOfWeek() - 1;
5083 for (
int n = 1; ; ++n)
5086 return mRepetition.count() + 1;
5087 if (mWorkDays.testBit((preDay + n) % 7))
5089 nextWork = nextWork.addDays(n);
5090 nextWork.setTime(mWorkDayStart);
5095 return (pre.secsTo(nextWork) - 1) / mRepetition.intervalSeconds() + 1;
5105 bool KAEvent::Private::mayOccurDailyDuringWork(
const KDateTime& kdt)
const
5107 if (!kdt.isDateOnly()
5108 && (kdt.time() < mWorkDayStart || kdt.time() >= mWorkDayEnd))
5111 const Duration interval = mRecurrence->regularInterval();
5112 if (interval && interval.
isDaily() && !(interval.
asDays() % 7))
5115 if (!mRepetition || (mRepetition.isDaily() && !(mRepetition.intervalDays() % 7)))
5119 int day = mRecurrence->startDateTime().date().dayOfWeek() - 1;
5120 const int repeatDays = mRepetition.intervalDays();
5121 const int maxRepeat = (mRepetition.count() < 6) ? mRepetition.count() : 6;
5122 for (
int i = 0; !mWorkDays.testBit(day); ++i, day = (day + repeatDays) % 7)
5134 #ifndef KALARMCAL_USE_KRESOURCES
5135 void KAEvent::Private::setAudioAlarm(
const Alarm::Ptr& alarm)
const
5137 void KAEvent::Private::setAudioAlarm(
Alarm* alarm)
const
5141 if (mSoundVolume >= 0)
5143 QString::fromLatin1(
"%1;%2;%3;%4").arg(QString::number(mSoundVolume,
'f', 2))
5144 .arg(QString::number(mFadeVolume,
'f', 2))
5145 .arg(mFadeSeconds));
5153 KAEvent::OccurType KAEvent::Private::nextRecurrence(
const KDateTime& preDateTime, DateTime& result)
const
5155 const KDateTime recurStart = mRecurrence->startDateTime();
5156 KDateTime pre = preDateTime.toTimeSpec(mStartDateTime.timeSpec());
5159 pre = pre.addDays(-1);
5162 const KDateTime dt = mRecurrence->getNextDateTime(pre);
5164 result.setDateOnly(mStartDateTime.isDateOnly());
5166 return NO_OCCURRENCE;
5167 if (dt == recurStart)
5168 return FIRST_OR_ONLY_OCCURRENCE;
5169 if (mRecurrence->duration() >= 0 && dt == mRecurrence->endDateTime())
5170 return LAST_RECURRENCE;
5171 return result.isDateOnly() ? RECURRENCE_DATE : RECURRENCE_DATE_TIME;
5196 const_cast<KAEvent::Private*
>(
this)->clearRecur();
5201 const_cast<KAEvent::Private*
>(
this)->clearRecur();
5211 #ifndef KALARMCAL_USE_KRESOURCES
5218 static const QChar SEPARATOR = QLatin1Char(
';');
5219 static const QChar LATE_CANCEL_CODE = QLatin1Char(
'C');
5220 static const QChar AT_LOGIN_CODE = QLatin1Char(
'L');
5221 static const QChar DEFERRAL_CODE = QLatin1Char(
'D');
5222 static const QString TEXT_PREFIX = QLatin1String(
"TEXT:");
5223 static const QString FILE_PREFIX = QLatin1String(
"FILE:");
5224 static const QString COMMAND_PREFIX = QLatin1String(
"CMD:");
5227 static const QString BEEP_CATEGORY = QLatin1String(
"BEEP");
5230 static const QString LATE_CANCEL_CAT = QLatin1String(
"LATECANCEL");
5233 static const QString TEMPL_DEF_TIME_CAT = QLatin1String(
"TMPLDEFTIME");
5236 static const QString EXEC_IN_XTERM_CAT = QLatin1String(
"XTERM");
5239 static const QString DATE_ONLY_CATEGORY = QLatin1String(
"DATE");
5240 static const QString EMAIL_BCC_CATEGORY = QLatin1String(
"BCC");
5241 static const QString CONFIRM_ACK_CATEGORY = QLatin1String(
"ACKCONF");
5242 static const QString KORGANIZER_CATEGORY = QLatin1String(
"KORG");
5243 static const QString DEFER_CATEGORY = QLatin1String(
"DEFER;");
5244 static const QString ARCHIVE_CATEGORY = QLatin1String(
"SAVE");
5245 static const QString ARCHIVE_CATEGORIES = QLatin1String(
"SAVE:");
5246 static const QString LATE_CANCEL_CATEGORY = QLatin1String(
"LATECANCEL;");
5247 static const QString AUTO_CLOSE_CATEGORY = QLatin1String(
"LATECLOSE;");
5248 static const QString TEMPL_AFTER_TIME_CATEGORY = QLatin1String(
"TMPLAFTTIME;");
5249 static const QString KMAIL_SERNUM_CATEGORY = QLatin1String(
"KMAIL:");
5250 static const QString LOG_CATEGORY = QLatin1String(
"LOG:");
5253 static const QByteArray KMAIL_ID_PROPERTY(
"KMAILID");
5256 static const QByteArray ARCHIVE_PROPERTY(
"ARCHIVE");
5257 static const QString ARCHIVE_REMINDER_ONCE_TYPE = QLatin1String(
"ONCE");
5258 static const QString REMINDER_ONCE_TYPE = QLatin1String(
"REMINDER_ONCE");
5259 static const QByteArray EMAIL_ID_PROPERTY(
"EMAILID");
5260 static const QByteArray SPEAK_PROPERTY(
"SPEAK");
5261 static const QByteArray CANCEL_ON_ERROR_PROPERTY(
"ERRCANCEL");
5262 static const QByteArray DONT_SHOW_ERROR_PROPERTY(
"ERRNOSHOW");
5264 bool adjustSummerTime =
false;
5265 if (calendarVersion == -Version(0,5,7))
5269 calendarVersion = -calendarVersion;
5270 adjustSummerTime =
true;
5273 if (calendarVersion >= currentCalendarVersion())
5276 kDebug() <<
"Adjusting version" << calendarVersion;
5277 const bool pre_0_7 = (calendarVersion < Version(0,7,0));
5278 const bool pre_0_9 = (calendarVersion < Version(0,9,0));
5279 const bool pre_0_9_2 = (calendarVersion < Version(0,9,2));
5280 const bool pre_1_1_1 = (calendarVersion < Version(1,1,1));
5281 const bool pre_1_2_1 = (calendarVersion < Version(1,2,1));
5282 const bool pre_1_3_0 = (calendarVersion < Version(1,3,0));
5283 const bool pre_1_3_1 = (calendarVersion < Version(1,3,1));
5284 const bool pre_1_4_14 = (calendarVersion < Version(1,4,14));
5285 const bool pre_1_5_0 = (calendarVersion < Version(1,5,0));
5286 const bool pre_1_9_0 = (calendarVersion < Version(1,9,0));
5287 const bool pre_1_9_2 = (calendarVersion < Version(1,9,2));
5288 const bool pre_1_9_7 = (calendarVersion < Version(1,9,7));
5289 const bool pre_1_9_9 = (calendarVersion < Version(1,9,9));
5290 const bool pre_1_9_10 = (calendarVersion < Version(1,9,10));
5291 const bool pre_2_2_9 = (calendarVersion < Version(2,2,9));
5292 const bool pre_2_3_0 = (calendarVersion < Version(2,3,0));
5293 const bool pre_2_3_2 = (calendarVersion < Version(2,3,2));
5294 const bool pre_2_7_0 = (calendarVersion < Version(2,7,0));
5295 Q_ASSERT(currentCalendarVersion() == Version(2,7,0));
5297 KTimeZone localZone;
5299 localZone = KSystemTimeZones::local();
5301 bool converted =
false;
5302 #ifndef KALARMCAL_USE_KRESOURCES
5307 for (
int ei = 0, eend = events.count(); ei < eend; ++ei)
5309 #ifndef KALARMCAL_USE_KRESOURCES
5312 Event*
event = events[ei];
5315 if (alarms.isEmpty())
5317 event->startUpdates();
5318 const bool readOnly =
event->isReadOnly();
5320 event->setReadOnly(
false);
5321 QStringList cats =
event->categories();
5322 bool addLateCancel =
false;
5325 if (pre_0_7 && event->
allDay())
5329 event->setAllDay(
false);
5346 for (
int ai = 0, aend = alarms.count(); ai < aend; ++ai)
5348 #ifndef KALARMCAL_USE_KRESOURCES
5351 Alarm* alarm = alarms[ai];
5353 bool atLogin =
false;
5354 bool deferral =
false;
5355 bool lateCancel =
false;
5357 QString txt = alarm->
text();
5358 const int length = txt.length();
5360 if (txt[0].isDigit())
5362 while (++i < length && txt[i].isDigit()) ;
5363 if (i < length && txt[i++] == SEPARATOR)
5367 const QChar ch = txt[i++];
5368 if (ch == SEPARATOR)
5370 if (ch == LATE_CANCEL_CODE)
5372 else if (ch == AT_LOGIN_CODE)
5374 else if (ch == DEFERRAL_CODE)
5381 if (txt.indexOf(TEXT_PREFIX, i) == i)
5382 i += TEXT_PREFIX.length();
5383 else if (txt.indexOf(FILE_PREFIX, i) == i)
5386 i += FILE_PREFIX.length();
5388 else if (txt.indexOf(COMMAND_PREFIX, i) == i)
5391 i += COMMAND_PREFIX.length();
5401 types += Private::FILE_TYPE;
5407 setProcedureAlarm(alarm, txt);
5415 types += Private::AT_LOGIN_TYPE;
5419 types += Private::TIME_DEFERRAL_TYPE;
5421 addLateCancel =
true;
5422 if (types.count() > 0)
5430 if (recur && recur->
recurs())
5439 if (adjustSummerTime)
5443 KDateTime dt = alarm->
time();
5444 const time_t t = dt.toTime_t();
5445 const struct tm* dtm = localtime(&t);
5448 dt = dt.addSecs(-3600);
5468 event->setCreated(event->
dtEnd());
5469 KDateTime start =
event->dtStart();
5472 event->setAllDay(
false);
5473 start.setTime(QTime(0, 0));
5474 flags += Private::DATE_ONLY_FLAG;
5476 event->setHasEndDate(
false);
5478 for (
int ai = 0, aend = alarms.count(); ai < aend; ++ai)
5480 #ifndef KALARMCAL_USE_KRESOURCES
5483 Alarm* alarm = alarms[ai];
5488 if (!cats.isEmpty())
5490 for (
int ai = 0, aend = alarms.count(); ai < aend; ++ai)
5492 #ifndef KALARMCAL_USE_KRESOURCES
5495 Alarm* alarm = alarms[ai];
5497 if (alarm->
type() == Alarm::Display)
5499 QString::fromLatin1(
"%1;;").arg(cats[0]));
5504 for (
int i = 0, end = cats.count(); i < end; ++i)
5506 if (cats[i] == BEEP_CATEGORY)
5510 #ifndef KALARMCAL_USE_KRESOURCES
5513 Alarm* alarm =
event->newAlarm();
5517 KDateTime dt =
event->dtStart();
5520 Private::AlarmMap alarmMap;
5521 Private::readAlarms(event, &alarmMap);
5522 Private::AlarmMap::ConstIterator it = alarmMap.constBegin();
5523 if (it != alarmMap.constEnd())
5525 dt = it.value().alarm->time();
5541 while ((i = cats.indexOf(LATE_CANCEL_CAT)) >= 0)
5544 addLateCancel =
true;
5554 for (
int ai = 0, aend = alarms.count(); ai < aend; ++ai)
5556 #ifndef KALARMCAL_USE_KRESOURCES
5559 Alarm* alarm = alarms[ai];
5561 if (alarm->
type() == Alarm::Display)
5563 const QString oldtext = alarm->
text();
5565 if (oldtext != newtext)
5578 while ((i = cats.indexOf(TEMPL_DEF_TIME_CAT)) >= 0)
5581 (flags += Private::TEMPL_AFTER_TIME_FLAG) += QLatin1String(
"0");
5592 while ((i = cats.indexOf(EXEC_IN_XTERM_CAT)) >= 0)
5606 CalEvent::setStatus(event, CalEvent::status(event));
5607 for (
int i = 0; i < cats.count(); )
5609 QString cat = cats[i];
5610 if (cat == DATE_ONLY_CATEGORY)
5611 flags += Private::DATE_ONLY_FLAG;
5612 else if (cat == CONFIRM_ACK_CATEGORY)
5613 flags += Private::CONFIRM_ACK_FLAG;
5614 else if (cat == EMAIL_BCC_CATEGORY)
5615 flags += Private::EMAIL_BCC_FLAG;
5616 else if (cat == KORGANIZER_CATEGORY)
5617 flags += Private::KORGANIZER_FLAG;
5618 else if (cat.startsWith(DEFER_CATEGORY))
5619 (flags += Private::DEFER_FLAG) += cat.mid(DEFER_CATEGORY.length());
5620 else if (cat.startsWith(TEMPL_AFTER_TIME_CATEGORY))
5621 (flags += Private::TEMPL_AFTER_TIME_FLAG) += cat.mid(TEMPL_AFTER_TIME_CATEGORY.length());
5622 else if (cat.startsWith(LATE_CANCEL_CATEGORY))
5623 (flags += Private::LATE_CANCEL_FLAG) += cat.mid(LATE_CANCEL_CATEGORY.length());
5624 else if (cat.startsWith(AUTO_CLOSE_CATEGORY))
5625 (flags += Private::AUTO_CLOSE_FLAG) += cat.mid(AUTO_CLOSE_CATEGORY.length());
5626 else if (cat.startsWith(KMAIL_SERNUM_CATEGORY))
5627 (flags += Private::KMAIL_SERNUM_FLAG) += cat.mid(KMAIL_SERNUM_CATEGORY.length());
5628 else if (cat == ARCHIVE_CATEGORY)
5630 else if (cat.startsWith(ARCHIVE_CATEGORIES))
5631 event->setCustomProperty(
KACalendar::APPNAME, ARCHIVE_PROPERTY, cat.mid(ARCHIVE_CATEGORIES.length()));
5632 else if (cat.startsWith(LOG_CATEGORY))
5633 event->setCustomProperty(
KACalendar::APPNAME, Private::LOG_PROPERTY, cat.mid(LOG_CATEGORY.length()));
5649 event->
shiftTimes(KDateTime::ClockTime, localZone);
5654 (flags += Private::LATE_CANCEL_FLAG) += QLatin1String(
"1");
5655 if (!flags.isEmpty())
5656 event->setCustomProperty(
KACalendar::APPNAME, Private::FLAGS_PROPERTY, flags.join(Private::SC));
5660 if ((pre_1_4_14 || (pre_1_9_7 && !pre_1_9_0))
5670 const QStringList flags =
event->customProperty(
KACalendar::APPNAME, Private::FLAGS_PROPERTY).split(Private::SC, QString::SkipEmptyParts);
5671 const bool dateOnly = flags.contains(Private::DATE_ONLY_FLAG);
5672 KDateTime startDateTime =
event->dtStart();
5674 startDateTime.setDateOnly(
true);
5676 KDateTime nextMainDateTime;
5677 bool mainExpired =
true;
5678 for (
int i = 0, alend = alarms.count(); i < alend; ++i)
5680 #ifndef KALARMCAL_USE_KRESOURCES
5683 Alarm* alarm = alarms[i];
5694 bool mainAlarm =
true;
5696 QStringList types =
property.split(QChar(
','), QString::SkipEmptyParts);
5697 for (
int t = 0; t < types.count(); ++t)
5699 QString type = types[t];
5700 if (type == Private::AT_LOGIN_TYPE
5701 || type == Private::TIME_DEFERRAL_TYPE
5702 || type == Private::DATE_DEFERRAL_TYPE
5703 || type == Private::REMINDER_TYPE
5704 || type == REMINDER_ONCE_TYPE)
5716 mainExpired =
false;
5717 nextMainDateTime = alarm->
time();
5718 nextMainDateTime.setDateOnly(dateOnly);
5719 nextMainDateTime = nextMainDateTime.toTimeSpec(startDateTime);
5720 if (nextMainDateTime != startDateTime)
5722 QDateTime dt = nextMainDateTime.dateTime();
5724 dt.toString(dateOnly ?
"yyyyMMdd" :
"yyyyMMddThhmmss"));
5737 KDateTime dt =
event->recurrence()->getNextDateTime(startDateTime.addDays(-1));
5738 dt.setDateOnly(dateOnly);
5739 adjustment = startDateTime.secsTo(dt);
5742 adjustment = startDateTime.secsTo(nextMainDateTime);
5746 for (
int i = 0, alend = alarms.count(); i < alend; ++i)
5748 #ifndef KALARMCAL_USE_KRESOURCES
5751 Alarm* alarm = alarms[i];
5756 const QStringList types =
property.split(QChar(
','), QString::SkipEmptyParts);
5757 for (
int t = 0; t < types.count(); ++t)
5759 const QString type = types[t];
5760 if (type == Private::TIME_DEFERRAL_TYPE
5761 || type == Private::DATE_DEFERRAL_TYPE)
5772 if (pre_1_5_0 || (pre_1_9_9 && !pre_1_9_0))
5778 for (
int i = 0, alend = alarms.count(); i < alend; ++i)
5780 #ifndef KALARMCAL_USE_KRESOURCES
5783 Alarm* alarm = alarms[i];
5802 if (Private::convertRepetition(event))
5806 if (pre_2_2_9 || (pre_2_3_2 && !pre_2_3_0))
5812 if (Private::convertStartOfDay(event))
5826 bool flagsValid =
false;
5829 bool reminderOnce =
false;
5831 if (!prop.isEmpty())
5834 flags =
event->customProperty(
KACalendar::APPNAME, Private::FLAGS_PROPERTY).split(Private::SC, QString::SkipEmptyParts);
5835 flags << Private::ARCHIVE_FLAG;
5837 if (prop != QLatin1String(
"0"))
5841 const QStringList list = prop.split(Private::SC, QString::SkipEmptyParts);
5842 for (
int i = 0; i < list.count(); ++i)
5844 if (list[i] == Private::AT_LOGIN_TYPE)
5845 flags << Private::AT_LOGIN_TYPE;
5846 else if (list[i] == ARCHIVE_REMINDER_ONCE_TYPE)
5847 reminderOnce =
true;
5848 else if (!list[i].isEmpty() && !list[i].startsWith(QChar::fromLatin1(
'-')))
5852 event->setCustomProperty(
KACalendar::APPNAME, Private::FLAGS_PROPERTY, flags.join(Private::SC));
5856 for (
int i = 0, alend = alarms.count(); i < alend; ++i)
5858 #ifndef KALARMCAL_USE_KRESOURCES
5861 Alarm* alarm = alarms[i];
5866 if (!property.isEmpty())
5868 flags << Private::EMAIL_ID_FLAG << property;
5873 flags << Private::SPEAK_FLAG;
5878 flags << Private::CANCEL_ON_ERROR_FLAG;
5883 flags << Private::DONT_SHOW_ERROR_FLAG;
5886 if (!flags.isEmpty())
5893 QStringList types =
property.split(QChar::fromLatin1(
','), QString::SkipEmptyParts);
5894 const int r = types.indexOf(REMINDER_ONCE_TYPE);
5898 types[r] = Private::REMINDER_TYPE;
5900 reminderOnce =
true;
5902 if (r >= 0 || types.contains(Private::REMINDER_TYPE))
5911 else if (offset < 0)
5912 reminder = reminderToString(offset / 60);
5915 if (!reminder.isEmpty())
5919 flags =
event->customProperty(
KACalendar::APPNAME, Private::FLAGS_PROPERTY).split(Private::SC, QString::SkipEmptyParts);
5920 if (flags.indexOf(Private::REMINDER_TYPE) < 0)
5922 flags += Private::REMINDER_TYPE;
5924 flags += Private::REMINDER_ONCE_FLAG;
5931 event->setReadOnly(
true);
5932 event->endUpdates();
5941 #ifndef KALARMCAL_USE_KRESOURCES
5942 bool KAEvent::Private::convertStartOfDay(
const Event::Ptr& event)
5944 bool KAEvent::Private::convertStartOfDay(
Event* event)
5947 bool changed =
false;
5948 const QTime midnight(0, 0);
5949 const QStringList flags =
event->customProperty(
KACalendar::APPNAME, Private::FLAGS_PROPERTY).split(Private::SC, QString::SkipEmptyParts);
5950 if (flags.indexOf(Private::DATE_ONLY_FLAG) >= 0)
5953 const KDateTime oldDt =
event->dtStart();
5954 const int adjustment = oldDt.time().secsTo(midnight);
5957 event->setDtStart(KDateTime(oldDt.date(), midnight, oldDt.timeSpec()));
5958 int deferralOffset = 0;
5960 readAlarms(event, &alarmMap);
5961 for (AlarmMap::ConstIterator it = alarmMap.constBegin(); it != alarmMap.constEnd(); ++it)
5963 const AlarmData& data = it.value();
5964 if (!data.alarm->hasStartOffset())
5966 if (data.timedDeferral)
5969 deferralOffset = data.alarm->startOffset().asSeconds();
5970 #ifndef KALARMCAL_USE_KRESOURCES
5971 const_cast<Alarm*
>(data.alarm.data())->setStartOffset(deferralOffset - adjustment);
5973 const_cast<Alarm*
>(data.alarm)->setStartOffset(deferralOffset - adjustment);
5976 else if (data.type == AUDIO_ALARM
5977 && data.alarm->startOffset().asSeconds() == deferralOffset)
5980 #ifndef KALARMCAL_USE_KRESOURCES
5981 const_cast<Alarm*
>(data.alarm.data())->setStartOffset(deferralOffset - adjustment);
5983 const_cast<Alarm*
>(data.alarm)->setStartOffset(deferralOffset - adjustment);
5993 bool foundDeferral =
false;
5994 int deferralOffset = 0;
5995 int newDeferralOffset = 0;
5997 const KDateTime nextMainDateTime = readDateTime(event,
false, start).kDateTime();
5999 readAlarms(event, &alarmMap);
6000 for (AlarmMap::ConstIterator it = alarmMap.constBegin(); it != alarmMap.constEnd(); ++it)
6002 const AlarmData& data = it.value();
6003 if (!data.alarm->hasStartOffset())
6005 if ((data.type & DEFERRED_ALARM) && !data.timedDeferral)
6008 KDateTime altime = data.alarm->startOffset().end(nextMainDateTime);
6009 altime.setTime(midnight);
6010 deferralOffset = data.alarm->startOffset().asSeconds();
6011 newDeferralOffset =
event->dtStart().secsTo(altime);
6012 #ifndef KALARMCAL_USE_KRESOURCES
6013 const_cast<Alarm*
>(data.alarm.data())->setStartOffset(newDeferralOffset);
6015 const_cast<Alarm*
>(data.alarm)->setStartOffset(newDeferralOffset);
6017 foundDeferral =
true;
6020 else if (foundDeferral
6021 && data.type == AUDIO_ALARM
6022 && data.alarm->startOffset().asSeconds() == deferralOffset)
6025 #ifndef KALARMCAL_USE_KRESOURCES
6026 const_cast<Alarm*
>(data.alarm.data())->setStartOffset(newDeferralOffset);
6028 const_cast<Alarm*
>(data.alarm)->setStartOffset(newDeferralOffset);
6045 #ifndef KALARMCAL_USE_KRESOURCES
6046 bool KAEvent::Private::convertRepetition(
const Event::Ptr& event)
6048 bool KAEvent::Private::convertRepetition(
Event* event)
6052 if (alarms.isEmpty())
6057 bool converted =
false;
6058 const bool readOnly =
event->isReadOnly();
6059 for (
int ai = 0, aend = alarms.count(); ai < aend; ++ai)
6061 #ifndef KALARMCAL_USE_KRESOURCES
6064 Alarm* alarm = alarms[ai];
6070 event->startUpdates();
6072 event->setReadOnly(
false);
6087 event->setReadOnly(
true);
6088 event->endUpdates();
6105 KAAlarm::Private::Private()
6106 : mType(INVALID_ALARM),
6108 mRepeatAtLogin(false),
6114 : d(new Private(*other.d))
6132 return d->mActionType;
6147 return (withRepeats && d->mNextRepeat && d->mRepetition)
6148 ? d->mRepetition.duration(d->mNextRepeat).end(d->mNextMainDateTime.kDateTime())
6149 : d->mNextMainDateTime;
6154 return d->mNextMainDateTime.date();
6159 return d->mNextMainDateTime.effectiveTime();
6164 return d->mRepeatAtLogin;
6174 return d->mDeferred;
6179 return d->mDeferred && d->mTimedDeferral;
6184 d->mNextMainDateTime = dt;
6189 d->mNextMainDateTime = dt;
6192 #ifdef KDE_NO_DEBUG_OUTPUT
6205 default:
return "INVALID";
6219 #ifndef KALARMCAL_USE_KRESOURCES
6220 EmailAddressList& EmailAddressList::operator=(
const Person::List& addresses)
6222 EmailAddressList& EmailAddressList::operator=(
const QList<Person>& addresses)
6226 for (
int p = 0, end = addresses.count(); p < end; ++p)
6228 #ifndef KALARMCAL_USE_KRESOURCES
6229 if (!addresses[p]->email().isEmpty())
6231 if (!addresses[p].email().isEmpty())
6233 append(addresses[p]);
6241 EmailAddressList::operator QStringList()
const
6244 for (
int p = 0, end = count(); p < end; ++p)
6253 QString EmailAddressList::join(
const QString& separator)
const
6257 for (
int p = 0, end = count(); p < end; ++p)
6262 result += separator;
6263 result += address(p);
6271 QString EmailAddressList::address(
int index)
const
6273 if (index < 0 || index > count())
6277 #ifndef KALARMCAL_USE_KRESOURCES
6278 const Person::Ptr person = (*this)[index];
6279 const QString name = person->name();
6281 const Person person = (*this)[index];
6282 const QString name = person.name();
6284 if (!name.isEmpty())
6287 for (
int i = 0, len = name.length(); i < len; ++i)
6289 const QChar ch = name[i];
6290 if (!ch.isLetterOrNumber())
6297 #ifndef KALARMCAL_USE_KRESOURCES
6298 result += (*this)[index]->name();
6300 result += (*this)[index].name();
6302 result += (quote ?
"\" <" :
" <");
6306 #ifndef KALARMCAL_USE_KRESOURCES
6307 result += person->email();
6309 result += person.email();
6319 QStringList EmailAddressList::pureAddresses()
const
6322 for (
int p = 0, end = count(); p < end; ++p)
6323 #ifndef KALARMCAL_USE_KRESOURCES
6324 list += at(p)->email();
6326 list += at(p).email();
6334 QString EmailAddressList::pureAddresses(
const QString& separator)
const
6338 for (
int p = 0, end = count(); p < end; ++p)
6343 result += separator;
6344 #ifndef KALARMCAL_USE_KRESOURCES
6345 result += at(p)->email();
6347 result += at(p).email();
6363 #ifndef KALARMCAL_USE_KRESOURCES
6364 static void setProcedureAlarm(
const Alarm::Ptr& alarm,
const QString& commandLine)
6366 static void setProcedureAlarm(
Alarm* alarm,
const QString& commandLine)
6372 bool quoted =
false;
6373 const uint posMax = commandLine.length();
6375 for (pos = 0; pos < posMax; ++pos)
6377 const QChar ch = commandLine[pos];
6380 if (ch == quoteChar)
6390 switch (ch.toLatin1())
6397 done = !command.isEmpty();
6401 if (command.isEmpty())
6419 for ( ; pos < posMax && commandLine[pos] == QLatin1Char(
' '); ++pos) ;
6420 arguments = commandLine.mid(pos);
6429 QString reminderToString(
int minutes)
6432 int count = abs(minutes);
6433 if (count % 1440 == 0)
6438 else if (count % 60 == 0)
6445 return QString(
"%1%2").arg(count).arg(unit);