libkcal Library API Documentation

icalformatimpl.cpp

00001 /*
00002     This file is part of libkcal.
00003     Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018     Boston, MA 02111-1307, USA.
00019 */
00020 
00021 #include <qdatetime.h>
00022 #include <qstring.h>
00023 #include <qptrlist.h>
00024 #include <qfile.h>
00025 
00026 #include <kdebug.h>
00027 #include <klocale.h>
00028 
00029 extern "C" {
00030   #include <ical.h>
00031   #include <icalss.h>
00032   #include <icalparser.h>
00033   #include <icalrestriction.h>
00034 }
00035 
00036 #include "calendar.h"
00037 #include "journal.h"
00038 #include "icalformat.h"
00039 #include "icalformatimpl.h"
00040 #include "compat.h"
00041 
00042 #define _ICAL_VERSION "2.0"
00043 
00044 using namespace KCal;
00045 
00046 const int gSecondsPerMinute = 60;
00047 const int gSecondsPerHour   = gSecondsPerMinute * 60;
00048 const int gSecondsPerDay    = gSecondsPerHour   * 24;
00049 const int gSecondsPerWeek   = gSecondsPerDay    * 7;
00050 
00051 ICalFormatImpl::ICalFormatImpl( ICalFormat *parent ) :
00052   mParent( parent )
00053 {
00054   mCompat = new Compat;
00055 }
00056 
00057 ICalFormatImpl::~ICalFormatImpl()
00058 {
00059   delete mCompat;
00060 }
00061 
00062 class ToStringVisitor : public Incidence::Visitor
00063 {
00064   public:
00065     ToStringVisitor( ICalFormatImpl *impl ) : mImpl( impl ), mComponent( 0 ) {}
00066 
00067     bool visit( Event *e ) { mComponent = mImpl->writeEvent( e ); return true; }
00068     bool visit( Todo *e ) { mComponent = mImpl->writeTodo( e ); return true; }
00069     bool visit( Journal *e ) { mComponent = mImpl->writeJournal( e ); return true; }
00070 
00071     icalcomponent *component() { return mComponent; }
00072 
00073   private:
00074     ICalFormatImpl *mImpl;
00075     icalcomponent *mComponent;
00076 };
00077 
00078 icalcomponent *ICalFormatImpl::writeIncidence(Incidence *incidence)
00079 {
00080   ToStringVisitor v( this );
00081   incidence->accept(v);
00082   return v.component();
00083 }
00084 
00085 icalcomponent *ICalFormatImpl::writeTodo(Todo *todo)
00086 {
00087   QString tmpStr;
00088   QStringList tmpStrList;
00089 
00090   icalcomponent *vtodo = icalcomponent_new(ICAL_VTODO_COMPONENT);
00091 
00092   writeIncidence(vtodo,todo);
00093 
00094   // due date
00095   if (todo->hasDueDate()) {
00096     icaltimetype due;
00097     if (todo->doesFloat()) {
00098       due = writeICalDate(todo->dtDue().date());
00099     } else {
00100       due = writeICalDateTime(todo->dtDue());
00101     }
00102     icalcomponent_add_property(vtodo,icalproperty_new_due(due));
00103   }
00104 
00105   // start time
00106   if (todo->hasStartDate()) {
00107     icaltimetype start;
00108     if (todo->doesFloat()) {
00109 //      kdDebug(5800) << "§§ Incidence " << todo->summary() << " floats." << endl;
00110       start = writeICalDate(todo->dtStart().date());
00111     } else {
00112 //      kdDebug(5800) << "§§ incidence " << todo->summary() << " has time." << endl;
00113       start = writeICalDateTime(todo->dtStart());
00114     }
00115     icalcomponent_add_property(vtodo,icalproperty_new_dtstart(start));
00116   }
00117 
00118   // completion date
00119   if (todo->isCompleted()) {
00120     if (!todo->hasCompletedDate()) {
00121       // If todo was created by KOrganizer <2.2 it has no correct completion
00122       // date. Set it to now.
00123       todo->setCompleted(QDateTime::currentDateTime());
00124     }
00125     icaltimetype completed = writeICalDateTime(todo->completed());
00126     icalcomponent_add_property(vtodo,icalproperty_new_completed(completed));
00127   }
00128 
00129   icalcomponent_add_property(vtodo,
00130       icalproperty_new_percentcomplete(todo->percentComplete()));
00131 
00132   return vtodo;
00133 }
00134 
00135 icalcomponent *ICalFormatImpl::writeEvent(Event *event)
00136 {
00137   kdDebug(5800) << "Write Event '" << event->summary() << "' (" << event->uid()
00138               << ")" << endl;
00139 
00140   QString tmpStr;
00141   QStringList tmpStrList;
00142 
00143   icalcomponent *vevent = icalcomponent_new(ICAL_VEVENT_COMPONENT);
00144 
00145   writeIncidence(vevent,event);
00146 
00147   // start time
00148   icaltimetype start;
00149   if (event->doesFloat()) {
00150 //    kdDebug(5800) << "§§ Incidence " << event->summary() << " floats." << endl;
00151     start = writeICalDate(event->dtStart().date());
00152   } else {
00153 //    kdDebug(5800) << "§§ incidence " << event->summary() << " has time." << endl;
00154     start = writeICalDateTime(event->dtStart());
00155   }
00156   icalcomponent_add_property(vevent,icalproperty_new_dtstart(start));
00157 
00158   // end time
00159   icaltimetype end;
00160   if (event->doesFloat()) {
00161 //    kdDebug(5800) << "§§ Event " << event->summary() << " floats." << endl;
00162     // +1 day because end date is non-inclusive.
00163     end = writeICalDate( event->dtEnd().date().addDays( 1 ) );
00164   } else {
00165 //    kdDebug(5800) << "§§ Event " << event->summary() << " has time." << endl;
00166     end = writeICalDateTime(event->dtEnd());
00167   }
00168   icalcomponent_add_property(vevent,icalproperty_new_dtend(end));
00169 
00170 // TODO: attachments, resources
00171 #if 0
00172   // attachments
00173   tmpStrList = anEvent->attachments();
00174   for ( QStringList::Iterator it = tmpStrList.begin();
00175         it != tmpStrList.end();
00176         ++it )
00177     addPropValue(vevent, VCAttachProp, (*it).utf8());
00178 
00179   // resources
00180   tmpStrList = anEvent->resources();
00181   tmpStr = tmpStrList.join(";");
00182   if (!tmpStr.isEmpty())
00183     addPropValue(vevent, VCResourcesProp, tmpStr.utf8());
00184 
00185 #endif
00186 
00187 // TODO: transparency
00188   // transparency
00189 //  tmpStr.sprintf("%i",anEvent->getTransparency());
00190 //  addPropValue(vevent, VCTranspProp, tmpStr.utf8());
00191 
00192   return vevent;
00193 }
00194 
00195 icalcomponent *ICalFormatImpl::writeFreeBusy(FreeBusy *freebusy,
00196                                              Scheduler::Method method)
00197 {
00198 #if QT_VERSION >= 300
00199   kdDebug(5800) << "icalformatimpl: writeFreeBusy: startDate: "
00200     << freebusy->dtStart().toString("ddd MMMM d yyyy: h:m:s ap") << " End Date: "
00201     << freebusy->dtEnd().toString("ddd MMMM d yyyy: h:m:s ap") << endl;
00202 #endif
00203 
00204   icalcomponent *vfreebusy = icalcomponent_new(ICAL_VFREEBUSY_COMPONENT);
00205 
00206   icalcomponent_add_property(vfreebusy,icalproperty_new_organizer(
00207       ("MAILTO:" + freebusy->organizer()).utf8()));
00208 
00209   if (freebusy->attendeeCount() != 0) {
00210     QPtrList<Attendee> al = freebusy->attendees();
00211     QPtrListIterator<Attendee> ai(al);
00212     for (; ai.current(); ++ai) {
00213       icalcomponent_add_property(vfreebusy,writeAttendee(ai.current()));
00214     }
00215   }
00216 
00217   icalcomponent_add_property(vfreebusy,icalproperty_new_dtstamp(
00218       writeICalDateTime(QDateTime::currentDateTime())));
00219 
00220   icalcomponent_add_property(vfreebusy, icalproperty_new_dtstart(
00221       writeICalDateTime(freebusy->dtStart())));
00222 
00223   icalcomponent_add_property(vfreebusy, icalproperty_new_dtend(
00224       writeICalDateTime(freebusy->dtEnd())));
00225 
00226   if (method == Scheduler::Request) {
00227     icalcomponent_add_property(vfreebusy,icalproperty_new_uid(
00228        freebusy->uid().utf8()));
00229   }
00230 
00231   //Loops through all the periods in the freebusy object
00232   QValueList<Period> list = freebusy->busyPeriods();
00233   QValueList<Period>::Iterator it;
00234   icalperiodtype period;
00235   for (it = list.begin(); it!= list.end(); ++it) {
00236     period.start = writeICalDateTime((*it).start());
00237     period.end = writeICalDateTime((*it).end());
00238     icalcomponent_add_property(vfreebusy, icalproperty_new_freebusy(period) );
00239   }
00240 
00241   return vfreebusy;
00242 }
00243 
00244 icalcomponent *ICalFormatImpl::writeJournal(Journal *journal)
00245 {
00246   icalcomponent *vjournal = icalcomponent_new(ICAL_VJOURNAL_COMPONENT);
00247 
00248   writeIncidence(vjournal,journal);
00249   
00250   // start time
00251   if (journal->dtStart().isValid()) {
00252     icaltimetype start;
00253     if (journal->doesFloat()) {
00254 //      kdDebug(5800) << "§§ Incidence " << event->summary() << " floats." << endl;
00255       start = writeICalDate(journal->dtStart().date());
00256     } else {
00257 //      kdDebug(5800) << "§§ incidence " << event->summary() << " has time." << endl;
00258       start = writeICalDateTime(journal->dtStart());
00259     }
00260     icalcomponent_add_property(vjournal,icalproperty_new_dtstart(start));
00261   }
00262 
00263   return vjournal;
00264 }
00265 
00266 void ICalFormatImpl::writeIncidence(icalcomponent *parent,Incidence *incidence)
00267 {
00268   // creation date
00269   icalcomponent_add_property(parent,icalproperty_new_created(
00270       writeICalDateTime(incidence->created())));
00271 
00272   // unique id
00273   icalcomponent_add_property(parent,icalproperty_new_uid(
00274       incidence->uid().utf8()));
00275 
00276   // revision
00277   icalcomponent_add_property(parent,icalproperty_new_sequence(
00278       incidence->revision()));
00279 
00280   // last modification date
00281   icalcomponent_add_property(parent,icalproperty_new_lastmodified(
00282       writeICalDateTime(incidence->lastModified())));
00283 
00284   icalcomponent_add_property(parent,icalproperty_new_dtstamp(
00285       writeICalDateTime(QDateTime::currentDateTime())));
00286 
00287   // organizer stuff
00288   icalcomponent_add_property(parent,icalproperty_new_organizer(
00289       ("MAILTO:" + incidence->organizer()).utf8()));
00290 
00291   // attendees
00292   if (incidence->attendeeCount() != 0) {
00293     QPtrList<Attendee> al = incidence->attendees();
00294     QPtrListIterator<Attendee> ai(al);
00295     for (; ai.current(); ++ai) {
00296       icalcomponent_add_property(parent,writeAttendee(ai.current()));
00297     }
00298   }
00299 
00300   // description
00301   if (!incidence->description().isEmpty()) {
00302     icalcomponent_add_property(parent,icalproperty_new_description(
00303         incidence->description().utf8()));
00304   }
00305 
00306   // summary
00307   if (!incidence->summary().isEmpty()) {
00308     icalcomponent_add_property(parent,icalproperty_new_summary(
00309         incidence->summary().utf8()));
00310   }
00311 
00312   // location
00313   if (!incidence->location().isEmpty()) {
00314     icalcomponent_add_property(parent,icalproperty_new_location(
00315         incidence->location().utf8()));
00316   }
00317 
00318 // TODO:
00319   // status
00320 //  addPropValue(parent, VCStatusProp, incidence->getStatusStr().utf8());
00321 
00322   // secrecy
00323   const char *classStr;
00324   switch (incidence->secrecy()) {
00325     case Incidence::SecrecyPublic:
00326       classStr = "PUBLIC";
00327       break;
00328     case Incidence::SecrecyConfidential:
00329       classStr = "CONFIDENTIAL";
00330       break;
00331     case Incidence::SecrecyPrivate:
00332     default:
00333       classStr = "PRIVATE";
00334       break;
00335   }
00336   icalcomponent_add_property(parent,icalproperty_new_class(classStr));
00337 
00338   // priority
00339   icalcomponent_add_property(parent,icalproperty_new_priority(
00340       incidence->priority()));
00341 
00342   // categories
00343   QStringList categories = incidence->categories();
00344   QStringList::Iterator it;
00345   for(it = categories.begin(); it != categories.end(); ++it ) {
00346     icalcomponent_add_property(parent,icalproperty_new_categories((*it).utf8()));
00347   }
00348 // TODO: Ensure correct concatenation of categories properties.
00349 
00350 /*
00351   // categories
00352   tmpStrList = incidence->getCategories();
00353   tmpStr = "";
00354   QString catStr;
00355   for ( QStringList::Iterator it = tmpStrList.begin();
00356         it != tmpStrList.end();
00357         ++it ) {
00358     catStr = *it;
00359     if (catStr[0] == ' ')
00360       tmpStr += catStr.mid(1);
00361     else
00362       tmpStr += catStr;
00363     // this must be a ';' character as the vCalendar specification requires!
00364     // vcc.y has been hacked to translate the ';' to a ',' when the vcal is
00365     // read in.
00366     tmpStr += ";";
00367   }
00368   if (!tmpStr.isEmpty()) {
00369     tmpStr.truncate(tmpStr.length()-1);
00370     icalcomponent_add_property(parent,icalproperty_new_categories(
00371         writeText(incidence->getCategories().join(";"))));
00372   }
00373 */
00374 
00375   // related event
00376   if (incidence->relatedTo()) {
00377     icalcomponent_add_property(parent,icalproperty_new_relatedto(
00378         incidence->relatedTo()->uid().utf8()));
00379   }
00380 
00381   // pilot sync stuff
00382   icalproperty *p =
00383       icalproperty_new_x((QString::number(incidence->pilotId())).utf8());
00384   icalproperty_set_x_name(p,"X-PILOTID");
00385   icalcomponent_add_property(parent,p);
00386   p = icalproperty_new_x((QString::number(incidence->syncStatus())).utf8());
00387   icalproperty_set_x_name(p,"X-PILOTSTAT");
00388   icalcomponent_add_property(parent,p);
00389 
00390   // recurrence rule stuff
00391   Recurrence *recur = incidence->recurrence();
00392   if (recur->doesRecur()) {
00393     kdDebug(5800) << "Write recurrence for '" << incidence->summary() << "' (" << incidence->uid()
00394               << ")" << endl;
00395     icalcomponent_add_property(parent,writeRecurrenceRule(recur));
00396   }
00397 
00398   // recurrence excpetion dates
00399   DateList dateList = incidence->exDates();
00400   DateList::ConstIterator exIt;
00401   for(exIt = dateList.begin(); exIt != dateList.end(); ++exIt) {
00402     icalcomponent_add_property(parent,icalproperty_new_exdate(
00403         writeICalDate(*exIt)));
00404   }
00405 
00406   // alarms
00407   QPtrList<Alarm> alarms = incidence->alarms();
00408   Alarm* alarm;
00409   for (alarm = alarms.first(); alarm; alarm = alarms.next()) {
00410     if (alarm->enabled()) {
00411       kdDebug(5800) << "Write alarm for " << incidence->summary() << endl;
00412       icalcomponent_add_component(parent,writeAlarm(alarm));
00413     }
00414   }
00415 
00416   // duration
00417 
00418 // turned off as it always is set to PTS0 (and must not occur together with DTEND
00419 
00420 //  if (incidence->hasDuration()) {
00421 //    icaldurationtype duration;
00422 //    duration = writeICalDuration(incidence->duration());
00423 //    icalcomponent_add_property(parent,icalproperty_new_duration(duration));
00424 //  }
00425 }
00426 
00427 icalproperty *ICalFormatImpl::writeAttendee(Attendee *attendee)
00428 {
00429   icalproperty *p = icalproperty_new_attendee("mailto:" + attendee->email().utf8());
00430 
00431   if (!attendee->name().isEmpty()) {
00432     icalproperty_add_parameter(p,icalparameter_new_cn(attendee->name().utf8()));
00433   }
00434 
00435 
00436   icalproperty_add_parameter(p,icalparameter_new_rsvp(
00437           attendee->RSVP() ? ICAL_RSVP_TRUE : ICAL_RSVP_FALSE ));
00438 
00439   icalparameter_partstat status = ICAL_PARTSTAT_NEEDSACTION;
00440   switch (attendee->status()) {
00441     default:
00442     case Attendee::NeedsAction:
00443       status = ICAL_PARTSTAT_NEEDSACTION;
00444       break;
00445     case Attendee::Accepted:
00446       status = ICAL_PARTSTAT_ACCEPTED;
00447       break;
00448     case Attendee::Declined:
00449       status = ICAL_PARTSTAT_DECLINED;
00450       break;
00451     case Attendee::Tentative:
00452       status = ICAL_PARTSTAT_TENTATIVE;
00453       break;
00454     case Attendee::Delegated:
00455       status = ICAL_PARTSTAT_DELEGATED;
00456       break;
00457     case Attendee::Completed:
00458       status = ICAL_PARTSTAT_COMPLETED;
00459       break;
00460     case Attendee::InProcess:
00461       status = ICAL_PARTSTAT_INPROCESS;
00462       break;
00463   }
00464   icalproperty_add_parameter(p,icalparameter_new_partstat(status));
00465 
00466   icalparameter_role role = ICAL_ROLE_REQPARTICIPANT;
00467   switch (attendee->role()) {
00468     case Attendee::Chair:
00469       role = ICAL_ROLE_CHAIR;
00470       break;
00471     default:
00472     case Attendee::ReqParticipant:
00473       role = ICAL_ROLE_REQPARTICIPANT;
00474       break;
00475     case Attendee::OptParticipant:
00476       role = ICAL_ROLE_OPTPARTICIPANT;
00477       break;
00478     case Attendee::NonParticipant:
00479       role = ICAL_ROLE_NONPARTICIPANT;
00480       break;
00481   }
00482   icalproperty_add_parameter(p,icalparameter_new_role(role));
00483 
00484   if (!attendee->uid().isEmpty()) {
00485     icalparameter* icalparameter_uid = icalparameter_new_x(attendee->uid().utf8());
00486     icalparameter_set_xname(icalparameter_uid,"X-UID");
00487     icalproperty_add_parameter(p,icalparameter_uid);
00488   }
00489 
00490   return p;
00491 }
00492 
00493 icalproperty *ICalFormatImpl::writeRecurrenceRule(Recurrence *recur)
00494 {
00495 //  kdDebug(5800) << "ICalFormatImpl::writeRecurrenceRule()" << endl;
00496 
00497   icalrecurrencetype r;
00498 
00499   icalrecurrencetype_clear(&r);
00500 
00501   int index = 0;
00502   int index2 = 0;
00503 
00504   QPtrList<Recurrence::rMonthPos> tmpPositions;
00505   QPtrList<int> tmpDays;
00506   int *tmpDay;
00507   Recurrence::rMonthPos *tmpPos;
00508   bool datetime = false;
00509   int day;
00510   int i;
00511 
00512   switch(recur->doesRecur()) {
00513     case Recurrence::rMinutely:
00514       r.freq = ICAL_MINUTELY_RECURRENCE;
00515       datetime = true;
00516       break;
00517     case Recurrence::rHourly:
00518       r.freq = ICAL_HOURLY_RECURRENCE;
00519       datetime = true;
00520       break;
00521     case Recurrence::rDaily:
00522       r.freq = ICAL_DAILY_RECURRENCE;
00523       break;
00524     case Recurrence::rWeekly:
00525       r.freq = ICAL_WEEKLY_RECURRENCE;
00526       r.week_start = static_cast<icalrecurrencetype_weekday>(recur->weekStart()%7 + 1);
00527       for (i = 0; i < 7; i++) {
00528         if (recur->days().testBit(i)) {
00529           day = (i + 1)%7 + 1;     // convert from Monday=0 to Sunday=1
00530           r.by_day[index++] = icalrecurrencetype_day_day_of_week(day);
00531         }
00532       }
00533 //      r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX;
00534       break;
00535     case Recurrence::rMonthlyPos:
00536       r.freq = ICAL_MONTHLY_RECURRENCE;
00537 
00538       tmpPositions = recur->monthPositions();
00539       for (tmpPos = tmpPositions.first();
00540            tmpPos;
00541            tmpPos = tmpPositions.next()) {
00542         for (i = 0; i < 7; i++) {
00543           if (tmpPos->rDays.testBit(i)) {
00544             day = (i + 1)%7 + 1;     // convert from Monday=0 to Sunday=1
00545             day += tmpPos->rPos*8;
00546             if (tmpPos->negative) day = -day;
00547             r.by_day[index++] = day;
00548           }
00549         }
00550       }
00551 //      r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX;
00552       break;
00553     case Recurrence::rMonthlyDay:
00554       r.freq = ICAL_MONTHLY_RECURRENCE;
00555 
00556       tmpDays = recur->monthDays();
00557       for (tmpDay = tmpDays.first();
00558            tmpDay;
00559            tmpDay = tmpDays.next()) {
00560         r.by_month_day[index++] = icalrecurrencetype_day_position(*tmpDay*8);//*tmpDay);
00561       }
00562 //      r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX;
00563       break;
00564     case Recurrence::rYearlyMonth:
00565     case Recurrence::rYearlyPos:
00566       r.freq = ICAL_YEARLY_RECURRENCE;
00567 
00568       tmpDays = recur->yearNums();
00569       for (tmpDay = tmpDays.first();
00570            tmpDay;
00571            tmpDay = tmpDays.next()) {
00572         r.by_month[index++] = *tmpDay;
00573       }
00574 //      r.by_set_pos[index] = ICAL_RECURRENCE_ARRAY_MAX;
00575       if (recur->doesRecur() == Recurrence::rYearlyPos) {
00576         tmpPositions = recur->monthPositions();
00577         for (tmpPos = tmpPositions.first();
00578              tmpPos;
00579              tmpPos = tmpPositions.next()) {
00580           for (i = 0; i < 7; i++) {
00581             if (tmpPos->rDays.testBit(i)) {
00582               day = (i + 1)%7 + 1;     // convert from Monday=0 to Sunday=1
00583               day += tmpPos->rPos*8;
00584               if (tmpPos->negative) day = -day;
00585               r.by_day[index2++] = day;
00586             }
00587           }
00588         }
00589 //        r.by_day[index2] = ICAL_RECURRENCE_ARRAY_MAX;
00590       }
00591       break;
00592     case Recurrence::rYearlyDay:
00593       r.freq = ICAL_YEARLY_RECURRENCE;
00594 
00595       tmpDays = recur->yearNums();
00596       for (tmpDay = tmpDays.first();
00597            tmpDay;
00598            tmpDay = tmpDays.next()) {
00599         r.by_year_day[index++] = *tmpDay;
00600       }
00601 //      r.by_year_day[index] = ICAL_RECURRENCE_ARRAY_MAX;
00602       break;
00603     default:
00604       r.freq = ICAL_NO_RECURRENCE;
00605       kdDebug(5800) << "ICalFormatImpl::writeRecurrence(): no recurrence" << endl;
00606       break;
00607   }
00608 
00609   r.interval = recur->frequency();
00610 
00611   if (recur->duration() > 0) {
00612     r.count = recur->duration();
00613   } else if (recur->duration() == -1) {
00614     r.count = 0;
00615   } else {
00616     if (datetime)
00617       r.until = writeICalDateTime(recur->endDateTime());
00618     else
00619       r.until = writeICalDate(recur->endDate());
00620   }
00621 
00622 // Debug output
00623 #if 0
00624   const char *str = icalrecurrencetype_as_string(&r);
00625   if (str) {
00626     kdDebug(5800) << " String: " << str << endl;
00627   } else {
00628     kdDebug(5800) << " No String" << endl;
00629   }
00630 #endif
00631 
00632   return icalproperty_new_rrule(r);
00633 }
00634 
00635 icalcomponent *ICalFormatImpl::writeAlarm(Alarm *alarm)
00636 {
00637   icalcomponent *a = icalcomponent_new(ICAL_VALARM_COMPONENT);
00638 
00639   icalproperty_action action;
00640   icalattachtype *attach = 0;
00641 
00642   if (!alarm->programFile().isEmpty()) {
00643     action = ICAL_ACTION_PROCEDURE;
00644     attach = icalattachtype_new();
00645     icalattachtype_set_url(attach,QFile::encodeName(alarm->programFile()).data());
00646     icalcomponent_add_property(a,icalproperty_new_attach(attach));
00647     icalattachtype_free(attach);
00648   } else if (!alarm->audioFile().isEmpty()) {
00649     action = ICAL_ACTION_AUDIO;
00650     attach = icalattachtype_new();
00651     icalattachtype_set_url(attach,QFile::encodeName( alarm->audioFile() ).data());
00652     icalcomponent_add_property(a,icalproperty_new_attach(attach));
00653     icalattachtype_free(attach);
00654   } else if (alarm->mailAddresses().count() > 0) {
00655     action = ICAL_ACTION_EMAIL;
00656     QStringList addresses = alarm->mailAddresses();
00657     for (QStringList::Iterator ad = addresses.begin();  ad != addresses.end();  ++ad) {
00658       icalcomponent_add_property(a,icalproperty_new_attendee((*ad).utf8()));
00659     }
00660     icalcomponent_add_property(a,icalproperty_new_summary(alarm->mailSubject().utf8()));
00661     icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8()));
00662     QStringList attachments = alarm->mailAttachments();
00663     if (attachments.count() > 0) {
00664       for (QStringList::Iterator at = attachments.begin();  at != attachments.end();  ++at) {
00665         attach = icalattachtype_new();
00666         icalattachtype_set_url(attach,QFile::encodeName( *at ).data());
00667         icalcomponent_add_property(a,icalproperty_new_attach(attach));
00668         icalattachtype_free(attach);
00669       }
00670     }
00671   } else {
00672     action = ICAL_ACTION_DISPLAY;
00673     icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8()));
00674   }
00675   icalcomponent_add_property(a,icalproperty_new_action(action));
00676 
00677   icaltriggertype trigger;
00678   if ( alarm->hasTime() ) {
00679     trigger.time = writeICalDateTime(alarm->time());
00680     trigger.duration = icaldurationtype_null_duration();
00681   } else {
00682     trigger.time = icaltime_null_time();
00683     trigger.duration = icaldurationtype_from_int( alarm->offset().asSeconds() );
00684   }
00685   icalcomponent_add_property(a,icalproperty_new_trigger(trigger));
00686 
00687   if (alarm->repeatCount()) {
00688     icalcomponent_add_property(a,icalproperty_new_repeat(alarm->repeatCount()));
00689     icalcomponent_add_property(a,icalproperty_new_duration(
00690                              icaldurationtype_from_int(alarm->snoozeTime()*60)));
00691   }
00692 
00693   return a;
00694 }
00695 
00696 Todo *ICalFormatImpl::readTodo(icalcomponent *vtodo)
00697 {
00698   Todo *todo = new Todo;
00699 
00700   readIncidence(vtodo,todo);
00701 
00702   icalproperty *p = icalcomponent_get_first_property(vtodo,ICAL_ANY_PROPERTY);
00703 
00704 //  int intvalue;
00705   icaltimetype icaltime;
00706 
00707   QStringList categories;
00708 
00709   while (p) {
00710     icalproperty_kind kind = icalproperty_isa(p);
00711     switch (kind) {
00712 
00713       case ICAL_DUE_PROPERTY:  // due date
00714         icaltime = icalproperty_get_due(p);
00715         if (icaltime.is_date) {
00716           todo->setDtDue(QDateTime(readICalDate(icaltime),QTime(0,0,0)));
00717           todo->setFloats(true);
00718 
00719         } else {
00720           todo->setDtDue(readICalDateTime(icaltime));
00721           todo->setFloats(false);
00722         }
00723         todo->setHasDueDate(true);
00724         break;
00725 
00726       case ICAL_COMPLETED_PROPERTY:  // completion date
00727         icaltime = icalproperty_get_completed(p);
00728         todo->setCompleted(readICalDateTime(icaltime));
00729         break;
00730 
00731       case ICAL_PERCENTCOMPLETE_PROPERTY:  // Percent completed
00732         todo->setPercentComplete(icalproperty_get_percentcomplete(p));
00733         break;
00734 
00735       case ICAL_RELATEDTO_PROPERTY:  // related todo (parent)
00736         todo->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p)));
00737         mTodosRelate.append(todo);
00738         break;
00739 
00740       case ICAL_DTSTART_PROPERTY:
00741         // Flag that todo has start date. Value is read in by readIncidence().
00742         todo->setHasStartDate(true);
00743         break;
00744 
00745       default:
00746 //        kdDebug(5800) << "ICALFormat::readTodo(): Unknown property: " << kind
00747 //                  << endl;
00748         break;
00749     }
00750 
00751     p = icalcomponent_get_next_property(vtodo,ICAL_ANY_PROPERTY);
00752   }
00753 
00754   return todo;
00755 }
00756 
00757 Event *ICalFormatImpl::readEvent(icalcomponent *vevent)
00758 {
00759   Event *event = new Event;
00760   event->setFloats(false);
00761 
00762   readIncidence(vevent,event);
00763 
00764   icalproperty *p = icalcomponent_get_first_property(vevent,ICAL_ANY_PROPERTY);
00765 
00766 //  int intvalue;
00767   icaltimetype icaltime;
00768 
00769   QStringList categories;
00770 
00771   while (p) {
00772     icalproperty_kind kind = icalproperty_isa(p);
00773     switch (kind) {
00774 
00775       case ICAL_DTEND_PROPERTY:  // start date and time
00776         icaltime = icalproperty_get_dtend(p);
00777         if (icaltime.is_date) {
00778           event->setFloats( true );
00779           // End date is non-inclusive
00780           QDate endDate = readICalDate( icaltime ).addDays( -1 );
00781           mCompat->fixFloatingEnd( endDate );
00782           if ( endDate < event->dtStart().date() ) {
00783             endDate = event->dtStart().date();
00784           }
00785           event->setDtEnd( QDateTime( endDate, QTime( 0, 0, 0 ) ) );
00786         } else {
00787           event->setDtEnd(readICalDateTime(icaltime));
00788         }
00789         break;
00790 
00791 // TODO:
00792   // at this point, there should be at least a start or end time.
00793   // fix up for events that take up no time but have a time associated
00794 #if 0
00795   if (!(vo = isAPropertyOf(vevent, VCDTstartProp)))
00796     anEvent->setDtStart(anEvent->dtEnd());
00797   if (!(vo = isAPropertyOf(vevent, VCDTendProp)))
00798     anEvent->setDtEnd(anEvent->dtStart());
00799 #endif
00800 
00801 // TODO: exdates
00802 #if 0
00803   // recurrence exceptions
00804   if ((vo = isAPropertyOf(vevent, VCExDateProp)) != 0) {
00805     anEvent->setExDates(s = fakeCString(vObjectUStringZValue(vo)));
00806     deleteStr(s);
00807   }
00808 #endif
00809 
00810 #if 0
00811   // secrecy
00812   if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) {
00813     anEvent->setSecrecy(s = fakeCString(vObjectUStringZValue(vo)));
00814     deleteStr(s);
00815   }
00816   else
00817     anEvent->setSecrecy("PUBLIC");
00818 
00819   // attachments
00820   tmpStrList.clear();
00821   initPropIterator(&voi, vevent);
00822   while (moreIteration(&voi)) {
00823     vo = nextVObject(&voi);
00824     if (strcmp(vObjectName(vo), VCAttachProp) == 0) {
00825       tmpStrList.append(s = fakeCString(vObjectUStringZValue(vo)));
00826       deleteStr(s);
00827     }
00828   }
00829   anEvent->setAttachments(tmpStrList);
00830 
00831   // resources
00832   if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) {
00833     QString resources = (s = fakeCString(vObjectUStringZValue(vo)));
00834     deleteStr(s);
00835     tmpStrList.clear();
00836     index1 = 0;
00837     index2 = 0;
00838     QString resource;
00839     while ((index2 = resources.find(';', index1)) != -1) {
00840       resource = resources.mid(index1, (index2 - index1));
00841       tmpStrList.append(resource);
00842       index1 = index2;
00843     }
00844     anEvent->setResources(tmpStrList);
00845   }
00846 #endif
00847 
00848 // TODO: transparency
00849 #if 0
00850   // transparency
00851   if ((vo = isAPropertyOf(vevent, VCTranspProp)) != 0) {
00852     anEvent->setTransparency(atoi(s = fakeCString(vObjectUStringZValue(vo))));
00853     deleteStr(s);
00854   }
00855 #endif
00856 
00857       case ICAL_RELATEDTO_PROPERTY:  // releated event (parent)
00858         event->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p)));
00859         mEventsRelate.append(event);
00860         break;
00861 
00862       case ICAL_X_PROPERTY:
00863         if (strcmp(icalproperty_get_name(p),"X-MICROSOFT-CDO-ALLDAYEVENT") == 0) {
00864           const char *text = icalproperty_get_value_as_string(p);
00865           bool floats = (strcmp(text, "TRUE") == 0);
00866           kdDebug(5800) << "ICALFormat::readEvent(): all day event: " << floats << endl;
00867           event->setFloats(floats);
00868           if (floats) {
00869             QDateTime endDate = event->dtEnd();
00870             event->setDtEnd(endDate.addDays(-1));
00871           }
00872         }
00873         break;
00874 
00875 
00876       default:
00877 //        kdDebug(5800) << "ICALFormat::readEvent(): Unknown property: " << kind
00878 //                  << endl;
00879         break;
00880     }
00881 
00882     p = icalcomponent_get_next_property(vevent,ICAL_ANY_PROPERTY);
00883   }
00884 
00885   // some stupid vCal exporters ignore the standard and use Description
00886   // instead of Summary for the default field.  Correct for this.
00887   if (event->summary().isEmpty() &&
00888       !(event->description().isEmpty())) {
00889     QString tmpStr = event->description().simplifyWhiteSpace();
00890     event->setDescription("");
00891     event->setSummary(tmpStr);
00892   }
00893 
00894   return event;
00895 }
00896 
00897 FreeBusy *ICalFormatImpl::readFreeBusy(icalcomponent *vfreebusy)
00898 {
00899   FreeBusy *freebusy = new FreeBusy;
00900 
00901   icalproperty *p = icalcomponent_get_first_property(vfreebusy,ICAL_ANY_PROPERTY);
00902 
00903   icaltimetype icaltime;
00904   icalperiodtype icalperiod;
00905   QDateTime period_start, period_end;
00906 
00907   while (p) {
00908     icalproperty_kind kind = icalproperty_isa(p);
00909     switch (kind) {
00910 
00911       case ICAL_UID_PROPERTY:  // unique id
00912         freebusy->setUid(QString::fromUtf8(icalproperty_get_uid(p)));
00913         break;
00914 
00915       case ICAL_ORGANIZER_PROPERTY:  // organizer
00916         freebusy->setOrganizer(QString::fromUtf8(icalproperty_get_organizer(p)));
00917         break;
00918 
00919       case ICAL_ATTENDEE_PROPERTY:  // attendee
00920         freebusy->addAttendee(readAttendee(p));
00921         break;
00922 
00923       case ICAL_DTSTART_PROPERTY:  // start date and time
00924         icaltime = icalproperty_get_dtstart(p);
00925         freebusy->setDtStart(readICalDateTime(icaltime));
00926         break;
00927 
00928       case ICAL_DTEND_PROPERTY:  // start End Date and Time
00929         icaltime = icalproperty_get_dtend(p);
00930         freebusy->setDtEnd(readICalDateTime(icaltime));
00931         break;
00932 
00933       case ICAL_FREEBUSY_PROPERTY:  //Any FreeBusy Times
00934         icalperiod = icalproperty_get_freebusy(p);
00935         period_start = readICalDateTime(icalperiod.start);
00936         period_end = readICalDateTime(icalperiod.end);
00937         freebusy->addPeriod(period_start, period_end);
00938         break;
00939 
00940       default:
00941         kdDebug(5800) << "ICALFormat::readIncidence(): Unknown property: " << kind
00942                   << endl;
00943       break;
00944     }
00945     p = icalcomponent_get_next_property(vfreebusy,ICAL_ANY_PROPERTY);
00946   }
00947 
00948   return freebusy;
00949 }
00950 
00951 Journal *ICalFormatImpl::readJournal(icalcomponent *vjournal)
00952 {
00953   Journal *journal = new Journal;
00954 
00955   readIncidence(vjournal,journal);
00956 
00957   return journal;
00958 }
00959 
00960 Attendee *ICalFormatImpl::readAttendee(icalproperty *attendee)
00961 {
00962   icalparameter *p = 0;
00963 
00964   QString email = QString::fromUtf8(icalproperty_get_attendee(attendee));
00965 
00966   QString name;
00967   QString uid = QString::null;
00968   p = icalproperty_get_first_parameter(attendee,ICAL_CN_PARAMETER);
00969   if (p) {
00970     name = QString::fromUtf8(icalparameter_get_cn(p));
00971   } else {
00972   }
00973 
00974   bool rsvp=false;
00975   p = icalproperty_get_first_parameter(attendee,ICAL_RSVP_PARAMETER);
00976   if (p) {
00977     icalparameter_rsvp rsvpParameter = icalparameter_get_rsvp(p);
00978     if (rsvpParameter == ICAL_RSVP_TRUE) rsvp = true;
00979   }
00980 
00981   Attendee::PartStat status = Attendee::NeedsAction;
00982   p = icalproperty_get_first_parameter(attendee,ICAL_PARTSTAT_PARAMETER);
00983   if (p) {
00984     icalparameter_partstat partStatParameter = icalparameter_get_partstat(p);
00985     switch(partStatParameter) {
00986       default:
00987       case ICAL_PARTSTAT_NEEDSACTION:
00988         status = Attendee::NeedsAction;
00989         break;
00990       case ICAL_PARTSTAT_ACCEPTED:
00991         status = Attendee::Accepted;
00992         break;
00993       case ICAL_PARTSTAT_DECLINED:
00994         status = Attendee::Declined;
00995         break;
00996       case ICAL_PARTSTAT_TENTATIVE:
00997         status = Attendee::Tentative;
00998         break;
00999       case ICAL_PARTSTAT_DELEGATED:
01000         status = Attendee::Delegated;
01001         break;
01002       case ICAL_PARTSTAT_COMPLETED:
01003         status = Attendee::Completed;
01004         break;
01005       case ICAL_PARTSTAT_INPROCESS:
01006         status = Attendee::InProcess;
01007         break;
01008     }
01009   }
01010 
01011   Attendee::Role role = Attendee::ReqParticipant;
01012   p = icalproperty_get_first_parameter(attendee,ICAL_ROLE_PARAMETER);
01013   if (p) {
01014     icalparameter_role roleParameter = icalparameter_get_role(p);
01015     switch(roleParameter) {
01016       case ICAL_ROLE_CHAIR:
01017         role = Attendee::Chair;
01018         break;
01019       default:
01020       case ICAL_ROLE_REQPARTICIPANT:
01021         role = Attendee::ReqParticipant;
01022         break;
01023       case ICAL_ROLE_OPTPARTICIPANT:
01024         role = Attendee::OptParticipant;
01025         break;
01026       case ICAL_ROLE_NONPARTICIPANT:
01027         role = Attendee::NonParticipant;
01028         break;
01029     }
01030   }
01031 
01032   p = icalproperty_get_first_parameter(attendee,ICAL_X_PARAMETER);
01033   uid = icalparameter_get_xvalue(p);
01034   // This should be added, but there seems to be a libical bug here.
01035   /*while (p) {
01036    // if (icalparameter_get_xname(p) == "X-UID") {
01037     uid = icalparameter_get_xvalue(p);
01038     p = icalproperty_get_next_parameter(attendee,ICAL_X_PARAMETER);
01039   } */
01040 
01041 
01042 
01043 
01044   return new Attendee( name, email, rsvp, status, role, uid );
01045 }
01046 
01047 void ICalFormatImpl::readIncidence(icalcomponent *parent,Incidence *incidence)
01048 {
01049   icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY);
01050 
01051   const char *text;
01052   int intvalue;
01053   icaltimetype icaltime;
01054   icaldurationtype icalduration;
01055 
01056   QStringList categories;
01057 
01058   while (p) {
01059     icalproperty_kind kind = icalproperty_isa(p);
01060     switch (kind) {
01061 
01062       case ICAL_CREATED_PROPERTY:
01063         icaltime = icalproperty_get_created(p);
01064         incidence->setCreated(readICalDateTime(icaltime));
01065         break;
01066 
01067       case ICAL_UID_PROPERTY:  // unique id
01068         text = icalproperty_get_uid(p);
01069         incidence->setUid(QString::fromUtf8(text));
01070         break;
01071 
01072       case ICAL_SEQUENCE_PROPERTY:  // sequence
01073         intvalue = icalproperty_get_sequence(p);
01074         incidence->setRevision(intvalue);
01075         break;
01076 
01077       case ICAL_LASTMODIFIED_PROPERTY:  // last modification date
01078         icaltime = icalproperty_get_lastmodified(p);
01079         incidence->setLastModified(readICalDateTime(icaltime));
01080         break;
01081 
01082       case ICAL_ORGANIZER_PROPERTY:  // organizer
01083         text = icalproperty_get_organizer(p);
01084         incidence->setOrganizer(QString::fromUtf8(text));
01085         break;
01086 
01087       case ICAL_ATTENDEE_PROPERTY:  // attendee
01088         incidence->addAttendee(readAttendee(p));
01089         break;
01090 
01091       case ICAL_DTSTART_PROPERTY:  // start date and time
01092         icaltime = icalproperty_get_dtstart(p);
01093         if (icaltime.is_date) {
01094           incidence->setDtStart(QDateTime(readICalDate(icaltime),QTime(0,0,0)));
01095           incidence->setFloats(true);
01096         } else {
01097           incidence->setDtStart(readICalDateTime(icaltime));
01098         }
01099         break;
01100 
01101       case ICAL_DURATION_PROPERTY:  // start date and time
01102         icalduration = icalproperty_get_duration(p);
01103         incidence->setDuration(readICalDuration(icalduration));
01104         break;
01105 
01106       case ICAL_DESCRIPTION_PROPERTY:  // description
01107         text = icalproperty_get_description(p);
01108         incidence->setDescription(QString::fromUtf8(text));
01109         break;
01110 
01111       case ICAL_SUMMARY_PROPERTY:  // summary
01112         text = icalproperty_get_summary(p);
01113         incidence->setSummary(QString::fromUtf8(text));
01114         break;
01115 
01116       case ICAL_LOCATION_PROPERTY:  // location
01117         text = icalproperty_get_location(p);
01118         incidence->setLocation(QString::fromUtf8(text));
01119         break;
01120 
01121 #if 0
01122   // status
01123   if ((vo = isAPropertyOf(vincidence, VCStatusProp)) != 0) {
01124     incidence->setStatus(s = fakeCString(vObjectUStringZValue(vo)));
01125     deleteStr(s);
01126   }
01127   else
01128     incidence->setStatus("NEEDS ACTION");
01129 #endif
01130 
01131       case ICAL_PRIORITY_PROPERTY:  // priority
01132         intvalue = icalproperty_get_priority(p);
01133         incidence->setPriority(intvalue);
01134         break;
01135 
01136       case ICAL_CATEGORIES_PROPERTY:  // categories
01137         text = icalproperty_get_categories(p);
01138         categories.append(QString::fromUtf8(text));
01139         break;
01140 
01141       case ICAL_RRULE_PROPERTY:
01142         readRecurrenceRule(p,incidence);
01143         break;
01144 
01145       case ICAL_EXDATE_PROPERTY:
01146         icaltime = icalproperty_get_exdate(p);
01147         incidence->addExDate(readICalDate(icaltime));
01148         break;
01149 
01150       case ICAL_CLASS_PROPERTY:
01151         text = icalproperty_get_class(p);
01152         if (strcmp(text,"PUBLIC") == 0) {
01153           incidence->setSecrecy(Incidence::SecrecyPublic);
01154         } else if (strcmp(text,"CONFIDENTIAL") == 0) {
01155           incidence->setSecrecy(Incidence::SecrecyConfidential);
01156         } else {
01157           incidence->setSecrecy(Incidence::SecrecyPrivate);
01158         }
01159         break;
01160 
01161 
01162       case ICAL_X_PROPERTY:
01163         if (strcmp(icalproperty_get_name(p),"X-PILOTID") == 0) {
01164           text = icalproperty_get_value_as_string(p);
01165           incidence->setPilotId(QString::fromUtf8(text).toInt());
01166         } else if (strcmp(icalproperty_get_name(p),"X-PILOTSTAT") == 0) {
01167           text = icalproperty_get_value_as_string(p);
01168           incidence->setSyncStatus(QString::fromUtf8(text).toInt());
01169         }
01170         break;
01171 
01172       default:
01173 //        kdDebug(5800) << "ICALFormat::readIncidence(): Unknown property: " << kind
01174 //                  << endl;
01175         break;
01176     }
01177 
01178     p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY);
01179   }
01180 
01181   // Cancel backwards compatibility mode for subsequent changes by the application
01182   incidence->recurrence()->setCompatVersion();
01183 
01184   // add categories
01185   incidence->setCategories(categories);
01186 
01187   // iterate through all alarms
01188   for (icalcomponent *alarm = icalcomponent_get_first_component(parent,ICAL_VALARM_COMPONENT);
01189        alarm;
01190        alarm = icalcomponent_get_next_component(parent,ICAL_VALARM_COMPONENT)) {
01191     readAlarm(alarm,incidence);
01192   }
01193 }
01194 
01195 void ICalFormatImpl::readRecurrenceRule(icalproperty *rrule,Incidence *incidence)
01196 {
01197 //  kdDebug(5800) << "Read recurrence for " << incidence->summary() << endl;
01198 
01199   Recurrence *recur = incidence->recurrence();
01200   recur->setCompatVersion(mCalendarVersion);
01201   recur->unsetRecurs();
01202 
01203   struct icalrecurrencetype r = icalproperty_get_rrule(rrule);
01204 
01205   dumpIcalRecurrence(r);
01206 
01207   readRecurrence( r, recur );
01208 }
01209 
01210 void ICalFormatImpl::readRecurrence( const struct icalrecurrencetype &r, Recurrence* recur )
01211 {
01212   int wkst;
01213   int index = 0;
01214   short day = 0;
01215   QBitArray qba(7);
01216 
01217   switch (r.freq) {
01218     case ICAL_MINUTELY_RECURRENCE:
01219       if (!icaltime_is_null_time(r.until)) {
01220         recur->setMinutely(r.interval,readICalDateTime(r.until));
01221       } else {
01222         if (r.count == 0)
01223           recur->setMinutely(r.interval,-1);
01224         else
01225           recur->setMinutely(r.interval,r.count);
01226       }
01227       break;
01228     case ICAL_HOURLY_RECURRENCE:
01229       if (!icaltime_is_null_time(r.until)) {
01230         recur->setHourly(r.interval,readICalDateTime(r.until));
01231       } else {
01232         if (r.count == 0)
01233           recur->setHourly(r.interval,-1);
01234         else
01235           recur->setHourly(r.interval,r.count);
01236       }
01237       break;
01238     case ICAL_DAILY_RECURRENCE:
01239       if (!icaltime_is_null_time(r.until)) {
01240         recur->setDaily(r.interval,readICalDate(r.until));
01241       } else {
01242         if (r.count == 0)
01243           recur->setDaily(r.interval,-1);
01244         else
01245           recur->setDaily(r.interval,r.count);
01246       }
01247       break;
01248     case ICAL_WEEKLY_RECURRENCE:
01249 //      kdDebug(5800) << "WEEKLY_RECURRENCE" << endl;
01250       wkst = (r.week_start + 5)%7 + 1;
01251       if (!icaltime_is_null_time(r.until)) {
01252         recur->setWeekly(r.interval,qba,readICalDate(r.until),wkst);
01253       } else {
01254         if (r.count == 0)
01255           recur->setWeekly(r.interval,qba,-1,wkst);
01256         else
01257           recur->setWeekly(r.interval,qba,r.count,wkst);
01258       }
01259       while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01260 //        kdDebug(5800) << " " << day << endl;
01261         qba.setBit((day+5)%7);    // convert from Sunday=1 to Monday=0
01262       }
01263       break;
01264     case ICAL_MONTHLY_RECURRENCE:
01265       if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01266         if (!icaltime_is_null_time(r.until)) {
01267           recur->setMonthly(Recurrence::rMonthlyPos,r.interval,
01268                             readICalDate(r.until));
01269         } else {
01270           if (r.count == 0)
01271             recur->setMonthly(Recurrence::rMonthlyPos,r.interval,-1);
01272           else
01273             recur->setMonthly(Recurrence::rMonthlyPos,r.interval,r.count);
01274         }
01275         bool useSetPos = false;
01276         short pos = 0;
01277         while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01278 //          kdDebug(5800) << "----a " << index << ": " << day << endl;
01279           pos = icalrecurrencetype_day_position(day);
01280           if (pos) {
01281             day = icalrecurrencetype_day_day_of_week(day);
01282             QBitArray ba(7);          // don't wipe qba
01283             ba.setBit((day+5)%7);     // convert from Sunday=1 to Monday=0
01284             recur->addMonthlyPos(pos,ba);
01285           } else {
01286             qba.setBit((day+5)%7);    // convert from Sunday=1 to Monday=0
01287             useSetPos = true;
01288           }
01289         }
01290         if (useSetPos) {
01291           if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01292             recur->addMonthlyPos(r.by_set_pos[0],qba);
01293           }
01294         }
01295       } else if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01296         if (!icaltime_is_null_time(r.until)) {
01297           recur->setMonthly(Recurrence::rMonthlyDay,r.interval,
01298                             readICalDate(r.until));
01299         } else {
01300           if (r.count == 0)
01301             recur->setMonthly(Recurrence::rMonthlyDay,r.interval,-1);
01302           else
01303             recur->setMonthly(Recurrence::rMonthlyDay,r.interval,r.count);
01304         }
01305         while((day = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01306 //          kdDebug(5800) << "----b " << day << endl;
01307           recur->addMonthlyDay(day);
01308         }
01309       }
01310       break;
01311     case ICAL_YEARLY_RECURRENCE:
01312       if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01313         if (!icaltime_is_null_time(r.until)) {
01314           recur->setYearly(Recurrence::rYearlyDay,r.interval,
01315                             readICalDate(r.until));
01316         } else {
01317           if (r.count == 0)
01318             recur->setYearly(Recurrence::rYearlyDay,r.interval,-1);
01319           else
01320             recur->setYearly(Recurrence::rYearlyDay,r.interval,r.count);
01321         }
01322         while((day = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01323           recur->addYearlyNum(day);
01324         }
01325       } if (r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01326         if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01327           if (!icaltime_is_null_time(r.until)) {
01328             recur->setYearly(Recurrence::rYearlyPos,r.interval,
01329                               readICalDate(r.until));
01330           } else {
01331             if (r.count == 0)
01332               recur->setYearly(Recurrence::rYearlyPos,r.interval,-1);
01333             else
01334               recur->setYearly(Recurrence::rYearlyPos,r.interval,r.count);
01335           }
01336           bool useSetPos = false;
01337           short pos = 0;
01338           while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01339 //            kdDebug(5800) << "----a " << index << ": " << day << endl;
01340             pos = icalrecurrencetype_day_position(day);
01341             if (pos) {
01342               day = icalrecurrencetype_day_day_of_week(day);
01343               QBitArray ba(7);          // don't wipe qba
01344               ba.setBit((day+5)%7);     // convert from Sunday=1 to Monday=0
01345               recur->addYearlyMonthPos(pos,ba);
01346             } else {
01347               qba.setBit((day+5)%7);    // convert from Sunday=1 to Monday=0
01348               useSetPos = true;
01349             }
01350           }
01351           if (useSetPos) {
01352             if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01353               recur->addYearlyMonthPos(r.by_set_pos[0],qba);
01354             }
01355           }
01356         } else {
01357           if (!icaltime_is_null_time(r.until)) {
01358             recur->setYearly(Recurrence::rYearlyMonth,r.interval,
01359                               readICalDate(r.until));
01360           } else {
01361             if (r.count == 0)
01362               recur->setYearly(Recurrence::rYearlyMonth,r.interval,-1);
01363             else
01364               recur->setYearly(Recurrence::rYearlyMonth,r.interval,r.count);
01365           }
01366         }
01367         index = 0;
01368         while((day = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01369           recur->addYearlyNum(day);
01370         }
01371       }
01372       break;
01373     default:
01374       kdDebug(5800) << "Unknown type of recurrence: " << r.freq << endl;
01375       break;
01376   }
01377 }
01378 
01379 void ICalFormatImpl::readAlarm(icalcomponent *alarm,Incidence *incidence)
01380 {
01381   //kdDebug(5800) << "Read alarm for " << incidence->summary() << endl;
01382 
01383   Alarm* ialarm = incidence->newAlarm();
01384   ialarm->setRepeatCount(0);
01385   ialarm->setEnabled(true);
01386 
01387   icalproperty *p = icalcomponent_get_first_property(alarm,ICAL_ANY_PROPERTY);
01388 
01389   icaltriggertype trigger;
01390   icalattachtype *attach;
01391   icaldurationtype duration;
01392 
01393   icalproperty_action action = ICAL_ACTION_NONE;
01394 
01395   while (p) {
01396     icalproperty_kind kind = icalproperty_isa(p);
01397 
01398     switch (kind) {
01399 
01400       case ICAL_ACTION_PROPERTY:
01401         action = icalproperty_get_action(p);
01402         break;
01403 
01404       case ICAL_TRIGGER_PROPERTY:
01405         trigger = icalproperty_get_trigger(p);
01406         if (icaltime_is_null_time(trigger.time)) {
01407           if (icaldurationtype_is_null_duration(trigger.duration)) {
01408             kdDebug(5800) << "ICalFormatImpl::readAlarm(): Trigger has no time and no duration." << endl;
01409           } else {
01410             ialarm->setOffset( Duration( icaldurationtype_as_int( trigger.duration ) ) );
01411           }
01412         } else {
01413           ialarm->setTime(readICalDateTime(trigger.time));
01414         }
01415         break;
01416 
01417       case ICAL_DURATION_PROPERTY:
01418         duration = icalproperty_get_duration(p);
01419         ialarm->setSnoozeTime(icaldurationtype_as_int(duration)/60);
01420         break;
01421 
01422       case ICAL_REPEAT_PROPERTY:
01423         ialarm->setRepeatCount(icalproperty_get_repeat(p));
01424         break;
01425 
01426       // Only in DISPLAY and EMAIL and PROCEDURE alarms
01427       case ICAL_DESCRIPTION_PROPERTY:
01428         ialarm->setText(QString::fromUtf8(icalproperty_get_description(p)));
01429         break;
01430 
01431       // Only in EMAIL alarm
01432       case ICAL_SUMMARY_PROPERTY:
01433         ialarm->setMailSubject(QString::fromUtf8(icalproperty_get_summary(p)));
01434         break;
01435 
01436       // Only in EMAIL alarm
01437       case ICAL_ATTENDEE_PROPERTY:
01438         ialarm->addMailAddress(QString::fromUtf8(icalproperty_get_attendee(p)));
01439         break;
01440 
01441       default:
01442         break;
01443     }
01444 
01445     p = icalcomponent_get_next_property(alarm,ICAL_ANY_PROPERTY);
01446   }
01447 
01448   // Now that the alarm action has been determined, process attachments
01449   p = icalcomponent_get_first_property(alarm,ICAL_ATTACH_PROPERTY);
01450   while ( p ) {
01451     attach = icalproperty_get_attach(p);
01452     QString url = QFile::decodeName(icalattachtype_get_url(attach));
01453     switch ( action ) {
01454       case ICAL_ACTION_AUDIO:
01455         ialarm->setAudioFile( url );
01456         break;
01457       case ICAL_ACTION_PROCEDURE:
01458         ialarm->setProgramFile( url );
01459         break;
01460       case ICAL_ACTION_EMAIL:
01461         ialarm->addMailAttachment( url );
01462         break;
01463       default:
01464         break;
01465     }
01466 
01467     p = icalcomponent_get_next_property(alarm,ICAL_ATTACH_PROPERTY);
01468   }
01469 
01470   // TODO: check for consistency of alarm properties
01471 }
01472 
01473 icaltimetype ICalFormatImpl::writeICalDate(const QDate &date)
01474 {
01475   icaltimetype t;
01476 
01477   t.year = date.year();
01478   t.month = date.month();
01479   t.day = date.day();
01480 
01481   t.hour = 0;
01482   t.minute = 0;
01483   t.second = 0;
01484 
01485   t.is_date = 1;
01486 
01487   t.is_utc = 0;
01488 
01489   t.zone = 0;
01490 
01491   return t;
01492 }
01493 
01494 icaltimetype ICalFormatImpl::writeICalDateTime(const QDateTime &datetime)
01495 {
01496   icaltimetype t;
01497 
01498   t.year = datetime.date().year();
01499   t.month = datetime.date().month();
01500   t.day = datetime.date().day();
01501 
01502   t.hour = datetime.time().hour();
01503   t.minute = datetime.time().minute();
01504   t.second = datetime.time().second();
01505 
01506   t.is_date = 0;
01507   t.zone = 0;
01508   t.is_utc = 0;
01509 
01510   if ( mParent->utc() ) {
01511     if (mParent->timeZoneId().isEmpty())
01512       t = icaltime_as_utc(t, 0);
01513     else
01514       t = icaltime_as_utc(t,mParent->timeZoneId().local8Bit());
01515   }
01516 
01517   return t;
01518 }
01519 
01520 QDateTime ICalFormatImpl::readICalDateTime(icaltimetype t)
01521 {
01522 /*
01523   kdDebug(5800) << "ICalFormatImpl::readICalDateTime()" << endl;
01524   kdDebug(5800) << "--- Y: " << t.year << " M: " << t.month << " D: " << t.day
01525             << endl;
01526   kdDebug(5800) << "--- H: " << t.hour << " M: " << t.minute << " S: " << t.second
01527             << endl;
01528   kdDebug(5800) << "--- isDate: " << t.is_date << endl;
01529 */
01530 
01531   if (t.is_utc) {
01532 //    kdDebug(5800) << "--- Converting time to zone '" << cal->timeZoneId() << "'." << endl;
01533     if (mParent->timeZoneId().isEmpty())
01534       t = icaltime_as_zone(t, 0);
01535     else
01536       t = icaltime_as_zone(t,mParent->timeZoneId().local8Bit());
01537   }
01538 
01539   return QDateTime(QDate(t.year,t.month,t.day),
01540                    QTime(t.hour,t.minute,t.second));
01541 }
01542 
01543 QDate ICalFormatImpl::readICalDate(icaltimetype t)
01544 {
01545   return QDate(t.year,t.month,t.day);
01546 }
01547 
01548 icaldurationtype ICalFormatImpl::writeICalDuration(int seconds)
01549 {
01550   icaldurationtype d;
01551 
01552   d.weeks    = seconds   % gSecondsPerWeek;
01553   seconds   -= d.weeks   * gSecondsPerWeek;
01554   d.days     = seconds   % gSecondsPerDay;
01555   seconds   -= d.days    * gSecondsPerDay;
01556   d.hours    = seconds   % gSecondsPerHour;
01557   seconds   -= d.hours   * gSecondsPerHour;
01558   d.minutes  = seconds   % gSecondsPerMinute;
01559   seconds   -= d.minutes * gSecondsPerMinute;
01560   d.seconds  = seconds;
01561   d.is_neg = 0;
01562 
01563   return d;
01564 }
01565 
01566 int ICalFormatImpl::readICalDuration(icaldurationtype d)
01567 {
01568   int result = 0;
01569 
01570   result += d.weeks   * gSecondsPerWeek;
01571   result += d.days    * gSecondsPerDay;
01572   result += d.hours   * gSecondsPerHour;
01573   result += d.minutes * gSecondsPerMinute;
01574   result += d.seconds;
01575 
01576   if (d.is_neg) result *= -1;
01577 
01578   return result;
01579 }
01580 
01581 icalcomponent *ICalFormatImpl::createCalendarComponent()
01582 {
01583   icalcomponent *calendar;
01584 
01585   // Root component
01586   calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
01587 
01588   icalproperty *p;
01589 
01590   // Product Identifier
01591   p = icalproperty_new_prodid(CalFormat::productId().utf8());
01592   icalcomponent_add_property(calendar,p);
01593 
01594   // TODO: Add time zone
01595 
01596   // iCalendar version (2.0)
01597   p = icalproperty_new_version(const_cast<char *>(_ICAL_VERSION));
01598   icalcomponent_add_property(calendar,p);
01599 
01600   return calendar;
01601 }
01602 
01603 
01604 
01605 // take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc.
01606 // and break it down from it's tree-like format into the dictionary format
01607 // that is used internally in the ICalFormatImpl.
01608 bool ICalFormatImpl::populate( Calendar *cal, icalcomponent *calendar)
01609 {
01610   // this function will populate the caldict dictionary and other event
01611   // lists. It turns vevents into Events and then inserts them.
01612 
01613     if (!calendar) return false;
01614 
01615 // TODO: check for METHOD
01616 #if 0
01617   if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) {
01618     char *methodType = 0;
01619     methodType = fakeCString(vObjectUStringZValue(curVO));
01620     if (mEnableDialogs)
01621       KMessageBox::information(mTopWidget,
01622                                i18n("This calendar is an iTIP transaction of type \"%1\".")
01623                                .arg(methodType),
01624                                i18n("%1: iTIP Transaction").arg(CalFormat::application()));
01625     delete methodType;
01626   }
01627 #endif
01628 
01629   icalproperty *p;
01630 
01631   p = icalcomponent_get_first_property(calendar,ICAL_PRODID_PROPERTY);
01632   if (!p) {
01633     kdDebug(5800) << "No PRODID property found" << endl;
01634 // TODO: does no PRODID really matter?
01635 //    mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
01636 //    return false;
01637     mLoadedProductId = "";
01638     mCalendarVersion = 0;
01639   } else {
01640     mLoadedProductId = QString::fromUtf8(icalproperty_get_prodid(p));
01641     mCalendarVersion = CalFormat::calendarVersion(mLoadedProductId);
01642     kdDebug(5800) << "VCALENDAR prodid: '" << mLoadedProductId << "'" << endl;
01643   
01644     delete mCompat;
01645     mCompat = CompatFactory::createCompat( mLoadedProductId );
01646   }
01647 
01648 // TODO: check for unknown PRODID
01649 #if 0
01650   if (!mCalendarVersion
01651   &&  CalFormat::productId() != mLoadedProductId) {
01652     // warn the user that we might have trouble reading non-known calendar.
01653     if (mEnableDialogs)
01654       KMessageBox::information(mTopWidget,
01655                              i18n("This vCalendar file was not created by KOrganizer "
01656                                      "or any other product we support. Loading anyway..."),
01657                              i18n("%1: Unknown vCalendar Vendor").arg(CalFormat::application()));
01658   }
01659 #endif
01660 
01661   p = icalcomponent_get_first_property(calendar,ICAL_VERSION_PROPERTY);
01662   if (!p) {
01663     kdDebug(5800) << "No VERSION property found" << endl;
01664     mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
01665     return false;
01666   } else {
01667     const char *version = icalproperty_get_version(p);
01668     kdDebug(5800) << "VCALENDAR version: '" << version << "'" << endl;
01669 
01670     if (strcmp(version,"1.0") == 0) {
01671       kdDebug(5800) << "Expected iCalendar, got vCalendar" << endl;
01672       mParent->setException(new ErrorFormat(ErrorFormat::CalVersion1,
01673                             i18n("Expected iCalendar format")));
01674       return false;
01675     } else if (strcmp(version,"2.0") != 0) {
01676       kdDebug(5800) << "Expected iCalendar, got unknown format" << endl;
01677       mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
01678       return false;
01679     }
01680   }
01681 
01682 
01683 // TODO: check for calendar format version
01684 #if 0
01685   // warn the user we might have trouble reading this unknown version.
01686   if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) {
01687     char *s = fakeCString(vObjectUStringZValue(curVO));
01688     if (strcmp(_VCAL_VERSION, s) != 0)
01689       if (mEnableDialogs)
01690         KMessageBox::sorry(mTopWidget,
01691                              i18n("This vCalendar file has version %1.\n"
01692                                   "We only support %2.")
01693                              .arg(s).arg(_VCAL_VERSION),
01694                              i18n("%1: Unknown vCalendar Version").arg(CalFormat::application()));
01695     deleteStr(s);
01696   }
01697 #endif
01698 
01699 // TODO: set time zone
01700 #if 0
01701   // set the time zone
01702   if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) {
01703     char *s = fakeCString(vObjectUStringZValue(curVO));
01704     cal->setTimeZone(s);
01705     deleteStr(s);
01706   }
01707 #endif
01708 
01709   // Store all events with a relatedTo property in a list for post-processing
01710   mEventsRelate.clear();
01711   mTodosRelate.clear();
01712   // TODO: make sure that only actually added ecvens go to this lists.
01713 
01714   icalcomponent *c;
01715 
01716   // Iterate through all todos
01717   c = icalcomponent_get_first_component(calendar,ICAL_VTODO_COMPONENT);
01718   while (c) {
01719 //    kdDebug(5800) << "----Todo found" << endl;
01720     Todo *todo = readTodo(c);
01721     if (!cal->todo(todo->uid())) cal->addTodo(todo);
01722     c = icalcomponent_get_next_component(calendar,ICAL_VTODO_COMPONENT);
01723   }
01724 
01725   // Iterate through all events
01726   c = icalcomponent_get_first_component(calendar,ICAL_VEVENT_COMPONENT);
01727   while (c) {
01728 //    kdDebug(5800) << "----Event found" << endl;
01729     Event *event = readEvent(c);
01730     if (!cal->event(event->uid())) cal->addEvent(event);
01731     c = icalcomponent_get_next_component(calendar,ICAL_VEVENT_COMPONENT);
01732   }
01733 
01734   // Iterate through all journals
01735   c = icalcomponent_get_first_component(calendar,ICAL_VJOURNAL_COMPONENT);
01736   while (c) {
01737 //    kdDebug(5800) << "----Journal found" << endl;
01738     Journal *journal = readJournal(c);
01739     if (!cal->journal(journal->uid())) cal->addJournal(journal);
01740     c = icalcomponent_get_next_component(calendar,ICAL_VJOURNAL_COMPONENT);
01741   }
01742 
01743 #if 0
01744   initPropIterator(&i, vcal);
01745 
01746   // go through all the vobjects in the vcal
01747   while (moreIteration(&i)) {
01748     curVO = nextVObject(&i);
01749 
01750     /************************************************************************/
01751 
01752     // now, check to see that the object is an event or todo.
01753     if (strcmp(vObjectName(curVO), VCEventProp) == 0) {
01754 
01755       if ((curVOProp = isAPropertyOf(curVO, KPilotStatusProp)) != 0) {
01756         char *s;
01757         s = fakeCString(vObjectUStringZValue(curVOProp));
01758         // check to see if event was deleted by the kpilot conduit
01759         if (atoi(s) == Event::SYNCDEL) {
01760           deleteStr(s);
01761           kdDebug(5800) << "skipping pilot-deleted event" << endl;
01762           goto SKIP;
01763         }
01764         deleteStr(s);
01765       }
01766 
01767       // this code checks to see if we are trying to read in an event
01768       // that we already find to be in the calendar.  If we find this
01769       // to be the case, we skip the event.
01770       if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) {
01771         char *s = fakeCString(vObjectUStringZValue(curVOProp));
01772         QString tmpStr(s);
01773         deleteStr(s);
01774 
01775         if (cal->event(tmpStr)) {
01776           goto SKIP;
01777         }
01778         if (cal->todo(tmpStr)) {
01779           goto SKIP;
01780         }
01781       }
01782 
01783       if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) &&
01784           (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) {
01785         kdDebug(5800) << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl;
01786         goto SKIP;
01787       }
01788 
01789       anEvent = VEventToEvent(curVO);
01790       // we now use addEvent instead of insertEvent so that the
01791       // signal/slot get connected.
01792       if (anEvent)
01793         cal->addEvent(anEvent);
01794       else {
01795         // some sort of error must have occurred while in translation.
01796         goto SKIP;
01797       }
01798     } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) {
01799       anEvent = VTodoToEvent(curVO);
01800       cal->addTodo(anEvent);
01801     } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) ||
01802                (strcmp(vObjectName(curVO), VCProdIdProp) == 0) ||
01803                (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) {
01804       // do nothing, we know these properties and we want to skip them.
01805       // we have either already processed them or are ignoring them.
01806       ;
01807     } else {
01808       kdDebug(5800) << "Ignoring unknown vObject \"" << vObjectName(curVO) << "\"" << endl;
01809     }
01810   SKIP:
01811     ;
01812   } // while
01813 #endif
01814 
01815   // Post-Process list of events with relations, put Event objects in relation
01816   Event *ev;
01817   for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) {
01818     ev->setRelatedTo(cal->event(ev->relatedToUid()));
01819   }
01820   Todo *todo;
01821   for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) {
01822     todo->setRelatedTo(cal->todo(todo->relatedToUid()));
01823   }
01824 
01825   return true;
01826 }
01827 
01828 QString ICalFormatImpl::extractErrorProperty(icalcomponent *c)
01829 {
01830 //  kdDebug(5800) << "ICalFormatImpl:extractErrorProperty: "
01831 //            << icalcomponent_as_ical_string(c) << endl;
01832 
01833   QString errorMessage;
01834 
01835   icalproperty *error;
01836   error = icalcomponent_get_first_property(c,ICAL_XLICERROR_PROPERTY);
01837   while(error) {
01838     errorMessage += icalproperty_get_xlicerror(error);
01839     errorMessage += "\n";
01840     error = icalcomponent_get_next_property(c,ICAL_XLICERROR_PROPERTY);
01841   }
01842 
01843 //  kdDebug(5800) << "ICalFormatImpl:extractErrorProperty: " << errorMessage << endl;
01844 
01845   return errorMessage;
01846 }
01847 
01848 void ICalFormatImpl::dumpIcalRecurrence(icalrecurrencetype r)
01849 {
01850   int i;
01851 
01852   kdDebug(5800) << " Freq: " << r.freq << endl;
01853   kdDebug(5800) << " Until: " << icaltime_as_ctime(r.until) << endl;
01854   kdDebug(5800) << " Count: " << r.count << endl;
01855   if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01856     int index = 0;
01857     QString out = " By Day: ";
01858     while((i = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01859       out.append(QString::number(i) + " ");
01860     }
01861     kdDebug(5800) << out << endl;
01862   }
01863   if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01864     int index = 0;
01865     QString out = " By Month Day: ";
01866     while((i = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01867       out.append(QString::number(i) + " ");
01868     }
01869     kdDebug(5800) << out << endl;
01870   }
01871   if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01872     int index = 0;
01873     QString out = " By Year Day: ";
01874     while((i = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01875       out.append(QString::number(i) + " ");
01876     }
01877     kdDebug(5800) << out << endl;
01878   }
01879   if (r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01880     int index = 0;
01881     QString out = " By Month: ";
01882     while((i = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01883       out.append(QString::number(i) + " ");
01884     }
01885     kdDebug(5800) << out << endl;
01886   }
01887   if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01888     int index = 0;
01889     QString out = " By Set Pos: ";
01890     while((i = r.by_set_pos[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01891       kdDebug(5800) << "========= " << i << endl;
01892       out.append(QString::number(i) + " ");
01893     }
01894     kdDebug(5800) << out << endl;
01895   }
01896 }
01897 
01898 icalcomponent *ICalFormatImpl::createScheduleComponent(IncidenceBase *incidence,
01899                                                    Scheduler::Method method)
01900 {
01901   icalcomponent *message = createCalendarComponent();
01902 
01903   icalproperty_method icalmethod = ICAL_METHOD_NONE;
01904 
01905   switch (method) {
01906     case Scheduler::Publish:
01907       icalmethod = ICAL_METHOD_PUBLISH;
01908       break;
01909     case Scheduler::Request:
01910       icalmethod = ICAL_METHOD_REQUEST;
01911       break;
01912     case Scheduler::Refresh:
01913       icalmethod = ICAL_METHOD_REFRESH;
01914       break;
01915     case Scheduler::Cancel:
01916       icalmethod = ICAL_METHOD_CANCEL;
01917       break;
01918     case Scheduler::Add:
01919       icalmethod = ICAL_METHOD_ADD;
01920       break;
01921     case Scheduler::Reply:
01922       icalmethod = ICAL_METHOD_REPLY;
01923       break;
01924     case Scheduler::Counter:
01925       icalmethod = ICAL_METHOD_COUNTER;
01926       break;
01927     case Scheduler::Declinecounter:
01928       icalmethod = ICAL_METHOD_DECLINECOUNTER;
01929       break;
01930     default:
01931       kdDebug(5800) << "ICalFormat::createScheduleMessage(): Unknow method" << endl;
01932       return message;
01933   }
01934 
01935   icalcomponent_add_property(message,icalproperty_new_method(icalmethod));
01936 
01937   // TODO: check, if dynamic cast is required
01938   if(incidence->type() == "Todo") {
01939     Todo *todo = static_cast<Todo *>(incidence);
01940     icalcomponent_add_component(message,writeTodo(todo));
01941   }
01942   if(incidence->type() == "Event") {
01943     Event *event = static_cast<Event *>(incidence);
01944     icalcomponent_add_component(message,writeEvent(event));
01945   }
01946   if(incidence->type() == "FreeBusy") {
01947     FreeBusy *freebusy = static_cast<FreeBusy *>(incidence);
01948     icalcomponent_add_component(message,writeFreeBusy(freebusy, method));
01949   }
01950 
01951   return message;
01952 }
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 15 11:40:27 2004 by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2001