summaryrefslogtreecommitdiffabout
path: root/libkcal
Side-by-side diff
Diffstat (limited to 'libkcal') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/attachment.cpp38
-rw-r--r--libkcal/attachment.h71
-rw-r--r--libkcal/icalformatimpl.cpp4
-rw-r--r--libkcal/incidence.cpp12
4 files changed, 96 insertions, 29 deletions
diff --git a/libkcal/attachment.cpp b/libkcal/attachment.cpp
index 1ead923..520ac95 100644
--- a/libkcal/attachment.cpp
+++ b/libkcal/attachment.cpp
@@ -1,86 +1,120 @@
/*
This file is part of libkcal.
+
Copyright (c) 2002 Michael Brade <brade@kde.org>
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., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "attachment.h"
using namespace KCal;
+Attachment::Attachment( const Attachment &attachment)
+{
+ mMimeType = attachment.mMimeType;
+ mData = attachment.mData;
+ mBinary = attachment.mBinary;
+ mShowInline = attachment.mShowInline;
+ mLabel = attachment.mLabel;
+}
+
Attachment::Attachment(const QString& uri, const QString& mime)
{
mMimeType = mime;
mData = uri;
mBinary = false;
+ mShowInline = false;
+ mLabel = QString::null;
}
Attachment::Attachment(const char *base64, const QString& mime)
{
mMimeType = mime;
mData = QString::fromUtf8(base64);
mBinary = true;
+ mShowInline = false;
+ mLabel = QString::null;
}
-bool Attachment::isURI() const
+bool Attachment::isUri() const
{
return !mBinary;
}
QString Attachment::uri() const
{
if (!mBinary)
return mData;
else
return QString::null;
}
-void Attachment::setURI(const QString& uri)
+void Attachment::setUri(const QString& uri)
{
mData = uri;
mBinary = false;
}
bool Attachment::isBinary() const
{
return mBinary;
}
char *Attachment::data() const
{
if (mBinary)
return mData.utf8().data();
else
return 0;
}
void Attachment::setData(const char *base64)
{
mData = QString::fromUtf8(base64);
mBinary = true;
}
QString Attachment::mimeType() const
{
return mMimeType;
}
void Attachment::setMimeType(const QString& mime)
{
mMimeType = mime;
}
+bool Attachment::showInline() const
+{
+ return mShowInline;
+}
+
+void Attachment::setShowInline( bool showinline )
+{
+ mShowInline = showinline;
+}
+
+QString Attachment::label() const
+{
+ return mLabel;
+}
+
+void Attachment::setLabel( const QString& label )
+{
+ mLabel = label;
+}
+
diff --git a/libkcal/attachment.h b/libkcal/attachment.h
index cdf2458..5301420 100644
--- a/libkcal/attachment.h
+++ b/libkcal/attachment.h
@@ -1,69 +1,94 @@
/*
This file is part of libkcal.
+
Copyright (c) 2002 Michael Brade <brade@kde.org>
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., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
+#ifndef KCAL_ATTACHMENT_H
+#define KCAL_ATTACHMENT_H
-#ifndef _ATTACHMENT_H
-#define _ATTACHMENT_H
-#include <qstring.h>
+#include <qstring.h>
namespace KCal {
/**
- * This class represents information related to an attachment.
- */
+ This class represents information related to an attachment.
+*/
class Attachment
{
-public:
+ public:
+
/**
- * Create a Reference to some URI.
- * @param uri the uri this attachment refers to
- * @param mime the mime type of the resource being linked to
- */
- Attachment(const QString& uri, const QString& mime = QString::null);
+ Create a Reference to some URI by copying an existing Attachment.
+
+ @param attachment the attachment to be duplicated
+ */
+ Attachment( const Attachment &attachment );
/**
- * Create a binary attachment.
- * @param base64 the attachment in base64 format
- * @param mime the mime type of the attachment
- */
- Attachment(const char *base64, const QString& mime = QString::null);
-
- /* The VALUE parameter in Cal */
- bool isURI() const;
+ Create a Reference to some URI.
+
+ @param uri the uri this attachment refers to
+ @param mime the mime type of the resource being linked to
+ */
+ Attachment( const QString &uri, const QString &mime = QString::null );
+
+ /**
+ Create a binary attachment.
+
+ @param base64 the attachment in base64 format
+ @param mime the mime type of the attachment
+ */
+ Attachment( const char *base64, const QString &mime = QString::null );
+
+ /* The VALUE parameter in iCal */
+ bool isUri() const;
QString uri() const;
- void setURI(const QString& uri);
+ void setUri( const QString &uri );
bool isBinary() const;
char *data() const;
- void setData(const char *base64);
+ void setData( const char *base64 );
/* The optional FMTTYPE parameter in iCal */
QString mimeType() const;
- void setMimeType(const QString& mime);
-private:
+ void setMimeType( const QString &mime );
+
+ /* The custom X-CONTENT-DISPOSITION parameter, used by OGo etc. */
+ bool showInline() const;
+ void setShowInline( bool showinline );
+
+ /* The custom X-LABEL parameter to show a human-readable title */
+ QString label() const;
+ void setLabel( const QString &label );
+
+ private:
QString mMimeType;
QString mData;
bool mBinary;
+ bool mShowInline;
+ QString mLabel;
+
+ class Private;
+ Private *d;
};
}
#endif
diff --git a/libkcal/icalformatimpl.cpp b/libkcal/icalformatimpl.cpp
index 53aa039..65eabc8 100644
--- a/libkcal/icalformatimpl.cpp
+++ b/libkcal/icalformatimpl.cpp
@@ -261,519 +261,519 @@ void ICalFormatImpl::writeIncidence(icalcomponent *parent,Incidence *incidence)
// TODO: move this application-specific code to kpilot
if (incidence->pilotId()) {
incidence->setNonKDECustomProperty("X-PILOTID", QString::number(incidence->pilotId()));
incidence->setNonKDECustomProperty("X-PILOTSTAT", QString::number(incidence->syncStatus()));
}
if ( !incidence->IDStr().isEmpty()) {
incidence->setNonKDECustomProperty("X-KOPIEXTID",incidence->IDStr() );
}
writeIncidenceBase(parent,incidence);
if (incidence->cancelled()) {
icalcomponent_add_property(parent,icalproperty_new_status(ICAL_STATUS_CANCELLED));
}
// creation date
icalcomponent_add_property(parent,icalproperty_new_created(
writeICalDateTime(incidence->created())));
// unique id
icalcomponent_add_property(parent,icalproperty_new_uid(
incidence->uid().utf8()));
// revision
icalcomponent_add_property(parent,icalproperty_new_sequence(
incidence->revision()));
// last modification date
icalcomponent_add_property(parent,icalproperty_new_lastmodified(
writeICalDateTime(incidence->lastModified())));
// description
if (!incidence->description().isEmpty()) {
icalcomponent_add_property(parent,icalproperty_new_description(
incidence->description().utf8()));
}
// summary
if (!incidence->summary().isEmpty()) {
icalcomponent_add_property(parent,icalproperty_new_summary(
incidence->summary().utf8()));
}
// location
if (!incidence->location().isEmpty()) {
icalcomponent_add_property(parent,icalproperty_new_location(
incidence->location().utf8()));
}
// TODO:
// status
// addPropValue(parent, VCStatusProp, incidence->getStatusStr().utf8());
// secrecy
enum icalproperty_class classInt;
switch (incidence->secrecy()) {
case Incidence::SecrecyPublic:
classInt = ICAL_CLASS_PUBLIC;
break;
case Incidence::SecrecyConfidential:
classInt = ICAL_CLASS_CONFIDENTIAL;
break;
case Incidence::SecrecyPrivate:
classInt =ICAL_CLASS_PRIVATE ;
default:
classInt =ICAL_CLASS_PRIVATE ;
break;
}
icalcomponent_add_property(parent,icalproperty_new_class(classInt));
// priority
icalcomponent_add_property(parent,icalproperty_new_priority(
incidence->priority()));
// categories
QStringList categories = incidence->categories();
QStringList::Iterator it;
for(it = categories.begin(); it != categories.end(); ++it ) {
icalcomponent_add_property(parent,icalproperty_new_categories((*it).utf8()));
}
// TODO: Ensure correct concatenation of categories properties.
/*
// categories
tmpStrList = incidence->getCategories();
tmpStr = "";
QString catStr;
for ( QStringList::Iterator it = tmpStrList.begin();
it != tmpStrList.end();
++it ) {
catStr = *it;
if (catStr[0] == ' ')
tmpStr += catStr.mid(1);
else
tmpStr += catStr;
// this must be a ';' character as the vCalendar specification requires!
// vcc.y has been hacked to translate the ';' to a ',' when the vcal is
// read in.
tmpStr += ";";
}
if (!tmpStr.isEmpty()) {
tmpStr.truncate(tmpStr.length()-1);
icalcomponent_add_property(parent,icalproperty_new_categories(
writeText(incidence->getCategories().join(";"))));
}
*/
// related event
if (!incidence->relatedToUid().isEmpty()) {
icalcomponent_add_property(parent,icalproperty_new_relatedto(
incidence->relatedToUid().utf8()));
}
// recurrence rule stuff
if (incidence->doesRecur()) {
icalcomponent_add_property(parent,writeRecurrenceRule(incidence->recurrence()));
// recurrence excpetion dates
DateList dateList = incidence->exDates();
DateList::ConstIterator exIt;
for(exIt = dateList.begin(); exIt != dateList.end(); ++exIt) {
icalcomponent_add_property(parent,icalproperty_new_exdate(
writeICalDate(*exIt)));
}
}
// attachments
QPtrList<Attachment> attachments = incidence->attachments();
for (Attachment *at = attachments.first(); at; at = attachments.next())
icalcomponent_add_property(parent,writeAttachment(at));
// alarms
QPtrList<Alarm> alarms = incidence->alarms();
Alarm* alarm;
for (alarm = alarms.first(); alarm; alarm = alarms.next()) {
if (alarm->enabled()) {
kdDebug(5800) << "Write alarm for " << incidence->summary() << endl;
icalcomponent_add_component(parent,writeAlarm(alarm));
}
}
if( incidence->hasRecurrenceID() ) {
icalcomponent_add_property(parent,
icalproperty_new_recurrenceid( writeICalDateTime( incidence->recurrenceID())));
}
// duration
// turned off as it always is set to PTS0 (and must not occur together with DTEND
if (incidence->hasDuration()) {
icaldurationtype duration;
duration = writeICalDuration(incidence->duration());
icalcomponent_add_property(parent,icalproperty_new_duration(duration));
}
}
void ICalFormatImpl::writeIncidenceBase(icalcomponent *parent,IncidenceBase *incidenceBase)
{
icalcomponent_add_property(parent,icalproperty_new_dtstamp(
writeICalDateTime(QDateTime::currentDateTime())));
// organizer stuff
icalcomponent_add_property(parent,icalproperty_new_organizer(
("MAILTO:" + incidenceBase->organizer()).utf8()));
// attendees
if (incidenceBase->attendeeCount() != 0) {
QPtrList<Attendee> al = incidenceBase->attendees();
QPtrListIterator<Attendee> ai(al);
for (; ai.current(); ++ai) {
icalcomponent_add_property(parent,writeAttendee(ai.current()));
}
}
// custom properties
writeCustomProperties(parent, incidenceBase);
}
void ICalFormatImpl::writeCustomProperties(icalcomponent *parent,CustomProperties *properties)
{
QMap<QCString, QString> custom = properties->customProperties();
for (QMap<QCString, QString>::Iterator c = custom.begin(); c != custom.end(); ++c) {
icalproperty *p = icalproperty_new_x(c.data().utf8());
icalproperty_set_x_name(p,c.key());
icalcomponent_add_property(parent,p);
}
}
icalproperty *ICalFormatImpl::writeAttendee(Attendee *attendee)
{
icalproperty *p = icalproperty_new_attendee("mailto:" + attendee->email().utf8());
if (!attendee->name().isEmpty()) {
icalproperty_add_parameter(p,icalparameter_new_cn(attendee->name().utf8()));
}
icalproperty_add_parameter(p,icalparameter_new_rsvp(
attendee->RSVP() ? ICAL_RSVP_TRUE : ICAL_RSVP_FALSE ));
icalparameter_partstat status = ICAL_PARTSTAT_NEEDSACTION;
switch (attendee->status()) {
default:
case Attendee::NeedsAction:
status = ICAL_PARTSTAT_NEEDSACTION;
break;
case Attendee::Accepted:
status = ICAL_PARTSTAT_ACCEPTED;
break;
case Attendee::Declined:
status = ICAL_PARTSTAT_DECLINED;
break;
case Attendee::Tentative:
status = ICAL_PARTSTAT_TENTATIVE;
break;
case Attendee::Delegated:
status = ICAL_PARTSTAT_DELEGATED;
break;
case Attendee::Completed:
status = ICAL_PARTSTAT_COMPLETED;
break;
case Attendee::InProcess:
status = ICAL_PARTSTAT_INPROCESS;
break;
}
icalproperty_add_parameter(p,icalparameter_new_partstat(status));
icalparameter_role role = ICAL_ROLE_REQPARTICIPANT;
switch (attendee->role()) {
case Attendee::Chair:
role = ICAL_ROLE_CHAIR;
break;
default:
case Attendee::ReqParticipant:
role = ICAL_ROLE_REQPARTICIPANT;
break;
case Attendee::OptParticipant:
role = ICAL_ROLE_OPTPARTICIPANT;
break;
case Attendee::NonParticipant:
role = ICAL_ROLE_NONPARTICIPANT;
break;
}
icalproperty_add_parameter(p,icalparameter_new_role(role));
if (!attendee->uid().isEmpty()) {
icalparameter* icalparameter_uid = icalparameter_new_x(attendee->uid().utf8());
icalparameter_set_xname(icalparameter_uid,"X-UID");
icalproperty_add_parameter(p,icalparameter_uid);
}
return p;
}
icalproperty *ICalFormatImpl::writeAttachment(Attachment *att)
{
#if 0
icalattachtype* attach = icalattachtype_new();
- if (att->isURI())
+ if (att->isUri())
icalattachtype_set_url(attach, att->uri().utf8().data());
else
icalattachtype_set_base64(attach, att->data(), 0);
#endif
icalattach *attach;
- if (att->isURI())
+ if (att->isUri())
attach = icalattach_new_from_url( att->uri().utf8().data());
else
attach = icalattach_new_from_data ( (unsigned char *)att->data(), 0, 0);
icalproperty *p = icalproperty_new_attach(attach);
if (!att->mimeType().isEmpty())
icalproperty_add_parameter(p,icalparameter_new_fmttype(att->mimeType().utf8().data()));
if (att->isBinary()) {
icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_BINARY));
icalproperty_add_parameter(p,icalparameter_new_encoding(ICAL_ENCODING_BASE64));
}
return p;
}
icalproperty *ICalFormatImpl::writeRecurrenceRule(Recurrence *recur)
{
// kdDebug(5800) << "ICalFormatImpl::writeRecurrenceRule()" << endl;
icalrecurrencetype r;
icalrecurrencetype_clear(&r);
int index = 0;
int index2 = 0;
QPtrList<Recurrence::rMonthPos> tmpPositions;
QPtrList<int> tmpDays;
int *tmpDay;
Recurrence::rMonthPos *tmpPos;
bool datetime = false;
int day;
int i;
switch(recur->doesRecur()) {
case Recurrence::rMinutely:
r.freq = ICAL_MINUTELY_RECURRENCE;
datetime = true;
break;
case Recurrence::rHourly:
r.freq = ICAL_HOURLY_RECURRENCE;
datetime = true;
break;
case Recurrence::rDaily:
r.freq = ICAL_DAILY_RECURRENCE;
break;
case Recurrence::rWeekly:
r.freq = ICAL_WEEKLY_RECURRENCE;
r.week_start = static_cast<icalrecurrencetype_weekday>(recur->weekStart()%7 + 1);
for (i = 0; i < 7; i++) {
if (recur->days().testBit(i)) {
day = (i + 1)%7 + 1; // convert from Monday=0 to Sunday=1
r.by_day[index++] = icalrecurrencetype_day_day_of_week(day);
}
}
// r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX;
break;
case Recurrence::rMonthlyPos:
r.freq = ICAL_MONTHLY_RECURRENCE;
tmpPositions = recur->monthPositions();
for (tmpPos = tmpPositions.first();
tmpPos;
tmpPos = tmpPositions.next()) {
for (i = 0; i < 7; i++) {
if (tmpPos->rDays.testBit(i)) {
day = (i + 1)%7 + 1; // convert from Monday=0 to Sunday=1
day += tmpPos->rPos*8;
if (tmpPos->negative) day = -day;
r.by_day[index++] = day;
}
}
}
// r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX;
break;
case Recurrence::rMonthlyDay:
r.freq = ICAL_MONTHLY_RECURRENCE;
tmpDays = recur->monthDays();
for (tmpDay = tmpDays.first();
tmpDay;
tmpDay = tmpDays.next()) {
r.by_month_day[index++] = icalrecurrencetype_day_position(*tmpDay*8);//*tmpDay);
}
// r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX;
break;
case Recurrence::rYearlyMonth:
case Recurrence::rYearlyPos:
r.freq = ICAL_YEARLY_RECURRENCE;
tmpDays = recur->yearNums();
for (tmpDay = tmpDays.first();
tmpDay;
tmpDay = tmpDays.next()) {
r.by_month[index++] = *tmpDay;
}
// r.by_set_pos[index] = ICAL_RECURRENCE_ARRAY_MAX;
if (recur->doesRecur() == Recurrence::rYearlyPos) {
tmpPositions = recur->monthPositions();
for (tmpPos = tmpPositions.first();
tmpPos;
tmpPos = tmpPositions.next()) {
for (i = 0; i < 7; i++) {
if (tmpPos->rDays.testBit(i)) {
day = (i + 1)%7 + 1; // convert from Monday=0 to Sunday=1
day += tmpPos->rPos*8;
if (tmpPos->negative) day = -day;
r.by_day[index2++] = day;
}
}
}
// r.by_day[index2] = ICAL_RECURRENCE_ARRAY_MAX;
}
break;
case Recurrence::rYearlyDay:
r.freq = ICAL_YEARLY_RECURRENCE;
tmpDays = recur->yearNums();
for (tmpDay = tmpDays.first();
tmpDay;
tmpDay = tmpDays.next()) {
r.by_year_day[index++] = *tmpDay;
}
// r.by_year_day[index] = ICAL_RECURRENCE_ARRAY_MAX;
break;
default:
r.freq = ICAL_NO_RECURRENCE;
kdDebug(5800) << "ICalFormatImpl::writeRecurrence(): no recurrence" << endl;
break;
}
r.interval = recur->frequency();
if (recur->duration() > 0) {
r.count = recur->duration();
} else if (recur->duration() == -1) {
r.count = 0;
} else {
if (datetime)
r.until = writeICalDateTime(recur->endDateTime());
else
r.until = writeICalDate(recur->endDate());
}
// Debug output
#if 0
const char *str = icalrecurrencetype_as_string(&r);
if (str) {
kdDebug(5800) << " String: " << str << endl;
} else {
kdDebug(5800) << " No String" << endl;
}
#endif
return icalproperty_new_rrule(r);
}
icalcomponent *ICalFormatImpl::writeAlarm(Alarm *alarm)
{
icalcomponent *a = icalcomponent_new(ICAL_VALARM_COMPONENT);
icalproperty_action action;
icalattach *attach = 0;
switch (alarm->type()) {
case Alarm::Procedure:
action = ICAL_ACTION_PROCEDURE;
attach = icalattach_new_from_url( QFile::encodeName(alarm->programFile()).data() );
icalcomponent_add_property(a,icalproperty_new_attach(attach));
if (!alarm->programArguments().isEmpty()) {
icalcomponent_add_property(a,icalproperty_new_description(alarm->programArguments().utf8()));
}
icalattach_unref( attach );
break;
case Alarm::Audio:
action = ICAL_ACTION_AUDIO;
if (!alarm->audioFile().isEmpty()) {
attach = icalattach_new_from_url(QFile::encodeName( alarm->audioFile() ).data());
icalcomponent_add_property(a,icalproperty_new_attach(attach));
icalattach_unref( attach );
}
break;
case Alarm::Email: {
action = ICAL_ACTION_EMAIL;
QValueList<Person> addresses = alarm->mailAddresses();
for (QValueList<Person>::Iterator ad = addresses.begin(); ad != addresses.end(); ++ad) {
icalproperty *p = icalproperty_new_attendee("MAILTO:" + (*ad).email().utf8());
if (!(*ad).name().isEmpty()) {
icalproperty_add_parameter(p,icalparameter_new_cn((*ad).name().utf8()));
}
icalcomponent_add_property(a,p);
}
icalcomponent_add_property(a,icalproperty_new_summary(alarm->mailSubject().utf8()));
icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8()));
QStringList attachments = alarm->mailAttachments();
if (attachments.count() > 0) {
for (QStringList::Iterator at = attachments.begin(); at != attachments.end(); ++at) {
attach = icalattach_new_from_url(QFile::encodeName( *at ).data());
icalcomponent_add_property(a,icalproperty_new_attach(attach));
icalattach_unref( attach );
}
}
break;
}
case Alarm::Display:
action = ICAL_ACTION_DISPLAY;
icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8()));
break;
case Alarm::Invalid:
default:
kdDebug(5800) << "Unknown type of alarm" << endl;
action = ICAL_ACTION_NONE;
break;
}
icalcomponent_add_property(a,icalproperty_new_action(action));
// Trigger time
icaltriggertype trigger;
if ( alarm->hasTime() ) {
trigger.time = writeICalDateTime(alarm->time());
trigger.duration = icaldurationtype_null_duration();
} else {
trigger.time = icaltime_null_time();
Duration offset;
if ( alarm->hasStartOffset() )
offset = alarm->startOffset();
else
offset = alarm->endOffset();
trigger.duration = icaldurationtype_from_int( offset.asSeconds() );
}
icalproperty *p = icalproperty_new_trigger(trigger);
if ( alarm->hasEndOffset() )
icalproperty_add_parameter(p,icalparameter_new_related(ICAL_RELATED_END));
icalcomponent_add_property(a,p);
// Repeat count and duration
if (alarm->repeatCount()) {
icalcomponent_add_property(a,icalproperty_new_repeat(alarm->repeatCount()));
icalcomponent_add_property(a,icalproperty_new_duration(
icaldurationtype_from_int(alarm->snoozeTime()*60)));
}
// Custom properties
QMap<QCString, QString> custom = alarm->customProperties();
for (QMap<QCString, QString>::Iterator c = custom.begin(); c != custom.end(); ++c) {
icalproperty *p = icalproperty_new_x(c.data().utf8());
icalproperty_set_x_name(p,c.key());
icalcomponent_add_property(a,p);
}
return a;
}
Todo *ICalFormatImpl::readTodo(icalcomponent *vtodo)
{
Todo *todo = new Todo;
diff --git a/libkcal/incidence.cpp b/libkcal/incidence.cpp
index 549014e..39c14f5 100644
--- a/libkcal/incidence.cpp
+++ b/libkcal/incidence.cpp
@@ -1,318 +1,325 @@
/*
This file is part of libkcal.
Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
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., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include <kglobal.h>
#include <klocale.h>
#include <kdebug.h>
#include "calformat.h"
#include "incidence.h"
#include "todo.h"
using namespace KCal;
Incidence::Incidence() :
IncidenceBase(),
mRelatedTo(0), mSecrecy(SecrecyPublic), mPriority(3)
{
mRecurrence = 0;//new Recurrence(this);
mCancelled = false;
recreate();
mHasStartDate = true;
mAlarms.setAutoDelete(true);
mAttachments.setAutoDelete(true);
mHasRecurrenceID = false;
mHoliday = false;
mBirthday = false;
mAnniversary = false;
}
Incidence::Incidence( const Incidence &i ) : IncidenceBase( i )
{
// 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;
+ mRelatedToUid = i.mRelatedToUid;
// QPtrList<Incidence> mRelations; QPtrList<Incidence> mRelations;
mExDates = i.mExDates;
- mAttachments = i.mAttachments;
+ QPtrListIterator<Attachment> itat( i.mAttachments );
+ Attachment *at;
+ while( (at = itat.current()) ) {
+ Attachment *a = new Attachment( *at );
+ mAttachments.append( a );
+ ++itat;
+ }
+ mAttachments.setAutoDelete( true );
mResources = i.mResources;
mSecrecy = i.mSecrecy;
mPriority = i.mPriority;
mLocation = i.mLocation;
mCancelled = i.mCancelled;
mHasStartDate = i.mHasStartDate;
QPtrListIterator<Alarm> it( i.mAlarms );
const Alarm *a;
while( (a = it.current()) ) {
Alarm *b = new Alarm( *a );
b->setParent( this );
mAlarms.append( b );
++it;
}
mAlarms.setAutoDelete(true);
mHasRecurrenceID = i.mHasRecurrenceID;
mRecurrenceID = i.mRecurrenceID;
if ( i.mRecurrence )
mRecurrence = new Recurrence( *(i.mRecurrence), this );
else
mRecurrence = 0;
mHoliday = i.mHoliday ;
mBirthday = i.mBirthday;
mAnniversary = i.mAnniversary;
}
Incidence::~Incidence()
{
Incidence *ev;
QPtrList<Incidence> Relations = relations();
for (ev=Relations.first();ev;ev=Relations.next()) {
if (ev->relatedTo() == this) ev->setRelatedTo(0);
}
if (relatedTo()) relatedTo()->removeRelation(this);
if ( mRecurrence )
delete mRecurrence;
}
QString Incidence::durationText()
{
return "---";
}
QString Incidence::durationText4Time( int offset )
{
int min = offset/60;
int hours = min /60;
min = min % 60;
int days = hours /24;
hours = hours % 24;
if ( doesFloat() || ( min == 0 && hours == 0 ) ) {
if ( days == 1 )
return "1" + i18n(" day");
else
return QString::number( days )+ i18n(" days");
}
QString message = QString::number ( hours ) +":";
if ( min < 10 ) message += "0";
message += QString::number ( min );
if ( days > 0 ) {
if ( days == 1 )
message = "1" + i18n(" day") + " "+message;
else
message = QString::number( days )+ i18n(" days") + " "+message;
}
return message;
}
bool Incidence::isHoliday() const
{
return mHoliday;
}
bool Incidence::isBirthday() const
{
return mBirthday ;
}
bool Incidence::isAnniversary() const
{
return mAnniversary ;
}
bool Incidence::hasRecurrenceID() const
{
return mHasRecurrenceID;
}
void Incidence::setHasRecurrenceID( bool b )
{
mHasRecurrenceID = b;
}
void Incidence::setRecurrenceID(QDateTime d)
{
mRecurrenceID = d;
mHasRecurrenceID = true;
updated();
}
QDateTime Incidence::recurrenceID () const
{
return mRecurrenceID;
}
bool Incidence::cancelled() const
{
return mCancelled;
}
void Incidence::setCancelled( bool b )
{
mCancelled = b;
updated();
}
bool Incidence::hasStartDate() const
{
return mHasStartDate;
}
void Incidence::setHasStartDate(bool f)
{
if (mReadOnly) return;
mHasStartDate = f;
updated();
}
// A string comparison that considers that null and empty are the same
static bool stringCompare( const QString& s1, const QString& s2 )
{
if ( s1.isEmpty() && s2.isEmpty() )
return true;
return s1 == s2;
}
bool KCal::operator==( const Incidence& i1, const Incidence& i2 )
{
if( i1.alarms().count() != i2.alarms().count() ) {
return false; // no need to check further
}
if ( i1.alarms().count() > 0 ) {
if ( !( *(i1.alarms().first()) == *(i2.alarms().first())) )
{
qDebug("alarm not equal ");
return false;
}
}
#if 0
QPtrListIterator<Alarm> a1( i1.alarms() );
QPtrListIterator<Alarm> a2( i2.alarms() );
for( ; a1.current() && a2.current(); ++a1, ++a2 ) {
if( *a1.current() == *a2.current() ) {
continue;
}
else {
return false;
}
}
#endif
if ( i1.hasRecurrenceID() == i2.hasRecurrenceID() ) {
if ( i1.hasRecurrenceID() ) {
if ( i1.recurrenceID() != i2.recurrenceID() )
return false;
}
} else {
return false;
}
if ( ! operator==( (const IncidenceBase&)i1, (const IncidenceBase&)i2 ) )
return false;
if ( i1.hasStartDate() == i2.hasStartDate() ) {
if ( i1.hasStartDate() ) {
if ( i1.dtStart() != i2.dtStart() )
return false;
}
} else {
return false;
}
if ( i1.mRecurrence != 0 && i2.mRecurrence != 0 ) {
if (!( *i1.mRecurrence == *i2.mRecurrence) ) {
//qDebug("recurrence is NOT equal ");
return false;
}
} else {
// one ( or both ) recurrence is 0
if ( i1.mRecurrence == 0 ) {
if ( i2.mRecurrence != 0 && i2.mRecurrence->doesRecur() != Recurrence::rNone )
return false;
} else {
// i1.mRecurrence != 0
// i2.mRecurrence == 0
if ( i1.mRecurrence->doesRecur() != Recurrence::rNone )
return false;
}
}
return
// i1.created() == i2.created() &&
stringCompare( i1.description(), i2.description() ) &&
stringCompare( i1.summary(), i2.summary() ) &&
i1.categories() == i2.categories() &&
// no need to compare mRelatedTo
stringCompare( i1.relatedToUid(), i2.relatedToUid() ) &&
// i1.relations() == i2.relations() &&
i1.exDates() == i2.exDates() &&
i1.attachments() == i2.attachments() &&
i1.resources() == i2.resources() &&
i1.secrecy() == i2.secrecy() &&
i1.priority() == i2.priority() &&
i1.cancelled() == i2.cancelled() &&
stringCompare( i1.location(), i2.location() );
}
Incidence* Incidence::recreateCloneException( QDate d )
{
Incidence* newInc = clone();
newInc->recreate();
if ( doesRecur() ) {
addExDate( d );
newInc->recurrence()->unsetRecurs();
if ( typeID() == eventID ) {
int len = dtStart().secsTo( ((Event*)this)->dtEnd());
QTime tim = dtStart().time();
newInc->setDtStart( QDateTime(d, tim) );
((Event*)newInc)->setDtEnd( newInc->dtStart().addSecs( len ) );
} else {
int len = dtStart().secsTo( ((Todo*)this)->dtDue());
QTime tim = ((Todo*)this)->dtDue().time();
((Todo*)newInc)->setDtDue( QDateTime(d, tim) );
((Todo*)newInc)->setDtStart( ((Todo*)newInc)->dtDue().addSecs( -len ) );
((Todo*)this)->setRecurDates();
}
newInc->setExDates( DateList () );
}
return newInc;
}
void Incidence::recreate()
{
setCreated(QDateTime::currentDateTime());
setUid(CalFormat::createUniqueId());
setRevision(0);
setIDStr( ":" );
setLastModified(QDateTime::currentDateTime());
}
void Incidence::cloneRelations( Incidence * newInc )
{
// newInc is already a clone of this incidence
Incidence * inc;
Incidence * cloneInc;
QPtrList<Incidence> Relations = relations();
@@ -504,342 +511,343 @@ QString Incidence::relatedToUid() const
void Incidence::setRelatedTo(Incidence *relatedTo)
{
//qDebug("Incidence::setRelatedTo %d ", relatedTo);
//qDebug("setRelatedTo(Incidence *relatedTo) %s %s", summary().latin1(), relatedTo->summary().latin1() );
if (mReadOnly || mRelatedTo == relatedTo) return;
if(mRelatedTo) {
// updated();
mRelatedTo->removeRelation(this);
}
mRelatedTo = relatedTo;
if (mRelatedTo) {
mRelatedTo->addRelation(this);
mRelatedToUid = mRelatedTo->uid();
} else {
mRelatedToUid = "";
}
}
Incidence *Incidence::relatedTo() const
{
return mRelatedTo;
}
QPtrList<Incidence> Incidence::relations() const
{
return mRelations;
}
void Incidence::addRelationsToList(QPtrList<Incidence> *rel)
{
Incidence* inc;
QPtrList<Incidence> Relations = relations();
for (inc=Relations.first();inc;inc=Relations.next()) {
inc->addRelationsToList( rel );
}
if ( rel->findRef( this ) == -1 )
rel->append( this );
}
void Incidence::addRelation(Incidence *event)
{
setLastModifiedSubInvalid();
if( mRelations.findRef( event ) == -1 ) {
mRelations.append(event);
//updated();
}
}
void Incidence::removeRelation(Incidence *event)
{
setLastModifiedSubInvalid();
mRelations.removeRef(event);
// if (event->getRelatedTo() == this) event->setRelatedTo(0);
}
bool Incidence::recursOn(const QDate &qd) const
{
if (mRecurrence && mRecurrence->recursOnPure(qd) && !isException(qd)) return true;
else return false;
}
void Incidence::setExDates(const DateList &exDates)
{
if (mReadOnly) return;
mExDates = exDates;
recurrence()->setRecurExDatesCount(mExDates.count());
updated();
}
void Incidence::addExDate(const QDate &date)
{
if (mReadOnly) return;
mExDates.append(date);
recurrence()->setRecurExDatesCount(mExDates.count());
updated();
}
DateList Incidence::exDates() const
{
return mExDates;
}
bool Incidence::isException(const QDate &date) const
{
DateList::ConstIterator it;
for( it = mExDates.begin(); it != mExDates.end(); ++it ) {
if ( (*it) == date ) {
return true;
}
}
return false;
}
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 QString& mime)
{
Attachment *at = mAttachments.first();
while (at) {
if (at->mimeType() == mime)
mAttachments.remove();
else
at = mAttachments.next();
}
}
QPtrList<Attachment> Incidence::attachments() const
{
return mAttachments;
}
QPtrList<Attachment> Incidence::attachments(const QString& mime) const
{
QPtrList<Attachment> attachments;
QPtrListIterator<Attachment> it( mAttachments );
Attachment *at;
while ( (at = it.current()) ) {
if (at->mimeType() == mime)
attachments.append(at);
++it;
}
return attachments;
}
void Incidence::setResources(const QStringList &resources)
{
if (mReadOnly) return;
mResources = resources;
updated();
}
QStringList Incidence::resources() const
{
return mResources;
}
void Incidence::setPriority(int priority)
{
if (mReadOnly) return;
mPriority = priority;
updated();
}
int Incidence::priority() const
{
return mPriority;
}
void Incidence::setSecrecy(int sec)
{
if (mReadOnly) return;
mSecrecy = sec;
updated();
}
int Incidence::secrecy() const
{
return mSecrecy;
}
QString Incidence::secrecyStr() const
{
return secrecyName(mSecrecy);
}
QString Incidence::secrecyName(int secrecy)
{
switch (secrecy) {
case SecrecyPublic:
return i18n("Public");
break;
case SecrecyPrivate:
return i18n("Private");
break;
case SecrecyConfidential:
return i18n("Confidential");
break;
default:
return i18n("Undefined");
break;
}
}
QStringList Incidence::secrecyList()
{
QStringList list;
list << secrecyName(SecrecyPublic);
list << secrecyName(SecrecyPrivate);
list << secrecyName(SecrecyConfidential);
return list;
}
QPtrList<Alarm> 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.clear();
updated();
}
bool Incidence::isAlarmEnabled() const
{
Alarm* alarm;
for (QPtrListIterator<Alarm> it(mAlarms); (alarm = it.current()) != 0; ++it) {
if (alarm->enabled())
return true;
}
return false;
}
#include <stdlib.h>
Recurrence *Incidence::recurrence()
{
if ( ! mRecurrence ) {
mRecurrence = new Recurrence(this);
mRecurrence->setRecurStart( dtStart() );
+ mRecurrence->setRecurReadOnly( isReadOnly());
//qDebug("creating new recurence ");
//abort();
}
return mRecurrence;
}
void Incidence::setRecurrence( Recurrence * r)
{
if ( mRecurrence )
delete mRecurrence;
mRecurrence = r;
}
void Incidence::setLocation(const QString &location)
{
if (mReadOnly) return;
mLocation = location;
updated();
}
QString Incidence::location() const
{
return mLocation;
}
QString Incidence::recurrenceText() const
{
if ( mRecurrence ) return mRecurrence->recurrenceText();
return i18n("No");
}
ushort Incidence::doesRecur() const
{
if ( mRecurrence ) return mRecurrence->doesRecur();
else return Recurrence::rNone;
}
QDateTime Incidence::getNextOccurence( const QDateTime& dt, bool* ok ) const
{
QDateTime incidenceStart = dt;
*ok = false;
if ( doesRecur() ) {
bool last;
mRecurrence->getPreviousDateTime( incidenceStart , &last );
int count = 0;
if ( !last ) {
while ( !last ) {
++count;
incidenceStart = mRecurrence->getNextDateTime( incidenceStart, &last );
if ( recursOn( incidenceStart.date() ) ) {
last = true; // exit while llop
} else {
if ( last ) { // no alarm on last recurrence
return QDateTime ();
}
int year = incidenceStart.date().year();
// workaround for bug in recurrence
if ( count == 100 || year < 1000 || year > 5000 ) {
return QDateTime ();
}
incidenceStart = incidenceStart.addSecs( 1 );
}
}
} else {
return QDateTime ();
}
} else {
if ( hasStartDate () ) {
incidenceStart = dtStart();
}
if ( typeID() == todoID ) {
if ( ((Todo*)this)->hasDueDate() )
incidenceStart = ((Todo*)this)->dtDue();
}
}
if ( incidenceStart > dt )
*ok = true;
return incidenceStart;
}
QDateTime Incidence::dtStart() const
{
if ( doesRecur() ) {
if ( typeID() == todoID ) {
((Todo*)this)->checkSetCompletedFalse();
}
}
return mDtStart;
}