22 #include <tqdatetime.h>
24 #include <tqptrlist.h>
26 #include <tqclipboard.h>
28 #include <tqtextstream.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::Latin1 );
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.file()->writeBlock( textUtf8.data(), textUtf8.size() - 1 );
128 if ( !file.close() ) {
129 kdDebug(5800) <<
"KSaveFile: close: status was " << file.status() <<
". See errno.h." << endl;
131 i18n(
"Could not save '%1'").arg(fileName)));
149 icalcomponent *calendar;
152 calendar = icalcomponent_new_from_string( const_cast<char*>( (
const char*)text ) );
155 kdDebug(5800) <<
"ICalFormat::load() parse error" << endl;
162 if (icalcomponent_isa(calendar) == ICAL_XROOT_COMPONENT) {
164 for ( comp = icalcomponent_get_first_component(calendar, ICAL_VCALENDAR_COMPONENT);
165 comp != 0; comp = icalcomponent_get_next_component(calendar, ICAL_VCALENDAR_COMPONENT) ) {
167 if ( !mImpl->populate( cal, comp ) ) {
168 kdDebug(5800) <<
"ICalFormat::load(): Could not populate calendar" << endl;
174 mLoadedProductId = mImpl->loadedProductId();
176 icalcomponent_free( comp );
178 }
else if (icalcomponent_isa(calendar) != ICAL_VCALENDAR_COMPONENT) {
179 kdDebug(5800) <<
"ICalFormat::load(): No VCALENDAR component found" << endl;
184 if ( !mImpl->populate( cal, calendar ) ) {
185 kdDebug(5800) <<
"ICalFormat::load(): Could not populate calendar" << endl;
191 mLoadedProductId = mImpl->loadedProductId();
194 icalcomponent_free( calendar );
195 icalmemory_free_ring();
207 if ( elist.count() > 0 ) {
208 ical = elist.first();
211 if ( tlist.count() > 0 ) {
212 ical = tlist.first();
215 if ( jlist.count() > 0 ) {
216 ical = jlist.first();
221 return ical ? ical->
clone() : 0;
228 icalcomponent *calendar = mImpl->createCalendarComponent(cal);
230 icalcomponent *component;
234 Todo::List::ConstIterator it;
235 for( it = todoList.begin(); it != todoList.end(); ++it ) {
238 component = mImpl->writeTodo( *it );
239 icalcomponent_add_component( calendar, component );
244 Event::List::ConstIterator it2;
245 for( it2 = events.begin(); it2 != events.end(); ++it2 ) {
248 component = mImpl->writeEvent( *it2 );
249 icalcomponent_add_component( calendar, component );
254 Journal::List::ConstIterator it3;
255 for( it3 = journals.begin(); it3 != journals.end(); ++it3 ) {
256 kdDebug(5800) <<
"ICalFormat::toString() write journal "
257 << (*it3)->uid() << endl;
258 component = mImpl->writeJournal( *it3 );
259 icalcomponent_add_component( calendar, component );
262 TQString text = TQString::fromUtf8( icalcomponent_as_ical_string( calendar ) );
264 icalcomponent_free( calendar );
265 icalmemory_free_ring();
269 i18n(
"libical error")));
285 icalcomponent *component;
287 component = mImpl->writeIncidence( incidence );
289 TQString text = TQString::fromUtf8( icalcomponent_as_ical_string( component ) );
291 icalcomponent_free( component );
298 icalcomponent *component;
305 IncidenceListIterator it;
308 parentIncidence = calendar->
incidence(*it);
310 if (il.count() > 0) {
311 for ( it = il.begin(); it != il.end(); ++it ) {
312 component = mImpl->writeIncidence( calendar->
incidence(*it) );
313 text = text + TQString::fromUtf8( icalcomponent_as_ical_string( component ) );
314 icalcomponent_free( component );
317 component = mImpl->writeIncidence( parentIncidence );
318 text = text + TQString::fromUtf8( icalcomponent_as_ical_string( component ) );
319 icalcomponent_free( component );
324 if (il.count() > 0) {
325 IncidenceListIterator it;
326 for ( it = il.begin(); it != il.end(); ++it ) {
327 component = mImpl->writeIncidence( calendar->
incidence(*it) );
328 text = text + TQString::fromUtf8( icalcomponent_as_ical_string( component ) );
329 icalcomponent_free( component );
332 component = mImpl->writeIncidence( incidence );
333 text = text + TQString::fromUtf8( icalcomponent_as_ical_string( component ) );
334 icalcomponent_free( component );
342 icalproperty *property;
343 property = icalproperty_new_rrule( mImpl->writeRecurrenceRule( recurrence ) );
344 TQString text = TQString::fromUtf8( icalproperty_as_ical_string( property ) );
345 icalproperty_free( property );
351 if ( !recurrence )
return false;
353 icalerror_clear_errno();
354 struct icalrecurrencetype recur = icalrecurrencetype_from_string( rrule.latin1() );
355 if ( icalerrno != ICAL_NO_ERROR ) {
356 kdDebug(5800) <<
"Recurrence parsing error: " << icalerror_strerror( icalerrno ) << endl;
361 mImpl->readRecurrence( recur, recurrence );
371 icalcomponent *message = 0;
374 if ( incidence->type() ==
"Event" || incidence->type() ==
"Todo" ) {
383 message = mImpl->createScheduleComponent( i, method );
391 message = mImpl->createScheduleComponent(incidence,method);
394 TQString messageText = TQString::fromUtf8( icalcomponent_as_ical_string(message) );
397 kdDebug(5800) <<
"ICalFormat::createScheduleMessage: message START\n"
399 <<
"ICalFormat::createScheduleMessage: message END" << endl;
409 icalcomponent *message;
410 message = icalparser_parse_string( str.utf8() );
412 if ( !message )
return 0;
417 for ( c = icalcomponent_get_first_component( message, ICAL_VFREEBUSY_COMPONENT );
418 c != 0; c = icalcomponent_get_next_component( message, ICAL_VFREEBUSY_COMPONENT ) ) {
419 FreeBusy *fb = mImpl->readFreeBusy( c );
422 freeBusy->merge( fb );
430 kdDebug(5800) <<
"ICalFormat:parseFreeBusy: object is not a freebusy."
436 const TQString &messageText )
441 if (messageText.isEmpty())
447 icalcomponent *message;
448 message = icalparser_parse_string(messageText.utf8());
456 icalproperty *m = icalcomponent_get_first_property(message,
457 ICAL_METHOD_PROPERTY);
467 c = icalcomponent_get_first_component(message,ICAL_VEVENT_COMPONENT);
469 icalcomponent *ctz = icalcomponent_get_first_component(message,ICAL_VTIMEZONE_COMPONENT);
470 incidence = mImpl->readEvent(c, ctz);
474 c = icalcomponent_get_first_component(message,ICAL_VTODO_COMPONENT);
476 incidence = mImpl->readTodo(c);
481 c = icalcomponent_get_first_component(message,ICAL_VJOURNAL_COMPONENT);
483 incidence = mImpl->readJournal(c);
488 c = icalcomponent_get_first_component(message,ICAL_VFREEBUSY_COMPONENT);
490 incidence = mImpl->readFreeBusy(c);
497 kdDebug(5800) <<
"ICalFormat:parseScheduleMessage: object is not a freebusy, event, todo or journal" << endl;
502 kdDebug(5800) <<
"ICalFormat::parseScheduleMessage() getting method..." << endl;
504 icalproperty_method icalmethod = icalproperty_get_method(m);
507 switch (icalmethod) {
508 case ICAL_METHOD_PUBLISH:
509 method = Scheduler::Publish;
511 case ICAL_METHOD_REQUEST:
512 method = Scheduler::Request;
514 case ICAL_METHOD_REFRESH:
515 method = Scheduler::Refresh;
517 case ICAL_METHOD_CANCEL:
518 method = Scheduler::Cancel;
520 case ICAL_METHOD_ADD:
521 method = Scheduler::Add;
523 case ICAL_METHOD_REPLY:
524 method = Scheduler::Reply;
526 case ICAL_METHOD_COUNTER:
527 method = Scheduler::Counter;
529 case ICAL_METHOD_DECLINECOUNTER:
530 method = Scheduler::Declinecounter;
533 method = Scheduler::NoMethod;
534 kdDebug(5800) <<
"ICalFormat::parseScheduleMessage(): Unknow method" << endl;
538 kdDebug(5800) <<
"ICalFormat::parseScheduleMessage() restriction..." << endl;
540 if (!icalrestriction_check(message)) {
541 kdWarning(5800) << k_funcinfo << endl <<
"libkcal reported a problem while parsing:" << endl;
551 icalcomponent *calendarComponent = mImpl->createCalendarComponent(cal);
555 if (existingIncidence) {
558 if (existingIncidence->type() ==
"Todo") {
559 Todo *todo =
static_cast<Todo *
>(existingIncidence);
560 icalcomponent_add_component(calendarComponent,
561 mImpl->writeTodo(todo));
563 if (existingIncidence->type() ==
"Event") {
564 Event *
event =
static_cast<Event *
>(existingIncidence);
565 icalcomponent_add_component(calendarComponent,
566 mImpl->writeEvent(event));
569 calendarComponent = 0;
572 kdDebug(5800) <<
"ICalFormat::parseScheduleMessage() classify..." << endl;
574 icalproperty_xlicclass result = icalclassify( message, calendarComponent,
577 kdDebug(5800) <<
"ICalFormat::parseScheduleMessage() returning..." << endl;
578 kdDebug(5800) <<
"ICalFormat::parseScheduleMessage(), result = " << result << endl;
583 case ICAL_XLICCLASS_PUBLISHNEW:
584 status = ScheduleMessage::PublishNew;
586 case ICAL_XLICCLASS_PUBLISHUPDATE:
587 status = ScheduleMessage::PublishUpdate;
589 case ICAL_XLICCLASS_OBSOLETE:
590 status = ScheduleMessage::Obsolete;
592 case ICAL_XLICCLASS_REQUESTNEW:
593 status = ScheduleMessage::RequestNew;
595 case ICAL_XLICCLASS_REQUESTUPDATE:
596 status = ScheduleMessage::RequestUpdate;
598 case ICAL_XLICCLASS_UNKNOWN:
600 status = ScheduleMessage::Unknown;
604 kdDebug(5800) <<
"ICalFormat::parseScheduleMessage(), status = " << status << endl;