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