00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kalarm.h"
00022
00023 #include <stdlib.h>
00024 #include <time.h>
00025 #include <ctype.h>
00026 #include <qcolor.h>
00027 #include <qregexp.h>
00028
00029 #include <klocale.h>
00030 #include <kdebug.h>
00031
00032 #include "alarmtext.h"
00033 #include "functions.h"
00034 #include "kalarmapp.h"
00035 #include "preferences.h"
00036 #include "alarmcalendar.h"
00037 #include "alarmevent.h"
00038 using namespace KCal;
00039
00040
00041 const QCString APPNAME("KALARM");
00042
00043
00044
00045
00046 QString KAEvent::calVersionString() { return QString::fromLatin1("1.4.14"); }
00047 int KAEvent::calVersion() { return KAlarm::Version(1,4,14); }
00048
00049
00050
00051
00052 static const QCString NEXT_RECUR_PROPERTY("NEXTRECUR");
00053 static const QCString REPEAT_PROPERTY("REPEAT");
00054
00055 static const QCString TYPE_PROPERTY("TYPE");
00056 static const QString FILE_TYPE = QString::fromLatin1("FILE");
00057 static const QString AT_LOGIN_TYPE = QString::fromLatin1("LOGIN");
00058 static const QString REMINDER_TYPE = QString::fromLatin1("REMINDER");
00059 static const QString REMINDER_ONCE_TYPE = QString::fromLatin1("REMINDER_ONCE");
00060 static const QString ARCHIVE_REMINDER_ONCE_TYPE = QString::fromLatin1("ONCE");
00061 static const QString TIME_DEFERRAL_TYPE = QString::fromLatin1("DEFERRAL");
00062 static const QString DATE_DEFERRAL_TYPE = QString::fromLatin1("DATE_DEFERRAL");
00063 static const QString DISPLAYING_TYPE = QString::fromLatin1("DISPLAYING");
00064 static const QString PRE_ACTION_TYPE = QString::fromLatin1("PRE");
00065 static const QString POST_ACTION_TYPE = QString::fromLatin1("POST");
00066 static const QCString NEXT_REPEAT_PROPERTY("NEXTREPEAT");
00067
00068 static const QCString FONT_COLOUR_PROPERTY("FONTCOLOR");
00069
00070 static const QCString KMAIL_ID_PROPERTY("KMAILID");
00071
00072 static const QCString VOLUME_PROPERTY("VOLUME");
00073 static const QCString SPEAK_PROPERTY("SPEAK");
00074
00075
00076 static const QString DATE_ONLY_CATEGORY = QString::fromLatin1("DATE");
00077 static const QString EMAIL_BCC_CATEGORY = QString::fromLatin1("BCC");
00078 static const QString CONFIRM_ACK_CATEGORY = QString::fromLatin1("ACKCONF");
00079 static const QString LATE_CANCEL_CATEGORY = QString::fromLatin1("LATECANCEL;");
00080 static const QString AUTO_CLOSE_CATEGORY = QString::fromLatin1("LATECLOSE;");
00081 static const QString TEMPL_AFTER_TIME_CATEGORY = QString::fromLatin1("TMPLAFTTIME;");
00082 static const QString KMAIL_SERNUM_CATEGORY = QString::fromLatin1("KMAIL:");
00083 static const QString KORGANIZER_CATEGORY = QString::fromLatin1("KORG");
00084 static const QString DEFER_CATEGORY = QString::fromLatin1("DEFER;");
00085 static const QString ARCHIVE_CATEGORY = QString::fromLatin1("SAVE");
00086 static const QString ARCHIVE_CATEGORIES = QString::fromLatin1("SAVE:");
00087 static const QString LOG_CATEGORY = QString::fromLatin1("LOG:");
00088 static const QString xtermURL = QString::fromLatin1("xterm:");
00089
00090
00091 static const QString DISABLED_STATUS = QString::fromLatin1("DISABLED");
00092
00093 static const QString EXPIRED_UID = QString::fromLatin1("-exp-");
00094 static const QString DISPLAYING_UID = QString::fromLatin1("-disp-");
00095 static const QString TEMPLATE_UID = QString::fromLatin1("-tmpl-");
00096 static const QString KORGANIZER_UID = QString::fromLatin1("-korg-");
00097
00098 struct AlarmData
00099 {
00100 const Alarm* alarm;
00101 QString cleanText;
00102 QString emailFromKMail;
00103 EmailAddressList emailAddresses;
00104 QString emailSubject;
00105 QStringList emailAttachments;
00106 QFont font;
00107 QColor bgColour, fgColour;
00108 float soundVolume;
00109 float fadeVolume;
00110 int fadeSeconds;
00111 int startOffsetSecs;
00112 bool speak;
00113 KAAlarm::SubType type;
00114 KAAlarmEventBase::Type action;
00115 int displayingFlags;
00116 bool defaultFont;
00117 bool reminderOnceOnly;
00118 bool isEmailText;
00119 bool commandScript;
00120 int repeatCount;
00121 int repeatInterval;
00122 int nextRepeat;
00123 };
00124 typedef QMap<KAAlarm::SubType, AlarmData> AlarmMap;
00125
00126 static void setProcedureAlarm(Alarm*, const QString& commandLine);
00127
00128
00129
00130
00131
00132
00133
00134 inline void KAEvent::set_deferral(DeferType type)
00135 {
00136 if (type)
00137 {
00138 if (!mDeferral)
00139 ++mAlarmCount;
00140 }
00141 else
00142 {
00143 if (mDeferral)
00144 --mAlarmCount;
00145 }
00146 mDeferral = type;
00147 }
00148
00149 inline void KAEvent::set_reminder(int minutes)
00150 {
00151 if (!mReminderMinutes)
00152 ++mAlarmCount;
00153 mReminderMinutes = minutes;
00154 mArchiveReminderMinutes = 0;
00155 }
00156
00157 inline void KAEvent::set_archiveReminder()
00158 {
00159 if (mReminderMinutes)
00160 --mAlarmCount;
00161 mArchiveReminderMinutes = mReminderMinutes;
00162 mReminderMinutes = 0;
00163 }
00164
00165
00166 void KAEvent::copy(const KAEvent& event)
00167 {
00168 KAAlarmEventBase::copy(event);
00169 mTemplateName = event.mTemplateName;
00170 mAudioFile = event.mAudioFile;
00171 mPreAction = event.mPreAction;
00172 mPostAction = event.mPostAction;
00173 mStartDateTime = event.mStartDateTime;
00174 mSaveDateTime = event.mSaveDateTime;
00175 mAtLoginDateTime = event.mAtLoginDateTime;
00176 mDeferralTime = event.mDeferralTime;
00177 mDisplayingTime = event.mDisplayingTime;
00178 mDisplayingFlags = event.mDisplayingFlags;
00179 mReminderMinutes = event.mReminderMinutes;
00180 mArchiveReminderMinutes = event.mArchiveReminderMinutes;
00181 mDeferDefaultMinutes = event.mDeferDefaultMinutes;
00182 mRevision = event.mRevision;
00183 mRemainingRecurrences = event.mRemainingRecurrences;
00184 mAlarmCount = event.mAlarmCount;
00185 mDeferral = event.mDeferral;
00186 mLogFile = event.mLogFile;
00187 mCommandXterm = event.mCommandXterm;
00188 mKMailSerialNumber = event.mKMailSerialNumber;
00189 mCopyToKOrganizer = event.mCopyToKOrganizer;
00190 mReminderOnceOnly = event.mReminderOnceOnly;
00191 mMainExpired = event.mMainExpired;
00192 mArchiveRepeatAtLogin = event.mArchiveRepeatAtLogin;
00193 mArchive = event.mArchive;
00194 mTemplateAfterTime = event.mTemplateAfterTime;
00195 mEnabled = event.mEnabled;
00196 mUpdated = event.mUpdated;
00197 delete mRecurrence;
00198 if (event.mRecurrence)
00199 mRecurrence = new KARecurrence(*event.mRecurrence);
00200 else
00201 mRecurrence = 0;
00202 }
00203
00204
00205
00206
00207 void KAEvent::set(const Event& event)
00208 {
00209
00210 mEventID = event.uid();
00211 mRevision = event.revision();
00212 mTemplateName = QString::null;
00213 mLogFile = QString::null;
00214 mTemplateAfterTime = -1;
00215 mBeep = false;
00216 mSpeak = false;
00217 mEmailBcc = false;
00218 mCommandXterm = false;
00219 mCopyToKOrganizer = false;
00220 mConfirmAck = false;
00221 mArchive = false;
00222 mReminderOnceOnly = false;
00223 mAutoClose = false;
00224 mArchiveRepeatAtLogin = false;
00225 mArchiveReminderMinutes = 0;
00226 mDeferDefaultMinutes = 0;
00227 mLateCancel = 0;
00228 mRepeatInterval = 0;
00229 mRepeatCount = 0;
00230 mKMailSerialNumber = 0;
00231 mBgColour = QColor(255, 255, 255);
00232 mFgColour = QColor(0, 0, 0);
00233 mDefaultFont = true;
00234 mEnabled = true;
00235 bool ok;
00236 bool dateOnly = false;
00237 const QStringList& cats = event.categories();
00238 for (unsigned int i = 0; i < cats.count(); ++i)
00239 {
00240 if (cats[i] == DATE_ONLY_CATEGORY)
00241 dateOnly = true;
00242 else if (cats[i] == CONFIRM_ACK_CATEGORY)
00243 mConfirmAck = true;
00244 else if (cats[i] == EMAIL_BCC_CATEGORY)
00245 mEmailBcc = true;
00246 else if (cats[i] == ARCHIVE_CATEGORY)
00247 mArchive = true;
00248 else if (cats[i] == KORGANIZER_CATEGORY)
00249 mCopyToKOrganizer = true;
00250 else if (cats[i].startsWith(KMAIL_SERNUM_CATEGORY))
00251 mKMailSerialNumber = cats[i].mid(KMAIL_SERNUM_CATEGORY.length()).toULong();
00252 else if (cats[i].startsWith(LOG_CATEGORY))
00253 {
00254 QString logUrl = cats[i].mid(LOG_CATEGORY.length());
00255 if (logUrl == xtermURL)
00256 mCommandXterm = true;
00257 else
00258 mLogFile = logUrl;
00259 }
00260 else if (cats[i].startsWith(ARCHIVE_CATEGORIES))
00261 {
00262
00263 mArchive = true;
00264 QStringList list = QStringList::split(';', cats[i].mid(ARCHIVE_CATEGORIES.length()));
00265 for (unsigned int j = 0; j < list.count(); ++j)
00266 {
00267 if (list[j] == AT_LOGIN_TYPE)
00268 mArchiveRepeatAtLogin = true;
00269 else if (list[j] == ARCHIVE_REMINDER_ONCE_TYPE)
00270 mReminderOnceOnly = true;
00271 else
00272 {
00273 char ch;
00274 const char* cat = list[j].latin1();
00275 while ((ch = *cat) != 0 && (ch < '0' || ch > '9'))
00276 ++cat;
00277 if (ch)
00278 {
00279 mArchiveReminderMinutes = ch - '0';
00280 while ((ch = *++cat) >= '0' && ch <= '9')
00281 mArchiveReminderMinutes = mArchiveReminderMinutes * 10 + ch - '0';
00282 switch (ch)
00283 {
00284 case 'M': break;
00285 case 'H': mArchiveReminderMinutes *= 60; break;
00286 case 'D': mArchiveReminderMinutes *= 1440; break;
00287 }
00288 }
00289 }
00290 }
00291 }
00292 else if (cats[i].startsWith(DEFER_CATEGORY))
00293 {
00294 mDeferDefaultMinutes = static_cast<int>(cats[i].mid(DEFER_CATEGORY.length()).toUInt(&ok));
00295 if (!ok)
00296 mDeferDefaultMinutes = 0;
00297 }
00298 else if (cats[i].startsWith(TEMPL_AFTER_TIME_CATEGORY))
00299 {
00300 mTemplateAfterTime = static_cast<int>(cats[i].mid(TEMPL_AFTER_TIME_CATEGORY.length()).toUInt(&ok));
00301 if (!ok)
00302 mTemplateAfterTime = -1;
00303 }
00304 else if (cats[i].startsWith(LATE_CANCEL_CATEGORY))
00305 {
00306 mLateCancel = static_cast<int>(cats[i].mid(LATE_CANCEL_CATEGORY.length()).toUInt(&ok));
00307 if (!ok || !mLateCancel)
00308 mLateCancel = 1;
00309 }
00310 else if (cats[i].startsWith(AUTO_CLOSE_CATEGORY))
00311 {
00312 mLateCancel = static_cast<int>(cats[i].mid(AUTO_CLOSE_CATEGORY.length()).toUInt(&ok));
00313 if (!ok || !mLateCancel)
00314 mLateCancel = 1;
00315 mAutoClose = true;
00316 }
00317 }
00318 QString prop = event.customProperty(APPNAME, REPEAT_PROPERTY);
00319 if (!prop.isEmpty())
00320 {
00321 QStringList list = QStringList::split(':', prop);
00322 if (list.count() >= 2)
00323 {
00324 int interval = static_cast<int>(list[0].toUInt());
00325 int count = static_cast<int>(list[1].toUInt());
00326 if (interval && count)
00327 {
00328 mRepeatInterval = interval;
00329 mRepeatCount = count;
00330 }
00331 }
00332 }
00333 mNextMainDateTime = readDateTime(event, dateOnly, mStartDateTime);
00334 mSaveDateTime = event.created();
00335 if (uidStatus() == TEMPLATE)
00336 mTemplateName = event.summary();
00337 if (event.statusStr() == DISABLED_STATUS)
00338 mEnabled = false;
00339
00340
00341
00342 mActionType = T_MESSAGE;
00343 mMainExpired = true;
00344 mRepeatAtLogin = false;
00345 mDisplaying = false;
00346 mRepeatSound = false;
00347 mCommandScript = false;
00348 mDeferral = NO_DEFERRAL;
00349 mSoundVolume = -1;
00350 mFadeVolume = -1;
00351 mFadeSeconds = 0;
00352 mReminderMinutes = 0;
00353 mNextRepeat = 0;
00354 mText = "";
00355 mAudioFile = "";
00356 mPreAction = "";
00357 mPostAction = "";
00358 mEmailFromKMail = "";
00359 mEmailSubject = "";
00360 mEmailAddresses.clear();
00361 mEmailAttachments.clear();
00362 clearRecur();
00363
00364
00365 AlarmMap alarmMap;
00366 readAlarms(event, &alarmMap);
00367
00368
00369 mAlarmCount = 0;
00370 DateTime alTime;
00371 bool set = false;
00372 bool isEmailText = false;
00373 bool setDeferralTime = false;
00374 Duration deferralOffset;
00375 for (AlarmMap::ConstIterator it = alarmMap.begin(); it != alarmMap.end(); ++it)
00376 {
00377 const AlarmData& data = it.data();
00378 DateTime dateTime = data.alarm->hasStartOffset() ? mNextMainDateTime.addSecs(data.alarm->startOffset().asSeconds()) : data.alarm->time();
00379 switch (data.type)
00380 {
00381 case KAAlarm::MAIN__ALARM:
00382 mMainExpired = false;
00383 alTime = dateTime;
00384 alTime.setDateOnly(mStartDateTime.isDateOnly());
00385 if (data.repeatCount && data.repeatInterval)
00386 {
00387 mRepeatInterval = data.repeatInterval;
00388 mRepeatCount = data.repeatCount;
00389 mNextRepeat = data.nextRepeat;
00390 }
00391 break;
00392 case KAAlarm::AT_LOGIN__ALARM:
00393 mRepeatAtLogin = true;
00394 mAtLoginDateTime = dateTime.rawDateTime();
00395 alTime = mAtLoginDateTime;
00396 break;
00397 case KAAlarm::REMINDER__ALARM:
00398 mReminderMinutes = -(data.startOffsetSecs / 60);
00399 if (mReminderMinutes)
00400 mArchiveReminderMinutes = 0;
00401 break;
00402 case KAAlarm::DEFERRED_REMINDER_DATE__ALARM:
00403 case KAAlarm::DEFERRED_DATE__ALARM:
00404 mDeferral = (data.type == KAAlarm::DEFERRED_REMINDER_DATE__ALARM) ? REMINDER_DEFERRAL : NORMAL_DEFERRAL;
00405 mDeferralTime = dateTime;
00406 mDeferralTime.setDateOnly(true);
00407 if (data.alarm->hasStartOffset())
00408 deferralOffset = data.alarm->startOffset();
00409 break;
00410 case KAAlarm::DEFERRED_REMINDER_TIME__ALARM:
00411 case KAAlarm::DEFERRED_TIME__ALARM:
00412 mDeferral = (data.type == KAAlarm::DEFERRED_REMINDER_TIME__ALARM) ? REMINDER_DEFERRAL : NORMAL_DEFERRAL;
00413 mDeferralTime = dateTime;
00414 if (data.alarm->hasStartOffset())
00415 deferralOffset = data.alarm->startOffset();
00416 break;
00417 case KAAlarm::DISPLAYING__ALARM:
00418 {
00419 mDisplaying = true;
00420 mDisplayingFlags = data.displayingFlags;
00421 bool dateOnly = (mDisplayingFlags & DEFERRAL) ? !(mDisplayingFlags & TIMED_FLAG)
00422 : mStartDateTime.isDateOnly();
00423 mDisplayingTime = dateTime;
00424 mDisplayingTime.setDateOnly(dateOnly);
00425 alTime = mDisplayingTime;
00426 break;
00427 }
00428 case KAAlarm::AUDIO__ALARM:
00429 mAudioFile = data.cleanText;
00430 mSpeak = data.speak && mAudioFile.isEmpty();
00431 mBeep = !mSpeak && mAudioFile.isEmpty();
00432 mSoundVolume = (!mBeep && !mSpeak) ? data.soundVolume : -1;
00433 mFadeVolume = (mSoundVolume >= 0 && data.fadeSeconds > 0) ? data.fadeVolume : -1;
00434 mFadeSeconds = (mFadeVolume >= 0) ? data.fadeSeconds : 0;
00435 mRepeatSound = (!mBeep && !mSpeak) && (data.repeatCount < 0);
00436 break;
00437 case KAAlarm::PRE_ACTION__ALARM:
00438 mPreAction = data.cleanText;
00439 break;
00440 case KAAlarm::POST_ACTION__ALARM:
00441 mPostAction = data.cleanText;
00442 break;
00443 case KAAlarm::INVALID__ALARM:
00444 default:
00445 break;
00446 }
00447
00448 if (data.reminderOnceOnly)
00449 mReminderOnceOnly = true;
00450 bool noSetNextTime = false;
00451 switch (data.type)
00452 {
00453 case KAAlarm::DEFERRED_REMINDER_DATE__ALARM:
00454 case KAAlarm::DEFERRED_DATE__ALARM:
00455 case KAAlarm::DEFERRED_REMINDER_TIME__ALARM:
00456 case KAAlarm::DEFERRED_TIME__ALARM:
00457 if (!set)
00458 {
00459
00460
00461 setDeferralTime = true;
00462 noSetNextTime = true;
00463 }
00464
00465 case KAAlarm::AT_LOGIN__ALARM:
00466 case KAAlarm::REMINDER__ALARM:
00467 case KAAlarm::DISPLAYING__ALARM:
00468 if (!set && !noSetNextTime)
00469 mNextMainDateTime = alTime;
00470
00471 case KAAlarm::MAIN__ALARM:
00472
00473
00474 if (!set)
00475 {
00476 mActionType = data.action;
00477 mText = (mActionType == T_COMMAND) ? data.cleanText.stripWhiteSpace() : data.cleanText;
00478 switch (data.action)
00479 {
00480 case T_MESSAGE:
00481 mFont = data.font;
00482 mDefaultFont = data.defaultFont;
00483 if (data.isEmailText)
00484 isEmailText = true;
00485
00486 case T_FILE:
00487 mBgColour = data.bgColour;
00488 mFgColour = data.fgColour;
00489 break;
00490 case T_COMMAND:
00491 mCommandScript = data.commandScript;
00492 break;
00493 case T_EMAIL:
00494 mEmailFromKMail = data.emailFromKMail;
00495 mEmailAddresses = data.emailAddresses;
00496 mEmailSubject = data.emailSubject;
00497 mEmailAttachments = data.emailAttachments;
00498 break;
00499 default:
00500 break;
00501 }
00502 set = true;
00503 }
00504 if (data.action == T_FILE && mActionType == T_MESSAGE)
00505 mActionType = T_FILE;
00506 ++mAlarmCount;
00507 break;
00508 case KAAlarm::AUDIO__ALARM:
00509 case KAAlarm::PRE_ACTION__ALARM:
00510 case KAAlarm::POST_ACTION__ALARM:
00511 case KAAlarm::INVALID__ALARM:
00512 default:
00513 break;
00514 }
00515 }
00516 if (!isEmailText)
00517 mKMailSerialNumber = 0;
00518 if (mRepeatAtLogin)
00519 mArchiveRepeatAtLogin = false;
00520
00521 Recurrence* recur = event.recurrence();
00522 if (recur && recur->doesRecur())
00523 {
00524 int nextRepeat = mNextRepeat;
00525 setRecurrence(*recur);
00526 if (nextRepeat <= mRepeatCount)
00527 mNextRepeat = nextRepeat;
00528 }
00529
00530 if (mMainExpired && deferralOffset.asSeconds() && checkRecur() != KARecurrence::NO_RECUR)
00531 {
00532
00533
00534 DateTime dt = mRecurrence->getNextDateTime(mStartDateTime.dateTime().addDays(-1));
00535 dt.setDateOnly(mStartDateTime.isDateOnly());
00536 if (mDeferralTime.isDateOnly())
00537 {
00538 mDeferralTime = dt.addSecs(deferralOffset.asSeconds());
00539 mDeferralTime.setDateOnly(true);
00540 }
00541 else
00542 mDeferralTime = deferralOffset.end(dt.dateTime());
00543 }
00544 if (mDeferral)
00545 {
00546 if (mNextMainDateTime == mDeferralTime)
00547 mDeferral = CANCEL_DEFERRAL;
00548 if (setDeferralTime)
00549 mNextMainDateTime = mDeferralTime;
00550 }
00551
00552 mUpdated = false;
00553 }
00554
00555
00556
00557
00558
00559 DateTime KAEvent::readDateTime(const Event& event, bool dateOnly, DateTime& start)
00560 {
00561 start.set(event.dtStart(), dateOnly);
00562 DateTime next = start;
00563 QString prop = event.customProperty(APPNAME, NEXT_RECUR_PROPERTY);
00564 if (prop.length() >= 8)
00565 {
00566
00567 QDate d(prop.left(4).toInt(), prop.mid(4,2).toInt(), prop.mid(6,2).toInt());
00568 if (d.isValid())
00569 {
00570 if (dateOnly && prop.length() == 8)
00571 next = d;
00572 else if (!dateOnly && prop.length() == 15 && prop[8] == QChar('T'))
00573 {
00574 QTime t(prop.mid(9,2).toInt(), prop.mid(11,2).toInt(), prop.mid(13,2).toInt());
00575 if (t.isValid())
00576 next = QDateTime(d, t);
00577 }
00578 }
00579 }
00580 return next;
00581 }
00582
00583
00584
00585
00586
00587 void KAEvent::readAlarms(const Event& event, void* almap)
00588 {
00589 AlarmMap* alarmMap = (AlarmMap*)almap;
00590 Alarm::List alarms = event.alarms();
00591 for (Alarm::List::ConstIterator it = alarms.begin(); it != alarms.end(); ++it)
00592 {
00593
00594 AlarmData data;
00595 readAlarm(**it, data);
00596 if (data.type != KAAlarm::INVALID__ALARM)
00597 alarmMap->insert(data.type, data);
00598 }
00599 }
00600
00601
00602
00603
00604
00605 void KAEvent::readAlarm(const Alarm& alarm, AlarmData& data)
00606 {
00607
00608 data.alarm = &alarm;
00609 data.startOffsetSecs = alarm.startOffset().asSeconds();
00610 data.displayingFlags = 0;
00611 data.isEmailText = false;
00612 data.nextRepeat = 0;
00613 data.repeatInterval = alarm.snoozeTime();
00614 data.repeatCount = alarm.repeatCount();
00615 if (data.repeatCount)
00616 {
00617 bool ok;
00618 QString property = alarm.customProperty(APPNAME, NEXT_REPEAT_PROPERTY);
00619 int n = static_cast<int>(property.toUInt(&ok));
00620 if (ok)
00621 data.nextRepeat = n;
00622 }
00623 switch (alarm.type())
00624 {
00625 case Alarm::Procedure:
00626 data.action = T_COMMAND;
00627 data.cleanText = alarm.programFile();
00628 data.commandScript = data.cleanText.isEmpty();
00629 if (!alarm.programArguments().isEmpty())
00630 {
00631 if (!data.commandScript)
00632 data.cleanText += ' ';
00633 data.cleanText += alarm.programArguments();
00634 }
00635 break;
00636 case Alarm::Email:
00637 data.action = T_EMAIL;
00638 data.emailFromKMail = alarm.customProperty(APPNAME, KMAIL_ID_PROPERTY);
00639 data.emailAddresses = alarm.mailAddresses();
00640 data.emailSubject = alarm.mailSubject();
00641 data.emailAttachments = alarm.mailAttachments();
00642 data.cleanText = alarm.mailText();
00643 break;
00644 case Alarm::Display:
00645 {
00646 data.action = T_MESSAGE;
00647 data.cleanText = AlarmText::fromCalendarText(alarm.text(), data.isEmailText);
00648 QString property = alarm.customProperty(APPNAME, FONT_COLOUR_PROPERTY);
00649 QStringList list = QStringList::split(QChar(';'), property, true);
00650 data.bgColour = QColor(255, 255, 255);
00651 data.fgColour = QColor(0, 0, 0);
00652 int n = list.count();
00653 if (n > 0)
00654 {
00655 if (!list[0].isEmpty())
00656 {
00657 QColor c(list[0]);
00658 if (c.isValid())
00659 data.bgColour = c;
00660 }
00661 if (n > 1 && !list[1].isEmpty())
00662 {
00663 QColor c(list[1]);
00664 if (c.isValid())
00665 data.fgColour = c;
00666 }
00667 }
00668 data.defaultFont = (n <= 2 || list[2].isEmpty());
00669 if (!data.defaultFont)
00670 data.font.fromString(list[2]);
00671 break;
00672 }
00673 case Alarm::Audio:
00674 {
00675 data.action = T_AUDIO;
00676 data.cleanText = alarm.audioFile();
00677 data.type = KAAlarm::AUDIO__ALARM;
00678 data.soundVolume = -1;
00679 data.fadeVolume = -1;
00680 data.fadeSeconds = 0;
00681 data.speak = !alarm.customProperty(APPNAME, SPEAK_PROPERTY).isNull();
00682 QString property = alarm.customProperty(APPNAME, VOLUME_PROPERTY);
00683 if (!property.isEmpty())
00684 {
00685 bool ok;
00686 float fadeVolume;
00687 int fadeSecs = 0;
00688 QStringList list = QStringList::split(QChar(';'), property, true);
00689 data.soundVolume = list[0].toFloat(&ok);
00690 if (!ok)
00691 data.soundVolume = -1;
00692 if (data.soundVolume >= 0 && list.count() >= 3)
00693 {
00694 fadeVolume = list[1].toFloat(&ok);
00695 if (ok)
00696 fadeSecs = static_cast<int>(list[2].toUInt(&ok));
00697 if (ok && fadeVolume >= 0 && fadeSecs > 0)
00698 {
00699 data.fadeVolume = fadeVolume;
00700 data.fadeSeconds = fadeSecs;
00701 }
00702 }
00703 }
00704 return;
00705 }
00706 case Alarm::Invalid:
00707 data.type = KAAlarm::INVALID__ALARM;
00708 return;
00709 }
00710
00711 bool atLogin = false;
00712 bool reminder = false;
00713 bool deferral = false;
00714 bool dateDeferral = false;
00715 data.reminderOnceOnly = false;
00716 data.type = KAAlarm::MAIN__ALARM;
00717 QString property = alarm.customProperty(APPNAME, TYPE_PROPERTY);
00718 QStringList types = QStringList::split(QChar(','), property);
00719 for (unsigned int i = 0; i < types.count(); ++i)
00720 {
00721 QString type = types[i];
00722 if (type == AT_LOGIN_TYPE)
00723 atLogin = true;
00724 else if (type == FILE_TYPE && data.action == T_MESSAGE)
00725 data.action = T_FILE;
00726 else if (type == REMINDER_TYPE)
00727 reminder = true;
00728 else if (type == REMINDER_ONCE_TYPE)
00729 reminder = data.reminderOnceOnly = true;
00730 else if (type == TIME_DEFERRAL_TYPE)
00731 deferral = true;
00732 else if (type == DATE_DEFERRAL_TYPE)
00733 dateDeferral = deferral = true;
00734 else if (type == DISPLAYING_TYPE)
00735 data.type = KAAlarm::DISPLAYING__ALARM;
00736 else if (type == PRE_ACTION_TYPE && data.action == T_COMMAND)
00737 data.type = KAAlarm::PRE_ACTION__ALARM;
00738 else if (type == POST_ACTION_TYPE && data.action == T_COMMAND)
00739 data.type = KAAlarm::POST_ACTION__ALARM;
00740 }
00741
00742 if (reminder)
00743 {
00744 if (data.type == KAAlarm::MAIN__ALARM)
00745 data.type = dateDeferral ? KAAlarm::DEFERRED_REMINDER_DATE__ALARM
00746 : deferral ? KAAlarm::DEFERRED_REMINDER_TIME__ALARM : KAAlarm::REMINDER__ALARM;
00747 else if (data.type == KAAlarm::DISPLAYING__ALARM)
00748 data.displayingFlags = dateDeferral ? REMINDER | DATE_DEFERRAL
00749 : deferral ? REMINDER | TIME_DEFERRAL : REMINDER;
00750 }
00751 else if (deferral)
00752 {
00753 if (data.type == KAAlarm::MAIN__ALARM)
00754 data.type = dateDeferral ? KAAlarm::DEFERRED_DATE__ALARM : KAAlarm::DEFERRED_TIME__ALARM;
00755 else if (data.type == KAAlarm::DISPLAYING__ALARM)
00756 data.displayingFlags = dateDeferral ? DATE_DEFERRAL : TIME_DEFERRAL;
00757 }
00758 if (atLogin)
00759 {
00760 if (data.type == KAAlarm::MAIN__ALARM)
00761 data.type = KAAlarm::AT_LOGIN__ALARM;
00762 else if (data.type == KAAlarm::DISPLAYING__ALARM)
00763 data.displayingFlags = REPEAT_AT_LOGIN;
00764 }
00765
00766 }
00767
00768
00769
00770
00771 void KAEvent::set(const QDateTime& dateTime, const QString& text, const QColor& bg, const QColor& fg,
00772 const QFont& font, Action action, int lateCancel, int flags)
00773 {
00774 clearRecur();
00775 mStartDateTime.set(dateTime, flags & ANY_TIME);
00776 mNextMainDateTime = mStartDateTime;
00777 switch (action)
00778 {
00779 case MESSAGE:
00780 case FILE:
00781 case COMMAND:
00782 case EMAIL:
00783 mActionType = (KAAlarmEventBase::Type)action;
00784 break;
00785 default:
00786 mActionType = T_MESSAGE;
00787 break;
00788 }
00789 mText = (mActionType == T_COMMAND) ? text.stripWhiteSpace() : text;
00790 mEventID = QString::null;
00791 mTemplateName = QString::null;
00792 mPreAction = QString::null;
00793 mPostAction = QString::null;
00794 mAudioFile = "";
00795 mSoundVolume = -1;
00796 mFadeVolume = -1;
00797 mTemplateAfterTime = -1;
00798 mFadeSeconds = 0;
00799 mBgColour = bg;
00800 mFgColour = fg;
00801 mFont = font;
00802 mAlarmCount = 1;
00803 mLateCancel = lateCancel;
00804 mDeferral = NO_DEFERRAL;
00805 set(flags);
00806 mKMailSerialNumber = 0;
00807 mReminderMinutes = 0;
00808 mArchiveReminderMinutes = 0;
00809 mDeferDefaultMinutes = 0;
00810 mRepeatInterval = 0;
00811 mRepeatCount = 0;
00812 mNextRepeat = 0;
00813 mArchiveRepeatAtLogin = false;
00814 mReminderOnceOnly = false;
00815 mDisplaying = false;
00816 mMainExpired = false;
00817 mArchive = false;
00818 mUpdated = false;
00819 }
00820
00821
00822
00823
00824 void KAEvent::setCommand(const QDate& d, const QString& command, int lateCancel, int flags, const QString& logfile)
00825 {
00826 if (!logfile.isEmpty())
00827 flags &= ~EXEC_IN_XTERM;
00828 set(d, command, QColor(), QColor(), QFont(), COMMAND, lateCancel, flags | ANY_TIME);
00829 mLogFile = logfile;
00830 }
00831
00832 void KAEvent::setCommand(const QDateTime& dt, const QString& command, int lateCancel, int flags, const QString& logfile)
00833 {
00834 if (!logfile.isEmpty())
00835 flags &= ~EXEC_IN_XTERM;
00836 set(dt, command, QColor(), QColor(), QFont(), COMMAND, lateCancel, flags);
00837 mLogFile = logfile;
00838 }
00839
00840 void KAEvent::setLogFile(const QString& logfile)
00841 {
00842 mLogFile = logfile;
00843 if (!logfile.isEmpty())
00844 mCommandXterm = false;
00845 }
00846
00847
00848
00849
00850 void KAEvent::setEmail(const QDate& d, const QString& from, const EmailAddressList& addresses, const QString& subject,
00851 const QString& message, const QStringList& attachments, int lateCancel, int flags)
00852 {
00853 set(d, message, QColor(), QColor(), QFont(), EMAIL, lateCancel, flags | ANY_TIME);
00854 mEmailFromKMail = from;
00855 mEmailAddresses = addresses;
00856 mEmailSubject = subject;
00857 mEmailAttachments = attachments;
00858 }
00859
00860 void KAEvent::setEmail(const QDateTime& dt, const QString& from, const EmailAddressList& addresses, const QString& subject,
00861 const QString& message, const QStringList& attachments, int lateCancel, int flags)
00862 {
00863 set(dt, message, QColor(), QColor(), QFont(), EMAIL, lateCancel, flags);
00864 mEmailFromKMail = from;
00865 mEmailAddresses = addresses;
00866 mEmailSubject = subject;
00867 mEmailAttachments = attachments;
00868 }
00869
00870 void KAEvent::setEmail(const QString& from, const EmailAddressList& addresses, const QString& subject, const QStringList& attachments)
00871 {
00872 mEmailFromKMail = from;
00873 mEmailAddresses = addresses;
00874 mEmailSubject = subject;
00875 mEmailAttachments = attachments;
00876 }
00877
00878 void KAEvent::setAudioFile(const QString& filename, float volume, float fadeVolume, int fadeSeconds)
00879 {
00880 mAudioFile = filename;
00881 mSoundVolume = filename.isEmpty() ? -1 : volume;
00882 if (mSoundVolume >= 0)
00883 {
00884 mFadeVolume = (fadeSeconds > 0) ? fadeVolume : -1;
00885 mFadeSeconds = (mFadeVolume >= 0) ? fadeSeconds : 0;
00886 }
00887 else
00888 {
00889 mFadeVolume = -1;
00890 mFadeSeconds = 0;
00891 }
00892 mUpdated = true;
00893 }
00894
00895 void KAEvent::setReminder(int minutes, bool onceOnly)
00896 {
00897 set_reminder(minutes);
00898 mReminderOnceOnly = onceOnly;
00899 mUpdated = true;
00900 }
00901
00902
00903
00904
00905
00906 void KAEvent::adjustStartDate(const QDate& d)
00907 {
00908 if (mStartDateTime.isDateOnly())
00909 {
00910 mStartDateTime = d;
00911 if (mRecurrence)
00912 mRecurrence->setStartDate(d);
00913 }
00914 else
00915 {
00916 mStartDateTime.set(d, mStartDateTime.time());
00917 if (mRecurrence)
00918 mRecurrence->setStartDateTime(mStartDateTime.dateTime());
00919 }
00920 mNextMainDateTime = mStartDateTime;
00921 }
00922
00923
00924
00925
00926
00927 DateTime KAEvent::nextDateTime(bool includeReminders) const
00928 {
00929 if (includeReminders && mReminderMinutes)
00930 {
00931 if (!mReminderOnceOnly || mNextMainDateTime == mStartDateTime)
00932 return mNextMainDateTime.addSecs(-mReminderMinutes * 60);
00933 }
00934 DateTime dt = mainDateTime(true);
00935 if (mDeferral > 0
00936 && (includeReminders || mDeferral != REMINDER_DEFERRAL))
00937 {
00938 if (mMainExpired)
00939 return mDeferralTime;
00940 return QMIN(mDeferralTime, dt);
00941 }
00942 return dt;
00943 }
00944
00945
00946
00947
00948 QString KAEvent::uid(const QString& id, Status status)
00949 {
00950 QString result = id;
00951 Status oldStatus;
00952 int i, len;
00953 if ((i = result.find(EXPIRED_UID)) > 0)
00954 {
00955 oldStatus = EXPIRED;
00956 len = EXPIRED_UID.length();
00957 }
00958 else if ((i = result.find(DISPLAYING_UID)) > 0)
00959 {
00960 oldStatus = DISPLAYING;
00961 len = DISPLAYING_UID.length();
00962 }
00963 else if ((i = result.find(TEMPLATE_UID)) > 0)
00964 {
00965 oldStatus = TEMPLATE;
00966 len = TEMPLATE_UID.length();
00967 }
00968 else if ((i = result.find(KORGANIZER_UID)) > 0)
00969 {
00970 oldStatus = KORGANIZER;
00971 len = KORGANIZER_UID.length();
00972 }
00973 else
00974 {
00975 oldStatus = ACTIVE;
00976 i = result.findRev('-');
00977 len = 1;
00978 }
00979 if (status != oldStatus && i > 0)
00980 {
00981 QString part;
00982 switch (status)
00983 {
00984 case ACTIVE: part = "-"; break;
00985 case EXPIRED: part = EXPIRED_UID; break;
00986 case DISPLAYING: part = DISPLAYING_UID; break;
00987 case TEMPLATE: part = TEMPLATE_UID; break;
00988 case KORGANIZER: part = KORGANIZER_UID; break;
00989 }
00990 result.replace(i, len, part);
00991 }
00992 return result;
00993 }
00994
00995
00996
00997
00998 KAEvent::Status KAEvent::uidStatus(const QString& uid)
00999 {
01000 if (uid.find(EXPIRED_UID) > 0)
01001 return EXPIRED;
01002 if (uid.find(DISPLAYING_UID) > 0)
01003 return DISPLAYING;
01004 if (uid.find(TEMPLATE_UID) > 0)
01005 return TEMPLATE;
01006 if (uid.find(KORGANIZER_UID) > 0)
01007 return KORGANIZER;
01008 return ACTIVE;
01009 }
01010
01011 void KAEvent::set(int flags)
01012 {
01013 KAAlarmEventBase::set(flags & ~READ_ONLY_FLAGS);
01014 mStartDateTime.setDateOnly(flags & ANY_TIME);
01015 set_deferral((flags & DEFERRAL) ? NORMAL_DEFERRAL : NO_DEFERRAL);
01016 mCommandXterm = flags & EXEC_IN_XTERM;
01017 mCopyToKOrganizer = flags & COPY_KORGANIZER;
01018 mEnabled = !(flags & DISABLED);
01019 mUpdated = true;
01020 }
01021
01022 int KAEvent::flags() const
01023 {
01024 return KAAlarmEventBase::flags()
01025 | (mStartDateTime.isDateOnly() ? ANY_TIME : 0)
01026 | (mDeferral > 0 ? DEFERRAL : 0)
01027 | (mCommandXterm ? EXEC_IN_XTERM : 0)
01028 | (mCopyToKOrganizer ? COPY_KORGANIZER : 0)
01029 | (mEnabled ? 0 : DISABLED);
01030 }
01031
01032
01033
01034
01035 Event* KAEvent::event() const
01036 {
01037 KCal::Event* ev = new KCal::Event;
01038 ev->setUid(mEventID);
01039 updateKCalEvent(*ev, false);
01040 return ev;
01041 }
01042
01043
01044
01045
01046
01047
01048
01049 bool KAEvent::updateKCalEvent(Event& ev, bool checkUid, bool original, bool cancelCancelledDefer) const
01050 {
01051 if (checkUid && !mEventID.isEmpty() && mEventID != ev.uid()
01052 || !mAlarmCount && (!original || !mMainExpired))
01053 return false;
01054
01055 checkRecur();
01056 bool readOnly = ev.isReadOnly();
01057 ev.setReadOnly(false);
01058 ev.setTransparency(Event::Transparent);
01059
01060
01061
01062
01063 ev.removeCustomProperty(APPNAME, NEXT_RECUR_PROPERTY);
01064 ev.removeCustomProperty(APPNAME, REPEAT_PROPERTY);
01065
01066 QStringList cats;
01067 if (mStartDateTime.isDateOnly())
01068 cats.append(DATE_ONLY_CATEGORY);
01069 if (mConfirmAck)
01070 cats.append(CONFIRM_ACK_CATEGORY);
01071 if (mEmailBcc)
01072 cats.append(EMAIL_BCC_CATEGORY);
01073 if (mKMailSerialNumber)
01074 cats.append(QString("%1%2").arg(KMAIL_SERNUM_CATEGORY).arg(mKMailSerialNumber));
01075 if (mCopyToKOrganizer)
01076 cats.append(KORGANIZER_CATEGORY);
01077 if (mCommandXterm)
01078 cats.append(LOG_CATEGORY + xtermURL);
01079 else if (!mLogFile.isEmpty())
01080 cats.append(LOG_CATEGORY + mLogFile);
01081 if (mLateCancel)
01082 cats.append(QString("%1%2").arg(mAutoClose ? AUTO_CLOSE_CATEGORY : LATE_CANCEL_CATEGORY).arg(mLateCancel));
01083 if (mDeferDefaultMinutes)
01084 cats.append(QString("%1%2").arg(DEFER_CATEGORY).arg(mDeferDefaultMinutes));
01085 if (!mTemplateName.isEmpty() && mTemplateAfterTime >= 0)
01086 cats.append(QString("%1%2").arg(TEMPL_AFTER_TIME_CATEGORY).arg(mTemplateAfterTime));
01087 if (mArchive && !original)
01088 {
01089 QStringList params;
01090 if (mArchiveReminderMinutes)
01091 {
01092 if (mReminderOnceOnly)
01093 params += ARCHIVE_REMINDER_ONCE_TYPE;
01094 char unit = 'M';
01095 int count = mArchiveReminderMinutes;
01096 if (count % 1440 == 0)
01097 {
01098 unit = 'D';
01099 count /= 1440;
01100 }
01101 else if (count % 60 == 0)
01102 {
01103 unit = 'H';
01104 count /= 60;
01105 }
01106 params += QString("%1%2").arg(count).arg(unit);
01107 }
01108 if (mArchiveRepeatAtLogin)
01109 params += AT_LOGIN_TYPE;
01110 if (params.count() > 0)
01111 {
01112 QString cat = ARCHIVE_CATEGORIES;
01113 cat += params.join(QString::fromLatin1(";"));
01114 cats.append(cat);
01115 }
01116 else
01117 cats.append(ARCHIVE_CATEGORY);
01118 }
01119 ev.setCategories(cats);
01120 ev.setCustomStatus(mEnabled ? QString::null : DISABLED_STATUS);
01121 ev.setRevision(mRevision);
01122 ev.clearAlarms();
01123
01124
01125
01126
01127
01128 ev.setDtStart(mStartDateTime.dateTime());
01129 ev.setFloats(false);
01130 ev.setHasEndDate(false);
01131
01132 DateTime dtMain = original ? mStartDateTime : mNextMainDateTime;
01133 int ancillaryType = 0;
01134 DateTime ancillaryTime;
01135 int ancillaryOffset = 0;
01136 if (!mMainExpired || original)
01137 {
01138
01139
01140
01141
01142
01143 if (!original && checkRecur() != KARecurrence::NO_RECUR)
01144 {
01145 QDateTime dt = mNextMainDateTime.dateTime();
01146 ev.setCustomProperty(APPNAME, NEXT_RECUR_PROPERTY,
01147 dt.toString(mNextMainDateTime.isDateOnly() ? "yyyyMMdd" : "yyyyMMddThhmmss"));
01148 }
01149
01150 initKCalAlarm(ev, 0, QStringList(), KAAlarm::MAIN_ALARM);
01151 ancillaryOffset = 0;
01152 ancillaryType = dtMain.isValid() ? 2 : 0;
01153 }
01154 else if (mRepeatCount && mRepeatInterval)
01155 {
01156
01157
01158 QString param = QString("%1:%2").arg(mRepeatInterval).arg(mRepeatCount);
01159 ev.setCustomProperty(APPNAME, REPEAT_PROPERTY, param);
01160 }
01161
01162
01163 if (mRepeatAtLogin || mArchiveRepeatAtLogin && original)
01164 {
01165 DateTime dtl;
01166 if (mArchiveRepeatAtLogin)
01167 dtl = mStartDateTime.dateTime().addDays(-1);
01168 else if (mAtLoginDateTime.isValid())
01169 dtl = mAtLoginDateTime;
01170 else if (mStartDateTime.isDateOnly())
01171 dtl = QDate::currentDate().addDays(-1);
01172 else
01173 dtl = QDateTime::currentDateTime();
01174 initKCalAlarm(ev, dtl, AT_LOGIN_TYPE);
01175 if (!ancillaryType && dtl.isValid())
01176 {
01177 ancillaryTime = dtl;
01178 ancillaryType = 1;
01179 }
01180 }
01181 if (mReminderMinutes || mArchiveReminderMinutes && original)
01182 {
01183 int minutes = mReminderMinutes ? mReminderMinutes : mArchiveReminderMinutes;
01184 initKCalAlarm(ev, -minutes * 60, QStringList(mReminderOnceOnly ? REMINDER_ONCE_TYPE : REMINDER_TYPE));
01185 if (!ancillaryType)
01186 {
01187 ancillaryOffset = -minutes * 60;
01188 ancillaryType = 2;
01189 }
01190 }
01191 if (mDeferral > 0 || mDeferral == CANCEL_DEFERRAL && !cancelCancelledDefer)
01192 {
01193 DateTime nextDateTime = mNextMainDateTime;
01194 if (mMainExpired && !original && checkRecur() != KARecurrence::NO_RECUR)
01195 {
01196
01197
01198
01199
01200
01201 nextDateTime = mRecurrence->getNextDateTime(mStartDateTime.dateTime().addDays(-1));
01202 nextDateTime.setDateOnly(mStartDateTime.isDateOnly());
01203 }
01204 int startOffset;
01205 QStringList list;
01206 if (mDeferralTime.isDateOnly())
01207 {
01208 startOffset = nextDateTime.secsTo(mDeferralTime.dateTime());
01209 list += DATE_DEFERRAL_TYPE;
01210 }
01211 else
01212 {
01213 startOffset = nextDateTime.dateTime().secsTo(mDeferralTime.dateTime());
01214 list += TIME_DEFERRAL_TYPE;
01215 }
01216 if (mDeferral == REMINDER_DEFERRAL)
01217 list += mReminderOnceOnly ? REMINDER_ONCE_TYPE : REMINDER_TYPE;
01218 initKCalAlarm(ev, startOffset, list);
01219 if (!ancillaryType && mDeferralTime.isValid())
01220 {
01221 ancillaryOffset = startOffset;
01222 ancillaryType = 2;
01223 }
01224 }
01225 if (!mTemplateName.isEmpty())
01226 ev.setSummary(mTemplateName);
01227 else if (mDisplaying)
01228 {
01229 QStringList list(DISPLAYING_TYPE);
01230 if (mDisplayingFlags & REPEAT_AT_LOGIN)
01231 list += AT_LOGIN_TYPE;
01232 else if (mDisplayingFlags & DEFERRAL)
01233 {
01234 if (mDisplayingFlags & TIMED_FLAG)
01235 list += TIME_DEFERRAL_TYPE;
01236 else
01237 list += DATE_DEFERRAL_TYPE;
01238 }
01239 if (mDisplayingFlags & REMINDER)
01240 list += mReminderOnceOnly ? REMINDER_ONCE_TYPE : REMINDER_TYPE;
01241 initKCalAlarm(ev, mDisplayingTime, list);
01242 if (!ancillaryType && mDisplayingTime.isValid())
01243 {
01244 ancillaryTime = mDisplayingTime;
01245 ancillaryType = 1;
01246 }
01247 }
01248 if (mBeep || mSpeak || !mAudioFile.isEmpty())
01249 {
01250
01251 if (ancillaryType == 2)
01252 initKCalAlarm(ev, ancillaryOffset, QStringList(), KAAlarm::AUDIO_ALARM);
01253 else
01254 initKCalAlarm(ev, ancillaryTime, QStringList(), KAAlarm::AUDIO_ALARM);
01255 }
01256 if (!mPreAction.isEmpty())
01257 {
01258
01259 if (ancillaryType == 2)
01260 initKCalAlarm(ev, ancillaryOffset, QStringList(PRE_ACTION_TYPE), KAAlarm::PRE_ACTION_ALARM);
01261 else
01262 initKCalAlarm(ev, ancillaryTime, QStringList(PRE_ACTION_TYPE), KAAlarm::PRE_ACTION_ALARM);
01263 }
01264 if (!mPostAction.isEmpty())
01265 {
01266
01267 if (ancillaryType == 2)
01268 initKCalAlarm(ev, ancillaryOffset, QStringList(POST_ACTION_TYPE), KAAlarm::POST_ACTION_ALARM);
01269 else
01270 initKCalAlarm(ev, ancillaryTime, QStringList(POST_ACTION_TYPE), KAAlarm::POST_ACTION_ALARM);
01271 }
01272
01273 if (mRecurrence)
01274 mRecurrence->writeRecurrence(*ev.recurrence());
01275 else
01276 ev.clearRecurrence();
01277 if (mSaveDateTime.isValid())
01278 ev.setCreated(mSaveDateTime);
01279 ev.setReadOnly(readOnly);
01280 return true;
01281 }
01282
01283
01284
01285
01286
01287
01288 Alarm* KAEvent::initKCalAlarm(Event& event, const DateTime& dt, const QStringList& types, KAAlarm::Type type) const
01289 {
01290 int startOffset = dt.isDateOnly() ? mStartDateTime.secsTo(dt)
01291 : mStartDateTime.dateTime().secsTo(dt.dateTime());
01292 return initKCalAlarm(event, startOffset, types, type);
01293 }
01294
01295 Alarm* KAEvent::initKCalAlarm(Event& event, int startOffsetSecs, const QStringList& types, KAAlarm::Type type) const
01296 {
01297 QStringList alltypes;
01298 Alarm* alarm = event.newAlarm();
01299 alarm->setEnabled(true);
01300 if (type != KAAlarm::MAIN_ALARM)
01301 {
01302
01303
01304 alarm->setStartOffset(startOffsetSecs);
01305 }
01306
01307 switch (type)
01308 {
01309 case KAAlarm::AUDIO_ALARM:
01310 alarm->setAudioAlarm(mAudioFile);
01311 if (mSpeak)
01312 alarm->setCustomProperty(APPNAME, SPEAK_PROPERTY, QString::fromLatin1("Y"));
01313 if (mRepeatSound)
01314 {
01315 alarm->setRepeatCount(-1);
01316 alarm->setSnoozeTime(0);
01317 }
01318 if (!mAudioFile.isEmpty() && mSoundVolume >= 0)
01319 alarm->setCustomProperty(APPNAME, VOLUME_PROPERTY,
01320 QString::fromLatin1("%1;%2;%3").arg(QString::number(mSoundVolume, 'f', 2))
01321 .arg(QString::number(mFadeVolume, 'f', 2))
01322 .arg(mFadeSeconds));
01323 break;
01324 case KAAlarm::PRE_ACTION_ALARM:
01325 setProcedureAlarm(alarm, mPreAction);
01326 break;
01327 case KAAlarm::POST_ACTION_ALARM:
01328 setProcedureAlarm(alarm, mPostAction);
01329 break;
01330 case KAAlarm::MAIN_ALARM:
01331 alarm->setSnoozeTime(mRepeatInterval);
01332 alarm->setRepeatCount(mRepeatCount);
01333 if (mRepeatCount)
01334 alarm->setCustomProperty(APPNAME, NEXT_REPEAT_PROPERTY,
01335 QString::number(mNextRepeat));
01336
01337 case KAAlarm::INVALID_ALARM:
01338 switch (mActionType)
01339 {
01340 case T_FILE:
01341 alltypes += FILE_TYPE;
01342
01343 case T_MESSAGE:
01344 alarm->setDisplayAlarm(AlarmText::toCalendarText(mText));
01345 alarm->setCustomProperty(APPNAME, FONT_COLOUR_PROPERTY,
01346 QString::fromLatin1("%1;%2;%3").arg(mBgColour.name())
01347 .arg(mFgColour.name())
01348 .arg(mDefaultFont ? QString::null : mFont.toString()));
01349 break;
01350 case T_COMMAND:
01351 if (mCommandScript)
01352 alarm->setProcedureAlarm("", mText);
01353 else
01354 setProcedureAlarm(alarm, mText);
01355 break;
01356 case T_EMAIL:
01357 alarm->setEmailAlarm(mEmailSubject, mText, mEmailAddresses, mEmailAttachments);
01358 if (!mEmailFromKMail.isEmpty())
01359 alarm->setCustomProperty(APPNAME, KMAIL_ID_PROPERTY, mEmailFromKMail);
01360 break;
01361 case T_AUDIO:
01362 break;
01363 }
01364 break;
01365 case KAAlarm::REMINDER_ALARM:
01366 case KAAlarm::DEFERRED_ALARM:
01367 case KAAlarm::DEFERRED_REMINDER_ALARM:
01368 case KAAlarm::AT_LOGIN_ALARM:
01369 case KAAlarm::DISPLAYING_ALARM:
01370 break;
01371 }
01372 alltypes += types;
01373 if (alltypes.count() > 0)
01374 alarm->setCustomProperty(APPNAME, TYPE_PROPERTY, alltypes.join(","));
01375 return alarm;
01376 }
01377
01378
01379
01380
01381 KAAlarm KAEvent::alarm(KAAlarm::Type type) const
01382 {
01383 checkRecur();
01384 KAAlarm al;
01385 if (mAlarmCount)
01386 {
01387 al.mEventID = mEventID;
01388 al.mActionType = mActionType;
01389 al.mText = mText;
01390 al.mBgColour = mBgColour;
01391 al.mFgColour = mFgColour;
01392 al.mFont = mFont;
01393 al.mDefaultFont = mDefaultFont;
01394 al.mBeep = mBeep;
01395 al.mSpeak = mSpeak;
01396 al.mSoundVolume = mSoundVolume;
01397 al.mFadeVolume = mFadeVolume;
01398 al.mFadeSeconds = mFadeSeconds;
01399 al.mRepeatSound = mRepeatSound;
01400 al.mConfirmAck = mConfirmAck;
01401 al.mRepeatCount = 0;
01402 al.mRepeatInterval = 0;
01403 al.mRepeatAtLogin = false;
01404 al.mDeferred = false;
01405 al.mLateCancel = mLateCancel;
01406 al.mAutoClose = mAutoClose;
01407 al.mEmailBcc = mEmailBcc;
01408 al.mCommandScript = mCommandScript;
01409 if (mActionType == T_EMAIL)
01410 {
01411 al.mEmailFromKMail = mEmailFromKMail;
01412 al.mEmailAddresses = mEmailAddresses;
01413 al.mEmailSubject = mEmailSubject;
01414 al.mEmailAttachments = mEmailAttachments;
01415 }
01416 switch (type)
01417 {
01418 case KAAlarm::MAIN_ALARM:
01419 if (!mMainExpired)
01420 {
01421 al.mType = KAAlarm::MAIN__ALARM;
01422 al.mNextMainDateTime = mNextMainDateTime;
01423 al.mRepeatCount = mRepeatCount;
01424 al.mRepeatInterval = mRepeatInterval;
01425 al.mNextRepeat = mNextRepeat;
01426 }
01427 break;
01428 case KAAlarm::REMINDER_ALARM:
01429 if (mReminderMinutes)
01430 {
01431 al.mType = KAAlarm::REMINDER__ALARM;
01432 if (mReminderOnceOnly)
01433 al.mNextMainDateTime = mStartDateTime.addMins(-mReminderMinutes);
01434 else
01435 al.mNextMainDateTime = mNextMainDateTime.addMins(-mReminderMinutes);
01436 }
01437 break;
01438 case KAAlarm::DEFERRED_REMINDER_ALARM:
01439 if (mDeferral != REMINDER_DEFERRAL)
01440 break;
01441
01442 case KAAlarm::DEFERRED_ALARM:
01443 if (mDeferral > 0)
01444 {
01445 al.mType = static_cast<KAAlarm::SubType>((mDeferral == REMINDER_DEFERRAL ? KAAlarm::DEFERRED_REMINDER_ALARM : KAAlarm::DEFERRED_ALARM)
01446 | (mDeferralTime.isDateOnly() ? 0 : KAAlarm::TIMED_DEFERRAL_FLAG));
01447 al.mNextMainDateTime = mDeferralTime;
01448 al.mDeferred = true;
01449 }
01450 break;
01451 case KAAlarm::AT_LOGIN_ALARM:
01452 if (mRepeatAtLogin)
01453 {
01454 al.mType = KAAlarm::AT_LOGIN__ALARM;
01455 al.mNextMainDateTime = mAtLoginDateTime;
01456 al.mRepeatAtLogin = true;
01457 al.mLateCancel = 0;
01458 al.mAutoClose = false;
01459 }
01460 break;
01461 case KAAlarm::DISPLAYING_ALARM:
01462 if (mDisplaying)
01463 {
01464 al.mType = KAAlarm::DISPLAYING__ALARM;
01465 al.mNextMainDateTime = mDisplayingTime;
01466 al.mDisplaying = true;
01467 }
01468 break;
01469 case KAAlarm::AUDIO_ALARM:
01470 case KAAlarm::PRE_ACTION_ALARM:
01471 case KAAlarm::POST_ACTION_ALARM:
01472 case KAAlarm::INVALID_ALARM:
01473 default:
01474 break;
01475 }
01476 }
01477 return al;
01478 }
01479
01480
01481
01482
01483
01484
01485
01486
01487 KAAlarm KAEvent::firstAlarm() const
01488 {
01489 if (mAlarmCount)
01490 {
01491 if (!mMainExpired)
01492 return alarm(KAAlarm::MAIN_ALARM);
01493 return nextAlarm(KAAlarm::MAIN_ALARM);
01494 }
01495 return KAAlarm();
01496 }
01497
01498
01499
01500
01501
01502
01503 KAAlarm KAEvent::nextAlarm(KAAlarm::Type prevType) const
01504 {
01505 switch (prevType)
01506 {
01507 case KAAlarm::MAIN_ALARM:
01508 if (mReminderMinutes)
01509 return alarm(KAAlarm::REMINDER_ALARM);
01510
01511 case KAAlarm::REMINDER_ALARM:
01512
01513 if (mDeferral == REMINDER_DEFERRAL)
01514 return alarm(KAAlarm::DEFERRED_REMINDER_ALARM);
01515 if (mDeferral == NORMAL_DEFERRAL)
01516 return alarm(KAAlarm::DEFERRED_ALARM);
01517
01518 case KAAlarm::DEFERRED_REMINDER_ALARM:
01519 case KAAlarm::DEFERRED_ALARM:
01520 if (mRepeatAtLogin)
01521 return alarm(KAAlarm::AT_LOGIN_ALARM);
01522
01523 case KAAlarm::AT_LOGIN_ALARM:
01524 if (mDisplaying)
01525 return alarm(KAAlarm::DISPLAYING_ALARM);
01526
01527 case KAAlarm::DISPLAYING_ALARM:
01528
01529 case KAAlarm::AUDIO_ALARM:
01530 case KAAlarm::PRE_ACTION_ALARM:
01531 case KAAlarm::POST_ACTION_ALARM:
01532 case KAAlarm::INVALID_ALARM:
01533 default:
01534 break;
01535 }
01536 return KAAlarm();
01537 }
01538
01539
01540
01541
01542
01543
01544 void KAEvent::removeExpiredAlarm(KAAlarm::Type type)
01545 {
01546 int count = mAlarmCount;
01547 switch (type)
01548 {
01549 case KAAlarm::MAIN_ALARM:
01550 mAlarmCount = 0;
01551 break;
01552 case KAAlarm::AT_LOGIN_ALARM:
01553 if (mRepeatAtLogin)
01554 {
01555
01556 mArchiveRepeatAtLogin = true;
01557 mRepeatAtLogin = false;
01558 --mAlarmCount;
01559 }
01560 break;
01561 case KAAlarm::REMINDER_ALARM:
01562
01563 set_archiveReminder();
01564 break;
01565 case KAAlarm::DEFERRED_REMINDER_ALARM:
01566 case KAAlarm::DEFERRED_ALARM:
01567 set_deferral(NO_DEFERRAL);
01568 break;
01569 case KAAlarm::DISPLAYING_ALARM:
01570 if (mDisplaying)
01571 {
01572 mDisplaying = false;
01573 --mAlarmCount;
01574 }
01575 break;
01576 case KAAlarm::AUDIO_ALARM:
01577 case KAAlarm::PRE_ACTION_ALARM:
01578 case KAAlarm::POST_ACTION_ALARM:
01579 case KAAlarm::INVALID_ALARM:
01580 default:
01581 break;
01582 }
01583 if (mAlarmCount != count)
01584 mUpdated = true;
01585 }
01586
01587
01588
01589
01590
01591
01592
01593
01594 bool KAEvent::defer(const DateTime& dateTime, bool reminder, bool adjustRecurrence)
01595 {
01596 bool result = false;
01597 bool setNextRepetition = false;
01598 bool checkRepetition = false;
01599 cancelCancelledDeferral();
01600 if (checkRecur() == KARecurrence::NO_RECUR)
01601 {
01602 if (mReminderMinutes || mDeferral == REMINDER_DEFERRAL || mArchiveReminderMinutes)
01603 {
01604 if (dateTime < mNextMainDateTime.dateTime())
01605 {
01606 set_deferral(REMINDER_DEFERRAL);
01607 mDeferralTime = dateTime;
01608 }
01609 else
01610 {
01611
01612 if (mReminderMinutes || mDeferral == REMINDER_DEFERRAL)
01613 set_deferral(NO_DEFERRAL);
01614 }
01615
01616 set_archiveReminder();
01617 }
01618 if (mDeferral != REMINDER_DEFERRAL)
01619 {
01620
01621 if (mRepeatCount && mRepeatInterval && dateTime < mainEndRepeatTime())
01622 {
01623
01624 set_deferral(NORMAL_DEFERRAL);
01625 mDeferralTime = dateTime;
01626 result = true;
01627 setNextRepetition = true;
01628 }
01629 else
01630 {
01631
01632 mNextMainDateTime = mDeferralTime = dateTime;
01633 set_deferral(NORMAL_DEFERRAL);
01634 if (!mMainExpired)
01635 {
01636
01637 mMainExpired = true;
01638 --mAlarmCount;
01639 if (mRepeatAtLogin)
01640 {
01641
01642 mArchiveRepeatAtLogin = true;
01643 mRepeatAtLogin = false;
01644 --mAlarmCount;
01645 }
01646 }
01647 }
01648 }
01649 }
01650 else if (reminder)
01651 {
01652
01653 if (dateTime >= mNextMainDateTime.dateTime())
01654 set_deferral(NO_DEFERRAL);
01655 else
01656 {
01657 set_deferral(REMINDER_DEFERRAL);
01658 mDeferralTime = dateTime;
01659 checkRepetition = true;
01660 }
01661 }
01662 else
01663 {
01664 mDeferralTime = dateTime;
01665 if (mDeferral <= 0)
01666 set_deferral(NORMAL_DEFERRAL);
01667 if (adjustRecurrence)
01668 {
01669 QDateTime now = QDateTime::currentDateTime();
01670 if (mainEndRepeatTime() < now)
01671 {
01672
01673
01674 if (!mMainExpired && setNextOccurrence(now) == NO_OCCURRENCE)
01675 {
01676 mMainExpired = true;
01677 --mAlarmCount;
01678 }
01679 }
01680 else
01681 setNextRepetition = (mRepeatCount && mRepeatInterval);
01682 }
01683 else
01684 checkRepetition = true;
01685 }
01686 if (checkRepetition)
01687 setNextRepetition = (mRepeatCount && mRepeatInterval && mDeferralTime < mainEndRepeatTime());
01688 if (setNextRepetition)
01689 {
01690
01691
01692 mNextRepeat = (mNextMainDateTime < mDeferralTime)
01693 ? mNextMainDateTime.secsTo(mDeferralTime) / (mRepeatInterval * 60) + 1 : 0;
01694 }
01695 mUpdated = true;
01696 return result;
01697 }
01698
01699
01700
01701
01702 void KAEvent::cancelDefer()
01703 {
01704 if (mDeferral > 0)
01705 {
01706
01707
01708 if (mMainExpired
01709 || nextOccurrence(QDateTime::currentDateTime(), mDeferralTime, RETURN_REPETITION) == NO_OCCURRENCE)
01710 {
01711
01712 mDeferralTime = DateTime();
01713 set_deferral(NO_DEFERRAL);
01714 }
01715 else
01716 set_deferral(CANCEL_DEFERRAL);
01717 mUpdated = true;
01718 }
01719 }
01720
01721
01722
01723
01724 void KAEvent::cancelCancelledDeferral()
01725 {
01726 if (mDeferral == CANCEL_DEFERRAL)
01727 {
01728 mDeferralTime = DateTime();
01729 set_deferral(NO_DEFERRAL);
01730 }
01731 }
01732
01733
01734
01735
01736 DateTime KAEvent::deferralLimit(KAEvent::DeferLimitType* limitType) const
01737 {
01738 DeferLimitType ltype;
01739 DateTime endTime;
01740 bool recurs = (checkRecur() != KARecurrence::NO_RECUR);
01741 if (recurs || mRepeatCount)
01742 {
01743
01744
01745 DateTime reminderTime;
01746 QDateTime now = QDateTime::currentDateTime();
01747 OccurType type = nextOccurrence(now, endTime, RETURN_REPETITION);
01748 if (type & OCCURRENCE_REPEAT)
01749 ltype = LIMIT_REPETITION;
01750 else if (type == NO_OCCURRENCE)
01751 ltype = LIMIT_NONE;
01752 else if (mReminderMinutes && (now < (reminderTime = endTime.addMins(-mReminderMinutes))))
01753 {
01754 endTime = reminderTime;
01755 ltype = LIMIT_REMINDER;
01756 }
01757 else if (type == FIRST_OR_ONLY_OCCURRENCE && !recurs)
01758 ltype = LIMIT_REPETITION;
01759 else
01760 ltype = LIMIT_RECURRENCE;
01761 }
01762 else if ((mReminderMinutes || mDeferral == REMINDER_DEFERRAL || mArchiveReminderMinutes)
01763 && QDateTime::currentDateTime() < mNextMainDateTime.dateTime())
01764 {
01765
01766 endTime = mNextMainDateTime;
01767 ltype = LIMIT_REMINDER;
01768 }
01769 else
01770 ltype = LIMIT_NONE;
01771 if (ltype != LIMIT_NONE)
01772 endTime = endTime.addMins(-1);
01773 if (limitType)
01774 *limitType = ltype;
01775 return endTime;
01776 }
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787 bool KAEvent::setDisplaying(const KAEvent& event, KAAlarm::Type alarmType, const QDateTime& repeatAtLoginTime)
01788 {
01789 if (!mDisplaying
01790 && (alarmType == KAAlarm::MAIN_ALARM
01791 || alarmType == KAAlarm::REMINDER_ALARM
01792 || alarmType == KAAlarm::DEFERRED_REMINDER_ALARM
01793 || alarmType == KAAlarm::DEFERRED_ALARM
01794 || alarmType == KAAlarm::AT_LOGIN_ALARM))
01795 {
01796
01797 KAAlarm al = event.alarm(alarmType);
01798 if (al.valid())
01799 {
01800 *this = event;
01801 setUid(DISPLAYING);
01802 mDisplaying = true;
01803 mDisplayingTime = (alarmType == KAAlarm::AT_LOGIN_ALARM) ? repeatAtLoginTime : al.dateTime();
01804 switch (al.type())
01805 {
01806 case KAAlarm::AT_LOGIN__ALARM: mDisplayingFlags = REPEAT_AT_LOGIN; break;
01807 case KAAlarm::REMINDER__ALARM: mDisplayingFlags = REMINDER; break;
01808 case KAAlarm::DEFERRED_REMINDER_TIME__ALARM: mDisplayingFlags = REMINDER | TIME_DEFERRAL; break;
01809 case KAAlarm::DEFERRED_REMINDER_DATE__ALARM: mDisplayingFlags = REMINDER | DATE_DEFERRAL; break;
01810 case KAAlarm::DEFERRED_TIME__ALARM: mDisplayingFlags = TIME_DEFERRAL; break;
01811 case KAAlarm::DEFERRED_DATE__ALARM: mDisplayingFlags = DATE_DEFERRAL; break;
01812 default: mDisplayingFlags = 0; break;
01813 }
01814 ++mAlarmCount;
01815 mUpdated = true;
01816 return true;
01817 }
01818 }
01819 return false;
01820 }
01821
01822
01823
01824
01825 KAAlarm KAEvent::convertDisplayingAlarm() const
01826 {
01827 KAAlarm al;
01828 if (mDisplaying)
01829 {
01830 al = alarm(KAAlarm::DISPLAYING_ALARM);
01831 if (mDisplayingFlags & REPEAT_AT_LOGIN)
01832 {
01833 al.mRepeatAtLogin = true;
01834 al.mType = KAAlarm::AT_LOGIN__ALARM;
01835 }
01836 else if (mDisplayingFlags & DEFERRAL)
01837 {
01838 al.mDeferred = true;
01839 al.mType = (mDisplayingFlags == (REMINDER | DATE_DEFERRAL)) ? KAAlarm::DEFERRED_REMINDER_DATE__ALARM
01840 : (mDisplayingFlags == (REMINDER | TIME_DEFERRAL)) ? KAAlarm::DEFERRED_REMINDER_TIME__ALARM
01841 : (mDisplayingFlags == DATE_DEFERRAL) ? KAAlarm::DEFERRED_DATE__ALARM
01842 : KAAlarm::DEFERRED_TIME__ALARM;
01843 }
01844 else if (mDisplayingFlags & REMINDER)
01845 al.mType = KAAlarm::REMINDER__ALARM;
01846 else
01847 al.mType = KAAlarm::MAIN__ALARM;
01848 }
01849 return al;
01850 }
01851
01852
01853
01854
01855 void KAEvent::reinstateFromDisplaying(const KAEvent& dispEvent)
01856 {
01857 if (dispEvent.mDisplaying)
01858 {
01859 *this = dispEvent;
01860 setUid(ACTIVE);
01861 mDisplaying = false;
01862 --mAlarmCount;
01863 mUpdated = true;
01864 }
01865 }
01866
01867
01868
01869
01870
01871
01872 bool KAEvent::occursAfter(const QDateTime& preDateTime, bool includeRepetitions) const
01873 {
01874 QDateTime dt;
01875 if (checkRecur() != KARecurrence::NO_RECUR)
01876 {
01877 if (mRecurrence->duration() < 0)
01878 return true;
01879 dt = mRecurrence->endDateTime();
01880 }
01881 else
01882 dt = mNextMainDateTime.dateTime();
01883 if (mStartDateTime.isDateOnly())
01884 {
01885 QDate pre = preDateTime.date();
01886 if (preDateTime.time() < Preferences::startOfDay())
01887 pre = pre.addDays(-1);
01888 if (pre < dt.date())
01889 return true;
01890 }
01891 else if (preDateTime < dt)
01892 return true;
01893
01894 if (includeRepetitions && mRepeatCount)
01895 {
01896 dt.addSecs(mRepeatCount * mRepeatInterval * 60);
01897 if (preDateTime < dt)
01898 return true;
01899 }
01900 return false;
01901 }
01902
01903
01904
01905
01906
01907
01908 KAEvent::OccurType KAEvent::nextOccurrence(const QDateTime& preDateTime, DateTime& result,
01909 KAEvent::OccurOption includeRepetitions) const
01910 {
01911 int repeatSecs = 0;
01912 QDateTime pre = preDateTime;
01913 if (includeRepetitions != IGNORE_REPETITION)
01914 {
01915 if (!mRepeatCount)
01916 includeRepetitions = IGNORE_REPETITION;
01917 else
01918 {
01919 repeatSecs = mRepeatInterval * 60;
01920 pre = preDateTime.addSecs(-mRepeatCount * repeatSecs);
01921 }
01922 }
01923
01924 OccurType type;
01925 bool recurs = (checkRecur() != KARecurrence::NO_RECUR);
01926 if (recurs)
01927 {
01928 int remainingCount;
01929 type = nextRecurrence(pre, result, remainingCount);
01930 }
01931 else if (pre < mNextMainDateTime.dateTime())
01932 {
01933 result = mNextMainDateTime;
01934 type = FIRST_OR_ONLY_OCCURRENCE;
01935 }
01936 else
01937 {
01938 result = DateTime();
01939 type = NO_OCCURRENCE;
01940 }
01941
01942 if (type != NO_OCCURRENCE && result <= preDateTime)
01943 {
01944
01945 int repetition = result.secsTo(preDateTime) / repeatSecs + 1;
01946 DateTime repeatDT = result.addSecs(repetition * repeatSecs);
01947 if (recurs)
01948 {
01949
01950
01951
01952
01953 DateTime dt;
01954 OccurType newType = previousOccurrence(repeatDT.dateTime(), dt, false);
01955 if (dt > result)
01956 {
01957 type = newType;
01958 result = dt;
01959 if (includeRepetitions == RETURN_REPETITION && result <= preDateTime)
01960 {
01961
01962 int repetition = result.secsTo(preDateTime) / repeatSecs + 1;
01963 result = result.addSecs(repetition * repeatSecs);
01964 type = static_cast<OccurType>(type | OCCURRENCE_REPEAT);
01965 }
01966 return type;
01967 }
01968 }
01969 if (includeRepetitions == RETURN_REPETITION)
01970 {
01971
01972 result = repeatDT;
01973 type = static_cast<OccurType>(type | OCCURRENCE_REPEAT);
01974 }
01975 }
01976 return type;
01977 }
01978
01979
01980
01981
01982
01983
01984
01985
01986 KAEvent::OccurType KAEvent::previousOccurrence(const QDateTime& afterDateTime, DateTime& result, bool includeRepetitions) const
01987 {
01988 if (mStartDateTime >= afterDateTime)
01989 {
01990 result = QDateTime();
01991 return NO_OCCURRENCE;
01992 }
01993
01994
01995 OccurType type;
01996 if (checkRecur() == KARecurrence::NO_RECUR)
01997 {
01998 result = mStartDateTime;
01999 type = FIRST_OR_ONLY_OCCURRENCE;
02000 }
02001 else
02002 {
02003 QDateTime recurStart = mRecurrence->startDateTime();
02004 QDateTime after = afterDateTime;
02005 if (mStartDateTime.isDateOnly() && afterDateTime.time() > Preferences::startOfDay())
02006 after = after.addDays(1);
02007 QDateTime dt = mRecurrence->getPreviousDateTime(after);
02008 result.set(dt, mStartDateTime.isDateOnly());
02009 if (!dt.isValid())
02010 return NO_OCCURRENCE;
02011 if (dt == recurStart)
02012 type = FIRST_OR_ONLY_OCCURRENCE;
02013 else if (mRecurrence->getNextDateTime(dt).isValid())
02014 type = result.isDateOnly() ? RECURRENCE_DATE : RECURRENCE_DATE_TIME;
02015 else
02016 type = LAST_RECURRENCE;
02017 }
02018
02019 if (includeRepetitions && mRepeatCount)
02020 {
02021
02022
02023
02024 int repeatSecs = mRepeatInterval * 60;
02025 DateTime lastRepetition = result.addSecs(mRepeatCount * repeatSecs);
02026 if (lastRepetition < afterDateTime)
02027 {
02028 result = lastRepetition;
02029 return static_cast<OccurType>(type | OCCURRENCE_REPEAT);
02030 }
02031 int repetition = (result.dateTime().secsTo(afterDateTime) - 1) / repeatSecs;
02032 if (repetition > 0)
02033 {
02034 result = result.addSecs(repetition * repeatSecs);
02035 return static_cast<OccurType>(type | OCCURRENCE_REPEAT);
02036 }
02037 }
02038 return type;
02039 }
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049 KAEvent::OccurType KAEvent::setNextOccurrence(const QDateTime& preDateTime)
02050 {
02051 if (preDateTime < mNextMainDateTime.dateTime())
02052 return FIRST_OR_ONLY_OCCURRENCE;
02053 QDateTime pre = preDateTime;
02054
02055
02056
02057 if (mRepeatCount && mRepeatInterval)
02058 pre = preDateTime.addSecs(-mRepeatCount * mRepeatInterval * 60);
02059
02060 DateTime dt;
02061 OccurType type;
02062 if (pre < mNextMainDateTime.dateTime())
02063 {
02064 dt = mNextMainDateTime;
02065 type = FIRST_OR_ONLY_OCCURRENCE;
02066 }
02067 else if (checkRecur() != KARecurrence::NO_RECUR)
02068 {
02069 int remainingCount;
02070 type = nextRecurrence(pre, dt, remainingCount);
02071 if (type == NO_OCCURRENCE)
02072 return NO_OCCURRENCE;
02073 if (type != FIRST_OR_ONLY_OCCURRENCE && dt != mNextMainDateTime)
02074 {
02075
02076 mNextMainDateTime = dt;
02077 if (mRecurrence->duration() > 0)
02078 mRemainingRecurrences = remainingCount;
02079
02080 if (mDeferral == REMINDER_DEFERRAL || mArchiveReminderMinutes)
02081 {
02082 if (mReminderOnceOnly)
02083 {
02084 if (mReminderMinutes)
02085 set_archiveReminder();
02086 }
02087 else
02088 set_reminder(mArchiveReminderMinutes);
02089 }
02090 if (mDeferral == REMINDER_DEFERRAL)
02091 set_deferral(NO_DEFERRAL);
02092 mUpdated = true;
02093 }
02094 }
02095 else
02096 return NO_OCCURRENCE;
02097
02098 if (mRepeatCount && mRepeatInterval)
02099 {
02100 int secs = dt.dateTime().secsTo(preDateTime);
02101 if (secs >= 0)
02102 {
02103
02104 type = static_cast<OccurType>(type | OCCURRENCE_REPEAT);
02105 mNextRepeat = (secs / (60 * mRepeatInterval)) + 1;
02106
02107 if (mReminderMinutes)
02108 set_archiveReminder();
02109 if (mDeferral == REMINDER_DEFERRAL)
02110 set_deferral(NO_DEFERRAL);
02111 mUpdated = true;
02112 }
02113 else if (mNextRepeat)
02114 {
02115
02116 mNextRepeat = 0;
02117 mUpdated = true;
02118 }
02119 }
02120 return type;
02121 }
02122
02123
02124
02125
02126
02127
02128
02129 KAEvent::OccurType KAEvent::nextRecurrence(const QDateTime& preDateTime, DateTime& result, int& remainingCount) const
02130 {
02131 QDateTime recurStart = mRecurrence->startDateTime();
02132 QDateTime pre = preDateTime;
02133 if (mStartDateTime.isDateOnly() && preDateTime.time() < Preferences::startOfDay())
02134 pre = pre.addDays(-1);
02135 remainingCount = 0;
02136 QDateTime dt = mRecurrence->getNextDateTime(pre);
02137 result.set(dt, mStartDateTime.isDateOnly());
02138 if (!dt.isValid())
02139 return NO_OCCURRENCE;
02140 if (dt == recurStart)
02141 {
02142 remainingCount = mRecurrence->duration();
02143 return FIRST_OR_ONLY_OCCURRENCE;
02144 }
02145 remainingCount = mRecurrence->duration() - mRecurrence->durationTo(dt) + 1;
02146 if (remainingCount == 1)
02147 return LAST_RECURRENCE;
02148 return result.isDateOnly() ? RECURRENCE_DATE : RECURRENCE_DATE_TIME;
02149 }
02150
02151
02152
02153
02154 QString KAEvent::recurrenceText(bool brief) const
02155 {
02156 if (mRepeatAtLogin)
02157 return brief ? i18n("Brief form of 'At Login'", "Login") : i18n("At login");
02158 if (mRecurrence)
02159 {
02160 int frequency = mRecurrence->frequency();
02161 switch (mRecurrence->defaultRRuleConst()->recurrenceType())
02162 {
02163 case RecurrenceRule::rMinutely:
02164 if (frequency < 60)
02165 return i18n("1 Minute", "%n Minutes", frequency);
02166 else if (frequency % 60 == 0)
02167 return i18n("1 Hour", "%n Hours", frequency/60);
02168 else
02169 {
02170 QString mins;
02171 return i18n("Hours and Minutes", "%1H %2M").arg(QString::number(frequency/60)).arg(mins.sprintf("%02d", frequency%60));
02172 }
02173 case RecurrenceRule::rDaily:
02174 return i18n("1 Day", "%n Days", frequency);
02175 case RecurrenceRule::rWeekly:
02176 return i18n("1 Week", "%n Weeks", frequency);
02177 case RecurrenceRule::rMonthly:
02178 return i18n("1 Month", "%n Months", frequency);
02179 case RecurrenceRule::rYearly:
02180 return i18n("1 Year", "%n Years", frequency);
02181 case RecurrenceRule::rNone:
02182 default:
02183 break;
02184 }
02185 }
02186 return brief ? QString::null : i18n("None");
02187 }
02188
02189
02190
02191
02192 QString KAEvent::repetitionText(bool brief) const
02193 {
02194 if (mRepeatCount)
02195 {
02196 if (mRepeatInterval % 1440)
02197 {
02198 if (mRepeatInterval < 60)
02199 return i18n("1 Minute", "%n Minutes", mRepeatInterval);
02200 if (mRepeatInterval % 60 == 0)
02201 return i18n("1 Hour", "%n Hours", mRepeatInterval/60);
02202 QString mins;
02203 return i18n("Hours and Minutes", "%1H %2M").arg(QString::number(mRepeatInterval/60)).arg(mins.sprintf("%02d", mRepeatInterval%60));
02204 }
02205 if (mRepeatInterval % (7*1440))
02206 return i18n("1 Day", "%n Days", mRepeatInterval/1440);
02207 return i18n("1 Week", "%n Weeks", mRepeatInterval/(7*1440));
02208 }
02209 return brief ? QString::null : i18n("None");
02210 }
02211
02212
02213
02214
02215
02216
02217 void KAEvent::setFirstRecurrence()
02218 {
02219 switch (checkRecur())
02220 {
02221 case KARecurrence::NO_RECUR:
02222 case KARecurrence::MINUTELY:
02223 return;
02224 case KARecurrence::ANNUAL_DATE:
02225 case KARecurrence::ANNUAL_POS:
02226 if (mRecurrence->yearMonths().isEmpty())
02227 return;
02228 break;
02229 case KARecurrence::DAILY:
02230 case KARecurrence::WEEKLY:
02231 case KARecurrence::MONTHLY_POS:
02232 case KARecurrence::MONTHLY_DAY:
02233 break;
02234 }
02235 QDateTime recurStart = mRecurrence->startDateTime();
02236 if (mRecurrence->recursOn(recurStart.date()))
02237 return;
02238
02239
02240 int frequency = mRecurrence->frequency();
02241 mRecurrence->setFrequency(1);
02242 int remainingCount;
02243 DateTime next;
02244 nextRecurrence(mNextMainDateTime.dateTime(), next, remainingCount);
02245 if (!next.isValid())
02246 mRecurrence->setStartDateTime(recurStart);
02247 else
02248 {
02249 mRecurrence->setStartDateTime(next.dateTime());
02250 mStartDateTime = mNextMainDateTime = next;
02251 mUpdated = true;
02252 }
02253 mRecurrence->setFrequency(frequency);
02254 }
02255
02256
02257
02258
02259
02260 void KAEvent::setRecurrence(const KARecurrence& recurrence)
02261 {
02262 mUpdated = true;
02263 delete mRecurrence;
02264 if (recurrence.doesRecur())
02265 {
02266 mRecurrence = new KARecurrence(recurrence);
02267 mRecurrence->setStartDateTime(mStartDateTime.dateTime());
02268 mRecurrence->setFloats(mStartDateTime.isDateOnly());
02269 mRemainingRecurrences = mMainExpired ? 0 : mRecurrence->duration();
02270 if (mRemainingRecurrences > 0 && !isTemplate())
02271 mRemainingRecurrences -= mRecurrence->durationTo(mNextMainDateTime.dateTime()) - 1;
02272 }
02273 else
02274 {
02275 mRecurrence = 0;
02276 mRemainingRecurrences = 0;
02277 }
02278
02279
02280 setRepetition(mRepeatInterval, mRepeatCount);
02281 }
02282
02283
02284
02285
02286
02287
02288 bool KAEvent::setRepetition(int interval, int count)
02289 {
02290 mUpdated = true;
02291 mRepeatInterval = 0;
02292 mRepeatCount = 0;
02293 mNextRepeat = 0;
02294 if (interval > 0 && count > 0 && !mRepeatAtLogin)
02295 {
02296 if (interval % 1440 && mStartDateTime.isDateOnly())
02297 return false;
02298 if (checkRecur() != KARecurrence::NO_RECUR)
02299 {
02300 int longestInterval = mRecurrence->longestInterval() - 1;
02301 if (interval * count > longestInterval)
02302 count = longestInterval / interval;
02303 }
02304 mRepeatInterval = interval;
02305 mRepeatCount = count;
02306 }
02307 return true;
02308 }
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320 bool KAEvent::setRecurMinutely(int freq, int count, const QDateTime& end)
02321 {
02322 return setRecur(RecurrenceRule::rMinutely, freq, count, end);
02323 }
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336 bool KAEvent::setRecurDaily(int freq, const QBitArray& days, int count, const QDate& end)
02337 {
02338 if (!setRecur(RecurrenceRule::rDaily, freq, count, end))
02339 return false;
02340 int n = 0;
02341 for (int i = 0; i < 7; ++i)
02342 {
02343 if (days.testBit(i))
02344 ++n;
02345 }
02346 if (n < 7)
02347 mRecurrence->addWeeklyDays(days);
02348 return true;
02349 }
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362 bool KAEvent::setRecurWeekly(int freq, const QBitArray& days, int count, const QDate& end)
02363 {
02364 if (!setRecur(RecurrenceRule::rWeekly, freq, count, end))
02365 return false;
02366 mRecurrence->addWeeklyDays(days);
02367 return true;
02368 }
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381 bool KAEvent::setRecurMonthlyByDate(int freq, const QValueList<int>& days, int count, const QDate& end)
02382 {
02383 if (!setRecur(RecurrenceRule::rMonthly, freq, count, end))
02384 return false;
02385 for (QValueListConstIterator<int> it = days.begin(); it != days.end(); ++it)
02386 mRecurrence->addMonthlyDate(*it);
02387 return true;
02388 }
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402 bool KAEvent::setRecurMonthlyByPos(int freq, const QValueList<MonthPos>& posns, int count, const QDate& end)
02403 {
02404 if (!setRecur(RecurrenceRule::rMonthly, freq, count, end))
02405 return false;
02406 for (QValueListConstIterator<MonthPos> it = posns.begin(); it != posns.end(); ++it)
02407 mRecurrence->addMonthlyPos((*it).weeknum, (*it).days);
02408 return true;
02409 }
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425 bool KAEvent::setRecurAnnualByDate(int freq, const QValueList<int>& months, int day, KARecurrence::Feb29Type feb29, int count, const QDate& end)
02426 {
02427 if (!setRecur(RecurrenceRule::rYearly, freq, count, end, feb29))
02428 return false;
02429 for (QValueListConstIterator<int> it = months.begin(); it != months.end(); ++it)
02430 mRecurrence->addYearlyMonth(*it);
02431 if (day)
02432 mRecurrence->addMonthlyDate(day);
02433 return true;
02434 }
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449 bool KAEvent::setRecurAnnualByPos(int freq, const QValueList<MonthPos>& posns, const QValueList<int>& months, int count, const QDate& end)
02450 {
02451 if (!setRecur(RecurrenceRule::rYearly, freq, count, end))
02452 return false;
02453 for (QValueListConstIterator<int> it = months.begin(); it != months.end(); ++it)
02454 mRecurrence->addYearlyMonth(*it);
02455 for (QValueListConstIterator<MonthPos> it = posns.begin(); it != posns.end(); ++it)
02456 mRecurrence->addYearlyPos((*it).weeknum, (*it).days);
02457 return true;
02458 }
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470 bool KAEvent::setRecur(RecurrenceRule::PeriodType recurType, int freq, int count, const QDateTime& end, KARecurrence::Feb29Type feb29)
02471 {
02472 if (count >= -1 && (count || end.date().isValid()))
02473 {
02474 if (!mRecurrence)
02475 mRecurrence = new KARecurrence;
02476 if (mRecurrence->init(recurType, freq, count, mNextMainDateTime, end, feb29))
02477 {
02478 mUpdated = true;
02479 mRemainingRecurrences = count;
02480 return true;
02481 }
02482 }
02483 clearRecur();
02484 return false;
02485 }
02486
02487
02488
02489
02490 void KAEvent::clearRecur()
02491 {
02492 mUpdated = true;
02493 delete mRecurrence;
02494 mRecurrence = 0;
02495 mRemainingRecurrences = 0;
02496 }
02497
02498
02499
02500
02501
02502
02503 KARecurrence::Type KAEvent::checkRecur() const
02504 {
02505 if (mRecurrence)
02506 {
02507 KARecurrence::Type type = mRecurrence->type();
02508 switch (type)
02509 {
02510 case KARecurrence::MINUTELY:
02511 case KARecurrence::DAILY:
02512 case KARecurrence::WEEKLY:
02513 case KARecurrence::MONTHLY_DAY:
02514 case KARecurrence::MONTHLY_POS:
02515 case KARecurrence::ANNUAL_DATE:
02516 case KARecurrence::ANNUAL_POS:
02517 return type;
02518 default:
02519 if (mRecurrence)
02520 {
02521 delete mRecurrence;
02522 const_cast<KAEvent*>(this)->mRecurrence = 0;
02523 }
02524 break;
02525 }
02526 }
02527 return KARecurrence::NO_RECUR;
02528 }
02529
02530
02531
02532
02533
02534 int KAEvent::recurInterval() const
02535 {
02536 if (mRecurrence)
02537 {
02538 switch (mRecurrence->type())
02539 {
02540 case KARecurrence::MINUTELY:
02541 case KARecurrence::DAILY:
02542 case KARecurrence::WEEKLY:
02543 case KARecurrence::MONTHLY_DAY:
02544 case KARecurrence::MONTHLY_POS:
02545 case KARecurrence::ANNUAL_DATE:
02546 case KARecurrence::ANNUAL_POS:
02547 return mRecurrence->frequency();
02548 default:
02549 break;
02550 }
02551 }
02552 return 0;
02553 }
02554
02555 #if 0
02556
02557
02558
02559 QValueList<KAEvent::MonthPos> KAEvent::convRecurPos(const QValueList<KCal::RecurrenceRule::WDayPos>& wdaypos)
02560 {
02561 QValueList<MonthPos> mposns;
02562 for (QValueList<KCal::RecurrenceRule::WDayPos>::ConstIterator it = wdaypos.begin(); it != wdaypos.end(); ++it)
02563 {
02564 int daybit = (*it).day() - 1;
02565 int weeknum = (*it).pos();
02566 bool found = false;
02567 for (QValueList<MonthPos>::Iterator mit = mposns.begin(); mit != mposns.end(); ++mit)
02568 {
02569 if ((*mit).weeknum == weeknum)
02570 {
02571 (*mit).days.setBit(daybit);
02572 found = true;
02573 break;
02574 }
02575 }
02576 if (!found)
02577 {
02578 MonthPos mpos;
02579 mpos.days.fill(false);
02580 mpos.days.setBit(daybit);
02581 mpos.weeknum = weeknum;
02582 mposns.append(mpos);
02583 }
02584 }
02585 return mposns;
02586 }
02587 #endif
02588
02589
02590
02591
02592
02593 KAEvent KAEvent::findTemplateName(AlarmCalendar& calendar, const QString& name)
02594 {
02595 KAEvent event;
02596 Event::List events = calendar.events();
02597 for (Event::List::ConstIterator evit = events.begin(); evit != events.end(); ++evit)
02598 {
02599 Event* ev = *evit;
02600 if (ev->summary() == name)
02601 {
02602 event.set(*ev);
02603 if (!event.isTemplate())
02604 return KAEvent();
02605 break;
02606 }
02607 }
02608 return event;
02609 }
02610
02611
02612
02613
02614
02615
02616
02617 bool KAEvent::adjustStartOfDay(const Event::List& events)
02618 {
02619 bool changed = false;
02620 QTime startOfDay = Preferences::startOfDay();
02621 for (Event::List::ConstIterator evit = events.begin(); evit != events.end(); ++evit)
02622 {
02623 Event* event = *evit;
02624 const QStringList& cats = event->categories();
02625 if (cats.find(DATE_ONLY_CATEGORY) != cats.end())
02626 {
02627
02628 QTime oldTime = event->dtStart().time();
02629 int adjustment = oldTime.secsTo(startOfDay);
02630 if (adjustment)
02631 {
02632 event->setDtStart(QDateTime(event->dtStart().date(), startOfDay));
02633 Alarm::List alarms = event->alarms();
02634 int deferralOffset = 0;
02635 for (Alarm::List::ConstIterator alit = alarms.begin(); alit != alarms.end(); ++alit)
02636 {
02637
02638 Alarm& alarm = **alit;
02639 AlarmData data;
02640 readAlarm(alarm, data);
02641 if (data.type & KAAlarm::TIMED_DEFERRAL_FLAG)
02642 {
02643
02644 deferralOffset = alarm.startOffset().asSeconds();
02645 alarm.setStartOffset(deferralOffset - adjustment);
02646 }
02647 else if (data.type == KAAlarm::AUDIO__ALARM
02648 && alarm.startOffset().asSeconds() == deferralOffset)
02649 {
02650
02651 alarm.setStartOffset(deferralOffset - adjustment);
02652 }
02653 }
02654 changed = true;
02655 }
02656 }
02657 else
02658 {
02659
02660 int deferralOffset = 0;
02661 int newDeferralOffset = 0;
02662 DateTime start;
02663 QDateTime nextMainDateTime = readDateTime(*event, false, start).rawDateTime();
02664 AlarmMap alarmMap;
02665 readAlarms(*event, &alarmMap);
02666 for (AlarmMap::Iterator it = alarmMap.begin(); it != alarmMap.end(); ++it)
02667 {
02668 const AlarmData& data = it.data();
02669 if (!data.alarm->hasStartOffset())
02670 continue;
02671 if ((data.type & KAAlarm::DEFERRED_ALARM)
02672 && !(data.type & KAAlarm::TIMED_DEFERRAL_FLAG))
02673 {
02674
02675 QDateTime altime = nextMainDateTime.addSecs(data.alarm->startOffset().asSeconds());
02676 altime.setTime(startOfDay);
02677 deferralOffset = data.alarm->startOffset().asSeconds();
02678 newDeferralOffset = event->dtStart().secsTo(altime);
02679 const_cast<Alarm*>(data.alarm)->setStartOffset(newDeferralOffset);
02680 changed = true;
02681 }
02682 else if (data.type == KAAlarm::AUDIO__ALARM
02683 && data.alarm->startOffset().asSeconds() == deferralOffset)
02684 {
02685
02686 const_cast<Alarm*>(data.alarm)->setStartOffset(newDeferralOffset);
02687 changed = true;
02688 }
02689 }
02690 }
02691 }
02692 return changed;
02693 }
02694
02695
02696
02697
02698
02699
02700 void KAEvent::convertKCalEvents(KCal::Calendar& calendar, int version, bool adjustSummerTime)
02701 {
02702
02703 static const QChar SEPARATOR = ';';
02704 static const QChar LATE_CANCEL_CODE = 'C';
02705 static const QChar AT_LOGIN_CODE = 'L';
02706 static const QChar DEFERRAL_CODE = 'D';
02707 static const QString TEXT_PREFIX = QString::fromLatin1("TEXT:");
02708 static const QString FILE_PREFIX = QString::fromLatin1("FILE:");
02709 static const QString COMMAND_PREFIX = QString::fromLatin1("CMD:");
02710
02711
02712 static const QString BEEP_CATEGORY = QString::fromLatin1("BEEP");
02713
02714
02715 static const QString LATE_CANCEL_CAT = QString::fromLatin1("LATECANCEL");
02716
02717
02718 static const QString TEMPL_DEF_TIME_CAT = QString::fromLatin1("TMPLDEFTIME");
02719
02720
02721 static const QString EXEC_IN_XTERM_CAT = QString::fromLatin1("XTERM");
02722
02723 if (version >= calVersion())
02724 return;
02725
02726 kdDebug(5950) << "KAEvent::convertKCalEvents(): adjusting version " << version << endl;
02727 bool pre_0_7 = (version < KAlarm::Version(0,7,0));
02728 bool pre_0_9 = (version < KAlarm::Version(0,9,0));
02729 bool pre_0_9_2 = (version < KAlarm::Version(0,9,2));
02730 bool pre_1_1_1 = (version < KAlarm::Version(1,1,1));
02731 bool pre_1_2_1 = (version < KAlarm::Version(1,2,1));
02732 bool pre_1_3_0 = (version < KAlarm::Version(1,3,0));
02733 bool pre_1_3_1 = (version < KAlarm::Version(1,3,1));
02734 bool pre_1_4_14 = (version < KAlarm::Version(1,4,14));
02735 Q_ASSERT(calVersion() == KAlarm::Version(1,4,14));
02736
02737 QDateTime dt0(QDate(1970,1,1), QTime(0,0,0));
02738 QTime startOfDay = Preferences::startOfDay();
02739
02740 Event::List events = calendar.rawEvents();
02741 for (Event::List::ConstIterator evit = events.begin(); evit != events.end(); ++evit)
02742 {
02743 Event* event = *evit;
02744 Alarm::List alarms = event->alarms();
02745 if (alarms.isEmpty())
02746 continue;
02747 QStringList cats = event->categories();
02748 bool addLateCancel = false;
02749
02750 if (pre_0_7 && event->doesFloat())
02751 {
02752
02753
02754 event->setFloats(false);
02755 }
02756
02757 if (pre_0_9)
02758 {
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771 for (Alarm::List::ConstIterator alit = alarms.begin(); alit != alarms.end(); ++alit)
02772 {
02773 Alarm* alarm = *alit;
02774 bool atLogin = false;
02775 bool deferral = false;
02776 bool lateCancel = false;
02777 KAAlarmEventBase::Type action = T_MESSAGE;
02778 QString txt = alarm->text();
02779 int length = txt.length();
02780 int i = 0;
02781 if (txt[0].isDigit())
02782 {
02783 while (++i < length && txt[i].isDigit()) ;
02784 if (i < length && txt[i++] == SEPARATOR)
02785 {
02786 while (i < length)
02787 {
02788 QChar ch = txt[i++];
02789 if (ch == SEPARATOR)
02790 break;
02791 if (ch == LATE_CANCEL_CODE)
02792 lateCancel = true;
02793 else if (ch == AT_LOGIN_CODE)
02794 atLogin = true;
02795 else if (ch == DEFERRAL_CODE)
02796 deferral = true;
02797 }
02798 }
02799 else
02800 i = 0;
02801 }
02802 if (txt.find(TEXT_PREFIX, i) == i)
02803 i += TEXT_PREFIX.length();
02804 else if (txt.find(FILE_PREFIX, i) == i)
02805 {
02806 action = T_FILE;
02807 i += FILE_PREFIX.length();
02808 }
02809 else if (txt.find(COMMAND_PREFIX, i) == i)
02810 {
02811 action = T_COMMAND;
02812 i += COMMAND_PREFIX.length();
02813 }
02814 else
02815 i = 0;
02816 txt = txt.mid(i);
02817
02818 QStringList types;
02819 switch (action)
02820 {
02821 case T_FILE:
02822 types += FILE_TYPE;
02823
02824 case T_MESSAGE:
02825 alarm->setDisplayAlarm(txt);
02826 break;
02827 case T_COMMAND:
02828 setProcedureAlarm(alarm, txt);
02829 break;
02830 case T_EMAIL:
02831 case T_AUDIO:
02832 break;
02833 }
02834 if (atLogin)
02835 {
02836 types += AT_LOGIN_TYPE;
02837 lateCancel = false;
02838 }
02839 else if (deferral)
02840 types += TIME_DEFERRAL_TYPE;
02841 if (lateCancel)
02842 addLateCancel = true;
02843 if (types.count() > 0)
02844 alarm->setCustomProperty(APPNAME, TYPE_PROPERTY, types.join(","));
02845
02846 if (pre_0_7 && alarm->repeatCount() > 0 && alarm->snoozeTime() > 0)
02847 {
02848
02849
02850 Recurrence* recur = event->recurrence();
02851 if (recur && recur->doesRecur())
02852 {
02853 recur->setMinutely(alarm->snoozeTime());
02854 recur->setDuration(alarm->repeatCount() + 1);
02855 alarm->setRepeatCount(0);
02856 alarm->setSnoozeTime(0);
02857 }
02858 }
02859
02860 if (adjustSummerTime)
02861 {
02862
02863
02864 QDateTime dt = alarm->time();
02865 time_t t = dt0.secsTo(dt);
02866 struct tm* dtm = localtime(&t);
02867 if (dtm->tm_isdst)
02868 {
02869 dt = dt.addSecs(-3600);
02870 alarm->setTime(dt);
02871 }
02872 }
02873 }
02874 }
02875
02876 if (pre_0_9_2)
02877 {
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888 if (uidStatus(event->uid()) == EXPIRED)
02889 event->setCreated(event->dtEnd());
02890 QDateTime start = event->dtStart();
02891 if (event->doesFloat())
02892 {
02893 event->setFloats(false);
02894 start.setTime(startOfDay);
02895 cats.append(DATE_ONLY_CATEGORY);
02896 }
02897 event->setHasEndDate(false);
02898
02899 Alarm::List::ConstIterator alit;
02900 for (alit = alarms.begin(); alit != alarms.end(); ++alit)
02901 {
02902 Alarm* alarm = *alit;
02903 QDateTime dt = alarm->time();
02904 alarm->setStartOffset(start.secsTo(dt));
02905 }
02906
02907 if (cats.count() > 0)
02908 {
02909 for (alit = alarms.begin(); alit != alarms.end(); ++alit)
02910 {
02911 Alarm* alarm = *alit;
02912 if (alarm->type() == Alarm::Display)
02913 alarm->setCustomProperty(APPNAME, FONT_COLOUR_PROPERTY,
02914 QString::fromLatin1("%1;;").arg(cats[0]));
02915 }
02916 cats.remove(cats.begin());
02917 }
02918
02919 for (QStringList::Iterator it = cats.begin(); it != cats.end(); ++it)
02920 {
02921 if (*it == BEEP_CATEGORY)
02922 {
02923 cats.remove(it);
02924
02925 Alarm* alarm = event->newAlarm();
02926 alarm->setEnabled(true);
02927 alarm->setAudioAlarm();
02928 QDateTime dt = event->dtStart();
02929
02930
02931 AlarmMap alarmMap;
02932 readAlarms(*event, &alarmMap);
02933 AlarmMap::ConstIterator it = alarmMap.begin();
02934 if (it != alarmMap.end())
02935 {
02936 dt = it.data().alarm->time();
02937 break;
02938 }
02939 alarm->setStartOffset(start.secsTo(dt));
02940 break;
02941 }
02942 }
02943
02944 }
02945
02946 if (pre_1_1_1)
02947 {
02948
02949
02950
02951
02952 QStringList::Iterator it;
02953 while ((it = cats.find(LATE_CANCEL_CAT)) != cats.end())
02954 {
02955 cats.remove(it);
02956 addLateCancel = true;
02957 }
02958 }
02959
02960 if (pre_1_2_1)
02961 {
02962
02963
02964
02965
02966 for (Alarm::List::ConstIterator alit = alarms.begin(); alit != alarms.end(); ++alit)
02967 {
02968 Alarm* alarm = *alit;
02969 if (alarm->type() == Alarm::Display)
02970 {
02971 QString oldtext = alarm->text();
02972 QString newtext = AlarmText::toCalendarText(oldtext);
02973 if (oldtext != newtext)
02974 alarm->setDisplayAlarm(newtext);
02975 }
02976 }
02977 }
02978
02979 if (pre_1_3_0)
02980 {
02981
02982
02983
02984
02985 QStringList::Iterator it;
02986 while ((it = cats.find(TEMPL_DEF_TIME_CAT)) != cats.end())
02987 {
02988 cats.remove(it);
02989 cats.append(QString("%1%2").arg(TEMPL_AFTER_TIME_CATEGORY).arg(0));
02990 }
02991 }
02992
02993 if (pre_1_3_1)
02994 {
02995
02996
02997
02998
02999 QStringList::Iterator it;
03000 while ((it = cats.find(EXEC_IN_XTERM_CAT)) != cats.end())
03001 {
03002 cats.remove(it);
03003 cats.append(LOG_CATEGORY + xtermURL);
03004 }
03005 }
03006
03007 if (addLateCancel)
03008 cats.append(QString("%1%2").arg(LATE_CANCEL_CATEGORY).arg(1));
03009
03010 event->setCategories(cats);
03011
03012
03013 if (pre_1_4_14
03014 && event->recurrence() && event->recurrence()->doesRecur())
03015 {
03016
03017
03018
03019
03020
03021
03022
03023 bool dateOnly = (cats.find(DATE_ONLY_CATEGORY) != cats.end());
03024 DateTime startDateTime(event->dtStart(), dateOnly);
03025
03026 DateTime nextMainDateTime;
03027 bool mainExpired = true;
03028 Alarm::List::ConstIterator alit;
03029 for (alit = alarms.begin(); alit != alarms.end(); ++alit)
03030 {
03031 Alarm* alarm = *alit;
03032 if (!alarm->hasStartOffset())
03033 continue;
03034 bool mainAlarm = true;
03035 QString property = alarm->customProperty(APPNAME, TYPE_PROPERTY);
03036 QStringList types = QStringList::split(QChar(','), property);
03037 for (unsigned int i = 0; i < types.count(); ++i)
03038 {
03039 QString type = types[i];
03040 if (type == AT_LOGIN_TYPE
03041 || type == TIME_DEFERRAL_TYPE
03042 || type == DATE_DEFERRAL_TYPE
03043 || type == REMINDER_TYPE
03044 || type == REMINDER_ONCE_TYPE
03045 || type == DISPLAYING_TYPE
03046 || type == PRE_ACTION_TYPE
03047 || type == POST_ACTION_TYPE)
03048 mainAlarm = false;
03049 }
03050 if (mainAlarm)
03051 {
03052 mainExpired = false;
03053 nextMainDateTime = alarm->time();
03054 nextMainDateTime.setDateOnly(dateOnly);
03055 if (nextMainDateTime != startDateTime)
03056 {
03057 QDateTime dt = nextMainDateTime.dateTime();
03058 event->setCustomProperty(APPNAME, NEXT_RECUR_PROPERTY,
03059 dt.toString(dateOnly ? "yyyyMMdd" : "yyyyMMddThhmmss"));
03060 }
03061 alarm->setStartOffset(0);
03062 }
03063 }
03064 int adjustment;
03065 if (mainExpired)
03066 {
03067
03068
03069
03070 DateTime dt = event->recurrence()->getNextDateTime(startDateTime.dateTime().addDays(-1));
03071 dt.setDateOnly(dateOnly);
03072 adjustment = startDateTime.secsTo(dt);
03073 }
03074 else
03075 adjustment = startDateTime.secsTo(nextMainDateTime);
03076 if (adjustment)
03077 {
03078
03079 for (alit = alarms.begin(); alit != alarms.end(); ++alit)
03080 {
03081 Alarm* alarm = *alit;
03082 if (!alarm->hasStartOffset())
03083 continue;
03084 QString property = alarm->customProperty(APPNAME, TYPE_PROPERTY);
03085 QStringList types = QStringList::split(QChar(','), property);
03086 for (unsigned int i = 0; i < types.count(); ++i)
03087 {
03088 QString type = types[i];
03089 if (type == TIME_DEFERRAL_TYPE
03090 || type == DATE_DEFERRAL_TYPE)
03091 {
03092 alarm->setStartOffset(alarm->startOffset().asSeconds() - adjustment);
03093 break;
03094 }
03095 }
03096 }
03097 }
03098 }
03099 }
03100 }
03101
03102 #ifndef NDEBUG
03103 void KAEvent::dumpDebug() const
03104 {
03105 kdDebug(5950) << "KAEvent dump:\n";
03106 KAAlarmEventBase::dumpDebug();
03107 if (!mTemplateName.isEmpty())
03108 {
03109 kdDebug(5950) << "-- mTemplateName:" << mTemplateName << ":\n";
03110 kdDebug(5950) << "-- mTemplateAfterTime:" << mTemplateAfterTime << ":\n";
03111 }
03112 if (mActionType == T_MESSAGE || mActionType == T_FILE)
03113 {
03114 kdDebug(5950) << "-- mAudioFile:" << mAudioFile << ":\n";
03115 kdDebug(5950) << "-- mPreAction:" << mPreAction << ":\n";
03116 kdDebug(5950) << "-- mPostAction:" << mPostAction << ":\n";
03117 }
03118 else if (mActionType == T_COMMAND)
03119 {
03120 kdDebug(5950) << "-- mCommandXterm:" << (mCommandXterm ? "true" : "false") << ":\n";
03121 kdDebug(5950) << "-- mLogFile:" << mLogFile << ":\n";
03122 }
03123 kdDebug(5950) << "-- mKMailSerialNumber:" << mKMailSerialNumber << ":\n";
03124 kdDebug(5950) << "-- mCopyToKOrganizer:" << (mCopyToKOrganizer ? "true" : "false") << ":\n";
03125 kdDebug(5950) << "-- mStartDateTime:" << mStartDateTime.toString() << ":\n";
03126 kdDebug(5950) << "-- mSaveDateTime:" << mSaveDateTime.toString() << ":\n";
03127 if (mRepeatAtLogin)
03128 kdDebug(5950) << "-- mAtLoginDateTime:" << mAtLoginDateTime.toString() << ":\n";
03129 kdDebug(5950) << "-- mArchiveRepeatAtLogin:" << (mArchiveRepeatAtLogin ? "true" : "false") << ":\n";
03130 kdDebug(5950) << "-- mEnabled:" << (mEnabled ? "true" : "false") << ":\n";
03131 if (mReminderMinutes)
03132 kdDebug(5950) << "-- mReminderMinutes:" << mReminderMinutes << ":\n";
03133 if (mArchiveReminderMinutes)
03134 kdDebug(5950) << "-- mArchiveReminderMinutes:" << mArchiveReminderMinutes << ":\n";
03135 if (mReminderMinutes || mArchiveReminderMinutes)
03136 kdDebug(5950) << "-- mReminderOnceOnly:" << mReminderOnceOnly << ":\n";
03137 else if (mDeferral > 0)
03138 {
03139 kdDebug(5950) << "-- mDeferral:" << (mDeferral == NORMAL_DEFERRAL ? "normal" : "reminder") << ":\n";
03140 kdDebug(5950) << "-- mDeferralTime:" << mDeferralTime.toString() << ":\n";
03141 }
03142 else if (mDeferral == CANCEL_DEFERRAL)
03143 kdDebug(5950) << "-- mDeferral:cancel:\n";
03144 kdDebug(5950) << "-- mDeferDefaultMinutes:" << mDeferDefaultMinutes << ":\n";
03145 if (mDisplaying)
03146 {
03147 kdDebug(5950) << "-- mDisplayingTime:" << mDisplayingTime.toString() << ":\n";
03148 kdDebug(5950) << "-- mDisplayingFlags:" << mDisplayingFlags << ":\n";
03149 }
03150 kdDebug(5950) << "-- mRevision:" << mRevision << ":\n";
03151 kdDebug(5950) << "-- mRecurrence:" << (mRecurrence ? "true" : "false") << ":\n";
03152 if (mRecurrence)
03153 kdDebug(5950) << "-- mRemainingRecurrences:" << mRemainingRecurrences << ":\n";
03154 kdDebug(5950) << "-- mAlarmCount:" << mAlarmCount << ":\n";
03155 kdDebug(5950) << "-- mMainExpired:" << (mMainExpired ? "true" : "false") << ":\n";
03156 kdDebug(5950) << "KAEvent dump end\n";
03157 }
03158 #endif
03159
03160
03161
03162
03163
03164
03165
03166 KAAlarm::KAAlarm(const KAAlarm& alarm)
03167 : KAAlarmEventBase(alarm),
03168 mType(alarm.mType),
03169 mRecurs(alarm.mRecurs),
03170 mDeferred(alarm.mDeferred)
03171 { }
03172
03173
03174 int KAAlarm::flags() const
03175 {
03176 return KAAlarmEventBase::flags()
03177 | (mDeferred ? KAEvent::DEFERRAL : 0);
03178
03179 }
03180
03181 #ifndef NDEBUG
03182 void KAAlarm::dumpDebug() const
03183 {
03184 kdDebug(5950) << "KAAlarm dump:\n";
03185 KAAlarmEventBase::dumpDebug();
03186 const char* altype = 0;
03187 switch (mType)
03188 {
03189 case MAIN__ALARM: altype = "MAIN"; break;
03190 case REMINDER__ALARM: altype = "REMINDER"; break;
03191 case DEFERRED_DATE__ALARM: altype = "DEFERRED(DATE)"; break;
03192 case DEFERRED_TIME__ALARM: altype = "DEFERRED(TIME)"; break;
03193 case DEFERRED_REMINDER_DATE__ALARM: altype = "DEFERRED_REMINDER(DATE)"; break;
03194 case DEFERRED_REMINDER_TIME__ALARM: altype = "DEFERRED_REMINDER(TIME)"; break;
03195 case AT_LOGIN__ALARM: altype = "LOGIN"; break;
03196 case DISPLAYING__ALARM: altype = "DISPLAYING"; break;
03197 case AUDIO__ALARM: altype = "AUDIO"; break;
03198 case PRE_ACTION__ALARM: altype = "PRE_ACTION"; break;
03199 case POST_ACTION__ALARM: altype = "POST_ACTION"; break;
03200 default: altype = "INVALID"; break;
03201 }
03202 kdDebug(5950) << "-- mType:" << altype << ":\n";
03203 kdDebug(5950) << "-- mRecurs:" << (mRecurs ? "true" : "false") << ":\n";
03204 kdDebug(5950) << "-- mDeferred:" << (mDeferred ? "true" : "false") << ":\n";
03205 kdDebug(5950) << "KAAlarm dump end\n";
03206 }
03207
03208 const char* KAAlarm::debugType(Type type)
03209 {
03210 switch (type)
03211 {
03212 case MAIN_ALARM: return "MAIN";
03213 case REMINDER_ALARM: return "REMINDER";
03214 case DEFERRED_ALARM: return "DEFERRED";
03215 case DEFERRED_REMINDER_ALARM: return "DEFERRED_REMINDER";
03216 case AT_LOGIN_ALARM: return "LOGIN";
03217 case DISPLAYING_ALARM: return "DISPLAYING";
03218 case AUDIO_ALARM: return "AUDIO";
03219 case PRE_ACTION_ALARM: return "PRE_ACTION";
03220 case POST_ACTION_ALARM: return "POST_ACTION";
03221 default: return "INVALID";
03222 }
03223 }
03224 #endif
03225
03226
03227
03228
03229
03230
03231 void KAAlarmEventBase::copy(const KAAlarmEventBase& rhs)
03232 {
03233 mEventID = rhs.mEventID;
03234 mText = rhs.mText;
03235 mNextMainDateTime = rhs.mNextMainDateTime;
03236 mBgColour = rhs.mBgColour;
03237 mFgColour = rhs.mFgColour;
03238 mFont = rhs.mFont;
03239 mEmailFromKMail = rhs.mEmailFromKMail;
03240 mEmailAddresses = rhs.mEmailAddresses;
03241 mEmailSubject = rhs.mEmailSubject;
03242 mEmailAttachments = rhs.mEmailAttachments;
03243 mSoundVolume = rhs.mSoundVolume;
03244 mFadeVolume = rhs.mFadeVolume;
03245 mFadeSeconds = rhs.mFadeSeconds;
03246 mActionType = rhs.mActionType;
03247 mCommandScript = rhs.mCommandScript;
03248 mRepeatCount = rhs.mRepeatCount;
03249 mRepeatInterval = rhs.mRepeatInterval;
03250 mNextRepeat = rhs.mNextRepeat;
03251 mBeep = rhs.mBeep;
03252 mSpeak = rhs.mSpeak;
03253 mRepeatSound = rhs.mRepeatSound;
03254 mRepeatAtLogin = rhs.mRepeatAtLogin;
03255 mDisplaying = rhs.mDisplaying;
03256 mLateCancel = rhs.mLateCancel;
03257 mAutoClose = rhs.mAutoClose;
03258 mEmailBcc = rhs.mEmailBcc;
03259 mConfirmAck = rhs.mConfirmAck;
03260 mDefaultFont = rhs.mDefaultFont;
03261 }
03262
03263 void KAAlarmEventBase::set(int flags)
03264 {
03265 mSpeak = flags & KAEvent::SPEAK;
03266 mBeep = (flags & KAEvent::BEEP) && !mSpeak;
03267 mRepeatSound = flags & KAEvent::REPEAT_SOUND;
03268 mRepeatAtLogin = flags & KAEvent::REPEAT_AT_LOGIN;
03269 mAutoClose = (flags & KAEvent::AUTO_CLOSE) && mLateCancel;
03270 mEmailBcc = flags & KAEvent::EMAIL_BCC;
03271 mConfirmAck = flags & KAEvent::CONFIRM_ACK;
03272 mDisplaying = flags & KAEvent::DISPLAYING_;
03273 mDefaultFont = flags & KAEvent::DEFAULT_FONT;
03274 mCommandScript = flags & KAEvent::SCRIPT;
03275 }
03276
03277 int KAAlarmEventBase::flags() const
03278 {
03279 return (mBeep && !mSpeak ? KAEvent::BEEP : 0)
03280 | (mSpeak ? KAEvent::SPEAK : 0)
03281 | (mRepeatSound ? KAEvent::REPEAT_SOUND : 0)
03282 | (mRepeatAtLogin ? KAEvent::REPEAT_AT_LOGIN : 0)
03283 | (mAutoClose ? KAEvent::AUTO_CLOSE : 0)
03284 | (mEmailBcc ? KAEvent::EMAIL_BCC : 0)
03285 | (mConfirmAck ? KAEvent::CONFIRM_ACK : 0)
03286 | (mDisplaying ? KAEvent::DISPLAYING_ : 0)
03287 | (mDefaultFont ? KAEvent::DEFAULT_FONT : 0)
03288 | (mCommandScript ? KAEvent::SCRIPT : 0);
03289 }
03290
03291 const QFont& KAAlarmEventBase::font() const
03292 {
03293 return mDefaultFont ? Preferences::messageFont() : mFont;
03294 }
03295
03296 #ifndef NDEBUG
03297 void KAAlarmEventBase::dumpDebug() const
03298 {
03299 kdDebug(5950) << "-- mEventID:" << mEventID << ":\n";
03300 kdDebug(5950) << "-- mActionType:" << (mActionType == T_MESSAGE ? "MESSAGE" : mActionType == T_FILE ? "FILE" : mActionType == T_COMMAND ? "COMMAND" : mActionType == T_EMAIL ? "EMAIL" : mActionType == T_AUDIO ? "AUDIO" : "??") << ":\n";
03301 kdDebug(5950) << "-- mText:" << mText << ":\n";
03302 if (mActionType == T_COMMAND)
03303 kdDebug(5950) << "-- mCommandScript:" << (mCommandScript ? "true" : "false") << ":\n";
03304 kdDebug(5950) << "-- mNextMainDateTime:" << mNextMainDateTime.toString() << ":\n";
03305 if (mActionType == T_EMAIL)
03306 {
03307 kdDebug(5950) << "-- mEmail: FromKMail:" << mEmailFromKMail << ":\n";
03308 kdDebug(5950) << "-- Addresses:" << mEmailAddresses.join(", ") << ":\n";
03309 kdDebug(5950) << "-- Subject:" << mEmailSubject << ":\n";
03310 kdDebug(5950) << "-- Attachments:" << mEmailAttachments.join(", ") << ":\n";
03311 kdDebug(5950) << "-- Bcc:" << (mEmailBcc ? "true" : "false") << ":\n";
03312 }
03313 kdDebug(5950) << "-- mBgColour:" << mBgColour.name() << ":\n";
03314 kdDebug(5950) << "-- mFgColour:" << mFgColour.name() << ":\n";
03315 kdDebug(5950) << "-- mDefaultFont:" << (mDefaultFont ? "true" : "false") << ":\n";
03316 if (!mDefaultFont)
03317 kdDebug(5950) << "-- mFont:" << mFont.toString() << ":\n";
03318 kdDebug(5950) << "-- mBeep:" << (mBeep ? "true" : "false") << ":\n";
03319 kdDebug(5950) << "-- mSpeak:" << (mSpeak ? "true" : "false") << ":\n";
03320 if (mActionType == T_AUDIO)
03321 {
03322 if (mSoundVolume >= 0)
03323 {
03324 kdDebug(5950) << "-- mSoundVolume:" << mSoundVolume << ":\n";
03325 if (mFadeVolume >= 0)
03326 {
03327 kdDebug(5950) << "-- mFadeVolume:" << mFadeVolume << ":\n";
03328 kdDebug(5950) << "-- mFadeSeconds:" << mFadeSeconds << ":\n";
03329 }
03330 else
03331 kdDebug(5950) << "-- mFadeVolume:-:\n";
03332 }
03333 else
03334 kdDebug(5950) << "-- mSoundVolume:-:\n";
03335 kdDebug(5950) << "-- mRepeatSound:" << (mRepeatSound ? "true" : "false") << ":\n";
03336 }
03337 kdDebug(5950) << "-- mConfirmAck:" << (mConfirmAck ? "true" : "false") << ":\n";
03338 kdDebug(5950) << "-- mRepeatAtLogin:" << (mRepeatAtLogin ? "true" : "false") << ":\n";
03339 kdDebug(5950) << "-- mRepeatCount:" << mRepeatCount << ":\n";
03340 kdDebug(5950) << "-- mRepeatInterval:" << mRepeatInterval << ":\n";
03341 kdDebug(5950) << "-- mNextRepeat:" << mNextRepeat << ":\n";
03342 kdDebug(5950) << "-- mDisplaying:" << (mDisplaying ? "true" : "false") << ":\n";
03343 kdDebug(5950) << "-- mLateCancel:" << mLateCancel << ":\n";
03344 kdDebug(5950) << "-- mAutoClose:" << (mAutoClose ? "true" : "false") << ":\n";
03345 }
03346 #endif
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357 EmailAddressList& EmailAddressList::operator=(const QValueList<Person>& addresses)
03358 {
03359 clear();
03360 for (QValueList<Person>::ConstIterator it = addresses.begin(); it != addresses.end(); ++it)
03361 {
03362 if (!(*it).email().isEmpty())
03363 append(*it);
03364 }
03365 return *this;
03366 }
03367
03368
03369
03370
03371
03372 QString EmailAddressList::join(const QString& separator) const
03373 {
03374 QString result;
03375 bool first = true;
03376 for (QValueList<Person>::ConstIterator it = begin(); it != end(); ++it)
03377 {
03378 if (first)
03379 first = false;
03380 else
03381 result += separator;
03382
03383 bool quote = false;
03384 QString name = (*it).name();
03385 if (!name.isEmpty())
03386 {
03387
03388 int len = name.length();
03389 for (int i = 0; i < len; ++i)
03390 {
03391 QChar ch = name[i];
03392 if (!ch.isLetterOrNumber())
03393 {
03394 quote = true;
03395 result += '\"';
03396 break;
03397 }
03398 }
03399 result += (*it).name();
03400 result += (quote ? "\" <" : " <");
03401 quote = true;
03402 }
03403
03404 result += (*it).email();
03405 if (quote)
03406 result += '>';
03407 }
03408 return result;
03409 }
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420
03421 static void setProcedureAlarm(Alarm* alarm, const QString& commandLine)
03422 {
03423 QString command = QString::null;
03424 QString arguments = QString::null;
03425 QChar quoteChar;
03426 bool quoted = false;
03427 uint posMax = commandLine.length();
03428 uint pos;
03429 for (pos = 0; pos < posMax; ++pos)
03430 {
03431 QChar ch = commandLine[pos];
03432 if (quoted)
03433 {
03434 if (ch == quoteChar)
03435 {
03436 ++pos;
03437 break;
03438 }
03439 command += ch;
03440 }
03441 else
03442 {
03443 bool done = false;
03444 switch (ch)
03445 {
03446 case ' ':
03447 case ';':
03448 case '|':
03449 case '<':
03450 case '>':
03451 done = !command.isEmpty();
03452 break;
03453 case '\'':
03454 case '"':
03455 if (command.isEmpty())
03456 {
03457
03458 quoted = true;
03459 quoteChar = ch;
03460 break;
03461 }
03462
03463 default:
03464 command += ch;
03465 break;
03466 }
03467 if (done)
03468 break;
03469 }
03470 }
03471
03472
03473 for ( ; pos < posMax && commandLine[pos] == ' '; ++pos) ;
03474 arguments = commandLine.mid(pos);
03475
03476 alarm->setProcedureAlarm(command, arguments);
03477 }