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