/* This file is part of libkcal. Copyright (c) 1998 Preston Brown Copyright (c) 2001 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "incidence.h" #include "todo.h" #include "alarm.h" using namespace KCal; Alarm::Alarm(Incidence *parent) : mParent(parent), mType(Invalid), mDescription(""), // to make operator==() not fail mFile(""), // to make operator==() not fail mMailSubject(""), // to make operator==() not fail mAlarmSnoozeTime(5), mAlarmRepeatCount(0), mEndOffset(false), mHasTime(false), mAlarmEnabled(false) { } Alarm::~Alarm() { } Alarm *Alarm::clone() { return new Alarm( *this ); } Alarm &Alarm::operator=( const Alarm &a ) { mParent = a.mParent; mType = a.mType; mDescription = a.mDescription; mFile = a.mFile; mMailAttachFiles = a.mMailAttachFiles; mMailAddresses = a.mMailAddresses; mMailSubject = a.mMailSubject; mAlarmSnoozeTime = a.mAlarmSnoozeTime; mAlarmRepeatCount = a.mAlarmRepeatCount; mAlarmTime = a.mAlarmTime; mOffset = a.mOffset; mEndOffset = a.mEndOffset; mHasTime = a.mHasTime; mAlarmEnabled = a.mAlarmEnabled; return *this; } bool Alarm::operator==( const Alarm& rhs ) const { if ( mType != rhs.mType || mAlarmSnoozeTime != rhs.mAlarmSnoozeTime || mAlarmRepeatCount != rhs.mAlarmRepeatCount || mAlarmEnabled != rhs.mAlarmEnabled || mHasTime != rhs.mHasTime) return false; if (mHasTime) { if (mAlarmTime != rhs.mAlarmTime) return false; } else { if (mOffset != rhs.mOffset || mEndOffset != rhs.mEndOffset) return false; } switch (mType) { case Display: return mDescription == rhs.mDescription; case Email: return mDescription == rhs.mDescription && mMailAttachFiles == rhs.mMailAttachFiles && mMailAddresses == rhs.mMailAddresses && mMailSubject == rhs.mMailSubject; case Procedure: return mFile == rhs.mFile && mDescription == rhs.mDescription; case Audio: return mFile == rhs.mFile; case Invalid: break; } return false; } void Alarm::setType(Alarm::Type type) { if (type == mType) return; switch (type) { case Display: mDescription = ""; break; case Procedure: mFile = mDescription = ""; break; case Audio: mFile = ""; break; case Email: mMailSubject = mDescription = ""; mMailAddresses.clear(); mMailAttachFiles.clear(); break; case Invalid: break; default: return; } mType = type; if ( mParent ) mParent->updated(); } Alarm::Type Alarm::type() const { return mType; } void Alarm::setAudioAlarm(const TQString &audioFile) { mType = Audio; mFile = audioFile; if ( mParent ) mParent->updated(); } void Alarm::setAudioFile(const TQString &audioFile) { if (mType == Audio) { mFile = audioFile; if ( mParent ) mParent->updated(); } } TQString Alarm::audioFile() const { return (mType == Audio) ? mFile : TQString(); } void Alarm::setProcedureAlarm(const TQString &programFile, const TQString &arguments) { mType = Procedure; mFile = programFile; mDescription = arguments; if ( mParent ) mParent->updated(); } void Alarm::setProgramFile(const TQString &programFile) { if (mType == Procedure) { mFile = programFile; if ( mParent ) mParent->updated(); } } TQString Alarm::programFile() const { return (mType == Procedure) ? mFile : TQString(); } void Alarm::setProgramArguments(const TQString &arguments) { if (mType == Procedure) { mDescription = arguments; if ( mParent ) mParent->updated(); } } TQString Alarm::programArguments() const { return (mType == Procedure) ? mDescription : TQString(); } void Alarm::setEmailAlarm(const TQString &subject, const TQString &text, const TQValueList &addressees, const TQStringList &attachments) { mType = Email; mMailSubject = subject; mDescription = text; mMailAddresses = addressees; mMailAttachFiles = attachments; if ( mParent ) mParent->updated(); } void Alarm::setMailAddress(const Person &mailAddress) { if (mType == Email) { mMailAddresses.clear(); mMailAddresses += mailAddress; if ( mParent ) mParent->updated(); } } void Alarm::setMailAddresses(const TQValueList &mailAddresses) { if (mType == Email) { mMailAddresses = mailAddresses; if ( mParent ) mParent->updated(); } } void Alarm::addMailAddress(const Person &mailAddress) { if (mType == Email) { mMailAddresses += mailAddress; if ( mParent ) mParent->updated(); } } TQValueList Alarm::mailAddresses() const { return (mType == Email) ? mMailAddresses : TQValueList(); } void Alarm::setMailSubject(const TQString &mailAlarmSubject) { if (mType == Email) { mMailSubject = mailAlarmSubject; if ( mParent ) mParent->updated(); } } TQString Alarm::mailSubject() const { return (mType == Email) ? mMailSubject : TQString(); } void Alarm::setMailAttachment(const TQString &mailAttachFile) { if (mType == Email) { mMailAttachFiles.clear(); mMailAttachFiles += mailAttachFile; if ( mParent ) mParent->updated(); } } void Alarm::setMailAttachments(const TQStringList &mailAttachFiles) { if (mType == Email) { mMailAttachFiles = mailAttachFiles; if ( mParent ) mParent->updated(); } } void Alarm::addMailAttachment(const TQString &mailAttachFile) { if (mType == Email) { mMailAttachFiles += mailAttachFile; if ( mParent ) mParent->updated(); } } TQStringList Alarm::mailAttachments() const { return (mType == Email) ? mMailAttachFiles : TQStringList(); } void Alarm::setMailText(const TQString &text) { if (mType == Email) { mDescription = text; if ( mParent ) mParent->updated(); } } TQString Alarm::mailText() const { return (mType == Email) ? mDescription : TQString(); } void Alarm::setDisplayAlarm(const TQString &text) { mType = Display; if ( !text.isNull() ) mDescription = text; if ( mParent ) mParent->updated(); } void Alarm::setText(const TQString &text) { if (mType == Display) { mDescription = text; if ( mParent ) mParent->updated(); } } TQString Alarm::text() const { return (mType == Display) ? mDescription : TQString(); } void Alarm::setTime(const TQDateTime &alarmTime) { mAlarmTime = alarmTime; mHasTime = true; if ( mParent ) mParent->updated(); } TQDateTime Alarm::time() const { if ( hasTime() ) { return mAlarmTime; } else if ( mParent ) { if ( mEndOffset ) { if ( mParent->type() == "Todo" ) { Todo *t = static_cast( mParent ); return mOffset.end( t->dtDue() ); } else { return mOffset.end( mParent->dtEnd() ); } } else { return mOffset.end( mParent->dtStart() ); } } else { return TQDateTime(); } } bool Alarm::hasTime() const { return mHasTime; } void Alarm::setSnoozeTime(const Duration &alarmSnoozeTime) { if (alarmSnoozeTime.value() > 0) { mAlarmSnoozeTime = alarmSnoozeTime; if ( mParent ) mParent->updated(); } } Duration Alarm::snoozeTime() const { return mAlarmSnoozeTime; } void Alarm::setRepeatCount(int alarmRepeatCount) { mAlarmRepeatCount = alarmRepeatCount; if ( mParent ) mParent->updated(); } int Alarm::repeatCount() const { return mAlarmRepeatCount; } Duration Alarm::duration() const { return Duration( mAlarmSnoozeTime.value() * mAlarmRepeatCount, mAlarmSnoozeTime.type() ); } TQDateTime Alarm::nextRepetition(const TQDateTime& preTime) const { // This method is coded to avoid 32-bit integer overflow using // TQDateTime::secsTo(), which occurs with time spans > 68 years. TQDateTime at = time(); if (at > preTime) return at; if (!mAlarmRepeatCount) return TQDateTime(); // there isn't an occurrence after the specified time int snoozeSecs = mAlarmSnoozeTime * 60; TQDateTime lastRepetition = at.addSecs(mAlarmRepeatCount * snoozeSecs); if (lastRepetition <= preTime) return TQDateTime(); // all repetitions have finished before the specified time int repetition = (at.secsTo(preTime) + snoozeSecs) / snoozeSecs; return at.addSecs(repetition * snoozeSecs); } TQDateTime Alarm::previousRepetition(const TQDateTime& afterTime) const { // This method is coded to avoid 32-bit integer overflow using // TQDateTime::secsTo(), which occurs with time spans > 68 years. TQDateTime at = time(); if (at >= afterTime) return TQDateTime(); // alarm's first/only time is at/after the specified time if (!mAlarmRepeatCount) return at; int snoozeSecs = mAlarmSnoozeTime * 60; TQDateTime lastRepetition = at.addSecs(mAlarmRepeatCount * snoozeSecs); if (lastRepetition < afterTime) return lastRepetition; // all repetitions have finished before the specified time int repetition = (at.secsTo(afterTime) - 1) / snoozeSecs; return at.addSecs(repetition * snoozeSecs); } TQDateTime Alarm::endTime() const { if (mAlarmRepeatCount) return time().addSecs(mAlarmRepeatCount * mAlarmSnoozeTime * 60); else return time(); } void Alarm::toggleAlarm() { mAlarmEnabled = !mAlarmEnabled; if ( mParent ) mParent->updated(); } void Alarm::setEnabled(bool enable) { mAlarmEnabled = enable; if ( mParent ) mParent->updated(); } bool Alarm::enabled() const { return mAlarmEnabled; } void Alarm::setStartOffset( const Duration &offset ) { mOffset = offset; mEndOffset = false; mHasTime = false; if ( mParent ) mParent->updated(); } Duration Alarm::startOffset() const { return (mHasTime || mEndOffset) ? Duration( 0 ) : mOffset; } bool Alarm::hasStartOffset() const { return !mHasTime && !mEndOffset; } bool Alarm::hasEndOffset() const { return !mHasTime && mEndOffset; } void Alarm::setEndOffset( const Duration &offset ) { mOffset = offset; mEndOffset = true; mHasTime = false; if ( mParent ) mParent->updated(); } Duration Alarm::endOffset() const { return (mHasTime || !mEndOffset) ? Duration( 0 ) : mOffset; } void Alarm::setParent( Incidence *parent ) { mParent = parent; } void Alarm::customPropertyUpdated() { if ( mParent ) mParent->updated(); }