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() )
98 return fromRawString( calendar, text.utf8() );
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)));
141 return fromRawString( cal, text.utf8() );
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;
170 if ( !exception() ) {
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;
187 if ( !exception() ) {
192 mLoadedProductId = mImpl->loadedProductId();
195 icalcomponent_free( calendar );
196 icalmemory_free_ring();
204 fromString(&cal, text);
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")));
281 return toString( &cal );
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;
virtual Todo::List rawTodos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending)=0
Return a sorted, unfiltered list of all Todos for this Calendar.
void setUid(const TQString &)
Set the unique id for the event.
bool isLocalTime() const
Determine if Calendar Incidences are to be written without a time zone.
This class provides a Todo in the sense of RFC2445.
IncidenceList childIncidences() const
Returns an EventList of all child incidences.
This is the main "calendar" object class.
This class provides the base class common to all calendar components.
This class provides an Event in the sense of RFC2445.
This class provides an encapsulation of a scheduling message.
virtual Event::List rawEvents(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)=0
Return a sorted, unfiltered list of all Events for this Calendar.
This class provides a calendar stored as a local file.
TQString timeZoneId() const
Get the Time Zone ID for the Calendar.
Provides the main "calendar" object class.
TQString uid() const
Return the unique id for the event.
This class provides the base class common to all calendar components.
Incidence * incidence(const TQString &uid)
Returns the Incidence associated with the given unique identifier.
Incidence * incidenceFromSchedulingID(const TQString &sid)
Returns the Incidence associated with the given scheduling identifier.
void setSchedulingID(const TQString &sid)
Set the event's/todo's scheduling ID.
Namespace KCal is for global classes, objects and/or functions in libkcal.
virtual bool addIncidence(Incidence *incidence)
Insert an Incidence into the Calendar.
virtual Journal::List journals(JournalSortField sortField=JournalSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return a sorted, filtered list of all Journals for this Calendar.
bool hasRecurrenceID() const
Returns true if the incidence has recurrenceID, otherwise return false.
virtual Todo::List todos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return a sorted, filtered list of all Todos for this Calendar.
static TQString translatedMethodName(Method)
Return a translated human-readable name for a iTIP method.
virtual Event::List events(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return a sorted, filtered list of all Events for this Calendar.
TQString schedulingID() const
Return the event's/todo's scheduling ID.
This class provides information about free/busy time of a calendar user.
virtual Incidence * clone()=0
Return copy of this object.
This class represents a recurrence rule for a calendar incidence.