|
|
|
/*
|
|
|
|
This file is part of libkcal.
|
|
|
|
|
|
|
|
Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
|
|
|
|
Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
|
|
|
|
|
|
|
|
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 <kglobal.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
|
|
|
|
#include "calformat.h"
|
|
|
|
|
|
|
|
#include "incidence.h"
|
|
|
|
#include "calendar.h"
|
|
|
|
|
|
|
|
using namespace KCal;
|
|
|
|
|
|
|
|
Incidence::Incidence() :
|
|
|
|
IncidenceBase(),
|
|
|
|
mRelatedTo(0), mStatus(StatusNone), mSecrecy(SecrecyPublic),
|
|
|
|
mPriority(0), mRecurrence(0),
|
|
|
|
mHasRecurrenceID( false ), mChildRecurrenceEvents()
|
|
|
|
{
|
|
|
|
recreate();
|
|
|
|
|
|
|
|
mAlarms.setAutoDelete(true);
|
|
|
|
mAttachments.setAutoDelete(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
Incidence::Incidence( const Incidence &i ) : IncidenceBase( i ),Recurrence::Observer()
|
|
|
|
{
|
|
|
|
// TODO: reenable attributes currently commented out.
|
|
|
|
mRevision = i.mRevision;
|
|
|
|
mCreated = i.mCreated;
|
|
|
|
mDescription = i.mDescription;
|
|
|
|
mSummary = i.mSummary;
|
|
|
|
mCategories = i.mCategories;
|
|
|
|
// Incidence *mRelatedTo; Incidence *mRelatedTo;
|
|
|
|
mRelatedTo = 0;
|
|
|
|
mRelatedToUid = i.mRelatedToUid;
|
|
|
|
// Incidence::List mRelations; Incidence::List mRelations;
|
|
|
|
mResources = i.mResources;
|
|
|
|
mStatusString = i.mStatusString;
|
|
|
|
mStatus = i.mStatus;
|
|
|
|
mSecrecy = i.mSecrecy;
|
|
|
|
mPriority = i.mPriority;
|
|
|
|
mLocation = i.mLocation;
|
|
|
|
mRecurrenceID = i.mRecurrenceID;
|
|
|
|
mHasRecurrenceID = i.mHasRecurrenceID;
|
|
|
|
mChildRecurrenceEvents = i.mChildRecurrenceEvents;
|
|
|
|
|
|
|
|
// Alarms and Attachments are stored in ListBase<...>, which is a TQValueList<...*>.
|
|
|
|
// We need to really duplicate the objects stored therein, otherwise deleting
|
|
|
|
// i will also delete all attachments from this object (setAutoDelete...)
|
|
|
|
Alarm::List::ConstIterator it;
|
|
|
|
for( it = i.mAlarms.begin(); it != i.mAlarms.end(); ++it ) {
|
|
|
|
Alarm *b = new Alarm( **it );
|
|
|
|
b->setParent( this );
|
|
|
|
mAlarms.append( b );
|
|
|
|
}
|
|
|
|
mAlarms.setAutoDelete(true);
|
|
|
|
|
|
|
|
Attachment::List::ConstIterator it1;
|
|
|
|
for ( it1 = i.mAttachments.begin(); it1 != i.mAttachments.end(); ++it1 ) {
|
|
|
|
Attachment *a = new Attachment( **it1 );
|
|
|
|
mAttachments.append( a );
|
|
|
|
}
|
|
|
|
mAttachments.setAutoDelete( true );
|
|
|
|
|
|
|
|
if (i.mRecurrence) {
|
|
|
|
mRecurrence = new Recurrence( *(i.mRecurrence) );
|
|
|
|
mRecurrence->addObserver( this );
|
|
|
|
} else
|
|
|
|
mRecurrence = 0;
|
|
|
|
|
|
|
|
mSchedulingID = i.mSchedulingID;
|
|
|
|
}
|
|
|
|
|
|
|
|
Incidence::~Incidence()
|
|
|
|
{
|
|
|
|
Incidence::List Relations = mRelations;
|
|
|
|
List::ConstIterator it;
|
|
|
|
for ( it = Relations.begin(); it != Relations.end(); ++it ) {
|
|
|
|
if ( (*it)->relatedTo() == this ) (*it)->mRelatedTo = 0;
|
|
|
|
}
|
|
|
|
if ( relatedTo() ) relatedTo()->removeRelation( this );
|
|
|
|
|
|
|
|
delete mRecurrence;
|
|
|
|
}
|
|
|
|
|
|
|
|
// A string comparison that considers that null and empty are the same
|
|
|
|
static bool stringCompare( const TQString& s1, const TQString& s2 )
|
|
|
|
{
|
|
|
|
return ( s1.isEmpty() && s2.isEmpty() ) || (s1 == s2);
|
|
|
|
}
|
|
|
|
|
|
|
|
Incidence& Incidence::operator=( const Incidence &i )
|
|
|
|
{
|
|
|
|
if ( &i == this )
|
|
|
|
return *this;
|
|
|
|
IncidenceBase::operator=( i );
|
|
|
|
mRevision = i.mRevision;
|
|
|
|
mCreated = i.mCreated;
|
|
|
|
mDescription = i.mDescription;
|
|
|
|
mSummary = i.mSummary;
|
|
|
|
mCategories = i.mCategories;
|
|
|
|
mRelatedTo = 0;
|
|
|
|
mRelatedToUid = i.mRelatedToUid;
|
|
|
|
mRelations.clear();
|
|
|
|
mResources = i.mResources;
|
|
|
|
mStatusString = i.mStatusString;
|
|
|
|
mStatus = i.mStatus;
|
|
|
|
mSecrecy = i.mSecrecy;
|
|
|
|
mPriority = i.mPriority;
|
|
|
|
mLocation = i.mLocation;
|
|
|
|
mRecurrenceID = i.mRecurrenceID;
|
|
|
|
mHasRecurrenceID = i.mHasRecurrenceID;
|
|
|
|
mChildRecurrenceEvents = i.mChildRecurrenceEvents;
|
|
|
|
|
|
|
|
mAlarms.clearAll();
|
|
|
|
Alarm::List::ConstIterator it;
|
|
|
|
for( it = i.mAlarms.begin(); it != i.mAlarms.end(); ++it ) {
|
|
|
|
Alarm *b = new Alarm( **it );
|
|
|
|
b->setParent( this );
|
|
|
|
mAlarms.append( b );
|
|
|
|
}
|
|
|
|
|
|
|
|
mAttachments.clearAll();
|
|
|
|
Attachment::List::ConstIterator it1;
|
|
|
|
for ( it1 = i.mAttachments.begin(); it1 != i.mAttachments.end(); ++it1 ) {
|
|
|
|
Attachment *a = new Attachment( **it1 );
|
|
|
|
mAttachments.append( a );
|
|
|
|
}
|
|
|
|
|
|
|
|
delete mRecurrence;
|
|
|
|
if (i.mRecurrence) {
|
|
|
|
mRecurrence = new Recurrence( *(i.mRecurrence) );
|
|
|
|
mRecurrence->addObserver( this );
|
|
|
|
} else
|
|
|
|
mRecurrence = 0;
|
|
|
|
|
|
|
|
mSchedulingID = i.mSchedulingID;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Incidence::operator==( const Incidence& i2 ) const
|
|
|
|
{
|
|
|
|
if( alarms().count() != i2.alarms().count() ) {
|
|
|
|
return false; // no need to check further
|
|
|
|
}
|
|
|
|
|
|
|
|
Alarm::List::ConstIterator a1 = alarms().begin();
|
|
|
|
Alarm::List::ConstIterator a2 = i2.alarms().begin();
|
|
|
|
for( ; a1 != alarms().end() && a2 != i2.alarms().end(); ++a1, ++a2 )
|
|
|
|
if( **a1 == **a2 )
|
|
|
|
continue;
|
|
|
|
else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !IncidenceBase::operator==(i2) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bool recurrenceEqual = ( mRecurrence == 0 && i2.mRecurrence == 0 );
|
|
|
|
if ( !recurrenceEqual )
|
|
|
|
{
|
|
|
|
recurrenceEqual = mRecurrence != 0 &&
|
|
|
|
i2.mRecurrence != 0 &&
|
|
|
|
*mRecurrence == *i2.mRecurrence;
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
recurrenceEqual &&
|
|
|
|
created() == i2.created() &&
|
|
|
|
stringCompare( description(), i2.description() ) &&
|
|
|
|
stringCompare( summary(), i2.summary() ) &&
|
|
|
|
categories() == i2.categories() &&
|
|
|
|
// no need to compare mRelatedTo
|
|
|
|
stringCompare( relatedToUid(), i2.relatedToUid() ) &&
|
|
|
|
relations() == i2.relations() &&
|
|
|
|
attachments() == i2.attachments() &&
|
|
|
|
resources() == i2.resources() &&
|
|
|
|
mStatus == i2.mStatus &&
|
|
|
|
( mStatus == StatusNone || stringCompare( mStatusString, i2.mStatusString ) ) &&
|
|
|
|
secrecy() == i2.secrecy() &&
|
|
|
|
priority() == i2.priority() &&
|
|
|
|
stringCompare( location(), i2.location() ) &&
|
|
|
|
stringCompare( schedulingID(), i2.schedulingID() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Incidence::recreate()
|
|
|
|
{
|
|
|
|
setCreated(TQDateTime::currentDateTime());
|
|
|
|
|
|
|
|
setUid(CalFormat::createUniqueId());
|
|
|
|
setSchedulingID( TQString() );
|
|
|
|
|
|
|
|
setRevision(0);
|
|
|
|
|
|
|
|
setLastModified(TQDateTime::currentDateTime());
|
|
|
|
setPilotId( 0 );
|
|
|
|
setSyncStatus( SYNCNONE );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setReadOnly( bool readOnly )
|
|
|
|
{
|
|
|
|
IncidenceBase::setReadOnly( readOnly );
|
|
|
|
if ( mRecurrence )
|
|
|
|
mRecurrence->setRecurReadOnly( readOnly );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setFloats(bool f)
|
|
|
|
{
|
|
|
|
if (mReadOnly) return;
|
|
|
|
if ( recurrence() )
|
|
|
|
recurrence()->setFloats( f );
|
|
|
|
IncidenceBase::setFloats( f );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setCreated( const TQDateTime &created )
|
|
|
|
{
|
|
|
|
if (mReadOnly) return;
|
|
|
|
mCreated = created;
|
|
|
|
|
|
|
|
// FIXME: Shouldn't we call updated for the creation date, too?
|
|
|
|
// updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQDateTime Incidence::created() const
|
|
|
|
{
|
|
|
|
return mCreated;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setRevision( int rev )
|
|
|
|
{
|
|
|
|
if (mReadOnly) return;
|
|
|
|
mRevision = rev;
|
|
|
|
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
int Incidence::revision() const
|
|
|
|
{
|
|
|
|
return mRevision;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setDtStart(const TQDateTime &dtStart)
|
|
|
|
{
|
|
|
|
if ( mRecurrence ) {
|
|
|
|
mRecurrence->setStartDateTime( dtStart );
|
|
|
|
mRecurrence->setFloats( doesFloat() );
|
|
|
|
}
|
|
|
|
IncidenceBase::setDtStart( dtStart );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setDescription(const TQString &description)
|
|
|
|
{
|
|
|
|
if (mReadOnly) return;
|
|
|
|
mDescription = description;
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Incidence::description() const
|
|
|
|
{
|
|
|
|
return mDescription;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Incidence::setSummary(const TQString &summary)
|
|
|
|
{
|
|
|
|
if (mReadOnly) return;
|
|
|
|
mSummary = summary;
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Incidence::summary() const
|
|
|
|
{
|
|
|
|
return mSummary;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setCategories(const TQStringList &categories)
|
|
|
|
{
|
|
|
|
if (mReadOnly) return;
|
|
|
|
mCategories = categories;
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: remove setCategories(TQString) function
|
|
|
|
void Incidence::setCategories(const TQString &catStr)
|
|
|
|
{
|
|
|
|
if (mReadOnly) return;
|
|
|
|
mCategories.clear();
|
|
|
|
|
|
|
|
if (catStr.isEmpty()) return;
|
|
|
|
|
|
|
|
mCategories = TQStringList::split(",",catStr);
|
|
|
|
|
|
|
|
TQStringList::Iterator it;
|
|
|
|
for(it = mCategories.begin();it != mCategories.end(); ++it) {
|
|
|
|
*it = (*it).stripWhiteSpace();
|
|
|
|
}
|
|
|
|
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList Incidence::categories() const
|
|
|
|
{
|
|
|
|
return mCategories;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Incidence::categoriesStr() const
|
|
|
|
{
|
|
|
|
return mCategories.join(",");
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setRelatedToUid(const TQString &relatedToUid)
|
|
|
|
{
|
|
|
|
if ( mReadOnly || mRelatedToUid == relatedToUid ) return;
|
|
|
|
mRelatedToUid = relatedToUid;
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Incidence::relatedToUid() const
|
|
|
|
{
|
|
|
|
return mRelatedToUid;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setRelatedTo(Incidence *relatedTo)
|
|
|
|
{
|
|
|
|
if (mReadOnly || mRelatedTo == relatedTo) return;
|
|
|
|
if(mRelatedTo)
|
|
|
|
mRelatedTo->removeRelation(this);
|
|
|
|
mRelatedTo = relatedTo;
|
|
|
|
if (mRelatedTo) {
|
|
|
|
mRelatedTo->addRelation(this);
|
|
|
|
if ( mRelatedTo->uid() != mRelatedToUid )
|
|
|
|
setRelatedToUid( mRelatedTo->uid() );
|
|
|
|
} else {
|
|
|
|
setRelatedToUid( TQString() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Incidence *Incidence::relatedTo() const
|
|
|
|
{
|
|
|
|
return mRelatedTo;
|
|
|
|
}
|
|
|
|
|
|
|
|
Incidence::List Incidence::relations() const
|
|
|
|
{
|
|
|
|
return mRelations;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::addRelation( Incidence *event )
|
|
|
|
{
|
|
|
|
if ( mRelations.find( event ) == mRelations.end() ) {
|
|
|
|
mRelations.append( event );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::removeRelation(Incidence *event)
|
|
|
|
// Remove the relation of our incident. E.g. if you have a task t and a
|
|
|
|
// subtask, the subtask will have its relation to the task t.
|
|
|
|
{
|
|
|
|
mRelations.removeRef(event);
|
|
|
|
// if (event->getRelatedTo() == this) event->setRelatedTo(0);
|
|
|
|
mRelatedToUid=TQString();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// %%%%%%%%%%%% Recurrence-related methods %%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
|
|
|
|
|
|
|
Recurrence *Incidence::recurrence() const
|
|
|
|
{
|
|
|
|
if (!mRecurrence)
|
|
|
|
{
|
|
|
|
const_cast<KCal::Incidence*>(this)->mRecurrence = new Recurrence();
|
|
|
|
mRecurrence->setStartDateTime( IncidenceBase::dtStart() );
|
|
|
|
mRecurrence->setFloats( doesFloat() );
|
|
|
|
mRecurrence->setRecurReadOnly( mReadOnly );
|
|
|
|
mRecurrence->addObserver( const_cast<KCal::Incidence*>(this) );
|
|
|
|
}
|
|
|
|
|
|
|
|
return mRecurrence;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::clearRecurrence()
|
|
|
|
{
|
|
|
|
delete mRecurrence;
|
|
|
|
mRecurrence = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint Incidence::recurrenceType() const
|
|
|
|
{
|
|
|
|
if ( mRecurrence ) return mRecurrence->recurrenceType();
|
|
|
|
else return Recurrence::rNone;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Incidence::doesRecur() const
|
|
|
|
{
|
|
|
|
if ( mRecurrence ) return mRecurrence->doesRecur();
|
|
|
|
else return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Incidence::recursOn(const TQDate &qd) const
|
|
|
|
{
|
|
|
|
bool doesRecur = false;
|
|
|
|
doesRecur = mRecurrence && mRecurrence->recursOn(qd);
|
|
|
|
|
|
|
|
return doesRecur;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Incidence::recursAt(const TQDateTime &qdt) const
|
|
|
|
{
|
|
|
|
bool doesRecur = false;
|
|
|
|
doesRecur = mRecurrence && mRecurrence->recursAt(qdt);
|
|
|
|
|
|
|
|
return doesRecur;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Incidence::recursOn(const TQDate &qd, Calendar *cal) const
|
|
|
|
{
|
|
|
|
bool doesRecur = false;
|
|
|
|
doesRecur = mRecurrence && mRecurrence->recursOn(qd);
|
|
|
|
|
|
|
|
// Make sure that this instance has not been moved through a RECURRENCE-ID statement
|
|
|
|
if (hasRecurrenceID() == false) {
|
|
|
|
IncidenceList il = childIncidences();
|
|
|
|
IncidenceListIterator it;
|
|
|
|
for ( it = il.begin(); it != il.end(); ++it ) {
|
|
|
|
TQDateTime modifiedDt = cal->incidence(*it)->recurrenceID();
|
|
|
|
modifiedDt.setTime(TQTime());
|
|
|
|
if (TQDateTime(qd) == modifiedDt) {
|
|
|
|
doesRecur = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return doesRecur;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Incidence::recursAt(const TQDateTime &qdt, Calendar *cal) const
|
|
|
|
{
|
|
|
|
bool doesRecur = false;
|
|
|
|
doesRecur = mRecurrence && mRecurrence->recursAt(qdt);
|
|
|
|
|
|
|
|
// Make sure that this instance has not been moved through a RECURRENCE-ID statement
|
|
|
|
if (hasRecurrenceID() == false) {
|
|
|
|
IncidenceList il = childIncidences();
|
|
|
|
IncidenceListIterator it;
|
|
|
|
for ( it = il.begin(); it != il.end(); ++it ) {
|
|
|
|
if (qdt == cal->incidence(*it)->recurrenceID()) {
|
|
|
|
doesRecur = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return doesRecur;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Calculates the start date/time for all recurrences that happen at some time
|
|
|
|
on the given date (might start before that date, but end on or after the
|
|
|
|
given date).
|
|
|
|
@param date the date where the incidence should occur
|
|
|
|
@return the start date/time of all occurences that overlap with the given
|
|
|
|
date. Empty list if the incidence does not overlap with the date at all
|
|
|
|
*/
|
|
|
|
TQValueList<TQDateTime> Incidence::startDateTimesForDate( const TQDate &date ) const
|
|
|
|
{
|
|
|
|
//kdDebug(5800) << "Incidence::startDateTimesForDate " << date << ", incidence=" << summary() << endl;
|
|
|
|
TQDateTime start = dtStart();
|
|
|
|
TQDateTime end = endDateRecurrenceBase();
|
|
|
|
|
|
|
|
TQValueList<TQDateTime> result;
|
|
|
|
|
|
|
|
// TODO_Recurrence: Also work if only due date is given...
|
|
|
|
if ( !start.isValid() && ! end.isValid() ) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if the incidence doesn't recur,
|
|
|
|
if ( !doesRecur() ) {
|
|
|
|
if ( !(start.date() > date || end.date() < date ) ) {
|
|
|
|
result << start;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
int days = start.daysTo( end );
|
|
|
|
// Account for possible recurrences going over midnight, while the original event doesn't
|
|
|
|
TQDate tmpday( date.addDays( -days - 1 ) );
|
|
|
|
TQDateTime tmp;
|
|
|
|
while ( tmpday <= date ) {
|
|
|
|
if ( recurrence()->recursOn( tmpday ) ) {
|
|
|
|
TQValueList<TQTime> times = recurrence()->recurTimesOn( tmpday );
|
|
|
|
for ( TQValueList<TQTime>::ConstIterator it = times.begin(); it != times.end(); ++it ) {
|
|
|
|
tmp = TQDateTime( tmpday, *it );
|
|
|
|
if ( endDateForStart( tmp ).date() >= date )
|
|
|
|
result << tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tmpday = tmpday.addDays( 1 );
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Calculates the start date/time for all recurrences that happen at the given
|
|
|
|
time.
|
|
|
|
@param datetime the date/time where the incidence should occur
|
|
|
|
@return the start date/time of all occurences that overlap with the given
|
|
|
|
date/time. Empty list if the incidence does not happen at the given
|
|
|
|
time at all.
|
|
|
|
*/
|
|
|
|
TQValueList<TQDateTime> Incidence::startDateTimesForDateTime( const TQDateTime &datetime ) const
|
|
|
|
{
|
|
|
|
// kdDebug(5800) << "Incidence::startDateTimesForDateTime " << datetime << ", incidence=" << summary() << endl;
|
|
|
|
TQDateTime start = dtStart();
|
|
|
|
TQDateTime end = endDateRecurrenceBase();
|
|
|
|
|
|
|
|
TQValueList<TQDateTime> result;
|
|
|
|
|
|
|
|
// TODO_Recurrence: Also work if only due date is given...
|
|
|
|
if ( !start.isValid() && ! end.isValid() ) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if the incidence doesn't recur,
|
|
|
|
if ( !doesRecur() ) {
|
|
|
|
if ( !(start > datetime || end < datetime ) ) {
|
|
|
|
result << start;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
int days = start.daysTo( end );
|
|
|
|
// Account for possible recurrences going over midnight, while the original event doesn't
|
|
|
|
TQDate tmpday( datetime.date().addDays( -days - 1 ) );
|
|
|
|
TQDateTime tmp;
|
|
|
|
while ( tmpday <= datetime.date() ) {
|
|
|
|
if ( recurrence()->recursOn( tmpday ) ) {
|
|
|
|
TQValueList<TQTime> times = recurrence()->recurTimesOn( tmpday );
|
|
|
|
for ( TQValueList<TQTime>::ConstIterator it = times.begin(); it != times.end(); ++it ) {
|
|
|
|
tmp = TQDateTime( tmpday, *it );
|
|
|
|
if ( !(tmp > datetime || endDateForStart( tmp ) < datetime ) )
|
|
|
|
result << tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tmpday = tmpday.addDays( 1 );
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Return the end time of the occurrence if it starts at the given date/time */
|
|
|
|
TQDateTime Incidence::endDateForStart( const TQDateTime &startDt ) const
|
|
|
|
{
|
|
|
|
TQDateTime start = dtStart();
|
|
|
|
TQDateTime end = endDateRecurrenceBase();
|
|
|
|
if ( !end.isValid() ) return start;
|
|
|
|
if ( !start.isValid() ) return end;
|
|
|
|
|
|
|
|
return startDt.addSecs( start.secsTo( end ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
// %%%%%%%%%%%%%%%%% begin:RecurrenceRule %%%%%%%%%%%%%%%%%
|
|
|
|
|
|
|
|
// Exception Dates
|
|
|
|
/*void Incidence::setExDates(const DateList &exDates)
|
|
|
|
{
|
|
|
|
if ( mReadOnly ) return;
|
|
|
|
recurrence()->setExDates( exDates );
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::addExDate( const TQDate &date )
|
|
|
|
{
|
|
|
|
if ( mReadOnly ) return;
|
|
|
|
recurrence()->addExDate( date );
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
DateList Incidence::exDates() const
|
|
|
|
{
|
|
|
|
if ( mRecurrence ) return mRecurrence->exDates();
|
|
|
|
else return DateList();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Exception DateTimes
|
|
|
|
void Incidence::setExDateTimes( const DateTimeList &exDates )
|
|
|
|
{
|
|
|
|
if ( mReadOnly ) return;
|
|
|
|
recurrence()->setExDateTimes( exDates );
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::addExDateTime( const TQDateTime &date )
|
|
|
|
{
|
|
|
|
if ( mReadOnly ) return;
|
|
|
|
recurrence()->addExDateTime( date );
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
DateTimeList Incidence::exDateTimes() const
|
|
|
|
{
|
|
|
|
if ( mRecurrence ) return mRecurrence->exDateTimes();
|
|
|
|
else return DateTimeList();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Recurrence Dates
|
|
|
|
void Incidence::setRDates(const DateList &exDates)
|
|
|
|
{
|
|
|
|
if ( mReadOnly ) return;
|
|
|
|
recurrence()->setRDates( exDates );
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::addRDate( const TQDate &date )
|
|
|
|
{
|
|
|
|
if ( mReadOnly ) return;
|
|
|
|
recurrence()->addRDate( date );
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
DateList Incidence::rDates() const
|
|
|
|
{
|
|
|
|
if ( mRecurrence ) return mRecurrence->rDates();
|
|
|
|
else return DateList();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Recurrence DateTimes
|
|
|
|
void Incidence::setRDateTimes( const DateTimeList &exDates )
|
|
|
|
{
|
|
|
|
if ( mReadOnly ) return;
|
|
|
|
recurrence()->setRDateTimes( exDates );
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::addRDateTime( const TQDateTime &date )
|
|
|
|
{
|
|
|
|
if ( mReadOnly ) return;
|
|
|
|
recurrence()->addRDateTime( date );
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
DateTimeList Incidence::rDateTimes() const
|
|
|
|
{
|
|
|
|
if ( mRecurrence ) return mRecurrence->rDateTimes();
|
|
|
|
else return DateTimeList();
|
|
|
|
}*/
|
|
|
|
|
|
|
|
// %%%%%%%%%%%%%%%%% end:RecurrenceRule %%%%%%%%%%%%%%%%%
|
|
|
|
|
|
|
|
void Incidence::addAttachment(Attachment *attachment)
|
|
|
|
{
|
|
|
|
if (mReadOnly || !attachment) return;
|
|
|
|
mAttachments.append(attachment);
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::deleteAttachment(Attachment *attachment)
|
|
|
|
{
|
|
|
|
mAttachments.removeRef(attachment);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::deleteAttachments( const TQString &mime )
|
|
|
|
{
|
|
|
|
Attachment::List::Iterator it = mAttachments.begin();
|
|
|
|
while( it != mAttachments.end() ) {
|
|
|
|
if ( (*it)->mimeType() == mime ) mAttachments.remove( it );
|
|
|
|
else ++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Attachment::List Incidence::attachments() const
|
|
|
|
{
|
|
|
|
return mAttachments;
|
|
|
|
}
|
|
|
|
|
|
|
|
Attachment::List Incidence::attachments(const TQString& mime) const
|
|
|
|
{
|
|
|
|
Attachment::List attachments;
|
|
|
|
Attachment::List::ConstIterator it;
|
|
|
|
for( it = mAttachments.begin(); it != mAttachments.end(); ++it ) {
|
|
|
|
if ( (*it)->mimeType() == mime ) attachments.append( *it );
|
|
|
|
}
|
|
|
|
|
|
|
|
return attachments;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::clearAttachments()
|
|
|
|
{
|
|
|
|
mAttachments.clearAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setResources(const TQStringList &resources)
|
|
|
|
{
|
|
|
|
if (mReadOnly) return;
|
|
|
|
mResources = resources;
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList Incidence::resources() const
|
|
|
|
{
|
|
|
|
return mResources;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Incidence::setPriority(int priority)
|
|
|
|
{
|
|
|
|
if (mReadOnly) return;
|
|
|
|
mPriority = priority;
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
int Incidence::priority() const
|
|
|
|
{
|
|
|
|
return mPriority;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::seStatus(Incidence::Status status)
|
|
|
|
{
|
|
|
|
if (mReadOnly || status == StatusX) return;
|
|
|
|
mStatus = status;
|
|
|
|
mStatusString = TQString();
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setCustomStatus(const TQString &status)
|
|
|
|
{
|
|
|
|
if (mReadOnly) return;
|
|
|
|
mStatus = status.isEmpty() ? StatusNone : StatusX;
|
|
|
|
mStatusString = status;
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
Incidence::Status Incidence::status() const
|
|
|
|
{
|
|
|
|
return mStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Incidence::statusStr() const
|
|
|
|
{
|
|
|
|
if (mStatus == StatusX)
|
|
|
|
return mStatusString;
|
|
|
|
return statusName(mStatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Incidence::statusName(Incidence::Status status)
|
|
|
|
{
|
|
|
|
switch (status) {
|
|
|
|
case StatusTentative: return i18n("incidence status", "Tentative");
|
|
|
|
case StatusConfirmed: return i18n("Confirmed");
|
|
|
|
case StatusCompleted: return i18n("Completed");
|
|
|
|
case StatusNeedsAction: return i18n("Needs-Action");
|
|
|
|
case StatusCanceled: return i18n("Canceled");
|
|
|
|
case StatusInProcess: return i18n("In-Process");
|
|
|
|
case StatusDraft: return i18n("Draft");
|
|
|
|
case StatusFinal: return i18n("Final");
|
|
|
|
case StatusX:
|
|
|
|
case StatusNone:
|
|
|
|
default: return TQString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setSecrecy(int sec)
|
|
|
|
{
|
|
|
|
if (mReadOnly) return;
|
|
|
|
mSecrecy = sec;
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
int Incidence::secrecy() const
|
|
|
|
{
|
|
|
|
return mSecrecy;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Incidence::secrecyStr() const
|
|
|
|
{
|
|
|
|
return secrecyName(mSecrecy);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Incidence::secrecyName(int secrecy)
|
|
|
|
{
|
|
|
|
switch (secrecy) {
|
|
|
|
case SecrecyPublic:
|
|
|
|
return i18n("Public");
|
|
|
|
case SecrecyPrivate:
|
|
|
|
return i18n("Private");
|
|
|
|
case SecrecyConfidential:
|
|
|
|
return i18n("Confidential");
|
|
|
|
default:
|
|
|
|
return i18n("Undefined");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList Incidence::secrecyList()
|
|
|
|
{
|
|
|
|
TQStringList list;
|
|
|
|
list << secrecyName(SecrecyPublic);
|
|
|
|
list << secrecyName(SecrecyPrivate);
|
|
|
|
list << secrecyName(SecrecyConfidential);
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const Alarm::List &Incidence::alarms() const
|
|
|
|
{
|
|
|
|
return mAlarms;
|
|
|
|
}
|
|
|
|
|
|
|
|
Alarm* Incidence::newAlarm()
|
|
|
|
{
|
|
|
|
Alarm* alarm = new Alarm(this);
|
|
|
|
mAlarms.append(alarm);
|
|
|
|
// updated();
|
|
|
|
return alarm;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::addAlarm(Alarm *alarm)
|
|
|
|
{
|
|
|
|
mAlarms.append(alarm);
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::removeAlarm(Alarm *alarm)
|
|
|
|
{
|
|
|
|
mAlarms.removeRef(alarm);
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::clearAlarms()
|
|
|
|
{
|
|
|
|
mAlarms.clearAll();
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Incidence::isAlarmEnabled() const
|
|
|
|
{
|
|
|
|
Alarm::List::ConstIterator it;
|
|
|
|
for( it = mAlarms.begin(); it != mAlarms.end(); ++it ) {
|
|
|
|
if ( (*it)->enabled() ) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setLocation(const TQString &location)
|
|
|
|
{
|
|
|
|
if (mReadOnly) return;
|
|
|
|
mLocation = location;
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Incidence::location() const
|
|
|
|
{
|
|
|
|
return mLocation;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setSchedulingID( const TQString& sid )
|
|
|
|
{
|
|
|
|
mSchedulingID = sid;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Incidence::schedulingID() const
|
|
|
|
{
|
|
|
|
if ( mSchedulingID.isNull() )
|
|
|
|
// Nothing set, so use the normal uid
|
|
|
|
return uid();
|
|
|
|
return mSchedulingID;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Incidence::hasRecurrenceID() const
|
|
|
|
{
|
|
|
|
return mHasRecurrenceID;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setHasRecurrenceID( bool hasRecurrenceID )
|
|
|
|
{
|
|
|
|
if ( mReadOnly ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mHasRecurrenceID = hasRecurrenceID;
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQDateTime Incidence::recurrenceID() const
|
|
|
|
{
|
|
|
|
return mRecurrenceID;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::setRecurrenceID( const TQDateTime &recurrenceID )
|
|
|
|
{
|
|
|
|
if ( mReadOnly ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// update();
|
|
|
|
mRecurrenceID = recurrenceID;
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::addChildIncidence( TQString childIncidence )
|
|
|
|
{
|
|
|
|
mChildRecurrenceEvents.append(childIncidence);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Incidence::deleteChildIncidence( TQString childIncidence )
|
|
|
|
{
|
|
|
|
mChildRecurrenceEvents.remove(childIncidence);
|
|
|
|
}
|
|
|
|
|
|
|
|
IncidenceList Incidence::childIncidences() const
|
|
|
|
{
|
|
|
|
return mChildRecurrenceEvents;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Observer interface for the recurrence class. If the recurrence is changed,
|
|
|
|
this method will be called for the incidence the recurrence object
|
|
|
|
belongs to. */
|
|
|
|
void Incidence::recurrenceUpdated( Recurrence *recurrence )
|
|
|
|
{
|
|
|
|
if ( recurrence == mRecurrence )
|
|
|
|
updated();
|
|
|
|
}
|
|
|
|
|