22 #include <tqdatetime.h>
24 #include <tqptrlist.h>
26 #include <tqclipboard.h>
28 #include <tqtextstream.h>
31 #include <tdelocale.h>
34 #include <libical/ical.h>
35 #include <libical/icalss.h>
36 #include <libical/icalparser.h>
37 #include <libical/icalrestriction.h>
38 #include <libical/icalmemory.h>
42 #include "calendarlocal.h"
45 #include "icalformat.h"
46 #include "icalformatimpl.h"
47 #include <ksavefile.h>
51 #define _ICAL_VERSION "2.0"
55 ICalFormat::ICalFormat() : mImpl(0)
57 setImplementation(
new ICalFormatImpl(
this ) );
63 ICalFormat::~ICalFormat()
68 void ICalFormat::setImplementation( ICalFormatImpl *impl )
70 if ( mImpl )
delete mImpl;
74 #if defined(_AIX) && defined(open)
80 kdDebug(5800) <<
"ICalFormat::load() " << fileName << endl;
84 TQFile file( fileName );
85 if (!file.open( IO_ReadOnly ) ) {
86 kdDebug(5800) <<
"ICalFormat::load() load error" << endl;
90 TQTextStream ts( &file );
91 ts.setEncoding( TQTextStream::UnicodeUTF8 );
92 TQString text = ts.read();
95 if ( text.stripWhiteSpace().isEmpty() )
104 kdDebug(5800) <<
"ICalFormat::save(): " << fileName << endl;
108 TQString text =
toString( calendar );
110 if ( text.isNull() )
return false;
113 KSaveFile::backupFile( fileName );
115 KSaveFile file( fileName );
116 if ( file.status() != 0 ) {
117 kdDebug(5800) <<
"ICalFormat::save() errno: " << strerror( file.status() )
120 i18n(
"Error saving to '%1'." ).arg( fileName ) ) );
125 TQCString textUtf8 = text.utf8();
126 file.textStream()->setEncoding( TQTextStream::UnicodeUTF8 );
127 file.file()->writeBlock(textUtf8.data(),textUtf8.size()-1);
129 if ( !file.close() ) {
130 kdDebug(5800) <<
"KSaveFile: close: status was " << file.status() <<
". See errno.h." << endl;
132 i18n(
"Could not save '%1'").arg(fileName)));
150 icalcomponent *calendar;
153 calendar = icalcomponent_new_from_string(
const_cast<char*
>( (
const char*)text ) );
156 kdDebug(5800) <<
"ICalFormat::load() parse error" << endl;
163 if (icalcomponent_isa(calendar) == ICAL_XROOT_COMPONENT) {
165 for ( comp = icalcomponent_get_first_component(calendar, ICAL_VCALENDAR_COMPONENT);
166 comp != 0; comp = icalcomponent_get_next_component(calendar, ICAL_VCALENDAR_COMPONENT) ) {
168 if ( !mImpl->populate( cal, comp ) ) {
169 kdDebug(5800) <<
"ICalFormat::load(): Could not populate calendar" << endl;
175 mLoadedProductId = mImpl->loadedProductId();
177 icalcomponent_free( comp );
179 }
else if (icalcomponent_isa(calendar) != ICAL_VCALENDAR_COMPONENT) {
180 kdDebug(5800) <<
"ICalFormat::load(): No VCALENDAR component found" << endl;
185 if ( !mImpl->populate( cal, calendar ) ) {
186 kdDebug(5800) <<
"ICalFormat::load(): Could not populate calendar" << endl;
192 mLoadedProductId = mImpl->loadedProductId();
195 icalcomponent_free( calendar );
196 icalmemory_free_ring();
208 if ( elist.count() > 0 ) {
209 ical = elist.first();
212 if ( tlist.count() > 0 ) {
213 ical = tlist.first();
216 if ( jlist.count() > 0 ) {
217 ical = jlist.first();
222 return ical ? ical->
clone() : 0;
229 icalcomponent *calendar = mImpl->createCalendarComponent(cal);
231 icalcomponent *component;
235 Todo::List::ConstIterator it;
236 for( it = todoList.begin(); it != todoList.end(); ++it ) {
239 component = mImpl->writeTodo( *it );
240 icalcomponent_add_component( calendar, component );
245 Event::List::ConstIterator it2;
246 for( it2 = events.begin(); it2 != events.end(); ++it2 ) {
249 component = mImpl->writeEvent( *it2 );
250 icalcomponent_add_component( calendar, component );
255 Journal::List::ConstIterator it3;
256 for( it3 = journals.begin(); it3 != journals.end(); ++it3 ) {
257 kdDebug(5800) <<
"ICalFormat::toString() write journal "
258 << (*it3)->uid() << endl;
259 component = mImpl->writeJournal( *it3 );
260 icalcomponent_add_component( calendar, component );
263 TQString text = TQString::fromUtf8( icalcomponent_as_ical_string( calendar ) );
265 icalcomponent_free( calendar );
266 icalmemory_free_ring();
270 i18n(
"libical error")));
286 icalcomponent *component;
288 component = mImpl->writeIncidence( incidence );
290 TQString text = TQString::fromUtf8( icalcomponent_as_ical_string( component ) );
292 icalcomponent_free( component );
299 icalcomponent *component;
306 IncidenceListIterator it;
309 parentIncidence = calendar->
incidence(*it);
311 if (il.count() > 0) {
312 for ( it = il.begin(); it != il.end(); ++it ) {
313 component = mImpl->writeIncidence( calendar->
incidence(*it) );
314 text = text + TQString::fromUtf8( icalcomponent_as_ical_string( component ) );
315 icalcomponent_free( component );
318 component = mImpl->writeIncidence( parentIncidence );
319 text = text + TQString::fromUtf8( icalcomponent_as_ical_string( component ) );
320 icalcomponent_free( component );
325 if (il.count() > 0) {
326 IncidenceListIterator it;
327 for ( it = il.begin(); it != il.end(); ++it ) {
328 component = mImpl->writeIncidence( calendar->
incidence(*it) );
329 text = text + TQString::fromUtf8( icalcomponent_as_ical_string( component ) );
330 icalcomponent_free( component );
333 component = mImpl->writeIncidence( incidence );
334 text = text + TQString::fromUtf8( icalcomponent_as_ical_string( component ) );
335 icalcomponent_free( component );
343 icalproperty *property;
344 property = icalproperty_new_rrule( mImpl->writeRecurrenceRule( recurrence ) );
345 TQString text = TQString::fromUtf8( icalproperty_as_ical_string( property ) );
346 icalproperty_free( property );
352 if ( !recurrence )
return false;
354 icalerror_clear_errno();
355 struct icalrecurrencetype recur = icalrecurrencetype_from_string( rrule.latin1() );
356 if ( icalerrno != ICAL_NO_ERROR ) {
357 kdDebug(5800) <<
"Recurrence parsing error: " << icalerror_strerror( icalerrno ) << endl;
362 mImpl->readRecurrence( recur, recurrence );
372 icalcomponent *message = 0;
375 if ( incidence->type() ==
"Event" || incidence->type() ==
"Todo" ) {
384 message = mImpl->createScheduleComponent( i, method );
392 message = mImpl->createScheduleComponent(incidence,method);
395 TQString messageText = TQString::fromUtf8( icalcomponent_as_ical_string(message) );
398 kdDebug(5800) <<
"ICalFormat::createScheduleMessage: message START\n"
400 <<
"ICalFormat::createScheduleMessage: message END" << endl;
410 icalcomponent *message;
411 message = icalparser_parse_string( str.utf8() );
413 if ( !message )
return 0;
418 for ( c = icalcomponent_get_first_component( message, ICAL_VFREEBUSY_COMPONENT );
419 c != 0; c = icalcomponent_get_next_component( message, ICAL_VFREEBUSY_COMPONENT ) ) {
420 FreeBusy *fb = mImpl->readFreeBusy( c );
423 freeBusy->merge( fb );
431 kdDebug(5800) <<
"ICalFormat:parseFreeBusy: object is not a freebusy."
437 const TQString &messageText )
442 if (messageText.isEmpty())
448 icalcomponent *message;
449 message = icalparser_parse_string(messageText.utf8());
457 icalproperty *m = icalcomponent_get_first_property(message,
458 ICAL_METHOD_PROPERTY);
468 c = icalcomponent_get_first_component(message,ICAL_VEVENT_COMPONENT);
470 icalcomponent *ctz = icalcomponent_get_first_component(message,ICAL_VTIMEZONE_COMPONENT);
471 incidence = mImpl->readEvent(c, ctz);
475 c = icalcomponent_get_first_component(message,ICAL_VTODO_COMPONENT);
477 incidence = mImpl->readTodo(c);
482 c = icalcomponent_get_first_component(message,ICAL_VJOURNAL_COMPONENT);
484 incidence = mImpl->readJournal(c);
489 c = icalcomponent_get_first_component(message,ICAL_VFREEBUSY_COMPONENT);
491 incidence = mImpl->readFreeBusy(c);
498 kdDebug(5800) <<
"ICalFormat:parseScheduleMessage: object is not a freebusy, event, todo or journal" << endl;
503 kdDebug(5800) <<
"ICalFormat::parseScheduleMessage() getting method..." << endl;
505 icalproperty_method icalmethod = icalproperty_get_method(m);
508 switch (icalmethod) {
509 case ICAL_METHOD_PUBLISH:
510 method = Scheduler::Publish;
512 case ICAL_METHOD_REQUEST:
513 method = Scheduler::Request;
515 case ICAL_METHOD_REFRESH:
516 method = Scheduler::Refresh;
518 case ICAL_METHOD_CANCEL:
519 method = Scheduler::Cancel;
521 case ICAL_METHOD_ADD:
522 method = Scheduler::Add;
524 case ICAL_METHOD_REPLY:
525 method = Scheduler::Reply;
527 case ICAL_METHOD_COUNTER:
528 method = Scheduler::Counter;
530 case ICAL_METHOD_DECLINECOUNTER:
531 method = Scheduler::Declinecounter;
534 method = Scheduler::NoMethod;
535 kdDebug(5800) <<
"ICalFormat::parseScheduleMessage(): Unknow method" << endl;
539 kdDebug(5800) <<
"ICalFormat::parseScheduleMessage() restriction..." << endl;
541 if (!icalrestriction_check(message)) {
542 kdWarning(5800) << k_funcinfo << endl <<
"libkcal reported a problem while parsing:" << endl;
552 icalcomponent *calendarComponent = mImpl->createCalendarComponent(cal);
556 if (existingIncidence) {
559 if (existingIncidence->type() ==
"Todo") {
560 Todo *todo =
static_cast<Todo *
>(existingIncidence);
561 icalcomponent_add_component(calendarComponent,
562 mImpl->writeTodo(todo));
564 if (existingIncidence->type() ==
"Event") {
565 Event *
event =
static_cast<Event *
>(existingIncidence);
566 icalcomponent_add_component(calendarComponent,
567 mImpl->writeEvent(event));
570 calendarComponent = 0;
573 kdDebug(5800) <<
"ICalFormat::parseScheduleMessage() classify..." << endl;
575 icalproperty_xlicclass result = icalclassify( message, calendarComponent,
578 kdDebug(5800) <<
"ICalFormat::parseScheduleMessage() returning..." << endl;
579 kdDebug(5800) <<
"ICalFormat::parseScheduleMessage(), result = " << result << endl;
584 case ICAL_XLICCLASS_PUBLISHNEW:
585 status = ScheduleMessage::PublishNew;
587 case ICAL_XLICCLASS_PUBLISHUPDATE:
588 status = ScheduleMessage::PublishUpdate;
590 case ICAL_XLICCLASS_OBSOLETE:
591 status = ScheduleMessage::Obsolete;
593 case ICAL_XLICCLASS_REQUESTNEW:
594 status = ScheduleMessage::RequestNew;
596 case ICAL_XLICCLASS_REQUESTUPDATE:
597 status = ScheduleMessage::RequestUpdate;
599 case ICAL_XLICCLASS_UNKNOWN:
601 status = ScheduleMessage::Unknown;
605 kdDebug(5800) <<
"ICalFormat::parseScheduleMessage(), status = " << status << endl;
Provides the main "calendar" object class.
This class provides a calendar stored as a local file.
This is the main "calendar" object class.
virtual bool addIncidence(Incidence *incidence)
Insert an Incidence into the Calendar.
bool isLocalTime() const
Determine if Calendar Incidences are to be written without a time zone.
Incidence * incidenceFromSchedulingID(const TQString &sid)
Returns the Incidence associated with the given scheduling identifier.
virtual Event::List rawEvents(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)=0
Return a sorted, unfiltered list of all Events for this Calendar.
TQString timeZoneId() const
Get the Time Zone ID for the Calendar.
virtual Event::List events(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return a sorted, filtered list of all Events for this Calendar.
virtual Journal::List journals(JournalSortField sortField=JournalSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return a sorted, filtered list of all Journals for this Calendar.
virtual Todo::List rawTodos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending)=0
Return a sorted, unfiltered list of all Todos for this Calendar.
Incidence * incidence(const TQString &uid)
Returns the Incidence associated with the given unique identifier.
virtual Todo::List todos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return a sorted, filtered list of all Todos for this Calendar.
This class provides an Event in the sense of RFC2445.
This class provides information about free/busy time of a calendar user.
This class provides the base class common to all calendar components.
TQString uid() const
Return the unique id for the event.
void setUid(const TQString &)
Set the unique id for the event.
This class provides the base class common to all calendar components.
virtual Incidence * clone()=0
Return copy of this object.
void setSchedulingID(const TQString &sid)
Set the event's/todo's scheduling ID.
IncidenceList childIncidences() const
Returns an EventList of all child incidences.
TQString schedulingID() const
Return the event's/todo's scheduling ID.
bool hasRecurrenceID() const
Returns true if the incidence has recurrenceID, otherwise return false.
This class represents a recurrence rule for a calendar incidence.
This class provides an encapsulation of a scheduling message.
static TQString translatedMethodName(Method)
Return a translated human-readable name for a iTIP method.
This class provides a Todo in the sense of RFC2445.
Namespace KCal is for global classes, objects and/or functions in libkcal.