summaryrefslogtreecommitdiffabout
path: root/libkcal
authorzautrix <zautrix>2005-07-29 20:08:52 (UTC)
committer zautrix <zautrix>2005-07-29 20:08:52 (UTC)
commite287df45507793e2e5ad16085a858153f3798941 (patch) (side-by-side diff)
treef91ff66a8ac59254b9a0158e55d6254ca2928d75 /libkcal
parent48a8fa71f1985fea9df4981808796ef65f0f974a (diff)
downloadkdepimpi-e287df45507793e2e5ad16085a858153f3798941.zip
kdepimpi-e287df45507793e2e5ad16085a858153f3798941.tar.gz
kdepimpi-e287df45507793e2e5ad16085a858153f3798941.tar.bz2
fixx
Diffstat (limited to 'libkcal') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/calendarlocal.cpp2
-rw-r--r--libkcal/icalformatimpl.cpp11
-rw-r--r--libkcal/journal.cpp2
3 files changed, 10 insertions, 5 deletions
diff --git a/libkcal/calendarlocal.cpp b/libkcal/calendarlocal.cpp
index eef8327..5baa7dc 100644
--- a/libkcal/calendarlocal.cpp
+++ b/libkcal/calendarlocal.cpp
@@ -1,1025 +1,1025 @@
/*
This file is part of libkcal.
Copyright (c) 1998 Preston Brown
Copyright (c) 2001,2003 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 <qdatetime.h>
#include <qstring.h>
#include <qptrlist.h>
#include <kdebug.h>
#include <kconfig.h>
#include <kglobal.h>
#include <klocale.h>
#include "vcaldrag.h"
#include "vcalformat.h"
#include "icalformat.h"
#include "exceptions.h"
#include "incidence.h"
#include "journal.h"
#include "filestorage.h"
#include "calfilter.h"
#include "calendarlocal.h"
// #ifndef DESKTOP_VERSION
// #include <qtopia/alarmserver.h>
// #endif
using namespace KCal;
CalendarLocal::CalendarLocal()
: Calendar()
{
init();
}
CalendarLocal::CalendarLocal(const QString &timeZoneId)
: Calendar(timeZoneId)
{
init();
}
void CalendarLocal::init()
{
mNextAlarmIncidence = 0;
}
CalendarLocal::~CalendarLocal()
{
registerObserver( 0 );
if ( mDeleteIncidencesOnClose )
close();
}
bool CalendarLocal::mergeCalendarFile( QString name )
{
CalendarLocal calendar( timeZoneId() );
calendar.setDefaultCalendar( 1 );
if ( calendar.load( name ) ) {
mergeCalendar( &calendar );
return true;
}
return false;
}
Incidence* CalendarLocal::incidenceForUid( const QString& uid , bool doNotCheckDuplicates)
{
Todo *todo;;
Incidence *retVal = 0;
for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) {
if ( todo->uid() == uid ) {
if ( doNotCheckDuplicates ) return todo;
if ( retVal ) {
if ( retVal->calID() > todo->calID() ) {
retVal = todo;
}
} else {
retVal = todo;
}
}
}
if ( retVal ) return retVal;
Event *event;
for ( event = mEventList.first(); event; event = mEventList.next() ) {
if ( event->uid() == uid ) {
if ( doNotCheckDuplicates ) return event;
if ( retVal ) {
if ( retVal->calID() > event->calID() ) {
retVal = event;
}
} else {
retVal = event;
}
}
}
if ( retVal ) return retVal;
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->uid() == uid ) {
if ( doNotCheckDuplicates ) return it;
if ( retVal ) {
if ( retVal->calID() > it->calID() ) {
retVal = it;
}
} else {
retVal = it;
}
}
return retVal;
}
bool CalendarLocal::mergeCalendar( Calendar* remote )
{
// 1 look for raw inc in local
// if inc not in remote, delete in local
// 2 look for raw inc in remote
// if inc in local, replace it
// if not in local, add it to default calendar
QPtrList<Incidence> localInc = rawIncidences();
Incidence* inL = localInc.first();
while ( inL ) {
if ( ! inL->isReadOnly () )
if ( !remote->incidenceForUid( inL->uid(), true ))
deleteIncidence( inL );
inL = localInc.next();
}
QPtrList<Incidence> er = remote->rawIncidences();
Incidence* inR = er.first();
while ( inR ) {
inL = incidenceForUid( inR->uid(),false );
if ( inL ) {
if ( ! inL->isReadOnly () || inL->uid().left(15) == QString("last-syncEvent-") ) {
int calID = inL->calID();
deleteIncidence( inL );
inL = inR->clone();
inL->setCalID( calID );
addIncidence( inL );
}
} else {
inL = inR->clone();
inL->setCalID( 0 );// add to default cal
addIncidence( inL );
}
inR = er.next();
}
return true;
}
bool CalendarLocal::addCalendarFile( QString name, int id )
{
CalendarLocal calendar( timeZoneId() );
calendar.setDefaultCalendar( id );
if ( calendar.load( name ) ) {
addCalendar( &calendar );
return true;
}
return false;
}
void CalendarLocal::setSyncEventsReadOnly()
{
Event * ev;
ev = mEventList.first();
while ( ev ) {
if ( ev->uid().left(15) == QString("last-syncEvent-") )
ev->setReadOnly( true );
ev = mEventList.next();
}
}
void CalendarLocal::addCalendar( Calendar* cal )
{
cal->setDontDeleteIncidencesOnClose();
{
QPtrList<Event> EventList = cal->rawEvents();
Event * ev = EventList.first();
while ( ev ) {
ev->unRegisterObserver( cal );
ev->registerObserver( this );
mEventList.append( ev );
ev = EventList.next();
}
}
{
QPtrList<Todo> TodoList = cal->rawTodos();
Todo * ev = TodoList.first();
while ( ev ) {
QString rel = ev->relatedToUid();
if ( !rel.isEmpty() ){
ev->setRelatedTo ( 0 );
ev->setRelatedToUid( rel );
}
ev = TodoList.next();
}
//TodoList = cal->rawTodos();
ev = TodoList.first();
while ( ev ) {
ev->unRegisterObserver( cal );
ev->registerObserver( this );
mTodoList.append( ev );
setupRelations( ev );
ev = TodoList.next();
}
}
{
QPtrList<Journal> JournalList = cal->journals();
Journal * ev = JournalList.first();
while ( ev ) {
ev->unRegisterObserver( cal );
ev->registerObserver( this );
mJournalList.append( ev );
ev = JournalList.next();
}
}
setModified( true );
}
bool CalendarLocal::load( const QString &fileName )
{
FileStorage storage( this, fileName );
return storage.load();
}
bool CalendarLocal::save( const QString &fileName, CalFormat *format )
{
FileStorage storage( this, fileName, format );
return storage.save();
}
void CalendarLocal::stopAllTodos()
{
for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() )
it->setRunning( false );
}
void CalendarLocal::close()
{
Todo * i;
for( i = mTodoList.first(); i; i = mTodoList.next() ) i->setRunning(false);
mEventList.setAutoDelete( true );
mTodoList.setAutoDelete( true );
- mJournalList.setAutoDelete( false );
+ mJournalList.setAutoDelete( true );
mEventList.clear();
mTodoList.clear();
mJournalList.clear();
mEventList.setAutoDelete( false );
mTodoList.setAutoDelete( false );
mJournalList.setAutoDelete( false );
setModified( false );
}
bool CalendarLocal::addAnniversaryNoDup( Event *event )
{
QString cat;
bool isBirthday = true;
if( event->categoriesStr() == i18n( "Anniversary" ) ) {
isBirthday = false;
cat = i18n( "Anniversary" );
} else if( event->categoriesStr() == i18n( "Birthday" ) ) {
isBirthday = true;
cat = i18n( "Birthday" );
} else {
qDebug("addAnniversaryNoDup called without fitting category! ");
return false;
}
Event * eve;
for ( eve = mEventList.first(); eve ; eve = mEventList.next() ) {
if ( !(eve->categories().contains( cat ) ))
continue;
// now we have an event with fitting category
if ( eve->dtStart().date() != event->dtStart().date() )
continue;
// now we have an event with fitting category+date
if ( eve->summary() != event->summary() )
continue;
// now we have an event with fitting category+date+summary
return false;
}
return addEvent( event );
}
bool CalendarLocal::addEventNoDup( Event *event )
{
Event * eve;
for ( eve = mEventList.first(); eve ; eve = mEventList.next() ) {
if ( *eve == *event ) {
//qDebug("CalendarLocal::Duplicate event found! Not inserted! ");
return false;
}
}
return addEvent( event );
}
bool CalendarLocal::addEvent( Event *event )
{
insertEvent( event );
event->registerObserver( this );
setModified( true );
if ( event->calID() == 0 )
event->setCalID( mDefaultCalendar );
event->setCalEnabled( true );
return true;
}
void CalendarLocal::deleteEvent( Event *event )
{
if ( mUndoIncidence ) delete mUndoIncidence;
mUndoIncidence = event->clone();
if ( mEventList.removeRef( event ) ) {
setModified( true );
}
}
Event *CalendarLocal::event( const QString &uid )
{
Event *event;
Event *retVal = 0;
for ( event = mEventList.first(); event; event = mEventList.next() ) {
if ( event->calEnabled() && event->uid() == uid ) {
if ( retVal ) {
if ( retVal->calID() > event->calID() ) {
retVal = event;
}
} else {
retVal = event;
}
}
}
return retVal;
}
bool CalendarLocal::addTodoNoDup( Todo *todo )
{
Todo * eve;
for ( eve = mTodoList.first(); eve ; eve = mTodoList.next() ) {
if ( *eve == *todo ) {
//qDebug("duplicate todo found! not inserted! ");
return false;
}
}
return addTodo( todo );
}
bool CalendarLocal::addTodo( Todo *todo )
{
mTodoList.append( todo );
todo->registerObserver( this );
// Set up subtask relations
setupRelations( todo );
setModified( true );
if ( todo->calID() == 0 )
todo->setCalID( mDefaultCalendar );
todo->setCalEnabled( true );
return true;
}
void CalendarLocal::deleteTodo( Todo *todo )
{
// Handle orphaned children
if ( mUndoIncidence ) delete mUndoIncidence;
removeRelations( todo );
mUndoIncidence = todo->clone();
if ( mTodoList.removeRef( todo ) ) {
setModified( true );
}
}
QPtrList<Todo> CalendarLocal::rawTodos()
{
QPtrList<Todo> el;
for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() )
if ( it->calEnabled() ) el.append( it );
return el;
}
Todo *CalendarLocal::todo( QString syncProf, QString id )
{
Todo *todo;
for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) {
if ( todo->calEnabled() && todo->getID( syncProf ) == id ) return todo;
}
return 0;
}
void CalendarLocal::removeSyncInfo( QString syncProfile)
{
QPtrList<Incidence> all = rawIncidences() ;
Incidence *inc;
for ( inc = all.first(); inc; inc = all.next() ) {
inc->removeID( syncProfile );
}
if ( syncProfile.isEmpty() ) {
QPtrList<Event> el;
Event *todo;
for ( todo = mEventList.first(); todo; todo = mEventList.next() ) {
if ( todo->uid().left( 15 ) == QString("last-syncEvent-") )
el.append( todo );
}
for ( todo = el.first(); todo; todo = el.next() ) {
deleteIncidence ( todo );
}
} else {
Event *lse = event( "last-syncEvent-"+ syncProfile);
if ( lse )
deleteIncidence ( lse );
}
}
QPtrList<Event> CalendarLocal::getExternLastSyncEvents()
{
QPtrList<Event> el;
Event *todo;
for ( todo = mEventList.first(); todo; todo = mEventList.next() ) {
if ( todo->uid().left( 15 ) == QString("last-syncEvent-") )
if ( todo->summary().left(3) == "E: " )
el.append( todo );
}
return el;
}
Event *CalendarLocal::event( QString syncProf, QString id )
{
Event *todo;
for ( todo = mEventList.first(); todo; todo = mEventList.next() ) {
if ( todo->calEnabled() && todo->getID( syncProf ) == id ) return todo;
}
return 0;
}
Todo *CalendarLocal::todo( const QString &uid )
{
Todo *todo;;
Todo *retVal = 0;
for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) {
if ( todo->calEnabled() && todo->uid() == uid ) {
if ( retVal ) {
if ( retVal->calID() > todo->calID() ) {
retVal = todo;
}
} else {
retVal = todo;
}
}
}
return retVal;
}
QString CalendarLocal::nextSummary() const
{
return mNextSummary;
}
QDateTime CalendarLocal::nextAlarmEventDateTime() const
{
return mNextAlarmEventDateTime;
}
void CalendarLocal::checkAlarmForIncidence( Incidence * incidence, bool deleted)
{
//mNextAlarmIncidence
//mNextAlarmDateTime
//return mNextSummary;
//return mNextAlarmEventDateTime;
bool newNextAlarm = false;
bool computeNextAlarm = false;
bool ok;
int offset;
QDateTime nextA;
// QString nextSum;
//QDateTime nextEvent;
if ( mNextAlarmIncidence == 0 || incidence == 0 ) {
computeNextAlarm = true;
} else {
if ( ! deleted ) {
nextA = incidence->getNextAlarmDateTime(& ok, &offset, QDateTime::currentDateTime() ) ;
if ( ok ) {
if ( nextA < mNextAlarmDateTime ) {
deRegisterAlarm();
mNextAlarmDateTime = nextA;
mNextSummary = incidence->summary();
mNextAlarmEventDateTime = nextA.addSecs(offset ) ;
mNextAlarmEventDateTimeString = KGlobal::locale()->formatDateTime(mNextAlarmEventDateTime);
newNextAlarm = true;
mNextAlarmIncidence = incidence;
} else {
if ( incidence == mNextAlarmIncidence ) {
computeNextAlarm = true;
}
}
} else {
if ( mNextAlarmIncidence == incidence ) {
computeNextAlarm = true;
}
}
} else { // deleted
if ( incidence == mNextAlarmIncidence ) {
computeNextAlarm = true;
}
}
}
if ( computeNextAlarm ) {
deRegisterAlarm();
nextA = nextAlarm( 1000 );
if (! mNextAlarmIncidence ) {
return;
}
newNextAlarm = true;
}
if ( newNextAlarm )
registerAlarm();
}
QString CalendarLocal:: getAlarmNotification()
{
QString ret;
// this should not happen
if (! mNextAlarmIncidence )
return "cal_alarm"+ mNextSummary.left( 25 )+"\n"+mNextAlarmEventDateTimeString;
Alarm* alarm = mNextAlarmIncidence->alarms().first();
if ( alarm->type() == Alarm::Procedure ) {
ret = "proc_alarm" + alarm->programFile()+"+++";
} else {
ret = "audio_alarm" +alarm->audioFile() +"+++";
}
ret += "cal_alarm"+ mNextSummary.left( 25 );
if ( mNextSummary.length() > 25 )
ret += "\n" + mNextSummary.mid(25, 25 );
ret+= "\n"+mNextAlarmEventDateTimeString;
return ret;
}
void CalendarLocal::registerAlarm()
{
mLastAlarmNotificationString = getAlarmNotification();
// qDebug("++ register Alarm %s %s",mNextAlarmDateTime.toString().latin1(), mLastAlarmNotificationString.latin1() );
emit addAlarm ( mNextAlarmDateTime, mLastAlarmNotificationString );
// #ifndef DESKTOP_VERSION
// AlarmServer::addAlarm ( mNextAlarmDateTime,"koalarm", mLastAlarmNotificationString.latin1() );
// #endif
}
void CalendarLocal::deRegisterAlarm()
{
if ( mLastAlarmNotificationString.isNull() )
return;
//qDebug("-- deregister Alarm %s ", mLastAlarmNotificationString.latin1() );
emit removeAlarm ( mNextAlarmDateTime, mLastAlarmNotificationString );
mNextAlarmEventDateTime = QDateTime();
// #ifndef DESKTOP_VERSION
// AlarmServer::deleteAlarm (mNextAlarmDateTime ,"koalarm" ,mLastAlarmNotificationString.latin1() );
// #endif
}
QPtrList<Todo> CalendarLocal::todos( const QDate &date )
{
QPtrList<Todo> todos;
Todo *todo;
for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) {
if ( !todo->calEnabled() ) continue;
if ( todo->hasDueDate() && todo->dtDue().date() == date ) {
todos.append( todo );
}
}
filter()->apply( &todos );
return todos;
}
void CalendarLocal::reInitAlarmSettings()
{
if ( !mNextAlarmIncidence ) {
nextAlarm( 1000 );
}
deRegisterAlarm();
mNextAlarmIncidence = 0;
checkAlarmForIncidence( 0, false );
}
QDateTime CalendarLocal::nextAlarm( int daysTo )
{
QDateTime nextA = QDateTime::currentDateTime().addDays( daysTo );
QDateTime start = QDateTime::currentDateTime().addSecs( 30 );
QDateTime next;
Event *e;
bool ok;
bool found = false;
int offset;
mNextAlarmIncidence = 0;
for( e = mEventList.first(); e; e = mEventList.next() ) {
if ( !e->calEnabled() ) continue;
next = e->getNextAlarmDateTime(& ok, &offset, QDateTime::currentDateTime() ) ;
if ( ok ) {
if ( next < nextA ) {
nextA = next;
found = true;
mNextSummary = e->summary();
mNextAlarmEventDateTime = next.addSecs(offset ) ;
mNextAlarmIncidence = (Incidence *) e;
}
}
}
Todo *t;
for( t = mTodoList.first(); t; t = mTodoList.next() ) {
if ( !t->calEnabled() ) continue;
next = t->getNextAlarmDateTime(& ok, &offset, QDateTime::currentDateTime() ) ;
if ( ok ) {
if ( next < nextA ) {
nextA = next;
found = true;
mNextSummary = t->summary();
mNextAlarmEventDateTime = next.addSecs(offset );
mNextAlarmIncidence = (Incidence *) t;
}
}
}
if ( mNextAlarmIncidence ) {
mNextAlarmEventDateTimeString = KGlobal::locale()->formatDateTime(mNextAlarmEventDateTime);
mNextAlarmDateTime = nextA;
}
return nextA;
}
Alarm::List CalendarLocal::alarmsTo( const QDateTime &to )
{
return alarms( QDateTime( QDate( 1900, 1, 1 ) ), to );
}
Alarm::List CalendarLocal::alarms( const QDateTime &from, const QDateTime &to )
{
Alarm::List alarms;
Event *e;
for( e = mEventList.first(); e; e = mEventList.next() ) {
if ( !e->calEnabled() ) continue;
if ( e->doesRecur() ) appendRecurringAlarms( alarms, e, from, to );
else appendAlarms( alarms, e, from, to );
}
Todo *t;
for( t = mTodoList.first(); t; t = mTodoList.next() ) {
if ( !t->calEnabled() ) continue;
appendAlarms( alarms, t, from, to );
}
return alarms;
}
void CalendarLocal::appendAlarms( Alarm::List &alarms, Incidence *incidence,
const QDateTime &from, const QDateTime &to )
{
QPtrList<Alarm> alarmList = incidence->alarms();
Alarm *alarm;
for( alarm = alarmList.first(); alarm; alarm = alarmList.next() ) {
// kdDebug(5800) << "CalendarLocal::appendAlarms() '" << alarm->text()
// << "': " << alarm->time().toString() << " - " << alarm->enabled() << endl;
if ( alarm->enabled() ) {
if ( alarm->time() >= from && alarm->time() <= to ) {
alarms.append( alarm );
}
}
}
}
void CalendarLocal::appendRecurringAlarms( Alarm::List &alarms,
Incidence *incidence,
const QDateTime &from,
const QDateTime &to )
{
QPtrList<Alarm> alarmList = incidence->alarms();
Alarm *alarm;
QDateTime qdt;
for( alarm = alarmList.first(); alarm; alarm = alarmList.next() ) {
if (incidence->recursOn(from.date())) {
qdt.setTime(alarm->time().time());
qdt.setDate(from.date());
}
else qdt = alarm->time();
// qDebug("1 %s %s %s", qdt.toString().latin1(), from.toString().latin1(), to.toString().latin1());
if ( alarm->enabled() ) {
if ( qdt >= from && qdt <= to ) {
alarms.append( alarm );
}
}
}
}
/****************************** PROTECTED METHODS ****************************/
// after changes are made to an event, this should be called.
void CalendarLocal::update( IncidenceBase *incidence )
{
incidence->setSyncStatus( Event::SYNCMOD );
incidence->setLastModified( QDateTime::currentDateTime() );
// we should probably update the revision number here,
// or internally in the Event itself when certain things change.
// need to verify with ical documentation.
setModified( true );
}
void CalendarLocal::insertEvent( Event *event )
{
if ( mEventList.findRef( event ) < 0 ) mEventList.append( event );
}
QPtrList<Event> CalendarLocal::rawEventsForDate( const QDate &qd, bool sorted )
{
QPtrList<Event> eventList;
Event *event;
for( event = mEventList.first(); event; event = mEventList.next() ) {
if ( !event->calEnabled() ) continue;
if ( event->doesRecur() ) {
if ( event->isMultiDay() ) {
int extraDays = event->dtStart().date().daysTo( event->dtEnd().date() );
int i;
for ( i = 0; i <= extraDays; i++ ) {
if ( event->recursOn( qd.addDays( -i ) ) ) {
eventList.append( event );
break;
}
}
} else {
if ( event->recursOn( qd ) )
eventList.append( event );
}
} else {
if ( event->dtStart().date() <= qd && event->dtEnd().date() >= qd ) {
eventList.append( event );
}
}
}
if ( !sorted ) {
return eventList;
}
// kdDebug(5800) << "Sorting events for date\n" << endl;
// now, we have to sort it based on dtStart.time()
QPtrList<Event> eventListSorted;
Event *sortEvent;
for ( event = eventList.first(); event; event = eventList.next() ) {
sortEvent = eventListSorted.first();
int i = 0;
while ( sortEvent && event->dtStart().time()>=sortEvent->dtStart().time() )
{
i++;
sortEvent = eventListSorted.next();
}
eventListSorted.insert( i, event );
}
return eventListSorted;
}
QPtrList<Event> CalendarLocal::rawEvents( const QDate &start, const QDate &end,
bool inclusive )
{
Event *event = 0;
QPtrList<Event> eventList;
// Get non-recurring events
for( event = mEventList.first(); event; event = mEventList.next() ) {
if ( !event->calEnabled() ) continue;
if ( event->doesRecur() ) {
QDate rStart = event->dtStart().date();
bool found = false;
if ( inclusive ) {
if ( rStart >= start && rStart <= end ) {
// Start date of event is in range. Now check for end date.
// if duration is negative, event recurs forever, so do not include it.
if ( event->recurrence()->duration() == 0 ) { // End date set
QDate rEnd = event->recurrence()->endDate();
if ( rEnd >= start && rEnd <= end ) { // End date within range
found = true;
}
} else if ( event->recurrence()->duration() > 0 ) { // Duration set
// TODO: Calculate end date from duration. Should be done in Event
// For now exclude all events with a duration.
}
}
} else {
bool founOne;
QDate next = event->getNextOccurence( start, &founOne ).date();
if ( founOne ) {
if ( next <= end ) {
found = true;
}
}
/*
// crap !!!
if ( rStart <= end ) { // Start date not after range
if ( rStart >= start ) { // Start date within range
found = true;
} else if ( event->recurrence()->duration() == -1 ) { // Recurs forever
found = true;
} else if ( event->recurrence()->duration() == 0 ) { // End date set
QDate rEnd = event->recurrence()->endDate();
if ( rEnd >= start && rEnd <= end ) { // End date within range
found = true;
}
} else { // Duration set
// TODO: Calculate end date from duration. Should be done in Event
// For now include all events with a duration.
found = true;
}
}
*/
}
if ( found ) eventList.append( event );
} else {
QDate s = event->dtStart().date();
QDate e = event->dtEnd().date();
if ( inclusive ) {
if ( s >= start && e <= end ) {
eventList.append( event );
}
} else {
if ( ( e >= start && s <= end ) ) {
eventList.append( event );
}
}
}
}
return eventList;
}
QPtrList<Event> CalendarLocal::rawEventsForDate( const QDateTime &qdt )
{
return rawEventsForDate( qdt.date() );
}
QPtrList<Event> CalendarLocal::rawEvents()
{
QPtrList<Event> el;
for ( Event *it = mEventList.first(); it; it = mEventList.next() )
if ( it->calEnabled() ) el.append( it );
return el;
}
bool CalendarLocal::addJournal(Journal *journal)
{
mJournalList.append(journal);
journal->registerObserver( this );
setModified( true );
if ( journal->calID() == 0 )
journal->setCalID( mDefaultCalendar );
journal->setCalEnabled( true );
return true;
}
void CalendarLocal::deleteJournal( Journal *journal )
{
if ( mUndoIncidence ) delete mUndoIncidence;
mUndoIncidence = journal->clone();
mUndoIncidence->setSummary( mUndoIncidence->description().left(25));
if ( mJournalList.removeRef(journal) ) {
setModified( true );
}
}
QPtrList<Journal> CalendarLocal::journals4Date( const QDate & date )
{
QPtrList<Journal> el;
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->calEnabled() && it->dtStart().date() == date) el.append( it );
return el;
}
Journal *CalendarLocal::journal( const QDate &date )
{
// kdDebug(5800) << "CalendarLocal::journal() " << date.toString() << endl;
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->calEnabled() && it->dtStart().date() == date )
return it;
return 0;
}
Journal *CalendarLocal::journal( const QString &uid )
{
Journal * retVal = 0;
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->calEnabled() && it->uid() == uid ) {
if ( retVal ) {
if ( retVal->calID() > it->calID() ) {
retVal = it;
}
} else {
retVal = it;
}
}
return retVal;
}
QPtrList<Journal> CalendarLocal::journals()
{
QPtrList<Journal> el;
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->calEnabled() ) el.append( it );
return el;
}
void CalendarLocal::setCalendarRemove( int id )
{
{
QPtrList<Event> EventList = mEventList;
Event * ev = EventList.first();
while ( ev ) {
if ( ev->calID() == id )
deleteEvent( ev );
ev = EventList.next();
}
}
{
QPtrList<Todo> TodoList = mTodoList;
Todo * ev = TodoList.first();
while ( ev ) {
if ( ev->calID() == id )
deleteTodo( ev );
ev = TodoList.next();
}
}
{
QPtrList<Journal> JournalList = mJournalList;
Journal * ev = JournalList.first();
while ( ev ) {
if ( ev->calID() == id )
deleteJournal( ev );
ev = JournalList.next();
}
}
if ( mUndoIncidence ) delete mUndoIncidence;
mUndoIncidence = 0;
}
void CalendarLocal::setCalendarEnabled( int id, bool enable )
{
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->calID() == id ) it->setCalEnabled( enable );
for ( Event *it = mEventList.first(); it; it = mEventList.next() )
if ( it->calID() == id ) it->setCalEnabled( enable );
for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() )
if ( it->calID() == id ) it->setCalEnabled( enable );
}
void CalendarLocal::setReadOnly( int id, bool enable )
{
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->calID() == id ) it->setReadOnly( enable );
for ( Event *it = mEventList.first(); it; it = mEventList.next() )
if ( it->calID() == id ) it->setReadOnly( enable );
for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() )
if ( it->calID() == id ) it->setReadOnly( enable );
}
void CalendarLocal::setAlarmEnabled( int id, bool enable )
{
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->calID() == id ) it->setAlarmEnabled( enable );
for ( Event *it = mEventList.first(); it; it = mEventList.next() )
if ( it->calID() == id ) it->setAlarmEnabled( enable );
for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() )
if ( it->calID() == id ) it->setAlarmEnabled( enable );
reInitAlarmSettings();
}
void CalendarLocal::setDefaultCalendarEnabledOnly()
{
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
it->setCalEnabled( it->calID() == mDefaultCalendar );
for ( Event *it = mEventList.first(); it; it = mEventList.next() )
it->setCalEnabled( it->calID() == mDefaultCalendar);
for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() )
it->setCalEnabled( it->calID() == mDefaultCalendar);
}
diff --git a/libkcal/icalformatimpl.cpp b/libkcal/icalformatimpl.cpp
index f349681..53aa039 100644
--- a/libkcal/icalformatimpl.cpp
+++ b/libkcal/icalformatimpl.cpp
@@ -237,1937 +237,1940 @@ icalcomponent *ICalFormatImpl::writeJournal(Journal *journal)
{
icalcomponent *vjournal = icalcomponent_new(ICAL_VJOURNAL_COMPONENT);
writeIncidence(vjournal,journal);
// start time
if (journal->dtStart().isValid()) {
icaltimetype start;
if (journal->doesFloat()) {
// kdDebug(5800) << "§§ Incidence " << event->summary() << " floats." << endl;
start = writeICalDate(journal->dtStart().date());
} else {
// kdDebug(5800) << "§§ incidence " << event->summary() << " has time." << endl;
start = writeICalDateTime(journal->dtStart());
}
icalcomponent_add_property(vjournal,icalproperty_new_dtstart(start));
}
return vjournal;
}
void ICalFormatImpl::writeIncidence(icalcomponent *parent,Incidence *incidence)
{
// pilot sync stuff
// 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())
icalattachtype_set_url(attach, att->uri().utf8().data());
else
icalattachtype_set_base64(attach, att->data(), 0);
#endif
icalattach *attach;
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;
readIncidence(vtodo,todo);
icalproperty *p = icalcomponent_get_first_property(vtodo,ICAL_ANY_PROPERTY);
// int intvalue;
icaltimetype icaltime;
QStringList categories;
while (p) {
icalproperty_kind kind = icalproperty_isa(p);
switch (kind) {
case ICAL_DUE_PROPERTY: // due date
icaltime = icalproperty_get_due(p);
if (icaltime.is_date) {
todo->setDtDue(QDateTime(readICalDate(icaltime),QTime(0,0,0)));
todo->setFloats(true);
} else {
todo->setDtDue(readICalDateTime(icaltime));
todo->setFloats(false);
}
todo->setHasDueDate(true);
break;
case ICAL_COMPLETED_PROPERTY: // completion date
icaltime = icalproperty_get_completed(p);
todo->setCompleted(readICalDateTime(icaltime));
break;
case ICAL_PERCENTCOMPLETE_PROPERTY: // Percent completed
todo->setPercentComplete(icalproperty_get_percentcomplete(p));
break;
case ICAL_RELATEDTO_PROPERTY: // related todo (parent)
todo->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p)));
mTodosRelate.append(todo);
break;
case ICAL_DTSTART_PROPERTY:
// Flag that todo has start date. Value is read in by readIncidence().
todo->setHasStartDate(true);
break;
default:
// kdDebug(5800) << "ICALFormat::readTodo(): Unknown property: " << kind
// << endl;
break;
}
p = icalcomponent_get_next_property(vtodo,ICAL_ANY_PROPERTY);
}
return todo;
}
Event *ICalFormatImpl::readEvent(icalcomponent *vevent)
{
Event *event = new Event;
event->setFloats(false);
readIncidence(vevent,event);
icalproperty *p = icalcomponent_get_first_property(vevent,ICAL_ANY_PROPERTY);
// int intvalue;
icaltimetype icaltime;
QStringList categories;
QString transparency;
while (p) {
icalproperty_kind kind = icalproperty_isa(p);
switch (kind) {
case ICAL_DTEND_PROPERTY: // start date and time
icaltime = icalproperty_get_dtend(p);
if (icaltime.is_date) {
event->setFloats( true );
// End date is non-inclusive
QDate endDate = readICalDate( icaltime ).addDays( -1 );
mCompat->fixFloatingEnd( endDate );
if ( endDate < event->dtStart().date() ) {
endDate = event->dtStart().date();
}
event->setDtEnd( QDateTime( endDate, QTime( 0, 0, 0 ) ) );
} else {
event->setDtEnd(readICalDateTime(icaltime));
}
break;
// TODO:
// at this point, there should be at least a start or end time.
// fix up for events that take up no time but have a time associated
#if 0
if (!(vo = isAPropertyOf(vevent, VCDTstartProp)))
anEvent->setDtStart(anEvent->dtEnd());
if (!(vo = isAPropertyOf(vevent, VCDTendProp)))
anEvent->setDtEnd(anEvent->dtStart());
#endif
// TODO: exdates
#if 0
// recurrence exceptions
if ((vo = isAPropertyOf(vevent, VCExDateProp)) != 0) {
anEvent->setExDates(s = fakeCString(vObjectUStringZValue(vo)));
deleteStr(s);
}
#endif
#if 0
// secrecy
if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) {
anEvent->setSecrecy(s = fakeCString(vObjectUStringZValue(vo)));
deleteStr(s);
}
else
anEvent->setSecrecy("PUBLIC");
// attachments
tmpStrList.clear();
initPropIterator(&voi, vevent);
while (moreIteration(&voi)) {
vo = nextVObject(&voi);
if (strcmp(vObjectName(vo), VCAttachProp) == 0) {
tmpStrList.append(s = fakeCString(vObjectUStringZValue(vo)));
deleteStr(s);
}
}
anEvent->setAttachments(tmpStrList);
// resources
if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) {
QString resources = (s = fakeCString(vObjectUStringZValue(vo)));
deleteStr(s);
tmpStrList.clear();
index1 = 0;
index2 = 0;
QString resource;
while ((index2 = resources.find(';', index1)) != -1) {
resource = resources.mid(index1, (index2 - index1));
tmpStrList.append(resource);
index1 = index2;
}
anEvent->setResources(tmpStrList);
}
#endif
case ICAL_RELATEDTO_PROPERTY: // releated event (parent)
event->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p)));
mEventsRelate.append(event);
break;
case ICAL_TRANSP_PROPERTY: // Transparency
if(icalproperty_get_transp(p) == ICAL_TRANSP_TRANSPARENT )
event->setTransparency( Event::Transparent );
else
event->setTransparency( Event::Opaque );
break;
default:
// kdDebug(5800) << "ICALFormat::readEvent(): Unknown property: " << kind
// << endl;
break;
}
p = icalcomponent_get_next_property(vevent,ICAL_ANY_PROPERTY);
}
QString msade = event->nonKDECustomProperty("X-MICROSOFT-CDO-ALLDAYEVENT");
if (!msade.isNull()) {
bool floats = (msade == QString::fromLatin1("TRUE"));
kdDebug(5800) << "ICALFormat::readEvent(): all day event: " << floats << endl;
event->setFloats(floats);
if (floats) {
QDateTime endDate = event->dtEnd();
event->setDtEnd(endDate.addDays(-1));
}
}
// some stupid vCal exporters ignore the standard and use Description
// instead of Summary for the default field. Correct for this.
if (event->summary().isEmpty() &&
!(event->description().isEmpty())) {
QString tmpStr = event->description().simplifyWhiteSpace();
event->setDescription("");
event->setSummary(tmpStr);
}
return event;
}
FreeBusy *ICalFormatImpl::readFreeBusy(icalcomponent *vfreebusy)
{
FreeBusy *freebusy = new FreeBusy;
readIncidenceBase(vfreebusy,freebusy);
icalproperty *p = icalcomponent_get_first_property(vfreebusy,ICAL_ANY_PROPERTY);
icaltimetype icaltime;
icalperiodtype icalperiod;
QDateTime period_start, period_end;
while (p) {
icalproperty_kind kind = icalproperty_isa(p);
switch (kind) {
case ICAL_DTSTART_PROPERTY: // start date and time
icaltime = icalproperty_get_dtstart(p);
freebusy->setDtStart(readICalDateTime(icaltime));
break;
case ICAL_DTEND_PROPERTY: // start End Date and Time
icaltime = icalproperty_get_dtend(p);
freebusy->setDtEnd(readICalDateTime(icaltime));
break;
case ICAL_FREEBUSY_PROPERTY: //Any FreeBusy Times
icalperiod = icalproperty_get_freebusy(p);
period_start = readICalDateTime(icalperiod.start);
period_end = readICalDateTime(icalperiod.end);
freebusy->addPeriod(period_start, period_end);
break;
-
+
default:
kdDebug(5800) << "ICALFormat::readIncidence(): Unknown property: " << kind
<< endl;
break;
}
p = icalcomponent_get_next_property(vfreebusy,ICAL_ANY_PROPERTY);
}
return freebusy;
}
Journal *ICalFormatImpl::readJournal(icalcomponent *vjournal)
{
Journal *journal = new Journal;
readIncidence(vjournal,journal);
if ( !journal->dtStart().isValid() && journal->created().isValid() ) {
journal->setDtStart( journal->created() );
}
return journal;
}
Attendee *ICalFormatImpl::readAttendee(icalproperty *attendee)
{
icalparameter *p = 0;
QString email = QString::fromUtf8(icalproperty_get_attendee(attendee));
QString name;
QString uid = QString::null;
p = icalproperty_get_first_parameter(attendee,ICAL_CN_PARAMETER);
if (p) {
name = QString::fromUtf8(icalparameter_get_cn(p));
} else {
}
bool rsvp=false;
p = icalproperty_get_first_parameter(attendee,ICAL_RSVP_PARAMETER);
if (p) {
icalparameter_rsvp rsvpParameter = icalparameter_get_rsvp(p);
if (rsvpParameter == ICAL_RSVP_TRUE) rsvp = true;
}
Attendee::PartStat status = Attendee::NeedsAction;
p = icalproperty_get_first_parameter(attendee,ICAL_PARTSTAT_PARAMETER);
if (p) {
icalparameter_partstat partStatParameter = icalparameter_get_partstat(p);
switch(partStatParameter) {
default:
case ICAL_PARTSTAT_NEEDSACTION:
status = Attendee::NeedsAction;
break;
case ICAL_PARTSTAT_ACCEPTED:
status = Attendee::Accepted;
break;
case ICAL_PARTSTAT_DECLINED:
status = Attendee::Declined;
break;
case ICAL_PARTSTAT_TENTATIVE:
status = Attendee::Tentative;
break;
case ICAL_PARTSTAT_DELEGATED:
status = Attendee::Delegated;
break;
case ICAL_PARTSTAT_COMPLETED:
status = Attendee::Completed;
break;
case ICAL_PARTSTAT_INPROCESS:
status = Attendee::InProcess;
break;
}
}
Attendee::Role role = Attendee::ReqParticipant;
p = icalproperty_get_first_parameter(attendee,ICAL_ROLE_PARAMETER);
if (p) {
icalparameter_role roleParameter = icalparameter_get_role(p);
switch(roleParameter) {
case ICAL_ROLE_CHAIR:
role = Attendee::Chair;
break;
default:
case ICAL_ROLE_REQPARTICIPANT:
role = Attendee::ReqParticipant;
break;
case ICAL_ROLE_OPTPARTICIPANT:
role = Attendee::OptParticipant;
break;
case ICAL_ROLE_NONPARTICIPANT:
role = Attendee::NonParticipant;
break;
}
}
p = icalproperty_get_first_parameter(attendee,ICAL_X_PARAMETER);
uid = icalparameter_get_xvalue(p);
// This should be added, but there seems to be a libical bug here.
/*while (p) {
// if (icalparameter_get_xname(p) == "X-UID") {
uid = icalparameter_get_xvalue(p);
p = icalproperty_get_next_parameter(attendee,ICAL_X_PARAMETER);
} */
return new Attendee( name, email, rsvp, status, role, uid );
}
Attachment *ICalFormatImpl::readAttachment(icalproperty *attach)
{
icalattach *a = icalproperty_get_attach(attach);
icalparameter_value v = ICAL_VALUE_NONE;
icalparameter_encoding e = ICAL_ENCODING_NONE;
Attachment *attachment = 0;
/*
icalparameter *vp = icalproperty_get_first_parameter(attach, ICAL_VALUE_PARAMETER);
if (vp)
v = icalparameter_get_value(vp);
icalparameter *ep = icalproperty_get_first_parameter(attach, ICAL_ENCODING_PARAMETER);
if (ep)
e = icalparameter_get_encoding(ep);
*/
int isurl = icalattach_get_is_url (a);
if (isurl == 0)
attachment = new Attachment((const char*)icalattach_get_data(a));
else {
attachment = new Attachment(QString(icalattach_get_url(a)));
}
icalparameter *p = icalproperty_get_first_parameter(attach, ICAL_FMTTYPE_PARAMETER);
if (p)
attachment->setMimeType(QString(icalparameter_get_fmttype(p)));
return attachment;
}
#include <qtextcodec.h>
void ICalFormatImpl::readIncidence(icalcomponent *parent,Incidence *incidence)
{
readIncidenceBase(parent,incidence);
icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY);
bool readrec = false;
const char *text;
int intvalue;
icaltimetype icaltime;
icaldurationtype icalduration;
struct icalrecurrencetype rectype;
QStringList categories;
while (p) {
icalproperty_kind kind = icalproperty_isa(p);
switch (kind) {
case ICAL_CREATED_PROPERTY:
icaltime = icalproperty_get_created(p);
incidence->setCreated(readICalDateTime(icaltime));
break;
case ICAL_SEQUENCE_PROPERTY: // sequence
intvalue = icalproperty_get_sequence(p);
incidence->setRevision(intvalue);
break;
case ICAL_LASTMODIFIED_PROPERTY: // last modification date
icaltime = icalproperty_get_lastmodified(p);
incidence->setLastModified(readICalDateTime(icaltime));
break;
case ICAL_DTSTART_PROPERTY: // start date and time
icaltime = icalproperty_get_dtstart(p);
if (icaltime.is_date) {
incidence->setDtStart(QDateTime(readICalDate(icaltime),QTime(0,0,0)));
incidence->setFloats(true);
} else {
incidence->setDtStart(readICalDateTime(icaltime));
}
break;
case ICAL_DURATION_PROPERTY: // start date and time
icalduration = icalproperty_get_duration(p);
incidence->setDuration(readICalDuration(icalduration));
break;
case ICAL_DESCRIPTION_PROPERTY: // description
text = icalproperty_get_description(p);
incidence->setDescription(QString::fromUtf8(text));
break;
case ICAL_SUMMARY_PROPERTY: // summary
{
text = icalproperty_get_summary(p);
incidence->setSummary(QString::fromUtf8(text));
}
break;
case ICAL_STATUS_PROPERTY: // summary
{
if ( ICAL_STATUS_CANCELLED == icalproperty_get_status(p) )
incidence->setCancelled( true );
}
break;
case ICAL_LOCATION_PROPERTY: // location
text = icalproperty_get_location(p);
incidence->setLocation(QString::fromUtf8(text));
break;
case ICAL_RECURRENCEID_PROPERTY:
icaltime = icalproperty_get_recurrenceid(p);
incidence->setRecurrenceID( readICalDateTime(icaltime) );
//qDebug(" RecurrenceID %s",incidence->recurrenceID().toString().latin1() );
break;
#if 0
// status
if ((vo = isAPropertyOf(vincidence, VCStatusProp)) != 0) {
incidence->setStatus(s = fakeCString(vObjectUStringZValue(vo)));
deleteStr(s);
}
else
incidence->setStatus("NEEDS ACTION");
#endif
case ICAL_PRIORITY_PROPERTY: // priority
intvalue = icalproperty_get_priority(p);
incidence->setPriority(intvalue);
break;
case ICAL_CATEGORIES_PROPERTY: // categories
text = icalproperty_get_categories(p);
categories.append(QString::fromUtf8(text));
break;
//*******************************************
case ICAL_RRULE_PROPERTY:
// we do need (maybe )start datetime of incidence for recurrence
// such that we can read recurrence only after we read incidence completely
readrec = true;
rectype = icalproperty_get_rrule(p);
break;
case ICAL_EXDATE_PROPERTY:
icaltime = icalproperty_get_exdate(p);
incidence->addExDate(readICalDate(icaltime));
break;
case ICAL_CLASS_PROPERTY: {
int inttext = icalproperty_get_class(p);
if (inttext == ICAL_CLASS_PUBLIC ) {
incidence->setSecrecy(Incidence::SecrecyPublic);
} else if (inttext == ICAL_CLASS_CONFIDENTIAL ) {
incidence->setSecrecy(Incidence::SecrecyConfidential);
} else {
incidence->setSecrecy(Incidence::SecrecyPrivate);
}
}
break;
case ICAL_ATTACH_PROPERTY: // attachments
incidence->addAttachment(readAttachment(p));
break;
default:
// kdDebug(5800) << "ICALFormat::readIncidence(): Unknown property: " << kind
// << endl;
break;
}
p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY);
}
if ( readrec ) {
readRecurrenceRule(rectype,incidence);
}
// kpilot stuff
// TODO: move this application-specific code to kpilot
QString kp = incidence->nonKDECustomProperty("X-PILOTID");
if (!kp.isNull()) {
incidence->setPilotId(kp.toInt());
}
kp = incidence->nonKDECustomProperty("X-PILOTSTAT");
if (!kp.isNull()) {
incidence->setSyncStatus(kp.toInt());
}
kp = incidence->nonKDECustomProperty("X-KOPIEXTID");
if (!kp.isNull()) {
incidence->setIDStr(kp);
}
// Cancel backwards compatibility mode for subsequent changes by the application
if ( readrec )
incidence->recurrence()->setCompatVersion();
// add categories
incidence->setCategories(categories);
// iterate through all alarms
for (icalcomponent *alarm = icalcomponent_get_first_component(parent,ICAL_VALARM_COMPONENT);
alarm;
alarm = icalcomponent_get_next_component(parent,ICAL_VALARM_COMPONENT)) {
readAlarm(alarm,incidence);
}
}
void ICalFormatImpl::readIncidenceBase(icalcomponent *parent,IncidenceBase *incidenceBase)
{
icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY);
while (p) {
icalproperty_kind kind = icalproperty_isa(p);
switch (kind) {
case ICAL_UID_PROPERTY: // unique id
incidenceBase->setUid(QString::fromUtf8(icalproperty_get_uid(p)));
break;
case ICAL_ORGANIZER_PROPERTY: // organizer
incidenceBase->setOrganizer(QString::fromUtf8(icalproperty_get_organizer(p)));
break;
case ICAL_ATTENDEE_PROPERTY: // attendee
incidenceBase->addAttendee(readAttendee(p));
break;
default:
break;
}
p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY);
}
// custom properties
readCustomProperties(parent, incidenceBase);
}
void ICalFormatImpl::readCustomProperties(icalcomponent *parent,CustomProperties *properties)
{
QMap<QCString, QString> customProperties;
icalproperty *p = icalcomponent_get_first_property(parent,ICAL_X_PROPERTY);
while (p) {
QString value = QString::fromUtf8(icalproperty_get_x(p));
customProperties[icalproperty_get_x_name(p)] = value;
//qDebug("ICalFormatImpl::readCustomProperties %s %s",value.latin1(), icalproperty_get_x_name(p) );
p = icalcomponent_get_next_property(parent,ICAL_X_PROPERTY);
}
properties->setCustomProperties(customProperties);
}
void ICalFormatImpl::readRecurrenceRule(struct icalrecurrencetype rrule,Incidence *incidence)
{
// kdDebug(5800) << "Read recurrence for " << incidence->summary() << endl;
Recurrence *recur = incidence->recurrence();
recur->setCompatVersion(mCalendarVersion);
recur->unsetRecurs();
struct icalrecurrencetype r = rrule;
dumpIcalRecurrence(r);
readRecurrence( r, recur, incidence);
}
void ICalFormatImpl::readRecurrence( const struct icalrecurrencetype &r, Recurrence* recur, Incidence *incidence)
{
int wkst;
int index = 0;
short day = 0;
QBitArray qba(7);
int frequ = r.freq;
int interv = r.interval;
// preprocessing for odd recurrence definitions
if ( r.freq == ICAL_MONTHLY_RECURRENCE ) {
if ( r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) {
interv = 12;
}
}
if ( r.freq == ICAL_YEARLY_RECURRENCE ) {
if ( r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX && r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX ) {
frequ = ICAL_MONTHLY_RECURRENCE;
interv = 12* r.interval;
}
}
switch (frequ) {
case ICAL_MINUTELY_RECURRENCE:
if (!icaltime_is_null_time(r.until)) {
recur->setMinutely(interv,readICalDateTime(r.until));
} else {
if (r.count == 0)
recur->setMinutely(interv,-1);
else
recur->setMinutely(interv,r.count);
}
break;
case ICAL_HOURLY_RECURRENCE:
if (!icaltime_is_null_time(r.until)) {
recur->setHourly(interv,readICalDateTime(r.until));
} else {
if (r.count == 0)
recur->setHourly(interv,-1);
else
recur->setHourly(interv,r.count);
}
break;
case ICAL_DAILY_RECURRENCE:
if (!icaltime_is_null_time(r.until)) {
recur->setDaily(interv,readICalDate(r.until));
} else {
if (r.count == 0)
recur->setDaily(interv,-1);
else
recur->setDaily(interv,r.count);
}
break;
case ICAL_WEEKLY_RECURRENCE:
// kdDebug(5800) << "WEEKLY_RECURRENCE" << endl;
wkst = (r.week_start + 5)%7 + 1;
if (!icaltime_is_null_time(r.until)) {
recur->setWeekly(interv,qba,readICalDate(r.until),wkst);
} else {
if (r.count == 0)
recur->setWeekly(interv,qba,-1,wkst);
else
recur->setWeekly(interv,qba,r.count,wkst);
}
if ( r.by_day[0] == ICAL_RECURRENCE_ARRAY_MAX) {
int wday = incidence->dtStart().date().dayOfWeek ()-1;
//qDebug("weekly error found ");
qba.setBit(wday);
} else {
while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
// kdDebug(5800) << " " << day << endl;
qba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0
}
}
break;
case ICAL_MONTHLY_RECURRENCE:
if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
if (!icaltime_is_null_time(r.until)) {
recur->setMonthly(Recurrence::rMonthlyPos,interv,
readICalDate(r.until));
} else {
if (r.count == 0)
recur->setMonthly(Recurrence::rMonthlyPos,interv,-1);
else
recur->setMonthly(Recurrence::rMonthlyPos,interv,r.count);
}
bool useSetPos = false;
short pos = 0;
while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
// kdDebug(5800) << "----a " << index << ": " << day << endl;
pos = icalrecurrencetype_day_position(day);
if (pos) {
day = icalrecurrencetype_day_day_of_week(day);
QBitArray ba(7); // don't wipe qba
ba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0
recur->addMonthlyPos(pos,ba);
} else {
qba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0
useSetPos = true;
}
}
if (useSetPos) {
if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
recur->addMonthlyPos(r.by_set_pos[0],qba);
}
}
} else if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
if (!icaltime_is_null_time(r.until)) {
recur->setMonthly(Recurrence::rMonthlyDay,interv,
readICalDate(r.until));
} else {
if (r.count == 0)
recur->setMonthly(Recurrence::rMonthlyDay,interv,-1);
else
recur->setMonthly(Recurrence::rMonthlyDay,interv,r.count);
}
while((day = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
// kdDebug(5800) << "----b " << day << endl;
recur->addMonthlyDay(day);
}
}
break;
case ICAL_YEARLY_RECURRENCE:
if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
//qDebug(" YEARLY DAY OF YEAR");
if (!icaltime_is_null_time(r.until)) {
recur->setYearly(Recurrence::rYearlyDay,interv,
readICalDate(r.until));
} else {
if (r.count == 0)
recur->setYearly(Recurrence::rYearlyDay,interv,-1);
else
recur->setYearly(Recurrence::rYearlyDay,interv,r.count);
}
while((day = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
recur->addYearlyNum(day);
}
} else if ( true /*r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX*/) {
if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
qDebug("YEARLY POS NOT SUPPORTED BY GUI");
if (!icaltime_is_null_time(r.until)) {
recur->setYearly(Recurrence::rYearlyPos,interv,
readICalDate(r.until));
} else {
if (r.count == 0)
recur->setYearly(Recurrence::rYearlyPos,interv,-1);
else
recur->setYearly(Recurrence::rYearlyPos,interv,r.count);
}
bool useSetPos = false;
short pos = 0;
while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
// kdDebug(5800) << "----a " << index << ": " << day << endl;
pos = icalrecurrencetype_day_position(day);
if (pos) {
day = icalrecurrencetype_day_day_of_week(day);
QBitArray ba(7); // don't wipe qba
ba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0
recur->addYearlyMonthPos(pos,ba);
} else {
qba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0
useSetPos = true;
}
}
if (useSetPos) {
if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
recur->addYearlyMonthPos(r.by_set_pos[0],qba);
}
}
} else {
//qDebug("YEARLY MONTH ");
if (!icaltime_is_null_time(r.until)) {
recur->setYearly(Recurrence::rYearlyMonth,interv,
readICalDate(r.until));
} else {
if (r.count == 0)
recur->setYearly(Recurrence::rYearlyMonth,interv,-1);
else
recur->setYearly(Recurrence::rYearlyMonth,interv,r.count);
}
if ( r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX ) {
index = 0;
while((day = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
recur->addYearlyNum(day);
}
} else {
recur->addYearlyNum(incidence->dtStart().date().month());
}
}
}
break;
default:
;
break;
}
}
void ICalFormatImpl::readAlarm(icalcomponent *alarm,Incidence *incidence)
{
//kdDebug(5800) << "Read alarm for " << incidence->summary() << endl;
Alarm* ialarm = incidence->newAlarm();
ialarm->setRepeatCount(0);
ialarm->setEnabled(true);
// Determine the alarm's action type
icalproperty *p = icalcomponent_get_first_property(alarm,ICAL_ACTION_PROPERTY);
if ( !p ) {
return;
}
icalproperty_action action = icalproperty_get_action(p);
Alarm::Type type = Alarm::Display;
switch ( action ) {
case ICAL_ACTION_DISPLAY: type = Alarm::Display; break;
case ICAL_ACTION_AUDIO: type = Alarm::Audio; break;
case ICAL_ACTION_PROCEDURE: type = Alarm::Procedure; break;
case ICAL_ACTION_EMAIL: type = Alarm::Email; break;
default:
;
return;
}
ialarm->setType(type);
p = icalcomponent_get_first_property(alarm,ICAL_ANY_PROPERTY);
while (p) {
icalproperty_kind kind = icalproperty_isa(p);
switch (kind) {
case ICAL_TRIGGER_PROPERTY: {
icaltriggertype trigger = icalproperty_get_trigger(p);
if (icaltime_is_null_time(trigger.time)) {
if (icaldurationtype_is_null_duration(trigger.duration)) {
kdDebug(5800) << "ICalFormatImpl::readAlarm(): Trigger has no time and no duration." << endl;
} else {
Duration duration = icaldurationtype_as_int( trigger.duration );
icalparameter *param = icalproperty_get_first_parameter(p,ICAL_RELATED_PARAMETER);
if (param && icalparameter_get_related(param) == ICAL_RELATED_END)
ialarm->setEndOffset(duration);
else
ialarm->setStartOffset(duration);
}
} else {
ialarm->setTime(readICalDateTime(trigger.time));
}
break;
}
case ICAL_DURATION_PROPERTY: {
icaldurationtype duration = icalproperty_get_duration(p);
ialarm->setSnoozeTime(icaldurationtype_as_int(duration)/60);
break;
}
case ICAL_REPEAT_PROPERTY:
ialarm->setRepeatCount(icalproperty_get_repeat(p));
break;
// Only in DISPLAY and EMAIL and PROCEDURE alarms
case ICAL_DESCRIPTION_PROPERTY: {
QString description = QString::fromUtf8(icalproperty_get_description(p));
switch ( action ) {
case ICAL_ACTION_DISPLAY:
ialarm->setText( description );
break;
case ICAL_ACTION_PROCEDURE:
ialarm->setProgramArguments( description );
break;
case ICAL_ACTION_EMAIL:
ialarm->setMailText( description );
break;
default:
break;
}
break;
}
// Only in EMAIL alarm
case ICAL_SUMMARY_PROPERTY:
ialarm->setMailSubject(QString::fromUtf8(icalproperty_get_summary(p)));
break;
// Only in EMAIL alarm
case ICAL_ATTENDEE_PROPERTY: {
QString email = QString::fromUtf8(icalproperty_get_attendee(p));
QString name;
icalparameter *param = icalproperty_get_first_parameter(p,ICAL_CN_PARAMETER);
if (param) {
name = QString::fromUtf8(icalparameter_get_cn(param));
}
ialarm->addMailAddress(Person(name, email));
break;
}
// Only in AUDIO and EMAIL and PROCEDURE alarms
case ICAL_ATTACH_PROPERTY: {
icalattach *attach = icalproperty_get_attach(p);
QString url = QFile::decodeName(icalattach_get_url(attach));
switch ( action ) {
case ICAL_ACTION_AUDIO:
ialarm->setAudioFile( url );
break;
case ICAL_ACTION_PROCEDURE:
ialarm->setProgramFile( url );
break;
case ICAL_ACTION_EMAIL:
ialarm->addMailAttachment( url );
break;
default:
break;
}
break;
}
default:
break;
}
p = icalcomponent_get_next_property(alarm,ICAL_ANY_PROPERTY);
}
// custom properties
readCustomProperties(alarm, ialarm);
// TODO: check for consistency of alarm properties
}
icaltimetype ICalFormatImpl::writeICalDate(const QDate &date)
{
icaltimetype t;
t.year = date.year();
t.month = date.month();
t.day = date.day();
t.hour = 0;
t.minute = 0;
t.second = 0;
t.is_date = 1;
t.is_utc = 0;
t.zone = 0;
return t;
}
icaltimetype ICalFormatImpl::writeICalDateTime(const QDateTime &dt )
{
icaltimetype t;
t.is_date = 0;
t.zone = 0;
QDateTime datetime;
if ( mParent->utc() ) {
int offset = KGlobal::locale()->localTimeOffset( dt );
datetime = dt.addSecs ( -offset*60);
t.is_utc = 1;
}
else {
datetime = dt;
t.is_utc = 0;
}
t.year = datetime.date().year();
t.month = datetime.date().month();
t.day = datetime.date().day();
t.hour = datetime.time().hour();
t.minute = datetime.time().minute();
t.second = datetime.time().second();
//qDebug("*** time %s localtime %s ",dt .toString().latin1() ,datetime .toString().latin1() );
// if ( mParent->utc() ) {
// datetime = KGlobal::locale()->localTime( dt );
// qDebug("*** time %s localtime %s ",dt .toString().latin1() ,datetime .toString().latin1() );
// if (mParent->timeZoneId().isEmpty())
// t = icaltime_as_utc(t, 0);
// else
// t = icaltime_as_utc(t,mParent->timeZoneId().local8Bit());
// }
return t;
}
QDateTime ICalFormatImpl::readICalDateTime(icaltimetype t)
{
QDateTime dt (QDate(t.year,t.month,t.day),
QTime(t.hour,t.minute,t.second) );
if (t.is_utc) {
int offset = KGlobal::locale()->localTimeOffset( dt );
dt = dt.addSecs ( offset*60);
}
return dt;
}
QDate ICalFormatImpl::readICalDate(icaltimetype t)
{
return QDate(t.year,t.month,t.day);
}
icaldurationtype ICalFormatImpl::writeICalDuration(int seconds)
{
icaldurationtype d;
d.is_neg = (seconds<0)?1:0;
if (seconds<0) seconds = -seconds;
d.weeks = seconds / gSecondsPerWeek;
seconds %= gSecondsPerWeek;
d.days = seconds / gSecondsPerDay;
seconds %= gSecondsPerDay;
d.hours = seconds / gSecondsPerHour;
seconds %= gSecondsPerHour;
d.minutes = seconds / gSecondsPerMinute;
seconds %= gSecondsPerMinute;
d.seconds = seconds;
return d;
}
int ICalFormatImpl::readICalDuration(icaldurationtype d)
{
int result = 0;
result += d.weeks * gSecondsPerWeek;
result += d.days * gSecondsPerDay;
result += d.hours * gSecondsPerHour;
result += d.minutes * gSecondsPerMinute;
result += d.seconds;
if (d.is_neg) result *= -1;
return result;
}
icalcomponent *ICalFormatImpl::createCalendarComponent(Calendar *cal)
{
icalcomponent *calendar;
// Root component
calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
icalproperty *p;
// Product Identifier
p = icalproperty_new_prodid(CalFormat::productId().utf8());
icalcomponent_add_property(calendar,p);
// TODO: Add time zone
// iCalendar version (2.0)
p = icalproperty_new_version(const_cast<char *>(_ICAL_VERSION));
icalcomponent_add_property(calendar,p);
// Custom properties
if( cal != 0 )
writeCustomProperties(calendar, cal);
return calendar;
}
// take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc.
// and break it down from its tree-like format into the dictionary format
// that is used internally in the ICalFormatImpl.
bool ICalFormatImpl::populate( Calendar *cal, icalcomponent *calendar)
{
// this function will populate the caldict dictionary and other event
// lists. It turns vevents into Events and then inserts them.
if (!calendar) return false;
// TODO: check for METHOD
#if 0
if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) {
char *methodType = 0;
methodType = fakeCString(vObjectUStringZValue(curVO));
if (mEnableDialogs)
KMessageBox::information(mTopWidget,
i18n("This calendar is an iTIP transaction of type \"%1\".")
.arg(methodType),
i18n("%1: iTIP Transaction").arg(CalFormat::application()));
delete methodType;
}
#endif
icalproperty *p;
p = icalcomponent_get_first_property(calendar,ICAL_PRODID_PROPERTY);
if (!p) {
// TODO: does no PRODID really matter?
// mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
// return false;
mLoadedProductId = "";
mCalendarVersion = 0;
} else {
mLoadedProductId = QString::fromUtf8(icalproperty_get_prodid(p));
mCalendarVersion = CalFormat::calendarVersion(mLoadedProductId);
delete mCompat;
mCompat = CompatFactory::createCompat( mLoadedProductId );
}
// TODO: check for unknown PRODID
#if 0
if (!mCalendarVersion
&& CalFormat::productId() != mLoadedProductId) {
// warn the user that we might have trouble reading non-known calendar.
if (mEnableDialogs)
KMessageBox::information(mTopWidget,
i18n("This vCalendar file was not created by KOrganizer "
"or any other product we support. Loading anyway..."),
i18n("%1: Unknown vCalendar Vendor").arg(CalFormat::application()));
}
#endif
p = icalcomponent_get_first_property(calendar,ICAL_VERSION_PROPERTY);
if (!p) {
mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
return false;
} else {
const char *version = icalproperty_get_version(p);
if (strcmp(version,"1.0") == 0) {
mParent->setException(new ErrorFormat(ErrorFormat::CalVersion1,
i18n("Expected iCalendar format")));
return false;
} else if (strcmp(version,"2.0") != 0) {
mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
return false;
}
}
// TODO: check for calendar format version
#if 0
// warn the user we might have trouble reading this unknown version.
if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) {
char *s = fakeCString(vObjectUStringZValue(curVO));
if (strcmp(_VCAL_VERSION, s) != 0)
if (mEnableDialogs)
KMessageBox::sorry(mTopWidget,
i18n("This vCalendar file has version %1.\n"
"We only support %2.")
.arg(s).arg(_VCAL_VERSION),
i18n("%1: Unknown vCalendar Version").arg(CalFormat::application()));
deleteStr(s);
}
#endif
// custom properties
readCustomProperties(calendar, cal);
// TODO: set time zone
#if 0
// set the time zone
if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) {
char *s = fakeCString(vObjectUStringZValue(curVO));
cal->setTimeZone(s);
deleteStr(s);
}
#endif
// Store all events with a relatedTo property in a list for post-processing
mEventsRelate.clear();
mTodosRelate.clear();
// TODO: make sure that only actually added ecvens go to this lists.
icalcomponent *c;
// Iterate through all todos
c = icalcomponent_get_first_component(calendar,ICAL_VTODO_COMPONENT);
while (c) {
// kdDebug(5800) << "----Todo found" << endl;
Todo *todo = readTodo(c);
- if (!cal->todo(todo->uid())) cal->addTodo(todo);
+ if (!cal->todo(todo->uid()))
+ cal->addTodo(todo);
c = icalcomponent_get_next_component(calendar,ICAL_VTODO_COMPONENT);
}
// Iterate through all events
c = icalcomponent_get_first_component(calendar,ICAL_VEVENT_COMPONENT);
while (c) {
// kdDebug(5800) << "----Event found" << endl;
Event *event = readEvent(c);
- if (!cal->event(event->uid())) cal->addEvent(event);
+ if (!cal->event(event->uid()))
+ cal->addEvent(event);
c = icalcomponent_get_next_component(calendar,ICAL_VEVENT_COMPONENT);
}
// Iterate through all journals
c = icalcomponent_get_first_component(calendar,ICAL_VJOURNAL_COMPONENT);
while (c) {
// kdDebug(5800) << "----Journal found" << endl;
Journal *journal = readJournal(c);
- if (!cal->journal(journal->uid())) cal->addJournal(journal);
+ if (!cal->journal(journal->uid()))
+ cal->addJournal(journal);
c = icalcomponent_get_next_component(calendar,ICAL_VJOURNAL_COMPONENT);
}
#if 0
initPropIterator(&i, vcal);
// go through all the vobjects in the vcal
while (moreIteration(&i)) {
curVO = nextVObject(&i);
/************************************************************************/
// now, check to see that the object is an event or todo.
if (strcmp(vObjectName(curVO), VCEventProp) == 0) {
if ((curVOProp = isAPropertyOf(curVO, KPilotStatusProp)) != 0) {
char *s;
s = fakeCString(vObjectUStringZValue(curVOProp));
// check to see if event was deleted by the kpilot conduit
if (atoi(s) == Event::SYNCDEL) {
deleteStr(s);
goto SKIP;
}
deleteStr(s);
}
// this code checks to see if we are trying to read in an event
// that we already find to be in the calendar. If we find this
// to be the case, we skip the event.
if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) {
char *s = fakeCString(vObjectUStringZValue(curVOProp));
QString tmpStr(s);
deleteStr(s);
if (cal->event(tmpStr)) {
goto SKIP;
}
if (cal->todo(tmpStr)) {
goto SKIP;
}
}
if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) &&
(!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) {
kdDebug(5800) << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl;
goto SKIP;
}
anEvent = VEventToEvent(curVO);
// we now use addEvent instead of insertEvent so that the
// signal/slot get connected.
if (anEvent)
cal->addEvent(anEvent);
else {
// some sort of error must have occurred while in translation.
goto SKIP;
}
} else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) {
anEvent = VTodoToEvent(curVO);
cal->addTodo(anEvent);
} else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) ||
(strcmp(vObjectName(curVO), VCProdIdProp) == 0) ||
(strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) {
// do nothing, we know these properties and we want to skip them.
// we have either already processed them or are ignoring them.
;
} else {
;
}
SKIP:
;
} // while
#endif
// Post-Process list of events with relations, put Event objects in relation
Event *ev;
for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) {
Incidence * inc = cal->event(ev->relatedToUid());
if ( inc )
ev->setRelatedTo( inc );
}
Todo *todo;
for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) {
Incidence * inc = cal->todo(todo->relatedToUid());
if ( inc )
todo->setRelatedTo( inc );
}
return true;
}
QString ICalFormatImpl::extractErrorProperty(icalcomponent *c)
{
// kdDebug(5800) << "ICalFormatImpl:extractErrorProperty: "
// << icalcomponent_as_ical_string(c) << endl;
QString errorMessage;
icalproperty *error;
error = icalcomponent_get_first_property(c,ICAL_XLICERROR_PROPERTY);
while(error) {
errorMessage += icalproperty_get_xlicerror(error);
errorMessage += "\n";
error = icalcomponent_get_next_property(c,ICAL_XLICERROR_PROPERTY);
}
// kdDebug(5800) << "ICalFormatImpl:extractErrorProperty: " << errorMessage << endl;
return errorMessage;
}
void ICalFormatImpl::dumpIcalRecurrence(icalrecurrencetype r)
{
int i;
if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
int index = 0;
QString out = " By Day: ";
while((i = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
out.append(QString::number(i) + " ");
}
}
if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
int index = 0;
QString out = " By Month Day: ";
while((i = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
out.append(QString::number(i) + " ");
}
}
if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
int index = 0;
QString out = " By Year Day: ";
while((i = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
out.append(QString::number(i) + " ");
}
}
if (r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) {
int index = 0;
QString out = " By Month: ";
while((i = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
out.append(QString::number(i) + " ");
}
}
if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
int index = 0;
QString out = " By Set Pos: ";
while((i = r.by_set_pos[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
out.append(QString::number(i) + " ");
}
}
}
icalcomponent *ICalFormatImpl::createScheduleComponent(IncidenceBase *incidence,
Scheduler::Method method)
{
icalcomponent *message = createCalendarComponent();
icalproperty_method icalmethod = ICAL_METHOD_NONE;
switch (method) {
case Scheduler::Publish:
icalmethod = ICAL_METHOD_PUBLISH;
break;
case Scheduler::Request:
icalmethod = ICAL_METHOD_REQUEST;
break;
case Scheduler::Refresh:
icalmethod = ICAL_METHOD_REFRESH;
break;
case Scheduler::Cancel:
icalmethod = ICAL_METHOD_CANCEL;
break;
case Scheduler::Add:
icalmethod = ICAL_METHOD_ADD;
break;
case Scheduler::Reply:
icalmethod = ICAL_METHOD_REPLY;
break;
case Scheduler::Counter:
icalmethod = ICAL_METHOD_COUNTER;
break;
case Scheduler::Declinecounter:
icalmethod = ICAL_METHOD_DECLINECOUNTER;
break;
default:
return message;
}
icalcomponent_add_property(message,icalproperty_new_method(icalmethod));
// TODO: check, if dynamic cast is required
if(incidence->typeID() == todoID ) {
Todo *todo = static_cast<Todo *>(incidence);
icalcomponent_add_component(message,writeTodo(todo));
}
if(incidence->typeID() == eventID ) {
Event *event = static_cast<Event *>(incidence);
icalcomponent_add_component(message,writeEvent(event));
}
if(incidence->typeID() == freebusyID) {
FreeBusy *freebusy = static_cast<FreeBusy *>(incidence);
icalcomponent_add_component(message,writeFreeBusy(freebusy, method));
}
return message;
}
diff --git a/libkcal/journal.cpp b/libkcal/journal.cpp
index 859161f..c4e4474 100644
--- a/libkcal/journal.cpp
+++ b/libkcal/journal.cpp
@@ -1,49 +1,51 @@
/*
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 "journal.h"
using namespace KCal;
Journal::Journal()
{
+ qDebug("New JJJ ");
}
Journal::~Journal()
{
+ qDebug("delete JJJ ");
}
Incidence *Journal::clone()
{
return new Journal(*this);
}
bool KCal::operator==( const Journal& j1, const Journal& j2 )
{
return operator==( (const Incidence&)j1, (const Incidence&)j2 );
}
QDateTime Journal::getNextAlarmDateTime( bool * ok, int * offset, QDateTime start_dt ) const
{
*ok = false;
return QDateTime ();
}