diff --git a/kcal/calendar.cpp b/kcal/calendar.cpp index f2a72c637..e5776be73 100644 --- a/kcal/calendar.cpp +++ b/kcal/calendar.cpp @@ -1,349 +1,348 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brown Copyright (c) 2000,2001 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // $Id$ #include #include #include #include "vcaldrag.h" #include "vcalformat.h" #include "icalformat.h" #include "exceptions.h" #include "calfilter.h" #include "calendar.h" #include "calendar.moc" using namespace KCal; /** \internal */ class AddIncidenceVisitor : public Incidence::Visitor { public: /** Add incidence to calendar \a calendar. */ AddIncidenceVisitor(Calendar *calendar) : mCalendar(calendar) {} bool visit(Event *e) { mCalendar->addEvent(e); return true; } bool visit(Todo *t) { mCalendar->addTodo(t); return true; } private: Calendar *mCalendar; }; Calendar::Calendar() : QObject() { init(); } Calendar::Calendar(const QString &timeZoneId) { mTimeZoneId = timeZoneId; init(); } void Calendar::init() { mDndFormat = new VCalFormat(this); mFormat = 0; mICalFormat = new ICalFormat(this); // Setup default filter, which does nothing mFilter = new CalFilter; mFilter->setEnabled(false); mDialogsOn = true; // initialize random numbers. This is a hack, and not // even that good of one at that. // srandom(time(0L)); // user information... setOwner(i18n("Unknown Name")); setEmail(i18n("unknown@nowhere")); #if 0 tmpStr = KOPrefs::instance()->mTimeZone; // kdDebug() << "Calendar::Calendar(): TimeZone: " << tmpStr << endl; int dstSetting = KOPrefs::instance()->mDaylightSavings; extern long int timezone; struct tm *now; time_t curtime; curtime = time(0); now = localtime(&curtime); int hourOff = - ((timezone / 60) / 60); if (now->tm_isdst) hourOff += 1; QString tzStr; tzStr.sprintf("%.2d%.2d", hourOff, abs((timezone / 60) % 60)); // if no time zone was in the config file, write what we just discovered. if (tmpStr.isEmpty()) { // KOPrefs::instance()->mTimeZone = tzStr; } else { tzStr = tmpStr; } // if daylight savings has changed since last load time, we need // to rewrite these settings to the config file. if ((now->tm_isdst && !dstSetting) || (!now->tm_isdst && dstSetting)) { KOPrefs::instance()->mTimeZone = tzStr; KOPrefs::instance()->mDaylightSavings = now->tm_isdst; } setTimeZone(tzStr); #endif // KOPrefs::instance()->writeConfig(); } Calendar::~Calendar() { delete mICalFormat; delete mDndFormat; delete mFormat; } ICalFormat *Calendar::iCalFormat() { return mICalFormat; } VCalDrag *Calendar::createDrag(Event *selectedEv, QWidget *owner) { return mDndFormat->createDrag(selectedEv,owner); } VCalDrag *Calendar::createDragTodo(Todo *selectedEv, QWidget *owner) { return mDndFormat->createDragTodo(selectedEv,owner); } Event *Calendar::createDrop(QDropEvent *de) { return mDndFormat->createDrop(de); } Todo *Calendar::createDropTodo(QDropEvent *de) { kdDebug() << "Calendar::createDropTodo()" << endl; return mDndFormat->createDropTodo(de); } void Calendar::cutEvent(Event *selectedEv) { if (copyEvent(selectedEv)) deleteEvent(selectedEv); } bool Calendar::copyEvent(Event *selectedEv) { return mDndFormat->copyEvent(selectedEv); } Event *Calendar::pasteEvent(const QDate &newDate,const QTime *newTime) { return mDndFormat->pasteEvent(newDate,newTime); } const QString &Calendar::getOwner() const { return mOwner; } void Calendar::setOwner(const QString &os) { int i; - // mOwner = os.ascii(); // to detach it - mOwner = os; // #### Why? This should be okay? + mOwner = os; i = mOwner.find(','); if (i != -1) mOwner = mOwner.left(i); } void Calendar::setTimeZone(const QString & tz) { bool neg = FALSE; int hours, minutes; QString tmpStr(tz); if (tmpStr.left(1) == "-") neg = TRUE; if (tmpStr.left(1) == "-" || tmpStr.left(1) == "+") tmpStr.remove(0, 1); hours = tmpStr.left(2).toInt(); if (tmpStr.length() > 2) minutes = tmpStr.right(2).toInt(); else minutes = 0; mTimeZone = (60*hours+minutes); if (neg) mTimeZone = -mTimeZone; } QString Calendar::getTimeZoneStr() const { QString tmpStr; int hours = abs(mTimeZone / 60); int minutes = abs(mTimeZone % 60); bool neg = mTimeZone < 0; tmpStr.sprintf("%c%.2d%.2d", (neg ? '-' : '+'), hours, minutes); return tmpStr; } void Calendar::setTimeZone(int tz) { mTimeZone = tz; } int Calendar::getTimeZone() const { return mTimeZone; } void Calendar::setTimeZoneId(const QString &id) { mTimeZoneId = id; } QString Calendar::timeZoneId() const { return mTimeZoneId; } const QString &Calendar::getEmail() { return mOwnerEmail; } void Calendar::setEmail(const QString &e) { mOwnerEmail = e; } void Calendar::showDialogs(bool d) { mDialogsOn = d; } // don't ever call this unless a kapp exists! void Calendar::updateConfig() { // kdDebug() << "Calendar::updateConfig()" << endl; bool updateFlag = FALSE; // TODO: update Organizer in all events #if 0 mOwner = KOPrefs::instance()->mName; // update events to new organizer (email address) // if it has changed... QString configEmail = KOPrefs::instance()->mEmail; if (mOwnerEmail != configEmail) { QString oldEmail = mOwnerEmail; // oldEmail.detach(); mOwnerEmail = configEmail; Event *firstEvent, *currEvent; bool atFirst = TRUE; firstEvent = last(); // gotta skip over the first one, which is same as first. // I know, bad coding. for (currEvent = prev(); currEvent; currEvent = prev()) { // kdDebug() << "in Calendar::updateConfig(), currEvent summary: " << currEvent->getSummary() << endl; if ((currEvent == firstEvent) && !atFirst) { break; } if (currEvent->getOrganizer() == oldEmail) { currEvent->setReadOnly(FALSE); currEvent->setOrganizer(mOwnerEmail); updateFlag = TRUE; } atFirst = FALSE; } } #endif // TODO: Fix time zone setting -// setTimeZone(KOPrefs::instance()->mTimeZone.latin1()); +// setTimeZone(KOPrefs::instance()->mTimeZone.local8Bit()); if (updateFlag) emit calUpdated((Event *) 0L); } void Calendar::setFilter(CalFilter *filter) { mFilter = filter; } CalFilter *Calendar::filter() { return mFilter; } QPtrList Calendar::getEventsForDate(const QDate &date,bool sorted) { QPtrList el = eventsForDate(date,sorted); mFilter->apply(&el); return el; } QPtrList Calendar::getEventsForDate(const QDateTime &qdt) { QPtrList el = eventsForDate(qdt); mFilter->apply(&el); return el; } QPtrList Calendar::getEvents(const QDate &start,const QDate &end, bool inclusive) { QPtrList el = events(start,end,inclusive); mFilter->apply(&el); return el; } void Calendar::addIncidence(Incidence *i) { AddIncidenceVisitor v(this); i->accept(v); } QPtrList Calendar::getFilteredTodoList() { QPtrList tl = getTodoList(); mFilter->apply(&tl); return tl; } diff --git a/kcal/icalformat.cpp b/kcal/icalformat.cpp index 9f516a3c9..f5422f875 100644 --- a/kcal/icalformat.cpp +++ b/kcal/icalformat.cpp @@ -1,531 +1,533 @@ /* This file is part of libkcal. Copyright (c) 2001 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // $Id$ #include #include #include #include #include #include #include #include extern "C" { #include #include #include #include } #include "calendar.h" #include "journal.h" #include "icalformat.h" #include "icalformatimpl.h" #define _ICAL_VERSION "2.0" using namespace KCal; ICalFormat::ICalFormat(Calendar *cal) : CalFormat(cal) { mImpl = new ICalFormatImpl(this,cal); } ICalFormat::~ICalFormat() { delete mImpl; } bool ICalFormat::load(const QString &fileName) { kdDebug() << "ICalFormat::load() " << fileName << endl; clearException(); QFile file( fileName ); if (!file.open( IO_ReadOnly ) ) { kdDebug() << "ICalFormat::load() load error" << endl; setException(new ErrorFormat(ErrorFormat::LoadError)); return false; } QTextStream ts( &file ); + ts.setEncoding(QTextStream::UnicodeUTF8); QString text = ts.read(); file.close(); // Get first VCALENDAR component. // TODO: Handle more than one VCALENDAR or non-VCALENDAR top components icalcomponent *calendar; - calendar = icalcomponent_new_from_string( const_cast(text.latin1())); + calendar = icalcomponent_new_from_string( text.local8Bit().data()); // kdDebug() << "Error: " << icalerror_perror() << endl; if (!calendar) { kdDebug() << "ICalFormat::load() parse error" << endl; setException(new ErrorFormat(ErrorFormat::ParseErrorIcal)); return false; } if (icalcomponent_isa(calendar) != ICAL_VCALENDAR_COMPONENT) { kdDebug() << "ICalFormat::load(): No VCALENDAR component found" << endl; setException(new ErrorFormat(ErrorFormat::NoCalendar)); return false; } // put all objects into their proper places if (!mImpl->populate(calendar)) { kdDebug() << "ICalFormat::load(): Could not populate calendar" << endl; setException(new ErrorFormat(ErrorFormat::ParseErrorKcal)); return false; } return true; } bool ICalFormat::save(const QString &fileName) { kdDebug() << "ICalFormat::save(): " << fileName << endl; clearException(); icalcomponent *calendar = mImpl->createCalendarComponent(); icalcomponent *component; // todos QPtrList todoList = mCalendar->getTodoList(); QPtrListIterator qlt(todoList); for (; qlt.current(); ++qlt) { component = mImpl->writeTodo(qlt.current()); icalcomponent_add_component(calendar,component); } // events QPtrList events = mCalendar->getAllEvents(); Event *ev; for(ev=events.first();ev;ev=events.next()) { component = mImpl->writeEvent(ev); icalcomponent_add_component(calendar,component); } // journals QPtrList journals = mCalendar->journalList(); Journal *j; for(j=journals.first();j;j=journals.next()) { component = mImpl->writeJournal(j); icalcomponent_add_component(calendar,component); } // TODO: write backup file QFile file( fileName ); if (!file.open( IO_WriteOnly ) ) { setException(new ErrorFormat(ErrorFormat::SaveError, i18n("Could not open file ´%1´").arg(fileName))); return false; } QTextStream ts( &file ); - char *text = icalcomponent_as_ical_string( calendar ); + ts.setEncoding(QTextStream::UnicodeUTF8); + const char *text = icalcomponent_as_ical_string( calendar ); if (!text) { setException(new ErrorFormat(ErrorFormat::SaveError, i18n("libical error"))); file.close(); return false; } - ts << QString::fromLatin1(text); + ts << QString::fromLocal8Bit(text); file.close(); return true; } // Disabled until iCalendar drag and drop is implemented VCalDrag *ICalFormat::createDrag(Event */*selectedEv*/, QWidget */*owner*/) { return 0; #if 0 VObject *vcal, *vevent; QString tmpStr; vcal = newVObject(VCCalProp); addPropValue(vcal,VCProdIdProp, productId()); tmpStr = mCalendar->getTimeZoneStr(); - addPropValue(vcal,VCTimeZoneProp, tmpStr.latin1()); + addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit()); addPropValue(vcal,VCVersionProp, _VCAL_VERSION); vevent = eventToVEvent(selectedEv); addVObjectProp(vcal, vevent); VCalDrag *vcd = new VCalDrag(vcal, owner); // free memory associated with vCalendar stuff cleanVObject(vcal); vcd->setPixmap(BarIcon("appointment")); return vcd; #endif } VCalDrag *ICalFormat::createDragTodo(Todo */*selectedEv*/, QWidget */*owner*/) { return 0; #if 0 VObject *vcal, *vevent; QString tmpStr; vcal = newVObject(VCCalProp); addPropValue(vcal,VCProdIdProp, productId()); tmpStr = mCalendar->getTimeZoneStr(); - addPropValue(vcal,VCTimeZoneProp, tmpStr.latin1()); + addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit()); addPropValue(vcal,VCVersionProp, _VCAL_VERSION); vevent = eventToVTodo(selectedEv); addVObjectProp(vcal, vevent); VCalDrag *vcd = new VCalDrag(vcal, owner); // free memory associated with vCalendar stuff cleanVObject(vcal); vcd->setPixmap(BarIcon("todo")); return vcd; #endif } Event *ICalFormat::createDrop(QDropEvent */*de*/) { return 0; #if 0 VObject *vcal; Event *event = 0; if (VCalDrag::decode(de, &vcal)) { de->accept(); VObjectIterator i; VObject *curvo; initPropIterator(&i, vcal); // we only take the first object. do { curvo = nextVObject(&i); } while (strcmp(vObjectName(curvo), VCEventProp) && strcmp(vObjectName(curvo), VCTodoProp)); if (strcmp(vObjectName(curvo), VCTodoProp) == 0) { kdDebug() << "ICalFormat::createDrop(): Got todo instead of event." << endl; } else if (strcmp(vObjectName(curvo), VCEventProp) == 0) { event = VEventToEvent(curvo); } else { kdDebug() << "ICalFormat::createDropTodo(): Unknown event type in drop." << endl; } // get rid of temporary VObject deleteVObject(vcal); } return event; #endif } Todo *ICalFormat::createDropTodo(QDropEvent */*de*/) { return 0; #if 0 VObject *vcal; Event *event = 0; if (VCalDrag::decode(de, &vcal)) { de->accept(); VObjectIterator i; VObject *curvo; initPropIterator(&i, vcal); // we only take the first object. do { curvo = nextVObject(&i); } while (strcmp(vObjectName(curvo), VCEventProp) && strcmp(vObjectName(curvo), VCTodoProp)); if (strcmp(vObjectName(curvo), VCEventProp) == 0) { kdDebug() << "ICalFormat::createDropTodo(): Got event instead of todo." << endl; } else if (strcmp(vObjectName(curvo), VCTodoProp) == 0) { event = VTodoToEvent(curvo); } else { kdDebug() << "ICalFormat::createDropTodo(): Unknown event type in drop." << endl; } // get rid of temporary VObject deleteVObject(vcal); } return event; #endif } bool ICalFormat::copyEvent(Event */*selectedEv*/) { return false; #if 0 QClipboard *cb = QApplication::clipboard(); VObject *vcal, *vevent; QString tmpStr; vcal = newVObject(VCCalProp); // addPropValue(vcal,VCLocationProp, "0.0"); addPropValue(vcal,VCProdIdProp, productId()); tmpStr = mCalendar->getTimeZoneStr(); - addPropValue(vcal,VCTimeZoneProp, tmpStr.ascii()); + addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit()); addPropValue(vcal,VCVersionProp, _VCAL_VERSION); vevent = eventToVEvent(selectedEv); addVObjectProp(vcal, vevent); // paste to clipboard cb->setData(new VCalDrag(vcal)); // free memory associated with vCalendar stuff cleanVObject(vcal); return TRUE; #endif } Event *ICalFormat::pasteEvent(const QDate &/*newDate*/,const QTime */*newTime*/) { return 0; #if 0 VObject *vcal, *curVO, *curVOProp; VObjectIterator i; int daysOffset; Event *anEvent = 0L; QClipboard *cb = QApplication::clipboard(); int bufsize; const char * buf; - buf = cb->text().ascii(); + buf = cb->text().local8Bit(); bufsize = strlen(buf); if (!VCalDrag::decode(cb->data(),&vcal)) { if (mEnableDialogs) { KMessageBox::sorry(mTopWidget, i18n("An error has occurred parsing the " "contents of the clipboard.\nYou can " "only paste a valid vCalendar into " "%1.\n").arg(application()), i18n("%1: Paste Calendar").arg(application())); return 0; } } initPropIterator(&i, vcal); // we only take the first object. do { curVO = nextVObject(&i); } while (strcmp(vObjectName(curVO), VCEventProp)); // now, check to see that the object is BOTH an event, and if so, // that it has a starting date if (strcmp(vObjectName(curVO), VCEventProp) == 0) { if ((curVOProp = isAPropertyOf(curVO, VCDTstartProp)) || (curVOProp = isAPropertyOf(curVO, VCDTendProp))) { // we found an event with a start time, put it in the dict anEvent = VEventToEvent(curVO); // if we pasted an event that was the result of a copy in our // own calendar, now we have duplicate UID strings. Need to generate // a new one for this new event. QString uidStr = createUniqueId(); if (mCalendar->getEvent(anEvent->VUID())) anEvent->setVUID(uidStr); daysOffset = anEvent->dtEnd().date().dayOfYear() - anEvent->dtStart().date().dayOfYear(); if (newTime) anEvent->setDtStart(QDateTime(*newDate, *newTime)); else anEvent->setDtStart(QDateTime(*newDate, anEvent->dtStart().time())); anEvent->setDtEnd(QDateTime(newDate->addDays(daysOffset), anEvent->dtEnd().time())); mCalendar->addEvent(anEvent); } else { kdDebug() << "found a VEvent with no DTSTART/DTEND! Skipping" << endl; } } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) { anEvent = VTodoToEvent(curVO); mCalendar->addTodo(anEvent); } else { kdDebug() << "unknown event type in paste!!!" << endl; } // get rid of temporary VObject deleteVObject(vcal); return anEvent; #endif } QString ICalFormat::createScheduleMessage(Incidence *incidence, Scheduler::Method method) { icalcomponent *message = mImpl->createScheduleComponent(incidence,method); QString messageText = icalcomponent_as_ical_string(message); #if 0 kdDebug() << "ICalFormat::createScheduleMessage: message START\n" << messageText << "ICalFormat::createScheduleMessage: message END" << endl; #endif return messageText; } ScheduleMessage *ICalFormat::parseScheduleMessage(const QString &messageText) { clearException(); if (messageText.isEmpty()) return 0; icalcomponent *message; - message = icalparser_parse_string(messageText.latin1()); + message = icalparser_parse_string(messageText.local8Bit()); if (!message) return 0; icalproperty *m = icalcomponent_get_first_property(message, ICAL_METHOD_PROPERTY); if (!m) return 0; icalcomponent *c; Incidence *incidence = 0; c = icalcomponent_get_first_component(message,ICAL_VEVENT_COMPONENT); if (c) { incidence = mImpl->readEvent(c); } else { c = icalcomponent_get_first_component(message,ICAL_VTODO_COMPONENT); if (c) { incidence = mImpl->readTodo(c); } } if (!incidence) return 0; kdDebug() << "ICalFormat::parseScheduleMessage() getting method..." << endl; icalproperty_method icalmethod = icalproperty_get_method(m); Scheduler::Method method; switch (icalmethod) { case ICAL_METHOD_PUBLISH: method = Scheduler::Publish; break; case ICAL_METHOD_REQUEST: method = Scheduler::Request; break; case ICAL_METHOD_REFRESH: method = Scheduler::Refresh; break; case ICAL_METHOD_CANCEL: method = Scheduler::Cancel; break; case ICAL_METHOD_ADD: method = Scheduler::Add; break; case ICAL_METHOD_REPLY: method = Scheduler::Reply; break; case ICAL_METHOD_COUNTER: method = Scheduler::Counter; break; case ICAL_METHOD_DECLINECOUNTER: method = Scheduler::Declinecounter; break; default: method = Scheduler::NoMethod; kdDebug() << "ICalFormat::parseScheduleMessage(): Unknow method" << endl; break; } kdDebug() << "ICalFormat::parseScheduleMessage() restriction..." << endl; if (!icalrestriction_check(message)) { setException(new ErrorFormat(ErrorFormat::Restriction, Scheduler::methodName(method) + ": " + mImpl->extractErrorProperty(c))); return 0; } icalcomponent *calendarComponent = mImpl->createCalendarComponent(); Incidence *existingIncidence = mCalendar->getEvent(incidence->VUID()); if (existingIncidence) { // TODO: check, if dynamic cast is required Todo *todo = dynamic_cast(existingIncidence); if (todo) { icalcomponent_add_component(calendarComponent, mImpl->writeTodo(todo)); } Event *event = dynamic_cast(existingIncidence); if (event) { icalcomponent_add_component(calendarComponent, mImpl->writeEvent(event)); } } else { calendarComponent = 0; } kdDebug() << "ICalFormat::parseScheduleMessage() classify..." << endl; icalclass result = icalclassify(message,calendarComponent,(char *)""); kdDebug() << "ICalFormat::parseScheduleMessage() returning..." << endl; ScheduleMessage::Status status; switch (result) { case ICAL_PUBLISH_NEW_CLASS: status = ScheduleMessage::PublishNew; break; case ICAL_OBSOLETE_CLASS: status = ScheduleMessage::Obsolete; break; case ICAL_REQUEST_NEW_CLASS: status = ScheduleMessage::RequestNew; break; case ICAL_REQUEST_UPDATE_CLASS: status = ScheduleMessage::RequestUpdate; break; case ICAL_UNKNOWN_CLASS: default: status = ScheduleMessage::Unknown; break; } return new ScheduleMessage(incidence,method,status); } diff --git a/kcal/icalformatimpl.cpp b/kcal/icalformatimpl.cpp index a100260d2..55c359eba 100644 --- a/kcal/icalformatimpl.cpp +++ b/kcal/icalformatimpl.cpp @@ -1,2031 +1,2031 @@ /* This file is part of libkcal. Copyright (c) 2001 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // $Id$ #include "config.h" #include #include #include #include #include #include //#include extern "C" { #include #include #include #include } #include "calendar.h" #include "journal.h" #include "icalformat.h" #include "icalformatimpl.h" #define _ICAL_VERSION "2.0" using namespace KCal; const int gSecondsPerMinute = 60; const int gSecondsPerHour = gSecondsPerMinute * 60; const int gSecondsPerDay = gSecondsPerHour * 24; const int gSecondsPerWeek = gSecondsPerDay * 7; ICalFormatImpl::ICalFormatImpl(ICalFormat *parent, Calendar *cal) { mParent = parent; mCalendar = cal; } ICalFormatImpl::~ICalFormatImpl() { } icalcomponent *ICalFormatImpl::writeTodo(Todo *todo) { QString tmpStr; QStringList tmpStrList; icalcomponent *vtodo = icalcomponent_new(ICAL_VTODO_COMPONENT); writeIncidence(vtodo,todo); // due date if (todo->hasDueDate()) { icaltimetype due; if (todo->doesFloat()) { due = writeICalDate(todo->dtDue().date()); } else { due = writeICalDateTime(todo->dtDue()); } icalcomponent_add_property(vtodo,icalproperty_new_due(due)); } // start time if (todo->hasStartDate()) { icaltimetype start; if (todo->doesFloat()) { // kdDebug() << "§§ Incidence " << todo->summary() << " floats." << endl; start = writeICalDate(todo->dtStart().date()); } else { // kdDebug() << "§§ incidence " << todo->summary() << " has time." << endl; start = writeICalDateTime(todo->dtStart()); } icalcomponent_add_property(vtodo,icalproperty_new_dtstart(start)); } // completion date if (todo->isCompleted()) { if (!todo->hasCompletedDate()) { // If todo was created by KOrganizer <2.2 it has no correct completion // date. Set it to now. todo->setCompleted(QDateTime::currentDateTime()); } icaltimetype completed = writeICalDateTime(todo->completed()); icalcomponent_add_property(vtodo,icalproperty_new_completed(completed)); } icalcomponent_add_property(vtodo, icalproperty_new_percentcomplete(todo->percentComplete())); return vtodo; } icalcomponent *ICalFormatImpl::writeEvent(Event *event) { kdDebug() << "Write Event '" << event->summary() << "' (" << event->VUID() << ")" << endl; QString tmpStr; QStringList tmpStrList; icalcomponent *vevent = icalcomponent_new(ICAL_VEVENT_COMPONENT); writeIncidence(vevent,event); // start time icaltimetype start; if (event->doesFloat()) { // kdDebug() << "§§ Incidence " << event->summary() << " floats." << endl; start = writeICalDate(event->dtStart().date()); } else { // kdDebug() << "§§ incidence " << event->summary() << " has time." << endl; start = writeICalDateTime(event->dtStart()); } icalcomponent_add_property(vevent,icalproperty_new_dtstart(start)); // end time icaltimetype end; if (event->doesFloat()) { // kdDebug() << "§§ Event " << event->summary() << " floats." << endl; end = writeICalDate(event->dtEnd().date()); } else { // kdDebug() << "§§ Event " << event->summary() << " has time." << endl; end = writeICalDateTime(event->dtEnd()); } icalcomponent_add_property(vevent,icalproperty_new_dtend(end)); // TODO: attachements, resources #if 0 // attachments tmpStrList = anEvent->attachments(); for ( QStringList::Iterator it = tmpStrList.begin(); it != tmpStrList.end(); ++it ) - addPropValue(vevent, VCAttachProp, (*it).ascii()); + addPropValue(vevent, VCAttachProp, (*it).local8Bit()); // resources tmpStrList = anEvent->resources(); tmpStr = tmpStrList.join(";"); if (!tmpStr.isEmpty()) - addPropValue(vevent, VCResourcesProp, tmpStr.ascii()); + addPropValue(vevent, VCResourcesProp, tmpStr.local8Bit()); #endif // TODO: transparency // transparency // tmpStr.sprintf("%i",anEvent->getTransparency()); -// addPropValue(vevent, VCTranspProp, tmpStr.ascii()); +// addPropValue(vevent, VCTranspProp, tmpStr.local8Bit()); return vevent; } icalcomponent *ICalFormatImpl::writeJournal(Journal *journal) { icalcomponent *vjournal = icalcomponent_new(ICAL_VJOURNAL_COMPONENT); writeIncidence(vjournal,journal); return vjournal; } void ICalFormatImpl::writeIncidence(icalcomponent *parent,Incidence *incidence) { // creation date icalcomponent_add_property(parent,icalproperty_new_created( writeICalDateTime(incidence->created()))); // unique id icalcomponent_add_property(parent,icalproperty_new_uid( - incidence->VUID().latin1())); + incidence->VUID().local8Bit())); // revision icalcomponent_add_property(parent,icalproperty_new_sequence( incidence->revision())); // last modification date icalcomponent_add_property(parent,icalproperty_new_lastmodified( writeICalDateTime(incidence->lastModified()))); icalcomponent_add_property(parent,icalproperty_new_dtstamp( writeICalDateTime(QDateTime::currentDateTime()))); // organizer stuff icalcomponent_add_property(parent,icalproperty_new_organizer( - ("MAILTO:" + incidence->organizer()).utf8())); + ("MAILTO:" + incidence->organizer()).local8Bit())); // attendees if (incidence->attendeeCount() != 0) { QPtrList al = incidence->attendees(); QPtrListIterator ai(al); for (; ai.current(); ++ai) { icalcomponent_add_property(parent,writeAttendee(ai.current())); } } // description if (!incidence->description().isEmpty()) { icalcomponent_add_property(parent,icalproperty_new_description( - incidence->description().utf8())); + incidence->description().local8Bit())); } // summary if (!incidence->summary().isEmpty()) { icalcomponent_add_property(parent,icalproperty_new_summary( - incidence->summary().utf8())); + incidence->summary().local8Bit())); } // TODO: // status -// addPropValue(parent, VCStatusProp, incidence->getStatusStr().ascii()); +// addPropValue(parent, VCStatusProp, incidence->getStatusStr().local8Bit()); // secrecy const char *classStr; switch (incidence->secrecy()) { case Incidence::SecrecyPublic: classStr = "PUBLIC"; break; case Incidence::SecrecyConfidential: classStr = "CONFIDENTIAL"; break; case Incidence::SecrecyPrivate: default: classStr = "PRIVATE"; break; } icalcomponent_add_property(parent,icalproperty_new_class(classStr)); // priority icalcomponent_add_property(parent,icalproperty_new_priority( incidence->priority())); // categories QStringList categories = incidence->categories(); QStringList::Iterator it; for(it = categories.begin(); it != categories.end(); ++it ) { - icalcomponent_add_property(parent,icalproperty_new_categories((*it).utf8())); + icalcomponent_add_property(parent,icalproperty_new_categories((*it).local8Bit())); } // TODO: Ensure correct concatenation of categories properties. /* // categories tmpStrList = incidence->getCategories(); tmpStr = ""; QString catStr; for ( QStringList::Iterator it = tmpStrList.begin(); it != tmpStrList.end(); ++it ) { catStr = *it; if (catStr[0] == ' ') tmpStr += catStr.mid(1); else tmpStr += catStr; // this must be a ';' character as the vCalendar specification requires! // vcc.y has been hacked to translate the ';' to a ',' when the vcal is // read in. tmpStr += ";"; } if (!tmpStr.isEmpty()) { tmpStr.truncate(tmpStr.length()-1); icalcomponent_add_property(parent,icalproperty_new_categories( writeText(incidence->getCategories().join(";")))); } */ // related event if (incidence->relatedTo()) { icalcomponent_add_property(parent,icalproperty_new_relatedto( - incidence->relatedTo()->VUID().latin1())); + incidence->relatedTo()->VUID().local8Bit())); } // pilot sync stuff icalproperty *p = - icalproperty_new_x((QString::number(incidence->pilotId())).utf8()); + icalproperty_new_x((QString::number(incidence->pilotId())).local8Bit()); icalproperty_set_x_name(p,"X-PILOTID"); icalcomponent_add_property(parent,p); - p = icalproperty_new_x((QString::number(incidence->syncStatus())).utf8()); + p = icalproperty_new_x((QString::number(incidence->syncStatus())).local8Bit()); icalproperty_set_x_name(p,"X-PILOTSTAT"); icalcomponent_add_property(parent,p); // recurrence rule stuff Recurrence *recur = incidence->recurrence(); if (recur->doesRecur()) { kdDebug() << "Write recurrence for '" << incidence->summary() << "' (" << incidence->VUID() << ")" << endl; icalcomponent_add_property(parent,writeRecurrenceRule(recur)); } // recurrence excpetion dates DateList dateList = incidence->exDates(); DateList::ConstIterator exIt; for(exIt = dateList.begin(); exIt != dateList.end(); ++exIt) { icalcomponent_add_property(parent,icalproperty_new_exdate( writeICalDate(*exIt))); } // alarms QPtrList alarms = incidence->alarms(); Alarm* alarm; for (alarm = alarms.first(); alarm; alarm = alarms.next()) { if (alarm->enabled()) { kdDebug() << "Write alarm for " << incidence->summary() << endl; icalcomponent_add_component(parent,writeAlarm(alarm)); } } // duration if (incidence->hasDuration()) { icaldurationtype duration; duration = writeICalDuration(incidence->duration()); icalcomponent_add_property(parent,icalproperty_new_duration(duration)); } } icalproperty *ICalFormatImpl::writeAttendee(Attendee *attendee) { - icalproperty *p = icalproperty_new_attendee("mailto:" + attendee->email().utf8()); + icalproperty *p = icalproperty_new_attendee("mailto:" + attendee->email().local8Bit()); if (!attendee->name().isEmpty()) { - icalproperty_add_parameter(p,icalparameter_new_cn(attendee->name())); + icalproperty_add_parameter(p,icalparameter_new_cn(attendee->name().local8Bit())); } icalproperty_add_parameter(p,icalparameter_new_rsvp( attendee->RSVP() ? ICAL_RSVP_TRUE : ICAL_RSVP_FALSE )); icalparameter_partstat status = ICAL_PARTSTAT_NEEDSACTION; switch (attendee->status()) { default: case Attendee::NeedsAction: status = ICAL_PARTSTAT_NEEDSACTION; break; case Attendee::Accepted: status = ICAL_PARTSTAT_ACCEPTED; break; case Attendee::Declined: status = ICAL_PARTSTAT_DECLINED; break; case Attendee::Tentative: status = ICAL_PARTSTAT_TENTATIVE; break; case Attendee::Delegated: status = ICAL_PARTSTAT_DELEGATED; break; case Attendee::Completed: status = ICAL_PARTSTAT_COMPLETED; break; case Attendee::InProcess: status = ICAL_PARTSTAT_INPROCESS; break; } icalproperty_add_parameter(p,icalparameter_new_partstat(status)); icalparameter_role role = ICAL_ROLE_REQPARTICIPANT; switch (attendee->role()) { case Attendee::Chair: role = ICAL_ROLE_CHAIR; break; default: case Attendee::ReqParticipant: role = ICAL_ROLE_REQPARTICIPANT; break; case Attendee::OptParticipant: role = ICAL_ROLE_OPTPARTICIPANT; break; case Attendee::NonParticipant: role = ICAL_ROLE_NONPARTICIPANT; break; } icalproperty_add_parameter(p,icalparameter_new_role(role)); return p; } icalproperty *ICalFormatImpl::writeRecurrenceRule(Recurrence *recur) { // kdDebug() << "ICalFormatImpl::writeRecurrenceRule()" << endl; icalrecurrencetype r; icalrecurrencetype_clear(&r); int index = 0; int index2 = 0; QPtrList tmpPositions; QPtrList tmpDays; int *tmpDay; Recurrence::rMonthPos *tmpPos; int day; int i; switch(recur->doesRecur()) { case Recurrence::rDaily: r.freq = ICAL_DAILY_RECURRENCE; #if 0 tmpStr.sprintf("D%i ",anEvent->rFreq); // if (anEvent->rDuration > 0) // tmpStr += "#"; #endif break; case Recurrence::rWeekly: r.freq = ICAL_WEEKLY_RECURRENCE; for (i = 0; i < 7; i++) { if (recur->days().testBit(i)) { if (i == 6) day = 1; else day = i + 2; r.by_day[index++] = icalrecurrencetype_day_day_of_week(day); } } // r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX; #if 0 tmpStr.sprintf("W%i ",anEvent->rFreq); for (i = 0; i < 7; i++) { if (anEvent->rDays.testBit(i)) tmpStr += dayFromNum(i); } #endif break; case Recurrence::rMonthlyPos: r.freq = ICAL_MONTHLY_RECURRENCE; tmpPositions = recur->monthPositions(); tmpPos = tmpPositions.first(); r.by_set_pos[index2++] = tmpPos->rPos; for (i = 0; i < 7; i++) { if (tmpPos->rDays.testBit(i)) { if (i == 6) day = 1; else day = i + 2; r.by_day[index++] = icalrecurrencetype_day_day_of_week(day); } } // r.by_month_day[index] = ICAL_RECURRENCE_ARRAY_MAX; #if 0 tmpStr.sprintf("MP%i ", anEvent->rFreq); // write out all rMonthPos's tmpPositions = anEvent->rMonthPositions; for (tmpPos = tmpPositions.first(); tmpPos; tmpPos = tmpPositions.next()) { tmpStr2.sprintf("%i", tmpPos->rPos); if (tmpPos->negative) tmpStr2 += "- "; else tmpStr2 += "+ "; tmpStr += tmpStr2; for (i = 0; i < 7; i++) { if (tmpPos->rDays.testBit(i)) tmpStr += dayFromNum(i); } } // loop for all rMonthPos's #endif break; case Recurrence::rMonthlyDay: r.freq = ICAL_MONTHLY_RECURRENCE; tmpDays = recur->monthDays(); for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { r.by_month_day[index++] = icalrecurrencetype_day_position(*tmpDay); } // r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX; #if 0 tmpStr.sprintf("MD%i ", anEvent->rFreq); // write out all rMonthDays; tmpDays = anEvent->rMonthDays; for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { tmpStr2.sprintf("%i ", *tmpDay); tmpStr += tmpStr2; } #endif break; case Recurrence::rYearlyMonth: r.freq = ICAL_YEARLY_RECURRENCE; tmpDays = recur->yearNums(); for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { r.by_month[index++] = *tmpDay; } // r.by_set_pos[index] = ICAL_RECURRENCE_ARRAY_MAX; #if 0 tmpStr.sprintf("YM%i ", anEvent->rFreq); // write out all the rYearNums; tmpDays = anEvent->rYearNums; for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { tmpStr2.sprintf("%i ", *tmpDay); tmpStr += tmpStr2; } #endif break; case Recurrence::rYearlyDay: r.freq = ICAL_YEARLY_RECURRENCE; tmpDays = recur->yearNums(); for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { r.by_year_day[index++] = *tmpDay; } // r.by_year_day[index] = ICAL_RECURRENCE_ARRAY_MAX; #if 0 tmpStr.sprintf("YD%i ", anEvent->rFreq); // write out all the rYearNums; tmpDays = anEvent->rYearNums; for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { tmpStr2.sprintf("%i ", *tmpDay); tmpStr += tmpStr2; } #endif break; default: r.freq = ICAL_NO_RECURRENCE; kdDebug() << "ICalFormatImpl::writeRecurrence(): no recurrence" << endl; break; } r.interval = recur->frequency(); if (recur->duration() > 0) { r.count = recur->duration(); } else if (recur->duration() == -1) { r.count = 0; } else { r.until = writeICalDate(recur->endDate()); } // Debug output #if 0 const char *str = icalrecurrencetype_as_string(&r); if (str) { kdDebug() << " String: " << str << endl; } else { kdDebug() << " No String" << endl; } #endif return icalproperty_new_rrule(r); #if 0 // some more variables QPtrList tmpPositions; QPtrList tmpDays; int *tmpDay; Event::rMonthPos *tmpPos; QString tmpStr2; switch(anEvent->doesRecur()) { case Event::rDaily: tmpStr.sprintf("D%i ",anEvent->rFreq); // if (anEvent->rDuration > 0) // tmpStr += "#"; break; case Event::rWeekly: tmpStr.sprintf("W%i ",anEvent->rFreq); for (int i = 0; i < 7; i++) { if (anEvent->rDays.testBit(i)) tmpStr += dayFromNum(i); } break; case Event::rMonthlyPos: tmpStr.sprintf("MP%i ", anEvent->rFreq); // write out all rMonthPos's tmpPositions = anEvent->rMonthPositions; for (tmpPos = tmpPositions.first(); tmpPos; tmpPos = tmpPositions.next()) { tmpStr2.sprintf("%i", tmpPos->rPos); if (tmpPos->negative) tmpStr2 += "- "; else tmpStr2 += "+ "; tmpStr += tmpStr2; for (int i = 0; i < 7; i++) { if (tmpPos->rDays.testBit(i)) tmpStr += dayFromNum(i); } } // loop for all rMonthPos's break; case Event::rMonthlyDay: tmpStr.sprintf("MD%i ", anEvent->rFreq); // write out all rMonthDays; tmpDays = anEvent->rMonthDays; for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { tmpStr2.sprintf("%i ", *tmpDay); tmpStr += tmpStr2; } break; case Event::rYearlyMonth: tmpStr.sprintf("YM%i ", anEvent->rFreq); // write out all the rYearNums; tmpDays = anEvent->rYearNums; for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { tmpStr2.sprintf("%i ", *tmpDay); tmpStr += tmpStr2; } break; case Event::rYearlyDay: tmpStr.sprintf("YD%i ", anEvent->rFreq); // write out all the rYearNums; tmpDays = anEvent->rYearNums; for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { tmpStr2.sprintf("%i ", *tmpDay); tmpStr += tmpStr2; } break; default: kdDebug() << "ERROR, it should never get here in eventToVEvent!" << endl; break; } // switch if (anEvent->rDuration > 0) { tmpStr2.sprintf("#%i",anEvent->rDuration); tmpStr += tmpStr2; } else if (anEvent->rDuration == -1) { tmpStr += "#0"; // defined as repeat forever } else { tmpStr += qDateTimeToISO(anEvent->rEndDate, FALSE); } - addPropValue(vevent,VCRRuleProp, tmpStr.ascii()); + addPropValue(vevent,VCRRuleProp, tmpStr.local8Bit()); } // event repeats #endif } icalcomponent *ICalFormatImpl::writeAlarm(Alarm *alarm) { icalcomponent *a = icalcomponent_new(ICAL_VALARM_COMPONENT); icalproperty_action action; icalattachtype *attach; if (!alarm->programFile().isEmpty()) { action = ICAL_ACTION_PROCEDURE; // The attachement crashes this function. Find the cause and reenable the code // later. #if 0 attach = icalattachtype_new(); icalattachtype_set_url(attach,QFile::encodeName(alarm->programFile()).data()); icalcomponent_add_property(a,icalproperty_new_attach(*attach)); #endif } else if (!alarm->audioFile().isEmpty()) { action = ICAL_ACTION_AUDIO; #if 0 attach = icalattachtype_new(); icalattachtype_set_url(attach,QFile::encodeName(alarm->audioFile()).data()); icalcomponent_add_property(a,icalproperty_new_attach(*attach)); #endif } else if (!alarm->mailAddress().isEmpty()) { action = ICAL_ACTION_EMAIL; icalcomponent_add_property(a,icalproperty_new_attendee(alarm->mailAddress())); // TODO: multiple attendees can be specified icalcomponent_add_property(a,icalproperty_new_summary(alarm->mailSubject())); icalcomponent_add_property(a,icalproperty_new_description(alarm->text())); } else { action = ICAL_ACTION_DISPLAY; icalcomponent_add_property(a,icalproperty_new_description(alarm->text())); } icalcomponent_add_property(a,icalproperty_new_action(action)); icaltriggertype trigger; trigger.time = writeICalDateTime(alarm->time()); icalcomponent_add_property(a,icalproperty_new_trigger(trigger)); if (alarm->repeatCount()) { icalcomponent_add_property(a,icalproperty_new_repeat(alarm->repeatCount())); icalcomponent_add_property(a,icalproperty_new_duration( icaldurationtype_from_int(alarm->snoozeTime()*60))); } return a; } Todo *ICalFormatImpl::readTodo(icalcomponent *vtodo) { Todo *todo = new Todo; readIncidence(vtodo,todo); icalproperty *p = icalcomponent_get_first_property(vtodo,ICAL_ANY_PROPERTY); const char *text; // int intvalue; icaltimetype icaltime; QStringList categories; while (p) { icalproperty_kind kind = icalproperty_isa(p); switch (kind) { case ICAL_DUE_PROPERTY: // due date icaltime = icalproperty_get_due(p); if (icaltime.is_date) { todo->setDtDue(QDateTime(readICalDate(icaltime),QTime(0,0,0))); todo->setFloats(true); } else { todo->setDtDue(readICalDateTime(icaltime)); todo->setFloats(false); } todo->setHasDueDate(true); break; case ICAL_COMPLETED_PROPERTY: // completion date icaltime = icalproperty_get_completed(p); todo->setCompleted(readICalDateTime(icaltime)); break; case ICAL_PERCENTCOMPLETE_PROPERTY: // Percent completed todo->setPercentComplete(icalproperty_get_percentcomplete(p)); break; case ICAL_RELATEDTO_PROPERTY: // releated todo (parent) text = icalproperty_get_relatedto(p); todo->setRelatedToVUID(text); mTodosRelate.append(todo); break; case ICAL_DTSTART_PROPERTY: // Flag that todo has start date. Value is read in by readIncidence(). todo->setHasStartDate(true); break; default: // kdDebug() << "ICALFormat::readTodo(): Unknown property: " << kind // << endl; break; } p = icalcomponent_get_next_property(vtodo,ICAL_ANY_PROPERTY); } return todo; } Event *ICalFormatImpl::readEvent(icalcomponent *vevent) { Event *event = new Event; event->setFloats(false); readIncidence(vevent,event); icalproperty *p = icalcomponent_get_first_property(vevent,ICAL_ANY_PROPERTY); const char *text; // int intvalue; icaltimetype icaltime; QStringList categories; while (p) { icalproperty_kind kind = icalproperty_isa(p); switch (kind) { case ICAL_DTEND_PROPERTY: // start date and time icaltime = icalproperty_get_dtend(p); if (icaltime.is_date) { event->setDtEnd(QDateTime(readICalDate(icaltime),QTime(0,0,0))); event->setFloats(true); } else { event->setDtEnd(readICalDateTime(icaltime)); } break; // TODO: // at this point, there should be at least a start or end time. // fix up for events that take up no time but have a time associated #if 0 if (!(vo = isAPropertyOf(vevent, VCDTstartProp))) anEvent->setDtStart(anEvent->dtEnd()); if (!(vo = isAPropertyOf(vevent, VCDTendProp))) anEvent->setDtEnd(anEvent->dtStart()); #endif // TODO: exdates #if 0 // recurrence exceptions if ((vo = isAPropertyOf(vevent, VCExDateProp)) != 0) { anEvent->setExDates(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } #endif #if 0 // secrecy if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) { anEvent->setSecrecy(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } else anEvent->setSecrecy("PUBLIC"); // attachments tmpStrList.clear(); initPropIterator(&voi, vevent); while (moreIteration(&voi)) { vo = nextVObject(&voi); if (strcmp(vObjectName(vo), VCAttachProp) == 0) { tmpStrList.append(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } } anEvent->setAttachments(tmpStrList); // resources if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) { QString resources = (s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); tmpStrList.clear(); index1 = 0; index2 = 0; QString resource; while ((index2 = resources.find(';', index1)) != -1) { resource = resources.mid(index1, (index2 - index1)); tmpStrList.append(resource); index1 = index2; } anEvent->setResources(tmpStrList); } #endif // TODO: transparency #if 0 // transparency if ((vo = isAPropertyOf(vevent, VCTranspProp)) != 0) { anEvent->setTransparency(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } #endif case ICAL_RELATEDTO_PROPERTY: // releated event (parent) text = icalproperty_get_relatedto(p); event->setRelatedToVUID(text); mEventsRelate.append(event); break; default: // kdDebug() << "ICALFormat::readEvent(): Unknown property: " << kind // << endl; break; } p = icalcomponent_get_next_property(vevent,ICAL_ANY_PROPERTY); } // some stupid vCal exporters ignore the standard and use Description // instead of Summary for the default field. Correct for this. if (event->summary().isEmpty() && !(event->description().isEmpty())) { QString tmpStr = event->description().simplifyWhiteSpace(); event->setDescription(""); event->setSummary(tmpStr); } return event; } Journal *ICalFormatImpl::readJournal(icalcomponent *vjournal) { Journal *journal = new Journal; readIncidence(vjournal,journal); return journal; } Attendee *ICalFormatImpl::readAttendee(icalproperty *attendee) { icalparameter *p = 0; - QString email = QString::fromUtf8(icalproperty_get_attendee(attendee)); + QString email = QString::fromLocal8Bit(icalproperty_get_attendee(attendee)); QString name; p = icalproperty_get_first_parameter(attendee,ICAL_CN_PARAMETER); if (p) { - name = icalparameter_get_cn(p); + name = QString::fromLocal8Bit(icalparameter_get_cn(p)); } else { } bool rsvp=false; p = icalproperty_get_first_parameter(attendee,ICAL_RSVP_PARAMETER); if (p) { icalparameter_rsvp rsvpParameter = icalparameter_get_rsvp(p); if (rsvpParameter == ICAL_RSVP_TRUE) rsvp = true; } Attendee::PartStat status = Attendee::NeedsAction; p = icalproperty_get_first_parameter(attendee,ICAL_PARTSTAT_PARAMETER); if (p) { icalparameter_partstat partStatParameter = icalparameter_get_partstat(p); switch(partStatParameter) { default: case ICAL_PARTSTAT_NEEDSACTION: status = Attendee::NeedsAction; break; case ICAL_PARTSTAT_ACCEPTED: status = Attendee::Accepted; break; case ICAL_PARTSTAT_DECLINED: status = Attendee::Declined; break; case ICAL_PARTSTAT_TENTATIVE: status = Attendee::Tentative; break; case ICAL_PARTSTAT_DELEGATED: status = Attendee::Delegated; break; case ICAL_PARTSTAT_COMPLETED: status = Attendee::Completed; break; case ICAL_PARTSTAT_INPROCESS: status = Attendee::InProcess; break; } } Attendee::Role role = Attendee::ReqParticipant; p = icalproperty_get_first_parameter(attendee,ICAL_ROLE_PARAMETER); if (p) { icalparameter_role roleParameter = icalparameter_get_role(p); switch(roleParameter) { case ICAL_ROLE_CHAIR: role = Attendee::Chair; break; default: case ICAL_ROLE_REQPARTICIPANT: role = Attendee::ReqParticipant; break; case ICAL_ROLE_OPTPARTICIPANT: role = Attendee::OptParticipant; break; case ICAL_ROLE_NONPARTICIPANT: role = Attendee::NonParticipant; break; } } return new Attendee( name, email, rsvp, status, role ); } void ICalFormatImpl::readIncidence(icalcomponent *parent,Incidence *incidence) { icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY); const char *text; int intvalue; icaltimetype icaltime; icaldurationtype icalduration; QStringList categories; while (p) { icalproperty_kind kind = icalproperty_isa(p); switch (kind) { case ICAL_CREATED_PROPERTY: icaltime = icalproperty_get_created(p); incidence->setCreated(readICalDateTime(icaltime)); break; case ICAL_UID_PROPERTY: // unique id text = icalproperty_get_uid(p); incidence->setVUID(text); break; case ICAL_SEQUENCE_PROPERTY: // sequence intvalue = icalproperty_get_sequence(p); incidence->setRevision(intvalue); break; case ICAL_LASTMODIFIED_PROPERTY: // last modification date icaltime = icalproperty_get_lastmodified(p); incidence->setLastModified(readICalDateTime(icaltime)); break; case ICAL_ORGANIZER_PROPERTY: // organizer text = icalproperty_get_organizer(p); - incidence->setOrganizer(QString::fromUtf8(text)); + incidence->setOrganizer(QString::fromLocal8Bit(text)); break; case ICAL_ATTENDEE_PROPERTY: // attendee incidence->addAttendee(readAttendee(p)); break; case ICAL_DTSTART_PROPERTY: // start date and time icaltime = icalproperty_get_dtstart(p); if (icaltime.is_date) { incidence->setDtStart(QDateTime(readICalDate(icaltime),QTime(0,0,0))); incidence->setFloats(true); } else { incidence->setDtStart(readICalDateTime(icaltime)); } break; case ICAL_DURATION_PROPERTY: // start date and time icalduration = icalproperty_get_duration(p); incidence->setDuration(readICalDuration(icalduration)); break; case ICAL_DESCRIPTION_PROPERTY: // description text = icalproperty_get_description(p); - incidence->setDescription(QString::fromUtf8(text)); + incidence->setDescription(QString::fromLocal8Bit(text)); break; case ICAL_SUMMARY_PROPERTY: // summary text = icalproperty_get_summary(p); - incidence->setSummary(QString::fromUtf8(text)); + incidence->setSummary(QString::fromLocal8Bit(text)); break; #if 0 // status if ((vo = isAPropertyOf(vincidence, VCStatusProp)) != 0) { incidence->setStatus(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } else incidence->setStatus("NEEDS ACTION"); #endif case ICAL_PRIORITY_PROPERTY: // priority intvalue = icalproperty_get_priority(p); incidence->setPriority(intvalue); break; case ICAL_CATEGORIES_PROPERTY: // categories text = icalproperty_get_categories(p); - categories.append(QString::fromUtf8(text)); + categories.append(QString::fromLocal8Bit(text)); break; case ICAL_RRULE_PROPERTY: readRecurrenceRule(p,incidence); break; case ICAL_EXDATE_PROPERTY: icaltime = icalproperty_get_exdate(p); incidence->addExDate(readICalDate(icaltime)); break; case ICAL_CLASS_PROPERTY: text = icalproperty_get_class(p); if (strcmp(text,"PUBLIC") == 0) { incidence->setSecrecy(Incidence::SecrecyPublic); } else if (strcmp(text,"CONFIDENTIAL") == 0) { incidence->setSecrecy(Incidence::SecrecyConfidential); } else { incidence->setSecrecy(Incidence::SecrecyPrivate); } break; case ICAL_X_PROPERTY: if (strcmp(icalproperty_get_name(p),"X-PILOTID") == 0) { text = icalproperty_get_value_as_string(p); - incidence->setPilotId(QString::fromUtf8(text).toInt()); + incidence->setPilotId(QString::fromLocal8Bit(text).toInt()); } else if (strcmp(icalproperty_get_name(p),"X-PILOTSTAT") == 0) { text = icalproperty_get_value_as_string(p); - incidence->setSyncStatus(QString::fromUtf8(text).toInt()); + incidence->setSyncStatus(QString::fromLocal8Bit(text).toInt()); } break; default: // kdDebug() << "ICALFormat::readIncidence(): Unknown property: " << kind // << endl; break; } p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY); } // add categories incidence->setCategories(categories); // iterate through all alarms for (icalcomponent *alarm = icalcomponent_get_first_component(parent,ICAL_VALARM_COMPONENT); alarm; alarm = icalcomponent_get_next_component(parent,ICAL_VALARM_COMPONENT)) { readAlarm(alarm,incidence); } } void ICalFormatImpl::readRecurrenceRule(icalproperty *rrule,Incidence *incidence) { // kdDebug() << "Read recurrence for " << incidence->summary() << endl; Recurrence *recur = incidence->recurrence(); recur->unsetRecurs(); struct icalrecurrencetype r = icalproperty_get_rrule(rrule); dumpIcalRecurrence(r); int index = 0; short day = 0; QBitArray qba(7); switch (r.freq) { case ICAL_DAILY_RECURRENCE: if (!icaltime_is_null_time(r.until)) { recur->setDaily(r.interval,readICalDate(r.until)); } else { if (r.count == 0) recur->setDaily(r.interval,-1); else recur->setDaily(r.interval,r.count); } break; case ICAL_WEEKLY_RECURRENCE: // kdDebug() << "WEEKLY_RECURRENCE" << endl; while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { // kdDebug() << " " << day << endl; if (day == 1) qba.setBit(6); else qba.setBit(day-2); } if (!icaltime_is_null_time(r.until)) { recur->setWeekly(r.interval,qba,readICalDate(r.until)); } else { if (r.count == 0) recur->setWeekly(r.interval,qba,-1); else recur->setWeekly(r.interval,qba,r.count); } break; case ICAL_MONTHLY_RECURRENCE: if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { // kdDebug() << "----a " << index << ": " << day << endl; if (day == 1) qba.setBit(6); else qba.setBit(day-2); } if (!icaltime_is_null_time(r.until)) { recur->setMonthly(Recurrence::rMonthlyPos,r.interval, readICalDate(r.until)); } else { if (r.count == 0) recur->setMonthly(Recurrence::rMonthlyPos,r.interval,-1); else recur->setMonthly(Recurrence::rMonthlyPos,r.interval,r.count); } if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) { recur->addMonthlyPos(r.by_set_pos[0],qba); } else { recur->addMonthlyPos(0,qba); } } else if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { while((day = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { // kdDebug() << "----b " << day << endl; recur->addMonthlyDay(day); } if (!icaltime_is_null_time(r.until)) { recur->setMonthly(Recurrence::rMonthlyDay,r.interval, readICalDate(r.until)); } else { if (r.count == 0) recur->setMonthly(Recurrence::rMonthlyDay,r.interval,-1); else recur->setMonthly(Recurrence::rMonthlyDay,r.interval,r.count); } } break; case ICAL_YEARLY_RECURRENCE: if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { while((day = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { recur->addYearlyNum(day); } if (!icaltime_is_null_time(r.until)) { recur->setYearly(Recurrence::rYearlyDay,r.interval, readICalDate(r.until)); } else { if (r.count == 0) recur->setYearly(Recurrence::rYearlyDay,r.interval,-1); else recur->setYearly(Recurrence::rYearlyDay,r.interval,r.count); } } if (r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) { while((day = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { recur->addYearlyNum(day); } if (!icaltime_is_null_time(r.until)) { recur->setYearly(Recurrence::rYearlyMonth,r.interval, readICalDate(r.until)); } else { if (r.count == 0) recur->setYearly(Recurrence::rYearlyMonth,r.interval,-1); else recur->setYearly(Recurrence::rYearlyMonth,r.interval,r.count); } } break; default: kdDebug() << "Unknown type of recurrence: " << r.freq << endl; break; } #if 0 // repeat stuff if ((vo = isAPropertyOf(vevent, VCRRuleProp)) != 0) { QString tmpStr = (s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); tmpStr.simplifyWhiteSpace(); tmpStr = tmpStr.upper(); /********************************* DAILY ******************************/ if (tmpStr.left(1) == "D") { int index = tmpStr.find(' '); int rFreq = tmpStr.mid(1, (index-1)).toInt(); index = tmpStr.findRev(' ') + 1; // advance to last field if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->setRecursDaily(rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) // VEvents set this to 0 forever, we use -1 anEvent->setRecursDaily(rFreq, -1); else anEvent->setRecursDaily(rFreq, rDuration); } } /********************************* WEEKLY ******************************/ else if (tmpStr.left(1) == "W") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(1, (index-1)).toInt(); index += 1; // advance to beginning of stuff after freq QBitArray qba(7); QString dayStr; if( index == last ) { // e.g. W1 #0 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1); } else { // e.g. W1 SU #0 while (index < last) { dayStr = tmpStr.mid(index, 3); int dayNum = numFromDay(dayStr); qba.setBit(dayNum); index += 3; // advance to next day, or possibly "#" } } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->setRecursWeekly(rFreq, qba, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->setRecursWeekly(rFreq, qba, -1); else anEvent->setRecursWeekly(rFreq, qba, rDuration); } } /**************************** MONTHLY-BY-POS ***************************/ else if (tmpStr.left(2) == "MP") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(2, (index-1)).toInt(); index += 1; // advance to beginning of stuff after freq QBitArray qba(7); short tmpPos; if( index == last ) { // e.g. MP1 #0 tmpPos = anEvent->dtStart().date().day()/7 + 1; if( tmpPos == 5 ) tmpPos = -1; qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1); anEvent->addRecursMonthlyPos(tmpPos, qba); } else { // e.g. MP1 1+ SU #0 while (index < last) { tmpPos = tmpStr.mid(index,1).toShort(); index += 1; if (tmpStr.mid(index,1) == "-") // convert tmpPos to negative tmpPos = 0 - tmpPos; index += 2; // advance to day(s) while (numFromDay(tmpStr.mid(index,3)) >= 0) { int dayNum = numFromDay(tmpStr.mid(index,3)); qba.setBit(dayNum); index += 3; // advance to next day, or possibly pos or "#" } anEvent->addRecursMonthlyPos(tmpPos, qba); qba.detach(); qba.fill(FALSE); // clear out } // while != "#" } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length() - index))).date(); anEvent->setRecursMonthly(Event::rMonthlyPos, rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->setRecursMonthly(Event::rMonthlyPos, rFreq, -1); else anEvent->setRecursMonthly(Event::rMonthlyPos, rFreq, rDuration); } } /**************************** MONTHLY-BY-DAY ***************************/ else if (tmpStr.left(2) == "MD") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(2, (index-1)).toInt(); index += 1; short tmpDay; if( index == last ) { // e.g. MD1 #0 tmpDay = anEvent->dtStart().date().day(); anEvent->addRecursMonthlyDay(tmpDay); } else { // e.g. MD1 3 #0 while (index < last) { int index2 = tmpStr.find(' ', index); tmpDay = tmpStr.mid(index, (index2-index)).toShort(); index = index2-1; if (tmpStr.mid(index, 1) == "-") tmpDay = 0 - tmpDay; index += 2; // advance the index; anEvent->addRecursMonthlyDay(tmpDay); } // while != # } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->setRecursMonthly(Event::rMonthlyDay, rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->setRecursMonthly(Event::rMonthlyDay, rFreq, -1); else anEvent->setRecursMonthly(Event::rMonthlyDay, rFreq, rDuration); } } /*********************** YEARLY-BY-MONTH *******************************/ else if (tmpStr.left(2) == "YM") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(2, (index-1)).toInt(); index += 1; short tmpMonth; if( index == last ) { // e.g. YM1 #0 tmpMonth = anEvent->dtStart().date().month(); anEvent->addRecursYearlyNum(tmpMonth); } else { // e.g. YM1 3 #0 while (index < last) { int index2 = tmpStr.find(' ', index); tmpMonth = tmpStr.mid(index, (index2-index)).toShort(); index = index2+1; anEvent->addRecursYearlyNum(tmpMonth); } // while != # } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->setRecursYearly(Event::rYearlyMonth, rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->setRecursYearly(Event::rYearlyMonth, rFreq, -1); else anEvent->setRecursYearly(Event::rYearlyMonth, rFreq, rDuration); } } /*********************** YEARLY-BY-DAY *********************************/ else if (tmpStr.left(2) == "YD") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(2, (index-1)).toInt(); index += 1; short tmpDay; if( index == last ) { // e.g. YD1 #0 tmpDay = anEvent->dtStart().date().dayOfYear(); anEvent->addRecursYearlyNum(tmpDay); } else { // e.g. YD1 123 #0 while (index < last) { int index2 = tmpStr.find(' ', index); tmpDay = tmpStr.mid(index, (index2-index)).toShort(); index = index2+1; anEvent->addRecursYearlyNum(tmpDay); } // while != # } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->setRecursYearly(Event::rYearlyDay, rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->setRecursYearly(Event::rYearlyDay, rFreq, -1); else anEvent->setRecursYearly(Event::rYearlyDay, rFreq, rDuration); } } else { kdDebug() << "we don't understand this type of recurrence!" << endl; } // if } // repeats #endif } void ICalFormatImpl::readAlarm(icalcomponent *alarm,Incidence *incidence) { //kdDebug() << "Read alarm for " << incidence->summary() << endl; Alarm* ialarm = incidence->newAlarm(); ialarm->setRepeatCount(0); ialarm->setEnabled(true); icalproperty *p = icalcomponent_get_first_property(alarm,ICAL_ANY_PROPERTY); icaltriggertype trigger; icalattachtype attach; icaldurationtype duration; icalproperty_action action; while (p) { icalproperty_kind kind = icalproperty_isa(p); switch (kind) { case ICAL_ACTION_PROPERTY: action = icalproperty_get_action(p); break; case ICAL_TRIGGER_PROPERTY: trigger = icalproperty_get_trigger(p); if (icaltime_is_null_time(trigger.time)) { // kdDebug() << "ICalFormatImpl::readAlarm(): Trigger has no time." << endl; if (icaldurationtype_is_null_duration(trigger.duration)) { // kdDebug() << "ICalFormatImpl::readAlarm(): Trigger has no duration." << endl; } else { // kdDebug() << "ICalFormatImpl::readAlarm(): Trigger has duration." << endl; } } else { ialarm->setTime(readICalDateTime(trigger.time)); } break; case ICAL_DURATION_PROPERTY: duration = icalproperty_get_duration(p); ialarm->setSnoozeTime(icaldurationtype_as_int(duration)/60); break; case ICAL_REPEAT_PROPERTY: ialarm->setRepeatCount(icalproperty_get_repeat(p)); break; // Only in AUDIO and PROCEDURE alarms case ICAL_ATTACH_PROPERTY: // TODO: move reading the attachement after reading the action type attach = icalproperty_get_attach(p); ialarm->setAudioFile(QFile::decodeName( icalattachtype_get_url(&attach))); break; // Only in DISPLAY and EMAIL and PROCEDURE alarms case ICAL_DESCRIPTION_PROPERTY: ialarm->setText(icalproperty_get_description(p)); break; // Only in EMAIL alarm case ICAL_SUMMARY_PROPERTY: ialarm->setMailSubject(icalproperty_get_summary(p)); break; // Only in EMAIL alarm case ICAL_ATTENDEE_PROPERTY: ialarm->setMailAddress(icalproperty_get_attendee(p)); // TODO: multiple attendees can be specified break; default: break; } p = icalcomponent_get_next_property(alarm,ICAL_ANY_PROPERTY); } // TODO: check for consistency of alarm properties // TODO: read alarms #if 0 /* alarm stuff */ if ((vo = isAPropertyOf(vevent, VCDAlarmProp))) { VObject *a; if ((a = isAPropertyOf(vo, VCRunTimeProp))) { anEvent->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a)))); deleteStr(s); } anEvent->setEnabled(true); if ((vo = isAPropertyOf(vevent, VCPAlarmProp))) { if ((a = isAPropertyOf(vo, VCProcedureNameProp))) { anEvent->setProgramFile(s = fakeCString(vObjectUStringZValue(a))); deleteStr(s); } } if ((vo = isAPropertyOf(vevent, VCAAlarmProp))) { if ((a = isAPropertyOf(vo, VCAudioContentProp))) { anEvent->setAudioFile(s = fakeCString(vObjectUStringZValue(a))); deleteStr(s); } } } if ((vo = isAPropertyOf(vtodo, VCDAlarmProp))) { VObject *a; if ((a = isAPropertyOf(vo, VCRunTimeProp))) { aTodo->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a)))); deleteStr(s); } aTodo->setEnabled(true); if ((vo = isAPropertyOf(vtodo, VCPAlarmProp))) { if ((a = isAPropertyOf(vo, VCProcedureNameProp))) { aTodo->setProgramFile(s = fakeCString(vObjectUStringZValue(a))); deleteStr(s); } } if ((vo = isAPropertyOf(vtodo, VCAAlarmProp))) { if ((a = isAPropertyOf(vo, VCAudioContentProp))) { aTodo->setAudioFile(s = fakeCString(vObjectUStringZValue(a))); deleteStr(s); } } } #endif } icaltimetype ICalFormatImpl::writeICalDate(const QDate &date) { icaltimetype t; t.year = date.year(); t.month = date.month(); t.day = date.day(); t.hour = 0; t.minute = 0; t.second = 0; t.is_date = 1; t.is_utc = 0; t.zone = 0; return t; } icaltimetype ICalFormatImpl::writeICalDateTime(const QDateTime &datetime, bool utc) { icaltimetype t; t.year = datetime.date().year(); t.month = datetime.date().month(); t.day = datetime.date().day(); t.hour = datetime.time().hour(); t.minute = datetime.time().minute(); t.second = datetime.time().second(); t.is_date = 0; if (utc) { t = icaltime_as_utc(t,mCalendar->timeZoneId().local8Bit()); t.is_utc = 1; } else { t.is_utc = 0; } t.zone = 0; return t; } QDateTime ICalFormatImpl::readICalDateTime(icaltimetype t) { /* kdDebug() << "ICalFormatImpl::readICalDateTime()" << endl; kdDebug() << "--- Y: " << t.year << " M: " << t.month << " D: " << t.day << endl; kdDebug() << "--- H: " << t.hour << " M: " << t.minute << " S: " << t.second << endl; kdDebug() << "--- isDate: " << t.is_date << endl; */ if (t.is_utc) { // kdDebug() << "--- Converting time to zone '" << mCalendar->timeZoneId() << "'." << endl; t = icaltime_as_zone(t,mCalendar->timeZoneId().local8Bit()); } return QDateTime(QDate(t.year,t.month,t.day), QTime(t.hour,t.minute,t.second)); } QDate ICalFormatImpl::readICalDate(icaltimetype t) { return QDate(t.year,t.month,t.day); } icaldurationtype ICalFormatImpl::writeICalDuration(int seconds) { icaldurationtype d; d.weeks = seconds % gSecondsPerWeek; seconds -= d.weeks * gSecondsPerWeek; d.days = seconds % gSecondsPerDay; seconds -= d.days * gSecondsPerDay; d.hours = seconds % gSecondsPerHour; seconds -= d.hours * gSecondsPerHour; d.minutes = seconds % gSecondsPerMinute; seconds -= d.minutes * gSecondsPerMinute; d.seconds = seconds; return d; } int ICalFormatImpl::readICalDuration(icaldurationtype d) { int result = 0; result += d.weeks * gSecondsPerWeek; result += d.days * gSecondsPerDay; result += d.hours * gSecondsPerHour; result += d.minutes * gSecondsPerMinute; result += d.seconds; if (d.is_neg) result *= -1; return result; } icalcomponent *ICalFormatImpl::createCalendarComponent() { icalcomponent *calendar; // Root component calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT); icalproperty *p; // Product Identifier - p = icalproperty_new_prodid(const_cast(CalFormat::productId().latin1())); + p = icalproperty_new_prodid(CalFormat::productId().local8Bit().data()); icalcomponent_add_property(calendar,p); // TODO: Add time zone // iCalendar version (2.0) p = icalproperty_new_version(const_cast(_ICAL_VERSION)); icalcomponent_add_property(calendar,p); return calendar; } // take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc. // and break it down from it's tree-like format into the dictionary format // that is used internally in the ICalFormatImpl. bool ICalFormatImpl::populate(icalcomponent *calendar) { // this function will populate the caldict dictionary and other event // lists. It turns vevents into Events and then inserts them. if (!calendar) return false; // TODO: check for METHOD #if 0 if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) { char *methodType = 0; methodType = fakeCString(vObjectUStringZValue(curVO)); if (mEnableDialogs) KMessageBox::information(mTopWidget, i18n("This calendar is an iTIP transaction of type \"%1\".") .arg(methodType), i18n("%1: iTIP Transaction").arg(CalFormat::application())); delete methodType; } #endif // TODO: check for unknown PRODID #if 0 // warn the user that we might have trouble reading non-known calendar. if ((curVO = isAPropertyOf(vcal, VCProdIdProp)) != 0) { char *s = fakeCString(vObjectUStringZValue(curVO)); - if (strcmp(CalFormat::productId().latin1(), s) != 0) + if (strcmp(CalFormat::productId().local8Bit(), s) != 0) if (mEnableDialogs) KMessageBox::information(mTopWidget, i18n("This vCalendar file was not created by KOrganizer\n" "or any other product we support. Loading anyway..."), i18n("%1: Unknown vCalendar Vendor").arg(CalFormat::application())); deleteStr(s); } #endif icalproperty *p; p = icalcomponent_get_first_property(calendar,ICAL_VERSION_PROPERTY); if (!p) { kdDebug() << "No VERSION property found" << endl; return false; } else { const char *version = icalproperty_get_version(p); kdDebug() << "VCALENDAR version: '" << version << "'" << endl; if (strcmp(version,"1.0") == 0) { kdDebug() << "Expected iCalendar, got vCalendar" << endl; mParent->setException(new ErrorFormat(ErrorFormat::CalVersion1, i18n("Expected iCalendar format"))); return false; } else if (strcmp(version,"2.0") != 0) { kdDebug() << "Expected iCalendar, got unknown format" << endl; mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); return false; } } // TODO: check for calendar format version #if 0 // warn the user we might have trouble reading this unknown version. if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) { char *s = fakeCString(vObjectUStringZValue(curVO)); if (strcmp(_VCAL_VERSION, s) != 0) if (mEnableDialogs) KMessageBox::sorry(mTopWidget, i18n("This vCalendar file has version %1.\n" "We only support %2.") .arg(s).arg(_VCAL_VERSION), i18n("%1: Unknown vCalendar Version").arg(CalFormat::application())); deleteStr(s); } #endif // TODO: set time zone #if 0 // set the time zone if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) { char *s = fakeCString(vObjectUStringZValue(curVO)); mCalendar->setTimeZone(s); deleteStr(s); } #endif // Store all events with a relatedTo property in a list for post-processing mEventsRelate.clear(); mTodosRelate.clear(); // TODO: make sure that only actually added ecvens go to this lists. icalcomponent *c; // Iterate through all todos c = icalcomponent_get_first_component(calendar,ICAL_VTODO_COMPONENT); while (c) { // kdDebug() << "----Todo found" << endl; Todo *todo = readTodo(c); if (!mCalendar->getTodo(todo->VUID())) mCalendar->addTodo(todo); c = icalcomponent_get_next_component(calendar,ICAL_VTODO_COMPONENT); } // Iterate through all events c = icalcomponent_get_first_component(calendar,ICAL_VEVENT_COMPONENT); while (c) { // kdDebug() << "----Event found" << endl; Event *event = readEvent(c); if (!mCalendar->getEvent(event->VUID())) mCalendar->addEvent(event); c = icalcomponent_get_next_component(calendar,ICAL_VEVENT_COMPONENT); } // Iterate through all journals c = icalcomponent_get_first_component(calendar,ICAL_VJOURNAL_COMPONENT); while (c) { // kdDebug() << "----Journal found" << endl; Journal *journal = readJournal(c); if (!mCalendar->journal(journal->VUID())) mCalendar->addJournal(journal); c = icalcomponent_get_next_component(calendar,ICAL_VJOURNAL_COMPONENT); } #if 0 initPropIterator(&i, vcal); // go through all the vobjects in the vcal while (moreIteration(&i)) { curVO = nextVObject(&i); /************************************************************************/ // now, check to see that the object is an event or todo. if (strcmp(vObjectName(curVO), VCEventProp) == 0) { if ((curVOProp = isAPropertyOf(curVO, KPilotStatusProp)) != 0) { char *s; s = fakeCString(vObjectUStringZValue(curVOProp)); // check to see if event was deleted by the kpilot conduit if (atoi(s) == Event::SYNCDEL) { deleteStr(s); kdDebug() << "skipping pilot-deleted event" << endl; goto SKIP; } deleteStr(s); } // this code checks to see if we are trying to read in an event // that we already find to be in the calendar. If we find this // to be the case, we skip the event. if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) { char *s = fakeCString(vObjectUStringZValue(curVOProp)); QString tmpStr(s); deleteStr(s); if (mCalendar->getEvent(tmpStr)) { goto SKIP; } if (mCalendar->getTodo(tmpStr)) { goto SKIP; } } if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) && (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) { kdDebug() << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl; goto SKIP; } anEvent = VEventToEvent(curVO); // we now use addEvent instead of insertEvent so that the // signal/slot get connected. if (anEvent) mCalendar->addEvent(anEvent); else { // some sort of error must have occurred while in translation. goto SKIP; } } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) { anEvent = VTodoToEvent(curVO); mCalendar->addTodo(anEvent); } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) || (strcmp(vObjectName(curVO), VCProdIdProp) == 0) || (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) { // do nothing, we know these properties and we want to skip them. // we have either already processed them or are ignoring them. ; } else { kdDebug() << "Ignoring unknown vObject \"" << vObjectName(curVO) << "\"" << endl; } SKIP: ; } // while #endif // Post-Process list of events with relations, put Event objects in relation Event *ev; for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) { ev->setRelatedTo(mCalendar->getEvent(ev->relatedToVUID())); } Todo *todo; for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) { todo->setRelatedTo(mCalendar->getTodo(todo->relatedToVUID())); } return true; } QString ICalFormatImpl::extractErrorProperty(icalcomponent *c) { // kdDebug() << "ICalFormatImpl:extractErrorProperty: " // << icalcomponent_as_ical_string(c) << endl; QString errorMessage; icalproperty *error; error = icalcomponent_get_first_property(c,ICAL_XLICERROR_PROPERTY); while(error) { errorMessage += icalproperty_get_xlicerror(error); errorMessage += "\n"; error = icalcomponent_get_next_property(c,ICAL_XLICERROR_PROPERTY); } // kdDebug() << "ICalFormatImpl:extractErrorProperty: " << errorMessage << endl; return errorMessage; } void ICalFormatImpl::dumpIcalRecurrence(icalrecurrencetype r) { int i; kdDebug() << " Freq: " << r.freq << endl; kdDebug() << " Until: " << icaltime_as_ctime(r.until) << endl; kdDebug() << " Count: " << r.count << endl; if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { int index = 0; QString out = " By Day: "; while((i = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { out.append(QString::number(i) + " "); } kdDebug() << out << endl; } if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { int index = 0; QString out = " By Month Day: "; while((i = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { out.append(QString::number(i) + " "); } kdDebug() << out << endl; } if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { int index = 0; QString out = " By Year Day: "; while((i = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { out.append(QString::number(i) + " "); } kdDebug() << out << endl; } if (r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) { int index = 0; QString out = " By Month: "; while((i = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { out.append(QString::number(i) + " "); } kdDebug() << out << endl; } if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) { int index = 0; QString out = " By Set Pos: "; while((i = r.by_set_pos[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { kdDebug() << "========= " << i << endl; out.append(QString::number(i) + " "); } kdDebug() << out << endl; } } icalcomponent *ICalFormatImpl::createScheduleComponent(Incidence *incidence, Scheduler::Method method) { icalcomponent *message = createCalendarComponent(); icalproperty_method icalmethod = ICAL_METHOD_NONE; switch (method) { case Scheduler::Publish: icalmethod = ICAL_METHOD_PUBLISH; break; case Scheduler::Request: icalmethod = ICAL_METHOD_REQUEST; break; case Scheduler::Refresh: icalmethod = ICAL_METHOD_REFRESH; break; case Scheduler::Cancel: icalmethod = ICAL_METHOD_CANCEL; break; case Scheduler::Add: icalmethod = ICAL_METHOD_ADD; break; case Scheduler::Reply: icalmethod = ICAL_METHOD_REPLY; break; case Scheduler::Counter: icalmethod = ICAL_METHOD_COUNTER; break; case Scheduler::Declinecounter: icalmethod = ICAL_METHOD_DECLINECOUNTER; break; default: kdDebug() << "ICalFormat::createScheduleMessage(): Unknow method" << endl; return message; } icalcomponent_add_property(message,icalproperty_new_method(icalmethod)); // TODO: check, if dynamic cast is required Todo *todo = dynamic_cast(incidence); if (todo) { icalcomponent_add_component(message,writeTodo(todo)); } Event *event = dynamic_cast(incidence); if (event) { icalcomponent_add_component(message,writeEvent(event)); } return message; } diff --git a/kcal/incidence.cpp b/kcal/incidence.cpp index 4e56335e5..aebfa8f11 100644 --- a/kcal/incidence.cpp +++ b/kcal/incidence.cpp @@ -1,442 +1,440 @@ /* This file is part of libkcal. Copyright (c) 2001 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // $Id$ #include #include #include #include "calformat.h" #include "incidence.h" #include "incidence.moc" using namespace KCal; Incidence::Incidence() : IncidenceBase(), mRelatedTo(0), mSecrecy(SecrecyPublic), mPriority(3), mPilotId(0), mSyncStatus(SYNCMOD) { mRecurrence = new Recurrence(this); recreate(); mAlarms.setAutoDelete(true); } Incidence::Incidence( const Incidence &i ) : IncidenceBase( i ) { // TODO: reenable attributes currently commented out. mRevision = i.mRevision; mLastModified = i.mLastModified; mCreated = i.mCreated; mDescription = i.mDescription; mSummary = i.mSummary; mCategories = i.mCategories; // Incidence *mRelatedTo; Incidence *mRelatedTo; mRelatedTo = 0; mRelatedToVUID = i.mRelatedToVUID; // QPtrList mRelations; QPtrList mRelations; mExDates = i.mExDates; mAttachments = i.mAttachments; mResources = i.mResources; mSecrecy = i.mSecrecy; mPriority = i.mPriority; mPilotId = i.mPilotId; mSyncStatus = i.mSyncStatus; // QPtrList mAlarms; QPtrList mAlarms; // Recurrence *mRecurrence; Recurrence *mRecurrence; mRecurrence = new Recurrence(this); } Incidence::~Incidence() { Incidence *ev; for (ev=mRelations.first();ev;ev=mRelations.next()) { if (ev->relatedTo() == this) ev->setRelatedTo(0); } if (relatedTo()) relatedTo()->removeRelation(this); delete mRecurrence; } void Incidence::recreate() { setCreated(QDateTime::currentDateTime()); setVUID(CalFormat::createUniqueId()); setRevision(0); setLastModified(QDateTime::currentDateTime()); } void Incidence::setReadOnly( bool readOnly ) { IncidenceBase::setReadOnly( readOnly ); recurrence()->setRecurReadOnly( readOnly); for (Alarm* alarm = mAlarms.first(); alarm; alarm = mAlarms.next()) alarm->setAlarmReadOnly( readOnly ); } void Incidence::setLastModified(const QDateTime &lm) { // DON'T! emit eventUpdated because we call this from // Calendar::updateEvent(). mLastModified = lm; } QDateTime Incidence::lastModified() const { return mLastModified; } void Incidence::setCreated(QDateTime created) { if (mReadOnly) return; mCreated = created; } QDateTime Incidence::created() const { return mCreated; } void Incidence::setRevision(int rev) { if (mReadOnly) return; mRevision = rev; emit eventUpdated(this); } int Incidence::revision() const { return mRevision; } - void Incidence::setDtStart(const QDateTime &dtStart) { recurrence()->setRecurStart( dtStart); IncidenceBase::setDtStart( dtStart ); } - void Incidence::setDescription(const QString &description) { if (mReadOnly) return; mDescription = description; emit eventUpdated(this); } QString Incidence::description() const { return mDescription; } void Incidence::setSummary(const QString &summary) { if (mReadOnly) return; mSummary = summary; emit eventUpdated(this); } QString Incidence::summary() const { return mSummary; } void Incidence::setCategories(const QStringList &categories) { if (mReadOnly) return; mCategories = categories; emit eventUpdated(this); } // TODO: remove setCategories(QString) function void Incidence::setCategories(const QString &catStr) { if (mReadOnly) return; if (catStr.isEmpty()) return; mCategories = QStringList::split(",",catStr); QStringList::Iterator it; for(it = mCategories.begin();it != mCategories.end(); ++it) { *it = (*it).stripWhiteSpace(); } emit eventUpdated(this); } QStringList Incidence::categories() const { return mCategories; } QString Incidence::categoriesStr() { return mCategories.join(","); } void Incidence::setRelatedToVUID(const QString &relatedToVUID) { if (mReadOnly) return; mRelatedToVUID = relatedToVUID; } QString Incidence::relatedToVUID() const { return mRelatedToVUID; } void Incidence::setRelatedTo(Incidence *relatedTo) { if (mReadOnly) return; Incidence *oldRelatedTo = mRelatedTo; if(oldRelatedTo) { oldRelatedTo->removeRelation(this); } mRelatedTo = relatedTo; if (mRelatedTo) mRelatedTo->addRelation(this); } Incidence *Incidence::relatedTo() const { return mRelatedTo; } QPtrList Incidence::relations() const { return mRelations; } void Incidence::addRelation(Incidence *event) { mRelations.append(event); emit eventUpdated(this); } void Incidence::removeRelation(Incidence *event) { mRelations.removeRef(event); // if (event->getRelatedTo() == this) event->setRelatedTo(0); } bool Incidence::recursOn(const QDate &qd) const { if (recurrence()->recursOnPure(qd) && !isException(qd)) return true; else return false; } void Incidence::setExDates(const DateList &exDates) { if (mReadOnly) return; mExDates = exDates; recurrence()->setRecurExDatesCount(mExDates.count()); emit eventUpdated(this); } void Incidence::addExDate(const QDate &date) { if (mReadOnly) return; mExDates.append(date); recurrence()->setRecurExDatesCount(mExDates.count()); emit eventUpdated(this); } DateList Incidence::exDates() const { return mExDates; } bool Incidence::isException(const QDate &date) const { DateList::ConstIterator it; for( it = mExDates.begin(); it != mExDates.end(); ++it ) { if ( (*it) == date ) { return true; } } return false; } void Incidence::setAttachments(const QStringList &attachments) { if (mReadOnly) return; mAttachments = attachments; emit eventUpdated(this); } QStringList Incidence::attachments() const { return mAttachments; } void Incidence::setResources(const QStringList &resources) { if (mReadOnly) return; mResources = resources; emit eventUpdated(this); } QStringList Incidence::resources() const { return mResources; } void Incidence::setPriority(int priority) { if (mReadOnly) return; mPriority = priority; emit eventUpdated(this); } int Incidence::priority() const { return mPriority; } void Incidence::setSecrecy(int sec) { if (mReadOnly) return; mSecrecy = sec; emit eventUpdated(this); } int Incidence::secrecy() const { return mSecrecy; } QString Incidence::secrecyStr() const { return secrecyName(mSecrecy); } QString Incidence::secrecyName(int secrecy) { switch (secrecy) { case SecrecyPublic: return i18n("Public"); break; case SecrecyPrivate: return i18n("Private"); break; case SecrecyConfidential: return i18n("Confidential"); break; default: return i18n("Undefined"); break; } } QStringList Incidence::secrecyList() { QStringList list; list << secrecyName(SecrecyPublic); list << secrecyName(SecrecyPrivate); list << secrecyName(SecrecyConfidential); return list; } void Incidence::setPilotId(int id) { if (mReadOnly) return; mPilotId = id; //emit eventUpdated(this); } int Incidence::pilotId() const { return mPilotId; } void Incidence::setSyncStatus(int stat) { if (mReadOnly) return; mSyncStatus = stat; // emit eventUpdated(this); } int Incidence::syncStatus() const { return mSyncStatus; } const QPtrList &Incidence::alarms() const { return mAlarms; } Alarm* Incidence::newAlarm() { Alarm* alarm = new Alarm(this); mAlarms.append(alarm); // emit eventUpdated(this); return alarm; } void Incidence::addAlarm(Alarm *alarm) { mAlarms.append(alarm); emit eventUpdated(this); } void Incidence::removeAlarm(Alarm *alarm) { mAlarms.removeRef(alarm); emit eventUpdated(this); } void Incidence::clearAlarms() { mAlarms.clear(); emit eventUpdated(this); } bool Incidence::isAlarmEnabled() const { Alarm* alarm; for (QPtrListIterator it(mAlarms); (alarm = it.current()) != 0; ++it) { if (alarm->enabled()) return true; } return false; } Recurrence *Incidence::recurrence() const { return mRecurrence; } diff --git a/kcal/vcalformat.cpp b/kcal/vcalformat.cpp index 79fd63a7e..f40be03ba 100644 --- a/kcal/vcalformat.cpp +++ b/kcal/vcalformat.cpp @@ -1,1878 +1,1871 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brwon Copyright (c) 2001 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // $Id$ #include #include #include #include #include #include #include #include #include #include #include #include #include "vcc.h" #include "vobject.h" #include "vcaldrag.h" #include "calendar.h" #include "vcalformat.h" using namespace KCal; VCalFormat::VCalFormat(Calendar *cal) : CalFormat(cal) { } VCalFormat::~VCalFormat() { } bool VCalFormat::load(const QString &fileName) { clearException(); kdDebug() << "VCalFormat::load() " << fileName << endl; VObject *vcal = 0L; // this is not necessarily only 1 vcal. Could be many vcals, or include // a vcard... vcal = Parse_MIME_FromFileName(const_cast(QFile::encodeName(fileName).data())); if (!vcal) { setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); return FALSE; } // any other top-level calendar stuff should be added/initialized here // put all vobjects into their proper places populate(vcal); // clean up from vcal API stuff cleanVObjects(vcal); cleanStrTbl(); return TRUE; } bool VCalFormat::save(const QString &fileName) { QString tmpStr; VObject *vcal, *vo; kdDebug() << "VCalFormat::save(): " << fileName << endl; vcal = newVObject(VCCalProp); // addPropValue(vcal,VCLocationProp, "0.0"); addPropValue(vcal,VCProdIdProp, productId()); tmpStr = mCalendar->getTimeZoneStr(); - addPropValue(vcal,VCTimeZoneProp, tmpStr.latin1()); + addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit()); addPropValue(vcal,VCVersionProp, _VCAL_VERSION); // TODO STUFF QPtrList todoList = mCalendar->getTodoList(); QPtrListIterator qlt(todoList); for (; qlt.current(); ++qlt) { vo = eventToVTodo(qlt.current()); addVObjectProp(vcal, vo); } // EVENT STUFF QPtrList events = mCalendar->getAllEvents(); Event *ev; for(ev=events.first();ev;ev=events.next()) { vo = eventToVEvent(ev); addVObjectProp(vcal, vo); } #if 0 QIntDictIterator > dictIt(*calDict); while (dictIt.current()) { QPtrListIterator listIt(*dictIt.current()); while (listIt.current()) { // if the event is multi-day, we only want to save the // first instance that is in the dictionary if (listIt.current()->isMultiDay()) { QPtrList *tmpList = calDict->find(makeKey(listIt.current()->dtStart().date())); if (dictIt.current() == tmpList) { vo = eventToVEvent(listIt.current()); addVObjectProp(vcal, vo); } } else { vo = eventToVEvent(listIt.current()); addVObjectProp(vcal, vo); } ++listIt; } ++dictIt; } // put in events that recurs QPtrListIterator qli(recursList); for (; qli.current(); ++qli) { vo = eventToVEvent(qli.current()); addVObjectProp(vcal, vo); } #endif - writeVObjectToFile(const_cast( - (const char *)QFile::encodeName(fileName) - ),vcal); + writeVObjectToFile(QFile::encodeName(fileName).data() ,vcal); cleanVObjects(vcal); cleanStrTbl(); if (QFile::exists(fileName)) { kdDebug() << "No error" << endl; return true; } else { kdDebug() << "Error" << endl; return false; // error } } VCalDrag *VCalFormat::createDrag(Event *selectedEv, QWidget *owner) { VObject *vcal, *vevent; QString tmpStr; vcal = newVObject(VCCalProp); addPropValue(vcal,VCProdIdProp, productId()); tmpStr = mCalendar->getTimeZoneStr(); - addPropValue(vcal,VCTimeZoneProp, tmpStr.latin1()); + addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit()); addPropValue(vcal,VCVersionProp, _VCAL_VERSION); vevent = eventToVEvent(selectedEv); addVObjectProp(vcal, vevent); VCalDrag *vcd = new VCalDrag(vcal, owner); // free memory associated with vCalendar stuff cleanVObject(vcal); vcd->setPixmap(BarIcon("appointment")); return vcd; } VCalDrag *VCalFormat::createDragTodo(Todo *selectedEv, QWidget *owner) { VObject *vcal, *vevent; QString tmpStr; vcal = newVObject(VCCalProp); addPropValue(vcal,VCProdIdProp, productId()); tmpStr = mCalendar->getTimeZoneStr(); - addPropValue(vcal,VCTimeZoneProp, tmpStr.latin1()); + addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit()); addPropValue(vcal,VCVersionProp, _VCAL_VERSION); vevent = eventToVTodo(selectedEv); addVObjectProp(vcal, vevent); VCalDrag *vcd = new VCalDrag(vcal, owner); // free memory associated with vCalendar stuff cleanVObject(vcal); vcd->setPixmap(BarIcon("todo")); return vcd; } Event *VCalFormat::createDrop(QDropEvent *de) { VObject *vcal; Event *event = 0; if (VCalDrag::decode(de, &vcal)) { de->accept(); VObjectIterator i; VObject *curvo; initPropIterator(&i, vcal); // we only take the first object. do { curvo = nextVObject(&i); } while (strcmp(vObjectName(curvo), VCEventProp) && strcmp(vObjectName(curvo), VCTodoProp)); if (strcmp(vObjectName(curvo), VCTodoProp) == 0) { kdDebug() << "VCalFormat::createDrop(): Got todo instead of event." << endl; } else if (strcmp(vObjectName(curvo), VCEventProp) == 0) { event = VEventToEvent(curvo); } else { kdDebug() << "VCalFormat::createDropTodo(): Unknown event type in drop." << endl; } // get rid of temporary VObject deleteVObject(vcal); } return event; } Todo *VCalFormat::createDropTodo(QDropEvent *de) { kdDebug() << "VCalFormat::createDropTodo()" << endl; VObject *vcal; Todo *event = 0; if (VCalDrag::decode(de, &vcal)) { de->accept(); VObjectIterator i; VObject *curvo; initPropIterator(&i, vcal); // we only take the first object. do { curvo = nextVObject(&i); } while (strcmp(vObjectName(curvo), VCEventProp) && strcmp(vObjectName(curvo), VCTodoProp)); if (strcmp(vObjectName(curvo), VCEventProp) == 0) { kdDebug() << "VCalFormat::createDropTodo(): Got event instead of todo." << endl; } else if (strcmp(vObjectName(curvo), VCTodoProp) == 0) { event = VTodoToEvent(curvo); } else { kdDebug() << "VCalFormat::createDropTodo(): Unknown event type in drop." << endl; } // get rid of temporary VObject deleteVObject(vcal); } return event; } bool VCalFormat::copyEvent(Event *selectedEv) { QClipboard *cb = QApplication::clipboard(); VObject *vcal, *vevent; QString tmpStr; vcal = newVObject(VCCalProp); // addPropValue(vcal,VCLocationProp, "0.0"); addPropValue(vcal,VCProdIdProp, productId()); tmpStr = mCalendar->getTimeZoneStr(); - addPropValue(vcal,VCTimeZoneProp, tmpStr.latin1()); + addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit()); addPropValue(vcal,VCVersionProp, _VCAL_VERSION); vevent = eventToVEvent(selectedEv); addVObjectProp(vcal, vevent); // paste to clipboard cb->setData(new VCalDrag(vcal)); // free memory associated with vCalendar stuff cleanVObject(vcal); return TRUE; } Event *VCalFormat::pasteEvent(const QDate &newDate, const QTime *newTime) { VObject *vcal, *curVO, *curVOProp; VObjectIterator i; int daysOffset; Event *anEvent = 0L; QClipboard *cb = QApplication::clipboard(); int bufsize; const char * buf; - buf = cb->text().latin1(); // vCalendar object is in latin1 + buf = cb->text().local8Bit(); // vCalendar object is in latin1 + //lukas: yeah, so why not screw it :( bufsize = strlen(buf); if (!VCalDrag::decode(cb->data(),&vcal)) { if (mEnableDialogs) { KMessageBox::sorry(mTopWidget, i18n("An error has occurred parsing the " "contents of the clipboard.\nYou can " "only paste a valid vCalendar into " "%1.\n").arg(application()), i18n("%1: Paste Calendar").arg(application())); return 0; } } initPropIterator(&i, vcal); // we only take the first object. do { curVO = nextVObject(&i); } while (strcmp(vObjectName(curVO), VCEventProp)); // now, check to see that the object is BOTH an event, and if so, // that it has a starting date if (strcmp(vObjectName(curVO), VCEventProp) == 0) { if ((curVOProp = isAPropertyOf(curVO, VCDTstartProp)) || (curVOProp = isAPropertyOf(curVO, VCDTendProp))) { // we found an event with a start time, put it in the dict anEvent = VEventToEvent(curVO); // if we pasted an event that was the result of a copy in our // own calendar, now we have duplicate UID strings. Need to generate // a new one for this new event. QString uidStr = createUniqueId(); if (mCalendar->getEvent(anEvent->VUID())) anEvent->setVUID(uidStr); daysOffset = anEvent->dtEnd().date().dayOfYear() - anEvent->dtStart().date().dayOfYear(); if (newTime) anEvent->setDtStart(QDateTime(newDate, *newTime)); else anEvent->setDtStart(QDateTime(newDate, anEvent->dtStart().time())); anEvent->setDtEnd(QDateTime(newDate.addDays(daysOffset), anEvent->dtEnd().time())); mCalendar->addEvent(anEvent); } else { kdDebug() << "found a VEvent with no DTSTART/DTEND! Skipping" << endl; } } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) { kdDebug() << "Trying to paste a Todo." << endl; // TODO: check, if todos can be pasted // Todo *aTodo = VTodoToEvent(curVO); // mCalendar->addTodo(aTodo); } else { kdDebug() << "unknown event type in paste!!!" << endl; } // get rid of temporary VObject deleteVObject(vcal); return anEvent; } VObject *VCalFormat::eventToVTodo(const Todo *anEvent) { VObject *vtodo; QString tmpStr; QStringList tmpStrList; vtodo = newVObject(VCTodoProp); // due date if (anEvent->hasDueDate()) { tmpStr = qDateTimeToISO(anEvent->dtDue(), !anEvent->doesFloat()); - addPropValue(vtodo, VCDueProp, tmpStr.latin1()); + addPropValue(vtodo, VCDueProp, tmpStr.local8Bit()); } // start date if (anEvent->hasStartDate()) { tmpStr = qDateTimeToISO(anEvent->dtStart(), !anEvent->doesFloat()); - addPropValue(vtodo, VCDTstartProp, tmpStr.latin1()); + addPropValue(vtodo, VCDTstartProp, tmpStr.local8Bit()); } // creation date tmpStr = qDateTimeToISO(anEvent->created()); - addPropValue(vtodo, VCDCreatedProp, tmpStr.latin1()); + addPropValue(vtodo, VCDCreatedProp, tmpStr.local8Bit()); // unique id addPropValue(vtodo, VCUniqueStringProp, - anEvent->VUID().latin1()); + anEvent->VUID().local8Bit()); // revision tmpStr.sprintf("%i", anEvent->revision()); - addPropValue(vtodo, VCSequenceProp, tmpStr.latin1()); + addPropValue(vtodo, VCSequenceProp, tmpStr.local8Bit()); // last modification date tmpStr = qDateTimeToISO(anEvent->lastModified()); - addPropValue(vtodo, VCLastModifiedProp, tmpStr.latin1()); + addPropValue(vtodo, VCLastModifiedProp, tmpStr.local8Bit()); // organizer stuff tmpStr = "MAILTO:" + anEvent->organizer(); - addPropValue(vtodo, ICOrganizerProp, - tmpStr.utf8()); + addPropValue(vtodo, ICOrganizerProp, tmpStr.local8Bit()); // attendees if (anEvent->attendeeCount() != 0) { QPtrList al = anEvent->attendees(); QPtrListIterator ai(al); Attendee *curAttendee; for (; ai.current(); ++ai) { curAttendee = ai.current(); if (!curAttendee->email().isEmpty() && !curAttendee->name().isEmpty()) tmpStr = "MAILTO:" + curAttendee->name() + " <" + curAttendee->email() + ">"; else if (curAttendee->name().isEmpty()) tmpStr = "MAILTO: " + curAttendee->email(); else if (curAttendee->email().isEmpty()) tmpStr = "MAILTO: " + curAttendee->name(); else if (curAttendee->name().isEmpty() && curAttendee->email().isEmpty()) kdDebug() << "warning! this Event has an attendee w/o name or email!" << endl; - VObject *aProp = addPropValue(vtodo, VCAttendeeProp, (const char *)tmpStr.utf8()); + VObject *aProp = addPropValue(vtodo, VCAttendeeProp, tmpStr.local8Bit()); addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE"); addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status())); } } // description BL: if (!anEvent->description().isEmpty()) { VObject *d = addPropValue(vtodo, VCDescriptionProp, - anEvent->description().utf8()); + anEvent->description().local8Bit()); if (anEvent->description().find('\n') != -1) addProp(d, VCQuotedPrintableProp); } // summary if (!anEvent->summary().isEmpty()) - addPropValue(vtodo, VCSummaryProp, anEvent->summary().utf8()); + addPropValue(vtodo, VCSummaryProp, anEvent->summary().local8Bit()); // completed // status // backward compatibility, KOrganizer used to interpret only these two values addPropValue(vtodo, VCStatusProp, anEvent->isCompleted() ? "COMPLETED" : "NEEDS_ACTION"); // completion date if (anEvent->hasCompletedDate()) { tmpStr = qDateTimeToISO(anEvent->completed()); - addPropValue(vtodo, VCCompletedProp, tmpStr.latin1()); + addPropValue(vtodo, VCCompletedProp, tmpStr.local8Bit()); } // priority tmpStr.sprintf("%i",anEvent->priority()); - addPropValue(vtodo, VCPriorityProp, tmpStr.latin1()); + addPropValue(vtodo, VCPriorityProp, tmpStr.local8Bit()); // related event if (anEvent->relatedTo()) { addPropValue(vtodo, VCRelatedToProp, - anEvent->relatedTo()->VUID().latin1()); + anEvent->relatedTo()->VUID().local8Bit()); } // categories tmpStrList = anEvent->categories(); tmpStr = ""; QString catStr; for ( QStringList::Iterator it = tmpStrList.begin(); it != tmpStrList.end(); ++it ) { catStr = *it; if (catStr[0] == ' ') tmpStr += catStr.mid(1); else tmpStr += catStr; // this must be a ';' character as the vCalendar specification requires! // vcc.y has been hacked to translate the ';' to a ',' when the vcal is // read in. tmpStr += ";"; } if (!tmpStr.isEmpty()) { tmpStr.truncate(tmpStr.length()-1); - addPropValue(vtodo, VCCategoriesProp, tmpStr.utf8()); + addPropValue(vtodo, VCCategoriesProp, tmpStr.local8Bit()); } // alarm stuff kdDebug() << "vcalformat::eventToVTodo was called" << endl; QPtrList alarms = anEvent->alarms(); Alarm* alarm; for (alarm = alarms.first(); alarm; alarm = alarms.next()) { if (alarm->enabled()) { VObject *a = addProp(vtodo, VCDAlarmProp); tmpStr = qDateTimeToISO(alarm->time()); - addPropValue(a, VCRunTimeProp, tmpStr.latin1()); + addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); addPropValue(a, VCDisplayStringProp, "beep!"); if (!alarm->audioFile().isEmpty()) { a = addProp(vtodo, VCAAlarmProp); - addPropValue(a, VCRunTimeProp, tmpStr.latin1()); + addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); - addPropValue(a, VCAudioContentProp, - (const char *)QFile::encodeName(alarm->audioFile())); + addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile())); } if (!alarm->programFile().isEmpty()) { a = addProp(vtodo, VCPAlarmProp); - addPropValue(a, VCRunTimeProp, tmpStr.latin1()); + addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); - addPropValue(a, VCProcedureNameProp, - (const char *)QFile::encodeName(alarm->programFile())); + addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile())); } } } // pilot sync stuff tmpStr.sprintf("%i",anEvent->pilotId()); - addPropValue(vtodo, KPilotIdProp, tmpStr.latin1()); + addPropValue(vtodo, KPilotIdProp, tmpStr.local8Bit()); tmpStr.sprintf("%i",anEvent->syncStatus()); - addPropValue(vtodo, KPilotStatusProp, tmpStr.latin1()); + addPropValue(vtodo, KPilotStatusProp, tmpStr.local8Bit()); return vtodo; } VObject* VCalFormat::eventToVEvent(const Event *anEvent) { VObject *vevent; QString tmpStr; QStringList tmpStrList; vevent = newVObject(VCEventProp); // start and end time tmpStr = qDateTimeToISO(anEvent->dtStart(), !anEvent->doesFloat()); - addPropValue(vevent, VCDTstartProp, tmpStr.latin1()); + addPropValue(vevent, VCDTstartProp, tmpStr.local8Bit()); // events that have time associated but take up no time should // not have both DTSTART and DTEND. if (anEvent->dtStart() != anEvent->dtEnd()) { tmpStr = qDateTimeToISO(anEvent->dtEnd(), !anEvent->doesFloat()); - addPropValue(vevent, VCDTendProp, tmpStr.latin1()); + addPropValue(vevent, VCDTendProp, tmpStr.local8Bit()); } // creation date tmpStr = qDateTimeToISO(anEvent->created()); - addPropValue(vevent, VCDCreatedProp, tmpStr.latin1()); + addPropValue(vevent, VCDCreatedProp, tmpStr.local8Bit()); // unique id addPropValue(vevent, VCUniqueStringProp, - anEvent->VUID().latin1()); + anEvent->VUID().local8Bit()); // revision tmpStr.sprintf("%i", anEvent->revision()); - addPropValue(vevent, VCSequenceProp, tmpStr.latin1()); + addPropValue(vevent, VCSequenceProp, tmpStr.local8Bit()); // last modification date tmpStr = qDateTimeToISO(anEvent->lastModified()); - addPropValue(vevent, VCLastModifiedProp, tmpStr.latin1()); + addPropValue(vevent, VCLastModifiedProp, tmpStr.local8Bit()); // attendee and organizer stuff tmpStr = "MAILTO:" + anEvent->organizer(); - addPropValue(vevent, ICOrganizerProp, - tmpStr.utf8()); + addPropValue(vevent, ICOrganizerProp, tmpStr.local8Bit()); if (anEvent->attendeeCount() != 0) { QPtrList al = anEvent->attendees(); QPtrListIterator ai(al); Attendee *curAttendee; // TODO: Put this functionality into Attendee class for (; ai.current(); ++ai) { curAttendee = ai.current(); if (!curAttendee->email().isEmpty() && !curAttendee->name().isEmpty()) tmpStr = "MAILTO:" + curAttendee->name() + " <" + curAttendee->email() + ">"; else if (curAttendee->name().isEmpty()) tmpStr = "MAILTO: " + curAttendee->email(); else if (curAttendee->email().isEmpty()) tmpStr = "MAILTO: " + curAttendee->name(); else if (curAttendee->name().isEmpty() && curAttendee->email().isEmpty()) kdDebug() << "warning! this Event has an attendee w/o name or email!" << endl; - VObject *aProp = addPropValue(vevent, VCAttendeeProp, (const char *)tmpStr.utf8()); + VObject *aProp = addPropValue(vevent, VCAttendeeProp, tmpStr.local8Bit()); addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE");; addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status())); } } // recurrence rule stuff if (anEvent->recurrence()->doesRecur()) { // some more variables QPtrList tmpPositions; QPtrList tmpDays; int *tmpDay; Recurrence::rMonthPos *tmpPos; QString tmpStr2; int i; switch(anEvent->recurrence()->doesRecur()) { case Recurrence::rDaily: tmpStr.sprintf("D%i ",anEvent->recurrence()->frequency()); // if (anEvent->rDuration > 0) // tmpStr += "#"; break; case Recurrence::rWeekly: tmpStr.sprintf("W%i ",anEvent->recurrence()->frequency()); for (i = 0; i < 7; i++) { if (anEvent->recurrence()->days().testBit(i)) tmpStr += dayFromNum(i); } break; case Recurrence::rMonthlyPos: tmpStr.sprintf("MP%i ", anEvent->recurrence()->frequency()); // write out all rMonthPos's tmpPositions = anEvent->recurrence()->monthPositions(); for (tmpPos = tmpPositions.first(); tmpPos; tmpPos = tmpPositions.next()) { tmpStr2.sprintf("%i", tmpPos->rPos); if (tmpPos->negative) tmpStr2 += "- "; else tmpStr2 += "+ "; tmpStr += tmpStr2; for (i = 0; i < 7; i++) { if (tmpPos->rDays.testBit(i)) tmpStr += dayFromNum(i); } } // loop for all rMonthPos's break; case Recurrence::rMonthlyDay: tmpStr.sprintf("MD%i ", anEvent->recurrence()->frequency()); // write out all rMonthDays; tmpDays = anEvent->recurrence()->monthDays(); for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { tmpStr2.sprintf("%i ", *tmpDay); tmpStr += tmpStr2; } break; case Recurrence::rYearlyMonth: tmpStr.sprintf("YM%i ", anEvent->recurrence()->frequency()); // write out all the rYearNums; tmpDays = anEvent->recurrence()->yearNums(); for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { tmpStr2.sprintf("%i ", *tmpDay); tmpStr += tmpStr2; } break; case Recurrence::rYearlyDay: tmpStr.sprintf("YD%i ", anEvent->recurrence()->frequency()); // write out all the rYearNums; tmpDays = anEvent->recurrence()->yearNums(); for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { tmpStr2.sprintf("%i ", *tmpDay); tmpStr += tmpStr2; } break; default: kdDebug() << "ERROR, it should never get here in eventToVEvent!" << endl; break; } // switch if (anEvent->recurrence()->duration() > 0) { tmpStr2.sprintf("#%i",anEvent->recurrence()->duration()); tmpStr += tmpStr2; } else if (anEvent->recurrence()->duration() == -1) { tmpStr += "#0"; // defined as repeat forever } else { tmpStr += qDateTimeToISO(anEvent->recurrence()->endDate(), FALSE); } - addPropValue(vevent,VCRRuleProp, tmpStr.latin1()); + addPropValue(vevent,VCRRuleProp, tmpStr.local8Bit()); } // event repeats // exceptions to recurrence DateList dateList = anEvent->exDates(); DateList::ConstIterator it; QString tmpStr2; for (it = dateList.begin(); it != dateList.end(); ++it) { tmpStr = qDateToISO(*it) + ";"; tmpStr2 += tmpStr; } if (!tmpStr2.isEmpty()) { tmpStr2.truncate(tmpStr2.length()-1); - addPropValue(vevent, VCExDateProp, tmpStr2.latin1()); + addPropValue(vevent, VCExDateProp, tmpStr2.local8Bit()); } // description if (!anEvent->description().isEmpty()) { VObject *d = addPropValue(vevent, VCDescriptionProp, - anEvent->description().utf8()); + anEvent->description().local8Bit()); if (anEvent->description().find('\n') != -1) addProp(d, VCQuotedPrintableProp); } // summary if (!anEvent->summary().isEmpty()) - addPropValue(vevent, VCSummaryProp, anEvent->summary().utf8()); + addPropValue(vevent, VCSummaryProp, anEvent->summary().local8Bit()); // status // TODO: define Event status -// addPropValue(vevent, VCStatusProp, anEvent->statusStr().latin1()); +// addPropValue(vevent, VCStatusProp, anEvent->statusStr().local8Bit()); // secrecy const char *text = 0; switch (anEvent->secrecy()) { case Incidence::SecrecyPublic: text = "PUBLIC"; break; case Incidence::SecrecyPrivate: text = "PRIVATE"; break; case Incidence::SecrecyConfidential: text = "CONFIDENTIAL"; break; } if (text) { addPropValue(vevent, VCClassProp, text); } // categories tmpStrList = anEvent->categories(); tmpStr = ""; QString catStr; for ( QStringList::Iterator it = tmpStrList.begin(); it != tmpStrList.end(); ++it ) { catStr = *it; if (catStr[0] == ' ') tmpStr += catStr.mid(1); else tmpStr += catStr; // this must be a ';' character as the vCalendar specification requires! // vcc.y has been hacked to translate the ';' to a ',' when the vcal is // read in. tmpStr += ";"; } if (!tmpStr.isEmpty()) { tmpStr.truncate(tmpStr.length()-1); - addPropValue(vevent, VCCategoriesProp, tmpStr.utf8()); + addPropValue(vevent, VCCategoriesProp, tmpStr.local8Bit()); } // attachments tmpStrList = anEvent->attachments(); for ( QStringList::Iterator it = tmpStrList.begin(); it != tmpStrList.end(); ++it ) - addPropValue(vevent, VCAttachProp, (*it).latin1()); + addPropValue(vevent, VCAttachProp, (*it).local8Bit()); // resources tmpStrList = anEvent->resources(); tmpStr = tmpStrList.join(";"); if (!tmpStr.isEmpty()) - addPropValue(vevent, VCResourcesProp, tmpStr.latin1()); + addPropValue(vevent, VCResourcesProp, tmpStr.local8Bit()); // alarm stuff QPtrList alarms = anEvent->alarms(); Alarm* alarm; for (alarm = alarms.first(); alarm; alarm = alarms.next()) { if (alarm->enabled()) { VObject *a = addProp(vevent, VCDAlarmProp); tmpStr = qDateTimeToISO(alarm->time()); - addPropValue(a, VCRunTimeProp, tmpStr.latin1()); + addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); addPropValue(a, VCDisplayStringProp, "beep!"); if (!alarm->audioFile().isEmpty()) { a = addProp(vevent, VCAAlarmProp); - addPropValue(a, VCRunTimeProp, tmpStr.latin1()); + addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); - addPropValue(a, VCAudioContentProp, - (const char *)QFile::encodeName(alarm->audioFile())); + addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile())); } if (!alarm->programFile().isEmpty()) { a = addProp(vevent, VCPAlarmProp); - addPropValue(a, VCRunTimeProp, tmpStr.latin1()); + addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); - addPropValue(a, VCProcedureNameProp, - (const char *)QFile::encodeName(alarm->programFile())); + addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile())); } } } // priority tmpStr.sprintf("%i",anEvent->priority()); - addPropValue(vevent, VCPriorityProp, tmpStr.latin1()); + addPropValue(vevent, VCPriorityProp, tmpStr.local8Bit()); // transparency tmpStr.sprintf("%i",anEvent->transparency()); - addPropValue(vevent, VCTranspProp, tmpStr.latin1()); + addPropValue(vevent, VCTranspProp, tmpStr.local8Bit()); // related event if (anEvent->relatedTo()) { addPropValue(vevent, VCRelatedToProp, - anEvent->relatedTo()->VUID().latin1()); + anEvent->relatedTo()->VUID().local8Bit()); } // pilot sync stuff tmpStr.sprintf("%i",anEvent->pilotId()); - addPropValue(vevent, KPilotIdProp, tmpStr.latin1()); + addPropValue(vevent, KPilotIdProp, tmpStr.local8Bit()); tmpStr.sprintf("%i",anEvent->syncStatus()); - addPropValue(vevent, KPilotStatusProp, tmpStr.latin1()); + addPropValue(vevent, KPilotStatusProp, tmpStr.local8Bit()); return vevent; } Todo *VCalFormat::VTodoToEvent(VObject *vtodo) { VObject *vo; VObjectIterator voi; char *s; Todo *anEvent = new Todo; // creation date if ((vo = isAPropertyOf(vtodo, VCDCreatedProp)) != 0) { anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } // unique id vo = isAPropertyOf(vtodo, VCUniqueStringProp); // while the UID property is preferred, it is not required. We'll use the // default Event UID if none is given. if (vo) { anEvent->setVUID(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } // last modification date if ((vo = isAPropertyOf(vtodo, VCLastModifiedProp)) != 0) { anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setLastModified(QDateTime(QDate::currentDate(), QTime::currentTime())); // organizer // if our extension property for the event's ORGANIZER exists, add it. if ((vo = isAPropertyOf(vtodo, ICOrganizerProp)) != 0) { anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } else { anEvent->setOrganizer(mCalendar->getEmail()); } // attendees. initPropIterator(&voi, vtodo); while (moreIteration(&voi)) { vo = nextVObject(&voi); if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) { Attendee *a; VObject *vp; s = fakeCString(vObjectUStringZValue(vo)); - QString tmpStr = QString::fromUtf8(s); + QString tmpStr = QString::fromLocal8Bit(s); deleteStr(s); tmpStr = tmpStr.simplifyWhiteSpace(); int emailPos1, emailPos2; if ((emailPos1 = tmpStr.find('<')) > 0) { // both email address and name emailPos2 = tmpStr.findRev('>'); a = new Attendee(tmpStr.left(emailPos1 - 1), tmpStr.mid(emailPos1 + 1, emailPos2 - (emailPos1 + 1))); } else if (tmpStr.find('@') > 0) { // just an email address a = new Attendee(0, tmpStr); } else { // just a name QString email = tmpStr.replace( QRegExp(" "), "." ); a = new Attendee(tmpStr,email); } // is there an RSVP property? if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0) a->setRSVP(vObjectStringZValue(vp)); // is there a status property? if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0) a->setStatus(readStatus(vObjectStringZValue(vp))); // add the attendee anEvent->addAttendee(a); } } // description for todo if ((vo = isAPropertyOf(vtodo, VCDescriptionProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); - anEvent->setDescription(QString::fromUtf8(s)); + anEvent->setDescription(QString::fromLocal8Bit(s)); deleteStr(s); } // summary if ((vo = isAPropertyOf(vtodo, VCSummaryProp))) { s = fakeCString(vObjectUStringZValue(vo)); - anEvent->setSummary(QString::fromUtf8(s)); + anEvent->setSummary(QString::fromLocal8Bit(s)); deleteStr(s); } // completed // was: status if ((vo = isAPropertyOf(vtodo, VCStatusProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); if (strcmp(s,"COMPLETED") == 0) { anEvent->setCompleted(true); } else { anEvent->setCompleted(false); } deleteStr(s); } else anEvent->setCompleted(false); // completion date if ((vo = isAPropertyOf(vtodo, VCCompletedProp)) != 0) { anEvent->setCompleted(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } // priority if ((vo = isAPropertyOf(vtodo, VCPriorityProp))) { anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } // due date if ((vo = isAPropertyOf(vtodo, VCDueProp)) != 0) { anEvent->setDtDue(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); anEvent->setHasDueDate(true); } else { anEvent->setHasDueDate(false); } // start time if ((vo = isAPropertyOf(vtodo, VCDTstartProp)) != 0) { anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); // kdDebug() << "s is " << // s << ", ISO is " << ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))).toString() << endl; deleteStr(s); anEvent->setHasStartDate(true); } else { anEvent->setHasStartDate(false); } /* alarm stuff */ //kdDebug() << "vcalformat::VTodoToEvent called" << endl; if ((vo = isAPropertyOf(vtodo, VCDAlarmProp))) { Alarm* alarm = anEvent->newAlarm(); VObject *a; if ((a = isAPropertyOf(vo, VCRunTimeProp))) { alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a)))); deleteStr(s); } alarm->setEnabled(true); if ((vo = isAPropertyOf(vtodo, VCPAlarmProp))) { if ((a = isAPropertyOf(vo, VCProcedureNameProp))) { s = fakeCString(vObjectUStringZValue(a)); alarm->setProgramFile(QFile::decodeName(s)); deleteStr(s); } } if ((vo = isAPropertyOf(vtodo, VCAAlarmProp))) { if ((a = isAPropertyOf(vo, VCAudioContentProp))) { s = fakeCString(vObjectUStringZValue(a)); alarm->setAudioFile(QFile::decodeName(s)); deleteStr(s); } } } // related todo if ((vo = isAPropertyOf(vtodo, VCRelatedToProp)) != 0) { anEvent->setRelatedToVUID(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); mTodosRelate.append(anEvent); } // categories QStringList tmpStrList; int index1 = 0; int index2 = 0; if ((vo = isAPropertyOf(vtodo, VCCategoriesProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); - QString categories = QString::fromUtf8(s); + QString categories = QString::fromLocal8Bit(s); deleteStr(s); //const char* category; QString category; while ((index2 = categories.find(',', index1)) != -1) { //category = (const char *) categories.mid(index1, (index2 - index1)); category = categories.mid(index1, (index2 - index1)); tmpStrList.append(category); index1 = index2+1; } // get last category category = categories.mid(index1, (categories.length()-index1)); tmpStrList.append(category); anEvent->setCategories(tmpStrList); } /* PILOT SYNC STUFF */ if ((vo = isAPropertyOf(vtodo, KPilotIdProp))) { anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setPilotId(0); if ((vo = isAPropertyOf(vtodo, KPilotStatusProp))) { anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setSyncStatus(Event::SYNCMOD); return anEvent; } Event* VCalFormat::VEventToEvent(VObject *vevent) { VObject *vo; VObjectIterator voi; char *s; Event *anEvent = new Event; // creation date if ((vo = isAPropertyOf(vevent, VCDCreatedProp)) != 0) { anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } // unique id vo = isAPropertyOf(vevent, VCUniqueStringProp); // while the UID property is preferred, it is not required. We'll use the // default Event UID if none is given. if (vo) { anEvent->setVUID(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } // revision // again NSCAL doesn't give us much to work with, so we improvise... if ((vo = isAPropertyOf(vevent, VCSequenceProp)) != 0) { anEvent->setRevision(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setRevision(0); // last modification date if ((vo = isAPropertyOf(vevent, VCLastModifiedProp)) != 0) { anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setLastModified(QDateTime(QDate::currentDate(), QTime::currentTime())); // organizer // if our extension property for the event's ORGANIZER exists, add it. if ((vo = isAPropertyOf(vevent, ICOrganizerProp)) != 0) { anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } else { anEvent->setOrganizer(mCalendar->getEmail()); } // deal with attendees. initPropIterator(&voi, vevent); while (moreIteration(&voi)) { vo = nextVObject(&voi); if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) { Attendee *a; VObject *vp; s = fakeCString(vObjectUStringZValue(vo)); - QString tmpStr = QString::fromUtf8(s); + QString tmpStr = QString::fromLocal8Bit(s); deleteStr(s); tmpStr = tmpStr.simplifyWhiteSpace(); int emailPos1, emailPos2; if ((emailPos1 = tmpStr.find('<')) > 0) { // both email address and name emailPos2 = tmpStr.findRev('>'); a = new Attendee(tmpStr.left(emailPos1 - 1), tmpStr.mid(emailPos1 + 1, emailPos2 - (emailPos1 + 1))); } else if (tmpStr.find('@') > 0) { // just an email address a = new Attendee(0, tmpStr); } else { // just a name QString email = tmpStr.replace( QRegExp(" "), "." ); a = new Attendee(tmpStr,email); } // is there an RSVP property? if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0) a->setRSVP(vObjectStringZValue(vp)); // is there a status property? if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0) a->setStatus(readStatus(vObjectStringZValue(vp))); // add the attendee anEvent->addAttendee(a); } } // This isn't strictly true. An event that doesn't have a start time // or an end time doesn't "float", it has an anchor in time but it doesn't // "take up" any time. /*if ((isAPropertyOf(vevent, VCDTstartProp) == 0) || (isAPropertyOf(vevent, VCDTendProp) == 0)) { anEvent->setFloats(TRUE); } else { }*/ anEvent->setFloats(FALSE); // start time if ((vo = isAPropertyOf(vevent, VCDTstartProp)) != 0) { anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); // kdDebug() << "s is " << // s << ", ISO is " << ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))).toString() << endl; deleteStr(s); if (anEvent->dtStart().time().isNull()) anEvent->setFloats(TRUE); } // stop time if ((vo = isAPropertyOf(vevent, VCDTendProp)) != 0) { anEvent->setDtEnd(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); if (anEvent->dtEnd().time().isNull()) anEvent->setFloats(TRUE); } // at this point, there should be at least a start or end time. // fix up for events that take up no time but have a time associated if (!(vo = isAPropertyOf(vevent, VCDTstartProp))) anEvent->setDtStart(anEvent->dtEnd()); if (!(vo = isAPropertyOf(vevent, VCDTendProp))) anEvent->setDtEnd(anEvent->dtStart()); /////////////////////////////////////////////////////////////////////////// // repeat stuff if ((vo = isAPropertyOf(vevent, VCRRuleProp)) != 0) { QString tmpStr = (s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); tmpStr.simplifyWhiteSpace(); tmpStr = tmpStr.upper(); /********************************* DAILY ******************************/ if (tmpStr.left(1) == "D") { int index = tmpStr.find(' '); int rFreq = tmpStr.mid(1, (index-1)).toInt(); index = tmpStr.findRev(' ') + 1; // advance to last field if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->recurrence()->setDaily(rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) // VEvents set this to 0 forever, we use -1 anEvent->recurrence()->setDaily(rFreq, -1); else anEvent->recurrence()->setDaily(rFreq, rDuration); } } /********************************* WEEKLY ******************************/ else if (tmpStr.left(1) == "W") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(1, (index-1)).toInt(); index += 1; // advance to beginning of stuff after freq QBitArray qba(7); QString dayStr; if( index == last ) { // e.g. W1 #0 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1); } else { // e.g. W1 SU #0 while (index < last) { dayStr = tmpStr.mid(index, 3); int dayNum = numFromDay(dayStr); qba.setBit(dayNum); index += 3; // advance to next day, or possibly "#" } } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->recurrence()->setWeekly(rFreq, qba, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->recurrence()->setWeekly(rFreq, qba, -1); else anEvent->recurrence()->setWeekly(rFreq, qba, rDuration); } } /**************************** MONTHLY-BY-POS ***************************/ else if (tmpStr.left(2) == "MP") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(2, (index-1)).toInt(); index += 1; // advance to beginning of stuff after freq QBitArray qba(7); short tmpPos; if( index == last ) { // e.g. MP1 #0 tmpPos = anEvent->dtStart().date().day()/7 + 1; if( tmpPos == 5 ) tmpPos = -1; qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1); anEvent->recurrence()->addMonthlyPos(tmpPos, qba); } else { // e.g. MP1 1+ SU #0 while (index < last) { tmpPos = tmpStr.mid(index,1).toShort(); index += 1; if (tmpStr.mid(index,1) == "-") // convert tmpPos to negative tmpPos = 0 - tmpPos; index += 2; // advance to day(s) while (numFromDay(tmpStr.mid(index,3)) >= 0) { int dayNum = numFromDay(tmpStr.mid(index,3)); qba.setBit(dayNum); index += 3; // advance to next day, or possibly pos or "#" } anEvent->recurrence()->addMonthlyPos(tmpPos, qba); qba.detach(); qba.fill(FALSE); // clear out } // while != "#" } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length() - index))).date(); anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, -1); else anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rDuration); } } /**************************** MONTHLY-BY-DAY ***************************/ else if (tmpStr.left(2) == "MD") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(2, (index-1)).toInt(); index += 1; short tmpDay; if( index == last ) { // e.g. MD1 #0 tmpDay = anEvent->dtStart().date().day(); anEvent->recurrence()->addMonthlyDay(tmpDay); } else { // e.g. MD1 3 #0 while (index < last) { int index2 = tmpStr.find(' ', index); tmpDay = tmpStr.mid(index, (index2-index)).toShort(); index = index2-1; if (tmpStr.mid(index, 1) == "-") tmpDay = 0 - tmpDay; index += 2; // advance the index; anEvent->recurrence()->addMonthlyDay(tmpDay); } // while != # } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, -1); else anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rDuration); } } /*********************** YEARLY-BY-MONTH *******************************/ else if (tmpStr.left(2) == "YM") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(2, (index-1)).toInt(); index += 1; short tmpMonth; if( index == last ) { // e.g. YM1 #0 tmpMonth = anEvent->dtStart().date().month(); anEvent->recurrence()->addYearlyNum(tmpMonth); } else { // e.g. YM1 3 #0 while (index < last) { int index2 = tmpStr.find(' ', index); tmpMonth = tmpStr.mid(index, (index2-index)).toShort(); index = index2+1; anEvent->recurrence()->addYearlyNum(tmpMonth); } // while != # } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, -1); else anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rDuration); } } /*********************** YEARLY-BY-DAY *********************************/ else if (tmpStr.left(2) == "YD") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(2, (index-1)).toInt(); index += 1; short tmpDay; if( index == last ) { // e.g. YD1 #0 tmpDay = anEvent->dtStart().date().dayOfYear(); anEvent->recurrence()->addYearlyNum(tmpDay); } else { // e.g. YD1 123 #0 while (index < last) { int index2 = tmpStr.find(' ', index); tmpDay = tmpStr.mid(index, (index2-index)).toShort(); index = index2+1; anEvent->recurrence()->addYearlyNum(tmpDay); } // while != # } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, -1); else anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rDuration); } } else { kdDebug() << "we don't understand this type of recurrence!" << endl; } // if } // repeats // recurrence exceptions if ((vo = isAPropertyOf(vevent, VCExDateProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); QStringList exDates = QStringList::split(",",s); QStringList::ConstIterator it; for(it = exDates.begin(); it != exDates.end(); ++it ) { anEvent->addExDate(ISOToQDate(*it)); } deleteStr(s); } // summary if ((vo = isAPropertyOf(vevent, VCSummaryProp))) { s = fakeCString(vObjectUStringZValue(vo)); - anEvent->setSummary(QString::fromUtf8(s)); + anEvent->setSummary(QString::fromLocal8Bit(s)); deleteStr(s); } // description if ((vo = isAPropertyOf(vevent, VCDescriptionProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); if (!anEvent->description().isEmpty()) { anEvent->setDescription(anEvent->description() + "\n" + - QString::fromUtf8(s)); + QString::fromLocal8Bit(s)); } else { - anEvent->setDescription(QString::fromUtf8(s)); + anEvent->setDescription(QString::fromLocal8Bit(s)); } deleteStr(s); } // some stupid vCal exporters ignore the standard and use Description // instead of Summary for the default field. Correct for this. if (anEvent->summary().isEmpty() && !(anEvent->description().isEmpty())) { QString tmpStr = anEvent->description().simplifyWhiteSpace(); anEvent->setDescription(""); anEvent->setSummary(tmpStr); } #if 0 // status if ((vo = isAPropertyOf(vevent, VCStatusProp)) != 0) { QString tmpStr(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); // TODO: Define Event status // anEvent->setStatus(tmpStr); } else // anEvent->setStatus("NEEDS ACTION"); #endif // secrecy int secrecy = Incidence::SecrecyPublic; if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); if (strcmp(s,"PRIVATE") == 0) { secrecy = Incidence::SecrecyPrivate; } else if (strcmp(s,"CONFIDENTIAL") == 0) { secrecy = Incidence::SecrecyConfidential; } deleteStr(s); } anEvent->setSecrecy(secrecy); // categories QStringList tmpStrList; int index1 = 0; int index2 = 0; if ((vo = isAPropertyOf(vevent, VCCategoriesProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); - QString categories = QString::fromUtf8(s); + QString categories = QString::fromLocal8Bit(s); deleteStr(s); //const char* category; QString category; while ((index2 = categories.find(',', index1)) != -1) { //category = (const char *) categories.mid(index1, (index2 - index1)); category = categories.mid(index1, (index2 - index1)); tmpStrList.append(category); index1 = index2+1; } // get last category category = categories.mid(index1, (categories.length()-index1)); tmpStrList.append(category); anEvent->setCategories(tmpStrList); } // attachments tmpStrList.clear(); initPropIterator(&voi, vevent); while (moreIteration(&voi)) { vo = nextVObject(&voi); if (strcmp(vObjectName(vo), VCAttachProp) == 0) { tmpStrList.append(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } } anEvent->setAttachments(tmpStrList); // resources if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) { QString resources = (s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); tmpStrList.clear(); index1 = 0; index2 = 0; QString resource; while ((index2 = resources.find(';', index1)) != -1) { resource = resources.mid(index1, (index2 - index1)); tmpStrList.append(resource); index1 = index2; } anEvent->setResources(tmpStrList); } /* alarm stuff */ if ((vo = isAPropertyOf(vevent, VCDAlarmProp))) { Alarm* alarm = anEvent->newAlarm(); VObject *a; if ((a = isAPropertyOf(vo, VCRunTimeProp))) { alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a)))); deleteStr(s); } alarm->setEnabled(true); if ((vo = isAPropertyOf(vevent, VCPAlarmProp))) { if ((a = isAPropertyOf(vo, VCProcedureNameProp))) { s = fakeCString(vObjectUStringZValue(a)); alarm->setProgramFile(QFile::decodeName(s)); deleteStr(s); } } if ((vo = isAPropertyOf(vevent, VCAAlarmProp))) { if ((a = isAPropertyOf(vo, VCAudioContentProp))) { s = fakeCString(vObjectUStringZValue(a)); alarm->setAudioFile(QFile::decodeName(s)); deleteStr(s); } } } // priority if ((vo = isAPropertyOf(vevent, VCPriorityProp))) { anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } // transparency if ((vo = isAPropertyOf(vevent, VCTranspProp)) != 0) { anEvent->setTransparency(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } // related event if ((vo = isAPropertyOf(vevent, VCRelatedToProp)) != 0) { anEvent->setRelatedToVUID(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); mEventsRelate.append(anEvent); } /* PILOT SYNC STUFF */ if ((vo = isAPropertyOf(vevent, KPilotIdProp))) { anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setPilotId(0); if ((vo = isAPropertyOf(vevent, KPilotStatusProp))) { anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setSyncStatus(Event::SYNCMOD); return anEvent; } QString VCalFormat::qDateToISO(const QDate &qd) { QString tmpStr; ASSERT(qd.isValid()); tmpStr.sprintf("%.2d%.2d%.2d", qd.year(), qd.month(), qd.day()); return tmpStr; } QString VCalFormat::qDateTimeToISO(const QDateTime &qdt, bool zulu) { QString tmpStr; ASSERT(qdt.date().isValid()); ASSERT(qdt.time().isValid()); if (zulu) { QDateTime tmpDT(qdt); tmpDT = tmpDT.addSecs(60*(-mCalendar->getTimeZone())); // correct to GMT. tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2dZ", tmpDT.date().year(), tmpDT.date().month(), tmpDT.date().day(), tmpDT.time().hour(), tmpDT.time().minute(), tmpDT.time().second()); } else { tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2d", qdt.date().year(), qdt.date().month(), qdt.date().day(), qdt.time().hour(), qdt.time().minute(), qdt.time().second()); } return tmpStr; } QDateTime VCalFormat::ISOToQDateTime(const QString & dtStr) { QDate tmpDate; QTime tmpTime; QString tmpStr; int year, month, day, hour, minute, second; tmpStr = dtStr; year = tmpStr.left(4).toInt(); month = tmpStr.mid(4,2).toInt(); day = tmpStr.mid(6,2).toInt(); hour = tmpStr.mid(9,2).toInt(); minute = tmpStr.mid(11,2).toInt(); second = tmpStr.mid(13,2).toInt(); tmpDate.setYMD(year, month, day); tmpTime.setHMS(hour, minute, second); ASSERT(tmpDate.isValid()); ASSERT(tmpTime.isValid()); QDateTime tmpDT(tmpDate, tmpTime); // correct for GMT if string is in Zulu format if (dtStr.at(dtStr.length()-1) == 'Z') tmpDT = tmpDT.addSecs(60*mCalendar->getTimeZone()); return tmpDT; } QDate VCalFormat::ISOToQDate(const QString &dateStr) { int year, month, day; year = dateStr.left(4).toInt(); month = dateStr.mid(4,2).toInt(); day = dateStr.mid(6,2).toInt(); return(QDate(year, month, day)); } // take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc. // and break it down from it's tree-like format into the dictionary format // that is used internally in the VCalFormat. void VCalFormat::populate(VObject *vcal) { // this function will populate the caldict dictionary and other event // lists. It turns vevents into Events and then inserts them. VObjectIterator i; VObject *curVO, *curVOProp; Event *anEvent; if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) { char *methodType = 0; methodType = fakeCString(vObjectUStringZValue(curVO)); if (mEnableDialogs) KMessageBox::information(mTopWidget, i18n("This calendar is an iTIP transaction of type \"%1\".") .arg(methodType), i18n("%1: iTIP Transaction").arg(application())); delete methodType; } // warn the user that we might have trouble reading non-known calendar. if ((curVO = isAPropertyOf(vcal, VCProdIdProp)) != 0) { char *s = fakeCString(vObjectUStringZValue(curVO)); - if (strcmp(productId().latin1(), s) != 0) + if (strcmp(productId().local8Bit(), s) != 0) if (mEnableDialogs) KMessageBox::information(mTopWidget, i18n("This vCalendar file was not created by KOrganizer\n" "or any other product we support. Loading anyway..."), i18n("%1: Unknown vCalendar Vendor").arg(application())); deleteStr(s); } // warn the user we might have trouble reading this unknown version. if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) { char *s = fakeCString(vObjectUStringZValue(curVO)); if (strcmp(_VCAL_VERSION, s) != 0) if (mEnableDialogs) KMessageBox::sorry(mTopWidget, i18n("This vCalendar file has version %1.\n" "We only support %2.") .arg(s).arg(_VCAL_VERSION), i18n("%1: Unknown vCalendar Version").arg(application())); deleteStr(s); } // set the time zone if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) { char *s = fakeCString(vObjectUStringZValue(curVO)); mCalendar->setTimeZone(s); deleteStr(s); } // Store all events with a relatedTo property in a list for post-processing mEventsRelate.clear(); mTodosRelate.clear(); initPropIterator(&i, vcal); // go through all the vobjects in the vcal while (moreIteration(&i)) { curVO = nextVObject(&i); /************************************************************************/ // now, check to see that the object is an event or todo. if (strcmp(vObjectName(curVO), VCEventProp) == 0) { if ((curVOProp = isAPropertyOf(curVO, KPilotStatusProp)) != 0) { char *s; s = fakeCString(vObjectUStringZValue(curVOProp)); // check to see if event was deleted by the kpilot conduit if (atoi(s) == Event::SYNCDEL) { deleteStr(s); kdDebug() << "skipping pilot-deleted event" << endl; goto SKIP; } deleteStr(s); } // this code checks to see if we are trying to read in an event // that we already find to be in the calendar. If we find this // to be the case, we skip the event. if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) { char *s = fakeCString(vObjectUStringZValue(curVOProp)); QString tmpStr(s); deleteStr(s); if (mCalendar->getEvent(tmpStr)) { // Disable message boxes, because it hinders merging of calendars and does not // give a sensible advice anyway. #if 0 if (mEnableDialogs) KMessageBox::error(mTopWidget, i18n("Aborting merge of an event already in " "calendar.\n" "UID is %1\n" "Please check your vCalendar file for " "duplicate UIDs\n" "and change them MANUALLY to be unique " "if you find any.\n").arg(tmpStr), i18n("%1: Possible Duplicate Event").arg(application())); #endif goto SKIP; } if (mCalendar->getTodo(tmpStr)) { #if 0 if (mEnableDialogs) KMessageBox::error(mTopWidget, i18n("Aborting merge of an event already in " "calendar.\n" "UID is %1\n" "Please check your vCalendar file for " "duplicate UIDs\n" "and change them MANUALLY to be unique " "if you find any.\n").arg(tmpStr), i18n("%1: Possible Duplicate Event").arg(application())); #endif goto SKIP; } } if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) && (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) { kdDebug() << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl; goto SKIP; } anEvent = VEventToEvent(curVO); // we now use addEvent instead of insertEvent so that the // signal/slot get connected. if (anEvent) mCalendar->addEvent(anEvent); else { // some sort of error must have occurred while in translation. goto SKIP; } } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) { Todo *aTodo = VTodoToEvent(curVO); mCalendar->addTodo(aTodo); } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) || (strcmp(vObjectName(curVO), VCProdIdProp) == 0) || (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) { // do nothing, we know these properties and we want to skip them. // we have either already processed them or are ignoring them. ; } else { kdDebug() << "Ignoring unknown vObject \"" << vObjectName(curVO) << "\"" << endl; } SKIP: ; } // while // Post-Process list of events with relations, put Event objects in relation Event *ev; for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) { ev->setRelatedTo(mCalendar->getEvent(ev->relatedToVUID())); } Todo *todo; for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) { todo->setRelatedTo(mCalendar->getTodo(todo->relatedToVUID())); } } const char *VCalFormat::dayFromNum(int day) { const char *days[7] = { "MO ", "TU ", "WE ", "TH ", "FR ", "SA ", "SU " }; return days[day]; } int VCalFormat::numFromDay(const QString &day) { if (day == "MO ") return 0; if (day == "TU ") return 1; if (day == "WE ") return 2; if (day == "TH ") return 3; if (day == "FR ") return 4; if (day == "SA ") return 5; if (day == "SU ") return 6; return -1; // something bad happened. :) } Attendee::PartStat VCalFormat::readStatus(const char *s) const { QString statStr = s; statStr = statStr.upper(); Attendee::PartStat status; if (statStr == "X-ACTION") status = Attendee::NeedsAction; else if (statStr == "NEEDS ACTION") status = Attendee::NeedsAction; else if (statStr== "ACCEPTED") status = Attendee::Accepted; else if (statStr== "SENT") status = Attendee::NeedsAction; else if (statStr== "TENTATIVE") status = Attendee::Tentative; else if (statStr== "CONFIRMED") status = Attendee::Accepted; else if (statStr== "DECLINED") status = Attendee::Declined; else if (statStr== "COMPLETED") status = Attendee::Completed; else if (statStr== "DELEGATED") status = Attendee::Delegated; else { kdDebug() << "error setting attendee mStatus, unknown mStatus!" << endl; status = Attendee::NeedsAction; } return status; } QCString VCalFormat::writeStatus(Attendee::PartStat status) const { switch(status) { default: case Attendee::NeedsAction: return "NEEDS ACTION"; break; case Attendee::Accepted: return "ACCEPTED"; break; case Attendee::Declined: return "DECLINED"; break; case Attendee::Tentative: return "TENTATIVE"; break; case Attendee::Delegated: return "DELEGATED"; break; case Attendee::Completed: return "COMPLETED"; break; case Attendee::InProcess: return "NEEDS ACTION"; break; } }