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 #include "alarmevent.h"
00023
00024 #include "alarmcalendar.h"
00025 #include "alarmtext.h"
00026 #include "functions.h"
00027 #include "kalarmapp.h"
00028 #include "preferences.h"
00029
00030 #include <stdlib.h>
00031 #include <time.h>
00032 #include <ctype.h>
00033 #include <QColor>
00034 #include <QRegExp>
00035 #include <QByteArray>
00036
00037 #include <ksystemtimezone.h>
00038 #include <klocale.h>
00039 #include <kdebug.h>
00040
00041 #include <kcal/calendarlocal.h>
00042
00043 using namespace KCal;
00044
00045
00046
00047
00048
00049 QString KAEvent::calVersionString() { return QString::fromLatin1("1.9.10"); }
00050 int KAEvent::calVersion() { return KAlarm::Version(1,9,10); }
00051
00052
00053
00054
00055
00056 static const QByteArray FLAGS_PROPERTY("FLAGS");
00057 static const QString DATE_ONLY_FLAG = QLatin1String("DATE");
00058 static const QString EMAIL_BCC_FLAG = QLatin1String("BCC");
00059 static const QString CONFIRM_ACK_FLAG = QLatin1String("ACKCONF");
00060 static const QString KORGANIZER_FLAG = QLatin1String("KORG");
00061 static const QString WORK_TIME_ONLY_FLAG = QLatin1String("WORKTIME");
00062 static const QString DEFER_FLAG = QLatin1String("DEFER");
00063 static const QString LATE_CANCEL_FLAG = QLatin1String("LATECANCEL");
00064 static const QString AUTO_CLOSE_FLAG = QLatin1String("LATECLOSE");
00065 static const QString TEMPL_AFTER_TIME_FLAG = QLatin1String("TMPLAFTTIME");
00066 static const QString KMAIL_SERNUM_FLAG = QLatin1String("KMAIL");
00067
00068 static const QByteArray NEXT_RECUR_PROPERTY("NEXTRECUR");
00069 static const QByteArray REPEAT_PROPERTY("REPEAT");
00070 static const QByteArray ARCHIVE_PROPERTY("ARCHIVE");
00071 static const QString ARCHIVE_REMINDER_ONCE_TYPE = QLatin1String("ONCE");
00072 static const QByteArray LOG_PROPERTY("LOG");
00073 static const QString xtermURL = QLatin1String("xterm:");
00074 static const QString displayURL = QLatin1String("display:");
00075
00076
00077 static const QByteArray TYPE_PROPERTY("TYPE");
00078 static const QString FILE_TYPE = QLatin1String("FILE");
00079 static const QString AT_LOGIN_TYPE = QLatin1String("LOGIN");
00080 static const QString REMINDER_TYPE = QLatin1String("REMINDER");
00081 static const QString REMINDER_ONCE_TYPE = QLatin1String("REMINDER_ONCE");
00082 static const QString TIME_DEFERRAL_TYPE = QLatin1String("DEFERRAL");
00083 static const QString DATE_DEFERRAL_TYPE = QLatin1String("DATE_DEFERRAL");
00084 static const QString DISPLAYING_TYPE = QLatin1String("DISPLAYING");
00085 static const QString PRE_ACTION_TYPE = QLatin1String("PRE");
00086 static const QString POST_ACTION_TYPE = QLatin1String("POST");
00087 static const QByteArray NEXT_REPEAT_PROPERTY("NEXTREPEAT");
00088
00089 static const QByteArray FONT_COLOUR_PROPERTY("FONTCOLOR");
00090
00091 static const QByteArray EMAIL_ID_PROPERTY("EMAILID");
00092
00093 static const QByteArray VOLUME_PROPERTY("VOLUME");
00094 static const QByteArray SPEAK_PROPERTY("SPEAK");
00095
00096 static const QByteArray CANCEL_ON_ERROR_PROPERTY("ERRCANCEL");
00097
00098
00099 static const QString DISABLED_STATUS = QLatin1String("DISABLED");
00100
00101
00102 static const QString DISP_DEFER = QLatin1String("DEFER");
00103 static const QString DISP_EDIT = QLatin1String("EDIT");
00104
00105 static const QString SC = QLatin1String(";");
00106
00107 struct AlarmData
00108 {
00109 const Alarm* alarm;
00110 QString cleanText;
00111 uint emailFromId;
00112 QFont font;
00113 QColor bgColour, fgColour;
00114 float soundVolume;
00115 float fadeVolume;
00116 int fadeSeconds;
00117 int nextRepeat;
00118 bool speak;
00119 KAAlarm::SubType type;
00120 KAAlarmEventBase::Type action;
00121 int displayingFlags;
00122 bool defaultFont;
00123 bool reminderOnceOnly;
00124 bool isEmailText;
00125 bool commandScript;
00126 bool cancelOnPreActErr;
00127 };
00128 typedef QMap<KAAlarm::SubType, AlarmData> AlarmMap;
00129
00130 static void setProcedureAlarm(Alarm*, const QString& commandLine);
00131
00132
00133
00134
00135
00136
00137
00138 inline void KAEvent::set_deferral(DeferType type)
00139 {
00140 if (type)
00141 {
00142 if (!mDeferral)
00143 ++mAlarmCount;
00144 }
00145 else
00146 {
00147 if (mDeferral)
00148 --mAlarmCount;
00149 }
00150 mDeferral = type;
00151 }
00152
00153 inline void KAEvent::set_reminder(int minutes)
00154 {
00155 if (!mReminderMinutes)
00156 ++mAlarmCount;
00157 mReminderMinutes = minutes;
00158 mArchiveReminderMinutes = 0;
00159 }
00160
00161 inline void KAEvent::set_archiveReminder()
00162 {
00163 if (mReminderMinutes)
00164 --mAlarmCount;
00165 mArchiveReminderMinutes = mReminderMinutes;
00166 mReminderMinutes = 0;
00167 }
00168
00169
00170 void KAEvent::copy(const KAEvent& event)
00171 {
00172 KAAlarmEventBase::copy(event);
00173 mTemplateName = event.mTemplateName;
00174 mResource = event.mResource;
00175 mResourceId = event.mResourceId;
00176 mAudioFile = event.mAudioFile;
00177 mPreAction = event.mPreAction;
00178 mPostAction = event.mPostAction;
00179 mStartDateTime = event.mStartDateTime;
00180 mSaveDateTime = event.mSaveDateTime;
00181 mAtLoginDateTime = event.mAtLoginDateTime;
00182 mDeferralTime = event.mDeferralTime;
00183 mAllTrigger = event.mAllTrigger;
00184 mMainTrigger = event.mMainTrigger;
00185 mAllWorkTrigger = event.mAllWorkTrigger;
00186 mMainWorkTrigger = event.mMainWorkTrigger;
00187 mDisplayingTime = event.mDisplayingTime;
00188 mDisplayingFlags = event.mDisplayingFlags;
00189 mReminderMinutes = event.mReminderMinutes;
00190 mArchiveReminderMinutes = event.mArchiveReminderMinutes;
00191 mDeferDefaultMinutes = event.mDeferDefaultMinutes;
00192 mRevision = event.mRevision;
00193 mAlarmCount = event.mAlarmCount;
00194 mDeferral = event.mDeferral;
00195 mLogFile = event.mLogFile;
00196 mCategory = event.mCategory;
00197 mCancelOnPreActErr = event.mCancelOnPreActErr;
00198 mCommandXterm = event.mCommandXterm;
00199 mCommandDisplay = event.mCommandDisplay;
00200 mSpeak = event.mSpeak;
00201 mKMailSerialNumber = event.mKMailSerialNumber;
00202 mCopyToKOrganizer = event.mCopyToKOrganizer;
00203 mWorkTimeOnly = event.mWorkTimeOnly;
00204 mReminderOnceOnly = event.mReminderOnceOnly;
00205 mMainExpired = event.mMainExpired;
00206 mArchiveRepeatAtLogin = event.mArchiveRepeatAtLogin;
00207 mArchive = event.mArchive;
00208 mTemplateAfterTime = event.mTemplateAfterTime;
00209 mDisplayingDefer = event.mDisplayingDefer;
00210 mDisplayingEdit = event.mDisplayingEdit;
00211 mEnabled = event.mEnabled;
00212 mUpdated = event.mUpdated;
00213 mChangeCount = 0;
00214 mChanged = false;
00215 delete mRecurrence;
00216 if (event.mRecurrence)
00217 mRecurrence = new KARecurrence(*event.mRecurrence);
00218 else
00219 mRecurrence = 0;
00220 if (event.mChanged)
00221 calcTriggerTimes();
00222 }
00223
00224
00225
00226
00227 void KAEvent::set(const Event* event)
00228 {
00229 startChanges();
00230
00231 mEventID = event->uid();
00232 mRevision = event->revision();
00233 mTemplateName.clear();
00234 mLogFile.clear();
00235 mResourceId.clear();
00236 mTemplateAfterTime = -1;
00237 mBeep = false;
00238 mSpeak = false;
00239 mEmailBcc = false;
00240 mCommandXterm = false;
00241 mCommandDisplay = false;
00242 mCopyToKOrganizer = false;
00243 mWorkTimeOnly = false;
00244 mConfirmAck = false;
00245 mArchive = false;
00246 mReminderOnceOnly = false;
00247 mAutoClose = false;
00248 mArchiveRepeatAtLogin = false;
00249 mDisplayingDefer = false;
00250 mDisplayingEdit = false;
00251 mResource = 0;
00252 mArchiveReminderMinutes = 0;
00253 mDeferDefaultMinutes = 0;
00254 mLateCancel = 0;
00255 mKMailSerialNumber = 0;
00256 mChangeCount = 0;
00257 mChanged = false;
00258 mBgColour = QColor(255, 255, 255);
00259 mFgColour = QColor(0, 0, 0);
00260 mDefaultFont = true;
00261 mEnabled = true;
00262 clearRecur();
00263 QString param;
00264 mCategory = KCalEvent::status(event, ¶m);
00265 if (mCategory == KCalEvent::DISPLAYING)
00266 {
00267
00268 QStringList params = param.split(SC, QString::KeepEmptyParts);
00269 int n = params.count();
00270 if (n)
00271 {
00272 mResourceId = params[0];
00273 for (int i = 1; i < n; ++i)
00274 {
00275 if (params[i] == DISP_DEFER)
00276 mDisplayingDefer = true;
00277 if (params[i] == DISP_EDIT)
00278 mDisplayingEdit = true;
00279 }
00280 }
00281 }
00282 bool ok;
00283 bool dateOnly = false;
00284 QStringList flags = event->customProperty(KCalendar::APPNAME, FLAGS_PROPERTY).split(SC, QString::SkipEmptyParts);
00285 flags += QString();
00286 for (int i = 0, end = flags.count() - 1; i < end; ++i)
00287 {
00288 if (flags[i] == DATE_ONLY_FLAG)
00289 dateOnly = true;
00290 else if (flags[i] == CONFIRM_ACK_FLAG)
00291 mConfirmAck = true;
00292 else if (flags[i] == EMAIL_BCC_FLAG)
00293 mEmailBcc = true;
00294 else if (flags[i] == KORGANIZER_FLAG)
00295 mCopyToKOrganizer = true;
00296 else if (flags[i] == WORK_TIME_ONLY_FLAG)
00297 mWorkTimeOnly = true;
00298 else if (flags[i]== KMAIL_SERNUM_FLAG)
00299 {
00300 unsigned long n = flags[i + 1].toULong(&ok);
00301 if (!ok)
00302 continue;
00303 mKMailSerialNumber = n;
00304 ++i;
00305 }
00306 else if (flags[i] == DEFER_FLAG)
00307 {
00308 int n = static_cast<int>(flags[i + 1].toUInt(&ok));
00309 if (!ok)
00310 continue;
00311 mDeferDefaultMinutes = n;
00312 ++i;
00313 }
00314 else if (flags[i] == TEMPL_AFTER_TIME_FLAG)
00315 {
00316 int n = static_cast<int>(flags[i + 1].toUInt(&ok));
00317 if (!ok)
00318 continue;
00319 mTemplateAfterTime = n;
00320 ++i;
00321 }
00322 else if (flags[i] == LATE_CANCEL_FLAG)
00323 {
00324 mLateCancel = static_cast<int>(flags[i + 1].toUInt(&ok));
00325 if (ok)
00326 ++i;
00327 if (!ok || !mLateCancel)
00328 mLateCancel = 1;
00329 }
00330 else if (flags[i] == AUTO_CLOSE_FLAG)
00331 {
00332 mLateCancel = static_cast<int>(flags[i + 1].toUInt(&ok));
00333 if (ok)
00334 ++i;
00335 if (!ok || !mLateCancel)
00336 mLateCancel = 1;
00337 mAutoClose = true;
00338 }
00339 }
00340
00341 QString prop = event->customProperty(KCalendar::APPNAME, LOG_PROPERTY);
00342 if (!prop.isEmpty())
00343 {
00344 if (prop == xtermURL)
00345 mCommandXterm = true;
00346 else if (prop == displayURL)
00347 mCommandDisplay = true;
00348 else
00349 mLogFile = prop;
00350 }
00351 prop = event->customProperty(KCalendar::APPNAME, REPEAT_PROPERTY);
00352 if (!prop.isEmpty())
00353 {
00354
00355 QStringList list = prop.split(QLatin1Char(':'));
00356 if (list.count() >= 2)
00357 {
00358 int interval = static_cast<int>(list[0].toUInt());
00359 int count = static_cast<int>(list[1].toUInt());
00360 if (interval && count)
00361 {
00362 if (interval % (24*60))
00363 mRepeatInterval = Duration(interval * 60, Duration::Seconds);
00364 else
00365 mRepeatInterval = Duration(interval / (24*60), Duration::Days);
00366 mRepeatCount = count;
00367 }
00368 }
00369 }
00370 prop = event->customProperty(KCalendar::APPNAME, ARCHIVE_PROPERTY);
00371 if (!prop.isEmpty())
00372 {
00373 mArchive = true;
00374 if (prop != QLatin1String("0"))
00375 {
00376
00377 QStringList list = prop.split(SC, QString::SkipEmptyParts);
00378 for (int j = 0; j < list.count(); ++j)
00379 {
00380 if (list[j] == AT_LOGIN_TYPE)
00381 mArchiveRepeatAtLogin = true;
00382 else if (list[j] == ARCHIVE_REMINDER_ONCE_TYPE)
00383 mReminderOnceOnly = true;
00384 else
00385 {
00386 char ch;
00387 const char* cat = list[j].toLatin1().constData();
00388 while ((ch = *cat) != 0 && (ch < '0' || ch > '9'))
00389 ++cat;
00390 if (ch)
00391 {
00392 mArchiveReminderMinutes = ch - '0';
00393 while ((ch = *++cat) >= '0' && ch <= '9')
00394 mArchiveReminderMinutes = mArchiveReminderMinutes * 10 + ch - '0';
00395 switch (ch)
00396 {
00397 case 'M': break;
00398 case 'H': mArchiveReminderMinutes *= 60; break;
00399 case 'D': mArchiveReminderMinutes *= 1440; break;
00400 }
00401 }
00402 }
00403 }
00404 }
00405 }
00406 mNextMainDateTime = readDateTime(event, dateOnly, mStartDateTime);
00407 mSaveDateTime = event->created();
00408 if (dateOnly && !mRepeatInterval.isDaily())
00409 mRepeatInterval = Duration(mRepeatInterval.asDays(), Duration::Days);
00410 if (category() == KCalEvent::TEMPLATE)
00411 mTemplateName = event->summary();
00412 if (event->statusStr() == DISABLED_STATUS)
00413 mEnabled = false;
00414
00415
00416
00417 mActionType = T_MESSAGE;
00418 mMainExpired = true;
00419 mRepeatAtLogin = false;
00420 mDisplaying = false;
00421 mRepeatSound = false;
00422 mCommandScript = false;
00423 mCancelOnPreActErr = false;
00424 mDeferral = NO_DEFERRAL;
00425 mSoundVolume = -1;
00426 mFadeVolume = -1;
00427 mFadeSeconds = 0;
00428 mReminderMinutes = 0;
00429 mEmailFromIdentity = 0;
00430 mText = "";
00431 mAudioFile = "";
00432 mPreAction = "";
00433 mPostAction = "";
00434 mEmailSubject = "";
00435 mEmailAddresses.clear();
00436 mEmailAttachments.clear();
00437
00438
00439 AlarmMap alarmMap;
00440 readAlarms(event, &alarmMap, mCommandDisplay);
00441
00442
00443 mAlarmCount = 0;
00444 DateTime alTime;
00445 bool set = false;
00446 bool isEmailText = false;
00447 bool setDeferralTime = false;
00448 Duration deferralOffset;
00449 for (AlarmMap::ConstIterator it = alarmMap.begin(); it != alarmMap.end(); ++it)
00450 {
00451 const AlarmData& data = it.value();
00452 DateTime dateTime = data.alarm->hasStartOffset() ? data.alarm->startOffset().end(mNextMainDateTime.effectiveKDateTime()) : data.alarm->time();
00453 switch (data.type)
00454 {
00455 case KAAlarm::MAIN__ALARM:
00456 mMainExpired = false;
00457 alTime = dateTime;
00458 alTime.setDateOnly(mStartDateTime.isDateOnly());
00459 if (data.alarm->repeatCount() && data.alarm->snoozeTime())
00460 {
00461 mRepeatInterval = data.alarm->snoozeTime();
00462 mRepeatCount = data.alarm->repeatCount();
00463 mNextRepeat = data.nextRepeat;
00464 }
00465 break;
00466 case KAAlarm::AT_LOGIN__ALARM:
00467 mRepeatAtLogin = true;
00468 mAtLoginDateTime = dateTime.kDateTime();
00469 alTime = mAtLoginDateTime;
00470 break;
00471 case KAAlarm::REMINDER__ALARM:
00472
00473 mReminderMinutes = -(data.alarm->startOffset().asSeconds() / 60);
00474 if (mReminderMinutes)
00475 mArchiveReminderMinutes = 0;
00476 break;
00477 case KAAlarm::DEFERRED_REMINDER_DATE__ALARM:
00478 case KAAlarm::DEFERRED_DATE__ALARM:
00479 mDeferral = (data.type == KAAlarm::DEFERRED_REMINDER_DATE__ALARM) ? REMINDER_DEFERRAL : NORMAL_DEFERRAL;
00480 mDeferralTime = dateTime;
00481 mDeferralTime.setDateOnly(true);
00482 if (data.alarm->hasStartOffset())
00483 deferralOffset = data.alarm->startOffset();
00484 break;
00485 case KAAlarm::DEFERRED_REMINDER_TIME__ALARM:
00486 case KAAlarm::DEFERRED_TIME__ALARM:
00487 mDeferral = (data.type == KAAlarm::DEFERRED_REMINDER_TIME__ALARM) ? REMINDER_DEFERRAL : NORMAL_DEFERRAL;
00488 mDeferralTime = dateTime;
00489 if (data.alarm->hasStartOffset())
00490 deferralOffset = data.alarm->startOffset();
00491 break;
00492 case KAAlarm::DISPLAYING__ALARM:
00493 {
00494 mDisplaying = true;
00495 mDisplayingFlags = data.displayingFlags;
00496 bool dateOnly = (mDisplayingFlags & DEFERRAL) ? !(mDisplayingFlags & TIMED_FLAG)
00497 : mStartDateTime.isDateOnly();
00498 mDisplayingTime = dateTime;
00499 mDisplayingTime.setDateOnly(dateOnly);
00500 alTime = mDisplayingTime;
00501 break;
00502 }
00503 case KAAlarm::AUDIO__ALARM:
00504 mAudioFile = data.cleanText;
00505 mSpeak = data.speak && mAudioFile.isEmpty();
00506 mBeep = !mSpeak && mAudioFile.isEmpty();
00507 mSoundVolume = (!mBeep && !mSpeak) ? data.soundVolume : -1;
00508 mFadeVolume = (mSoundVolume >= 0 && data.fadeSeconds > 0) ? data.fadeVolume : -1;
00509 mFadeSeconds = (mFadeVolume >= 0) ? data.fadeSeconds : 0;
00510 mRepeatSound = (!mBeep && !mSpeak) && (data.alarm->repeatCount() < 0);
00511 break;
00512 case KAAlarm::PRE_ACTION__ALARM:
00513 mPreAction = data.cleanText;
00514 mCancelOnPreActErr = data.cancelOnPreActErr;
00515 break;
00516 case KAAlarm::POST_ACTION__ALARM:
00517 mPostAction = data.cleanText;
00518 break;
00519 case KAAlarm::INVALID__ALARM:
00520 default:
00521 break;
00522 }
00523
00524 if (data.reminderOnceOnly)
00525 mReminderOnceOnly = true;
00526 bool noSetNextTime = false;
00527 switch (data.type)
00528 {
00529 case KAAlarm::DEFERRED_REMINDER_DATE__ALARM:
00530 case KAAlarm::DEFERRED_DATE__ALARM:
00531 case KAAlarm::DEFERRED_REMINDER_TIME__ALARM:
00532 case KAAlarm::DEFERRED_TIME__ALARM:
00533 if (!set)
00534 {
00535
00536
00537 setDeferralTime = true;
00538 noSetNextTime = true;
00539 }
00540
00541 case KAAlarm::AT_LOGIN__ALARM:
00542 case KAAlarm::REMINDER__ALARM:
00543 case KAAlarm::DISPLAYING__ALARM:
00544 if (!set && !noSetNextTime)
00545 mNextMainDateTime = alTime;
00546
00547 case KAAlarm::MAIN__ALARM:
00548
00549
00550 if (!set)
00551 {
00552 mActionType = data.action;
00553 mText = (mActionType == T_COMMAND) ? data.cleanText.trimmed() : data.cleanText;
00554 switch (data.action)
00555 {
00556 case T_COMMAND:
00557 mCommandScript = data.commandScript;
00558 if (!mCommandDisplay)
00559 break;
00560
00561 case T_MESSAGE:
00562 mFont = data.font;
00563 mDefaultFont = data.defaultFont;
00564 if (data.isEmailText)
00565 isEmailText = true;
00566
00567 case T_FILE:
00568 mBgColour = data.bgColour;
00569 mFgColour = data.fgColour;
00570 break;
00571 case T_EMAIL:
00572 mEmailFromIdentity = data.emailFromId;
00573 mEmailAddresses = data.alarm->mailAddresses();
00574 mEmailSubject = data.alarm->mailSubject();
00575 mEmailAttachments = data.alarm->mailAttachments();
00576 break;
00577 default:
00578 break;
00579 }
00580 set = true;
00581 }
00582 if (data.action == T_FILE && mActionType == T_MESSAGE)
00583 mActionType = T_FILE;
00584 ++mAlarmCount;
00585 break;
00586 case KAAlarm::AUDIO__ALARM:
00587 case KAAlarm::PRE_ACTION__ALARM:
00588 case KAAlarm::POST_ACTION__ALARM:
00589 case KAAlarm::INVALID__ALARM:
00590 default:
00591 break;
00592 }
00593 }
00594 if (!isEmailText)
00595 mKMailSerialNumber = 0;
00596 if (mRepeatAtLogin)
00597 mArchiveRepeatAtLogin = false;
00598
00599 Recurrence* recur = event->recurrence();
00600 if (recur && recur->recurs())
00601 {
00602 int nextRepeat = mNextRepeat;
00603 setRecurrence(*recur);
00604 if (nextRepeat <= mRepeatCount)
00605 mNextRepeat = nextRepeat;
00606 }
00607 else
00608 checkRepetition();
00609
00610 if (mMainExpired && deferralOffset && checkRecur() != KARecurrence::NO_RECUR)
00611 {
00612
00613
00614 DateTime dt = mRecurrence->getNextDateTime(mStartDateTime.addDays(-1).kDateTime());
00615 dt.setDateOnly(mStartDateTime.isDateOnly());
00616 if (mDeferralTime.isDateOnly())
00617 {
00618 mDeferralTime = deferralOffset.end(dt.kDateTime());
00619 mDeferralTime.setDateOnly(true);
00620 }
00621 else
00622 mDeferralTime = deferralOffset.end(dt.effectiveKDateTime());
00623 }
00624 if (mDeferral)
00625 {
00626 if (mNextMainDateTime == mDeferralTime)
00627 mDeferral = CANCEL_DEFERRAL;
00628 if (setDeferralTime)
00629 mNextMainDateTime = mDeferralTime;
00630 }
00631 mChanged = true;
00632 endChanges();
00633
00634 mUpdated = false;
00635 }
00636
00637
00638
00639
00640
00641 DateTime KAEvent::readDateTime(const Event* event, bool dateOnly, DateTime& start)
00642 {
00643 start = event->dtStart();
00644 if (dateOnly)
00645 {
00646
00647
00648 start.setDateOnly(true);
00649 }
00650 DateTime next = start;
00651 QString prop = event->customProperty(KCalendar::APPNAME, NEXT_RECUR_PROPERTY);
00652 if (prop.length() >= 8)
00653 {
00654
00655 QDate d(prop.left(4).toInt(), prop.mid(4,2).toInt(), prop.mid(6,2).toInt());
00656 if (d.isValid())
00657 {
00658 if (dateOnly && prop.length() == 8)
00659 next.setDate(d);
00660 else if (!dateOnly && prop.length() == 15 && prop[8] == QChar('T'))
00661 {
00662 QTime t(prop.mid(9,2).toInt(), prop.mid(11,2).toInt(), prop.mid(13,2).toInt());
00663 if (t.isValid())
00664 {
00665 next.setDate(d);
00666 next.setTime(t);
00667 }
00668 }
00669 }
00670 }
00671 return next;
00672 }
00673
00674
00675
00676
00677
00678 void KAEvent::readAlarms(const Event* event, void* almap, bool cmdDisplay)
00679 {
00680 AlarmMap* alarmMap = (AlarmMap*)almap;
00681 Alarm::List alarms = event->alarms();
00682 for (Alarm::List::ConstIterator it = alarms.begin(); it != alarms.end(); ++it)
00683 {
00684
00685 AlarmData data;
00686 readAlarm(*it, data, cmdDisplay);
00687 if (data.type != KAAlarm::INVALID__ALARM)
00688 alarmMap->insert(data.type, data);
00689 }
00690 }
00691
00692
00693
00694
00695
00696 void KAEvent::readAlarm(const Alarm* alarm, AlarmData& data, bool cmdDisplay)
00697 {
00698
00699 data.alarm = alarm;
00700 data.displayingFlags = 0;
00701 data.isEmailText = false;
00702 data.nextRepeat = 0;
00703 if (alarm->repeatCount())
00704 {
00705 bool ok;
00706 QString property = alarm->customProperty(KCalendar::APPNAME, NEXT_REPEAT_PROPERTY);
00707 int n = static_cast<int>(property.toUInt(&ok));
00708 if (ok)
00709 data.nextRepeat = n;
00710 }
00711 switch (alarm->type())
00712 {
00713 case Alarm::Procedure:
00714 data.action = T_COMMAND;
00715 data.cleanText = alarm->programFile();
00716 data.commandScript = data.cleanText.isEmpty();
00717 if (!alarm->programArguments().isEmpty())
00718 {
00719 if (!data.commandScript)
00720 data.cleanText += ' ';
00721 data.cleanText += alarm->programArguments();
00722 }
00723 data.cancelOnPreActErr = !alarm->customProperty(KCalendar::APPNAME, CANCEL_ON_ERROR_PROPERTY).isNull();
00724 if (!cmdDisplay)
00725 break;
00726
00727 case Alarm::Display:
00728 {
00729 if (alarm->type() == Alarm::Display)
00730 {
00731 data.action = T_MESSAGE;
00732 data.cleanText = AlarmText::fromCalendarText(alarm->text(), data.isEmailText);
00733 }
00734 QString property = alarm->customProperty(KCalendar::APPNAME, FONT_COLOUR_PROPERTY);
00735 QStringList list = property.split(QLatin1Char(';'), QString::KeepEmptyParts);
00736 data.bgColour = QColor(255, 255, 255);
00737 data.fgColour = QColor(0, 0, 0);
00738 int n = list.count();
00739 if (n > 0)
00740 {
00741 if (!list[0].isEmpty())
00742 {
00743 QColor c(list[0]);
00744 if (c.isValid())
00745 data.bgColour = c;
00746 }
00747 if (n > 1 && !list[1].isEmpty())
00748 {
00749 QColor c(list[1]);
00750 if (c.isValid())
00751 data.fgColour = c;
00752 }
00753 }
00754 data.defaultFont = (n <= 2 || list[2].isEmpty());
00755 if (!data.defaultFont)
00756 data.font.fromString(list[2]);
00757 break;
00758 }
00759 case Alarm::Email:
00760 data.action = T_EMAIL;
00761 data.emailFromId = alarm->customProperty(KCalendar::APPNAME, EMAIL_ID_PROPERTY).toUInt();
00762 data.cleanText = alarm->mailText();
00763 break;
00764 case Alarm::Audio:
00765 {
00766 data.action = T_AUDIO;
00767 data.cleanText = alarm->audioFile();
00768 data.type = KAAlarm::AUDIO__ALARM;
00769 data.soundVolume = -1;
00770 data.fadeVolume = -1;
00771 data.fadeSeconds = 0;
00772 data.speak = !alarm->customProperty(KCalendar::APPNAME, SPEAK_PROPERTY).isNull();
00773 QString property = alarm->customProperty(KCalendar::APPNAME, VOLUME_PROPERTY);
00774 if (!property.isEmpty())
00775 {
00776 bool ok;
00777 float fadeVolume;
00778 int fadeSecs = 0;
00779 QStringList list = property.split(QLatin1Char(';'), QString::KeepEmptyParts);
00780 data.soundVolume = list[0].toFloat(&ok);
00781 if (!ok)
00782 data.soundVolume = -1;
00783 if (data.soundVolume >= 0 && list.count() >= 3)
00784 {
00785 fadeVolume = list[1].toFloat(&ok);
00786 if (ok)
00787 fadeSecs = static_cast<int>(list[2].toUInt(&ok));
00788 if (ok && fadeVolume >= 0 && fadeSecs > 0)
00789 {
00790 data.fadeVolume = fadeVolume;
00791 data.fadeSeconds = fadeSecs;
00792 }
00793 }
00794 }
00795 return;
00796 }
00797 case Alarm::Invalid:
00798 data.type = KAAlarm::INVALID__ALARM;
00799 return;
00800 }
00801
00802 bool atLogin = false;
00803 bool reminder = false;
00804 bool deferral = false;
00805 bool dateDeferral = false;
00806 data.reminderOnceOnly = false;
00807 data.type = KAAlarm::MAIN__ALARM;
00808 QString property = alarm->customProperty(KCalendar::APPNAME, TYPE_PROPERTY);
00809 QStringList types = property.split(QLatin1Char(','), QString::SkipEmptyParts);
00810 for (int i = 0, end = types.count(); i < end; ++i)
00811 {
00812 QString type = types[i];
00813 if (type == AT_LOGIN_TYPE)
00814 atLogin = true;
00815 else if (type == FILE_TYPE && data.action == T_MESSAGE)
00816 data.action = T_FILE;
00817 else if (type == REMINDER_TYPE)
00818 reminder = true;
00819 else if (type == REMINDER_ONCE_TYPE)
00820 reminder = data.reminderOnceOnly = true;
00821 else if (type == TIME_DEFERRAL_TYPE)
00822 deferral = true;
00823 else if (type == DATE_DEFERRAL_TYPE)
00824 dateDeferral = deferral = true;
00825 else if (type == DISPLAYING_TYPE)
00826 data.type = KAAlarm::DISPLAYING__ALARM;
00827 else if (type == PRE_ACTION_TYPE && data.action == T_COMMAND)
00828 data.type = KAAlarm::PRE_ACTION__ALARM;
00829 else if (type == POST_ACTION_TYPE && data.action == T_COMMAND)
00830 data.type = KAAlarm::POST_ACTION__ALARM;
00831 }
00832
00833 if (reminder)
00834 {
00835 if (data.type == KAAlarm::MAIN__ALARM)
00836 data.type = dateDeferral ? KAAlarm::DEFERRED_REMINDER_DATE__ALARM
00837 : deferral ? KAAlarm::DEFERRED_REMINDER_TIME__ALARM : KAAlarm::REMINDER__ALARM;
00838 else if (data.type == KAAlarm::DISPLAYING__ALARM)
00839 data.displayingFlags = dateDeferral ? REMINDER | DATE_DEFERRAL
00840 : deferral ? REMINDER | TIME_DEFERRAL : REMINDER;
00841 }
00842 else if (deferral)
00843 {
00844 if (data.type == KAAlarm::MAIN__ALARM)
00845 data.type = dateDeferral ? KAAlarm::DEFERRED_DATE__ALARM : KAAlarm::DEFERRED_TIME__ALARM;
00846 else if (data.type == KAAlarm::DISPLAYING__ALARM)
00847 data.displayingFlags = dateDeferral ? DATE_DEFERRAL : TIME_DEFERRAL;
00848 }
00849 if (atLogin)
00850 {
00851 if (data.type == KAAlarm::MAIN__ALARM)
00852 data.type = KAAlarm::AT_LOGIN__ALARM;
00853 else if (data.type == KAAlarm::DISPLAYING__ALARM)
00854 data.displayingFlags = REPEAT_AT_LOGIN;
00855 }
00856
00857 }
00858
00859
00860
00861
00862 void KAEvent::set(const KDateTime& dateTime, const QString& text, const QColor& bg, const QColor& fg,
00863 const QFont& font, Action action, int lateCancel, int flags, bool changesPending)
00864 {
00865 clearRecur();
00866 mStartDateTime = dateTime;
00867 mStartDateTime.setDateOnly(flags & ANY_TIME);
00868 mNextMainDateTime = mStartDateTime;
00869 switch (action)
00870 {
00871 case MESSAGE:
00872 case FILE:
00873 case COMMAND:
00874 case EMAIL:
00875