diff options
Diffstat (limited to 'src/calendarhandler.cpp')
-rw-r--r-- | src/calendarhandler.cpp | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/src/calendarhandler.cpp b/src/calendarhandler.cpp new file mode 100644 index 0000000..c8953fd --- /dev/null +++ b/src/calendarhandler.cpp @@ -0,0 +1,251 @@ +/*************************************************************************** + copyright : (C) 2005-2006 by Robby Stephenson + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License as * + * published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#include "calendarhandler.h" +#include "entry.h" +#include "tellico_kernel.h" +#include "tellico_debug.h" + +#include <klocale.h> +#include <kstandarddirs.h> +#include <kconfig.h> + +#ifdef USE_KCAL +#include <libkcal/calendarresources.h> +#include <libkcal/todo.h> +#include <libkcal/resourcelocal.h> +// #include <libkcal/resourceremote.h> // this file is moving around, API differences +#endif + +// needed for ::readlink +#include <unistd.h> +#include <limits.h> + +// most of this code came from konsolekalendar in kdepim + +using Tellico::CalendarHandler; + +void CalendarHandler::addLoans(Data::LoanVec loans_) { +#ifdef USE_KCAL + addLoans(loans_, 0); +#else + Q_UNUSED(loans_); +#endif +} + +#ifdef USE_KCAL +void CalendarHandler::addLoans(Data::LoanVec loans_, KCal::CalendarResources* resources_) { + if(loans_.isEmpty()) { + return; + } + + KCal::CalendarResources* calendarResources; + if(resources_) { + calendarResources = resources_; + } else { + calendarResources = new KCal::CalendarResources(timezone()); + calendarResources->readConfig(); + calendarResources->load(); + if(!checkCalendar(calendarResources)) { + return; + } + } + + for(Data::LoanVec::Iterator loan = loans_.begin(); loan != loans_.end(); ++loan) { + // only add loans with a due date + if(loan->dueDate().isNull()) { + continue; + } + + KCal::Todo* todo = new KCal::Todo(); + populateTodo(todo, loan); + + calendarResources->addTodo(todo); + loan->setInCalendar(true); + } + calendarResources->save(); + // don't close if a pointer was passed + if(!resources_) { + calendarResources->close(); + calendarResources->deleteLater(); + } +} +#endif + +void CalendarHandler::modifyLoans(Data::LoanVec loans_) { +#ifndef USE_KCAL + Q_UNUSED(loans_); + return; +#else + if(loans_.isEmpty()) { + return; + } + + KCal::CalendarResources calendarResources(timezone()); + calendarResources.readConfig(); + if(!checkCalendar(&calendarResources)) { + return; + } + calendarResources.load(); + + for(Data::LoanVec::Iterator loan = loans_.begin(); loan != loans_.end(); ++loan) { + KCal::Todo* todo = calendarResources.todo(loan->uid()); + if(!todo) { +// myDebug() << "couldn't find existing todo, adding a new todo" << endl; + Data::LoanVec newLoans; + newLoans.append(loan); + addLoans(newLoans, &calendarResources); // add loan + continue; + } + if(loan->dueDate().isNull()) { + myDebug() << "removing todo" << endl; + calendarResources.deleteIncidence(todo); + continue; + } + + populateTodo(todo, loan); + todo->updated(); + + loan->setInCalendar(true); + } + calendarResources.save(); + calendarResources.close(); +#endif +} + +void CalendarHandler::removeLoans(Data::LoanVec loans_) { +#ifndef USE_KCAL + Q_UNUSED(loans_); + return; +#else + if(loans_.isEmpty()) { + return; + } + + KCal::CalendarResources calendarResources(timezone()); + calendarResources.readConfig(); + if(!checkCalendar(&calendarResources)) { + return; + } + calendarResources.load(); + + for(Data::LoanVec::Iterator loan = loans_.begin(); loan != loans_.end(); ++loan) { + KCal::Todo* todo = calendarResources.todo(loan->uid()); + if(todo) { + // maybe this is too much, we could just set the todo as done + calendarResources.deleteIncidence(todo); + } + } + calendarResources.save(); + calendarResources.close(); +#endif +} + +#ifdef USE_KCAL +bool CalendarHandler::checkCalendar(KCal::CalendarResources* resources) { + KCal::CalendarResourceManager* manager = resources->resourceManager(); + if(manager->isEmpty()) { + kdWarning() << "Tellico::CalendarHandler::checkCalendar() - adding default calendar" << endl; + KConfig config(QString::fromLatin1("korganizerrc")); + config.setGroup("General"); + QString fileName = config.readPathEntry("Active Calendar"); + + QString resourceName; + KCal::ResourceCalendar* defaultResource = 0; + if(fileName.isEmpty()) { + fileName = locateLocal("appdata", QString::fromLatin1("std.ics")); + resourceName = i18n("Default Calendar"); + defaultResource = new KCal::ResourceLocal(fileName); + } else { + KURL url = KURL::fromPathOrURL(fileName); + if(url.isLocalFile()) { + defaultResource = new KCal::ResourceLocal(url.path()); + } else { +// defaultResource = new KCal::ResourceRemote(url); + Kernel::self()->sorry(i18n("At the moment, Tellico only supports local calendar resources. " + "The active calendar is remotely located, so your loans will not " + "be added.")); + return false; + } + resourceName = i18n("Active Calendar"); + } + + defaultResource->setResourceName(resourceName); + + manager->add(defaultResource); + manager->setStandardResource(defaultResource); + } + return true; +} + +void CalendarHandler::populateTodo(KCal::Todo* todo_, Data::LoanPtr loan_) { + if(!todo_ || !loan_) { + return; + } + + todo_->setUid(loan_->uid()); + + todo_->setDtStart(loan_->loanDate()); + todo_->setHasStartDate(true); + todo_->setDtDue(loan_->dueDate()); + todo_->setHasDueDate(true); + QString person = loan_->borrower()->name(); + QString summary = i18n("Tellico: %1 is due to return \"%2\"").arg(person).arg(loan_->entry()->title()); + todo_->setSummary(summary); + QString note = loan_->note(); + if(note.isEmpty()) { + note = summary; + } + todo_->setDescription(note); + todo_->setSecrecy(KCal::Incidence::SecrecyPrivate); // private by default + + todo_->clearAttendees(); + // not adding email of borrower for now, but request RSVP? + KCal::Attendee* attendee = new KCal::Attendee(loan_->borrower()->name(), + QString::null, false /*rsvp*/, + KCal::Attendee::NeedsAction, + KCal::Attendee::ReqParticipant, + loan_->borrower()->uid()); + todo_->addAttendee(attendee); + + todo_->clearAlarms(); + KCal::Alarm* alarm = todo_->newAlarm(); + alarm->setDisplayAlarm(summary); + alarm->setEnabled(true); +} + +// taken from kpimprefs.cpp +QString CalendarHandler::timezone() { + QString zone; + + KConfig korgcfg(locate(QString::fromLatin1("config"), QString::fromLatin1("korganizerrc"))); + korgcfg.setGroup("Time & Date"); + QString tz(korgcfg.readEntry("TimeZoneId")); + if(!tz.isEmpty()) { + zone = tz; + } else { + char zonefilebuf[PATH_MAX]; + + int len = ::readlink("/etc/localtime", zonefilebuf, PATH_MAX); + if(len > 0 && len < PATH_MAX) { + zone = QString::fromLocal8Bit(zonefilebuf, len); + zone = zone.mid(zone.find(QString::fromLatin1("zoneinfo/")) + 9); + } else { + tzset(); + zone = tzname[0]; + } + } + return zone; +} + +#endif |