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