icalformat.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qdatetime.h>
00022 #include <qstring.h>
00023 #include <qptrlist.h>
00024 #include <qregexp.h>
00025 #include <qclipboard.h>
00026 #include <qfile.h>
00027 #include <qtextstream.h>
00028
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031
00032 extern "C" {
00033 #include <ical.h>
00034 #include <icalss.h>
00035 #include <icalparser.h>
00036 #include <icalrestriction.h>
00037 }
00038
00039 #include "calendar.h"
00040 #include "journal.h"
00041
00042 #include "icalformat.h"
00043 #include "icalformatimpl.h"
00044
00045 #define _ICAL_VERSION "2.0"
00046
00047 using namespace KCal;
00048
00049 ICalFormat::ICalFormat()
00050 {
00051 mImpl = new ICalFormatImpl( this );
00052
00053 mTimeZoneId = "UTC";
00054 mUtc = true;
00055 }
00056
00057 ICalFormat::~ICalFormat()
00058 {
00059 delete mImpl;
00060 }
00061
00062 bool ICalFormat::load( Calendar *calendar, const QString &fileName)
00063 {
00064 kdDebug(5800) << "ICalFormat::load() " << fileName << endl;
00065
00066 clearException();
00067
00068 QFile file( fileName );
00069 if (!file.open( IO_ReadOnly ) ) {
00070 kdDebug(5800) << "ICalFormat::load() load error" << endl;
00071 setException(new ErrorFormat(ErrorFormat::LoadError));
00072 return false;
00073 }
00074 QTextStream ts( &file );
00075 QString text = ts.read();
00076 file.close();
00077
00078 return fromString( calendar, text );
00079 }
00080
00081
00082 bool ICalFormat::save( Calendar *calendar, const QString &fileName )
00083 {
00084 kdDebug(5800) << "ICalFormat::save(): " << fileName << endl;
00085
00086 clearException();
00087
00088 QString text = toString( calendar );
00089
00090 if ( text.isNull() ) return false;
00091
00092
00093
00094 QFile file( fileName );
00095 if (!file.open( IO_WriteOnly ) ) {
00096 setException(new ErrorFormat(ErrorFormat::SaveError,
00097 i18n("Could not open file '%1'").arg(fileName)));
00098 return false;
00099 }
00100 QTextStream ts( &file );
00101 ts << text;
00102 file.close();
00103
00104 return true;
00105 }
00106
00107 bool ICalFormat::fromString( Calendar *cal, const QString &text )
00108 {
00109 setTimeZone( cal->timeZoneId(), !cal->isLocalTime() );
00110
00111
00112
00113 icalcomponent *calendar;
00114
00115 calendar = icalcomponent_new_from_string( text.utf8().data());
00116
00117 if (!calendar) {
00118 kdDebug(5800) << "ICalFormat::load() parse error" << endl;
00119 setException(new ErrorFormat(ErrorFormat::ParseErrorIcal));
00120 return false;
00121 }
00122
00123 bool success = true;
00124
00125 if (icalcomponent_isa(calendar) != ICAL_VCALENDAR_COMPONENT) {
00126 kdDebug(5800) << "ICalFormat::load(): No VCALENDAR component found" << endl;
00127 setException(new ErrorFormat(ErrorFormat::NoCalendar));
00128 success = false;
00129 } else {
00130
00131 if ( !mImpl->populate( cal, calendar ) ) {
00132 kdDebug(5800) << "ICalFormat::load(): Could not populate calendar" << endl;
00133 if ( !exception() ) {
00134 setException(new ErrorFormat(ErrorFormat::ParseErrorKcal));
00135 }
00136 success = false;
00137 } else
00138 mLoadedProductId = mImpl->loadedProductId();
00139 }
00140
00141 icalcomponent_free( calendar );
00142
00143 return success;
00144 }
00145
00146 QString ICalFormat::toString( Calendar *cal )
00147 {
00148 setTimeZone( cal->timeZoneId(), !cal->isLocalTime() );
00149
00150 icalcomponent *calendar = mImpl->createCalendarComponent();
00151
00152 icalcomponent *component;
00153
00154
00155 QPtrList<Todo> todoList = cal->rawTodos();
00156 QPtrListIterator<Todo> qlt(todoList);
00157 for (; qlt.current(); ++qlt) {
00158 component = mImpl->writeTodo(qlt.current());
00159 icalcomponent_add_component(calendar,component);
00160 }
00161
00162
00163 QPtrList<Event> events = cal->rawEvents();
00164 Event *ev;
00165 for(ev=events.first();ev;ev=events.next()) {
00166 component = mImpl->writeEvent(ev);
00167 icalcomponent_add_component(calendar,component);
00168 }
00169
00170
00171 QPtrList<Journal> journals = cal->journals();
00172 Journal *j;
00173 for(j=journals.first();j;j=journals.next()) {
00174 component = mImpl->writeJournal(j);
00175 icalcomponent_add_component(calendar,component);
00176 }
00177
00178 QString text = QString::fromUtf8( icalcomponent_as_ical_string( calendar ) );
00179
00180 icalcomponent_free( calendar );
00181
00182 if (!text) {
00183 setException(new ErrorFormat(ErrorFormat::SaveError,
00184 i18n("libical error")));
00185 return QString::null;
00186 }
00187
00188 return text;
00189 }
00190
00191 QString ICalFormat::toString( Incidence *incidence )
00192 {
00193 icalcomponent *component;
00194
00195 component = mImpl->writeIncidence( incidence );
00196
00197 QString text = QString::fromUtf8( icalcomponent_as_ical_string( component ) );
00198
00199 icalcomponent_free( component );
00200
00201 return text;
00202 }
00203
00204 QString ICalFormat::toString( Recurrence *recurrence )
00205 {
00206 icalproperty *property;
00207 property = mImpl->writeRecurrenceRule( recurrence );
00208 QString text = QString::fromUtf8( icalproperty_as_ical_string( property ) );
00209 icalproperty_free( property );
00210 return text;
00211 }
00212
00213 bool ICalFormat::fromString( Recurrence * recurrence, const QString& rrule )
00214 {
00215 bool success = true;
00216 icalerror_clear_errno();
00217 struct icalrecurrencetype recur = icalrecurrencetype_from_string( rrule );
00218 if ( icalerrno != ICAL_NO_ERROR ) {
00219 kdDebug() << "Recurrence parsing error: " << icalerror_strerror( icalerrno ) << endl;
00220 success = false;
00221 }
00222
00223 if ( success ) {
00224 mImpl->readRecurrence( recur, recurrence );
00225 }
00226
00227 return success;
00228 }
00229
00230
00231 QString ICalFormat::createScheduleMessage(IncidenceBase *incidence,
00232 Scheduler::Method method)
00233 {
00234 icalcomponent *message = mImpl->createScheduleComponent(incidence,method);
00235
00236 QString messageText = QString::fromUtf8( icalcomponent_as_ical_string(message) );
00237
00238 #if 0
00239 kdDebug(5800) << "ICalFormat::createScheduleMessage: message START\n"
00240 << messageText
00241 << "ICalFormat::createScheduleMessage: message END" << endl;
00242 #endif
00243
00244 return messageText;
00245 }
00246
00247 ScheduleMessage *ICalFormat::parseScheduleMessage( Calendar *cal,
00248 const QString &messageText )
00249 {
00250 clearException();
00251
00252 if (messageText.isEmpty()) return 0;
00253
00254 icalcomponent *message;
00255 message = icalparser_parse_string(messageText.local8Bit());
00256
00257 if (!message) return 0;
00258
00259 icalproperty *m = icalcomponent_get_first_property(message,
00260 ICAL_METHOD_PROPERTY);
00261
00262 if (!m) return 0;
00263
00264 icalcomponent *c;
00265
00266 IncidenceBase *incidence = 0;
00267 c = icalcomponent_get_first_component(message,ICAL_VEVENT_COMPONENT);
00268 if (c) {
00269 incidence = mImpl->readEvent(c);
00270 }
00271
00272 c = icalcomponent_get_first_component(message,ICAL_VTODO_COMPONENT);
00273 if (c) {
00274 incidence = mImpl->readTodo(c);
00275 }
00276
00277 c = icalcomponent_get_first_component(message,ICAL_VFREEBUSY_COMPONENT);
00278 if (c) {
00279 incidence = mImpl->readFreeBusy(c);
00280 }
00281
00282 if (!incidence) {
00283 kdDebug() << "ICalFormat:parseScheduleMessage: object is not a freebusy, event or todo" << endl;
00284 return 0;
00285 }
00286
00287 kdDebug(5800) << "ICalFormat::parseScheduleMessage() getting method..." << endl;
00288
00289 icalproperty_method icalmethod = icalproperty_get_method(m);
00290 Scheduler::Method method;
00291
00292 switch (icalmethod) {
00293 case ICAL_METHOD_PUBLISH:
00294 method = Scheduler::Publish;
00295 break;
00296 case ICAL_METHOD_REQUEST:
00297 method = Scheduler::Request;
00298 break;
00299 case ICAL_METHOD_REFRESH:
00300 method = Scheduler::Refresh;
00301 break;
00302 case ICAL_METHOD_CANCEL:
00303 method = Scheduler::Cancel;
00304 break;
00305 case ICAL_METHOD_ADD:
00306 method = Scheduler::Add;
00307 break;
00308 case ICAL_METHOD_REPLY:
00309 method = Scheduler::Reply;
00310 break;
00311 case ICAL_METHOD_COUNTER:
00312 method = Scheduler::Counter;
00313 break;
00314 case ICAL_METHOD_DECLINECOUNTER:
00315 method = Scheduler::Declinecounter;
00316 break;
00317 default:
00318 method = Scheduler::NoMethod;
00319 kdDebug(5800) << "ICalFormat::parseScheduleMessage(): Unknow method" << endl;
00320 break;
00321 }
00322
00323 kdDebug(5800) << "ICalFormat::parseScheduleMessage() restriction..." << endl;
00324
00325 if (!icalrestriction_check(message)) {
00326 setException(new ErrorFormat(ErrorFormat::Restriction,
00327 Scheduler::methodName(method) + ": " +
00328 mImpl->extractErrorProperty(c)));
00329 return 0;
00330 }
00331
00332 icalcomponent *calendarComponent = mImpl->createCalendarComponent();
00333
00334 Incidence *existingIncidence = cal->event(incidence->uid());
00335 if (existingIncidence) {
00336
00337 if (existingIncidence->type() == "Todo") {
00338 Todo *todo = static_cast<Todo *>(existingIncidence);
00339 icalcomponent_add_component(calendarComponent,
00340 mImpl->writeTodo(todo));
00341 }
00342 if (existingIncidence->type() == "Event") {
00343 Event *event = static_cast<Event *>(existingIncidence);
00344 icalcomponent_add_component(calendarComponent,
00345 mImpl->writeEvent(event));
00346 }
00347 } else {
00348 calendarComponent = 0;
00349 }
00350
00351 kdDebug(5800) << "ICalFormat::parseScheduleMessage() classify..." << endl;
00352
00353 icalclass result = icalclassify(message,calendarComponent,(char *)"");
00354
00355 kdDebug(5800) << "ICalFormat::parseScheduleMessage() returning..." << endl;
00356
00357 ScheduleMessage::Status status;
00358
00359 switch (result) {
00360 case ICAL_PUBLISH_NEW_CLASS:
00361 status = ScheduleMessage::PublishNew;
00362 break;
00363 case ICAL_OBSOLETE_CLASS:
00364 status = ScheduleMessage::Obsolete;
00365 break;
00366 case ICAL_REQUEST_NEW_CLASS:
00367 status = ScheduleMessage::RequestNew;
00368 break;
00369 case ICAL_REQUEST_UPDATE_CLASS:
00370 status = ScheduleMessage::RequestUpdate;
00371 break;
00372 case ICAL_UNKNOWN_CLASS:
00373 default:
00374 status = ScheduleMessage::Unknown;
00375 break;
00376 }
00377
00378 return new ScheduleMessage(incidence,method,status);
00379 }
00380
00381 void ICalFormat::setTimeZone( const QString &id, bool utc )
00382 {
00383 mTimeZoneId = id;
00384 mUtc = utc;
00385 }
00386
00387 QString ICalFormat::timeZoneId() const
00388 {
00389 return mTimeZoneId;
00390 }
00391
00392 bool ICalFormat::utc() const
00393 {
00394 return mUtc;
00395 }
This file is part of the documentation for kdelibs Version 3.1.5.