You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tellico/src/calendarhandler.cpp

252 lines
7.4 KiB

/***************************************************************************
copyright : (C) 2005-2006 by Robby Stephenson
email : robby@periapsis.org
***************************************************************************/
/***************************************************************************
* *
* 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 <tdelocale.h>
#include <kstandarddirs.h>
#include <tdeconfig.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 tdepim
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;
TDEConfig config(TQString::fromLatin1("korganizerrc"));
config.setGroup("General");
TQString fileName = config.readPathEntry("Active Calendar");
TQString resourceName;
KCal::ResourceCalendar* defaultResource = 0;
if(fileName.isEmpty()) {
fileName = locateLocal("appdata", TQString::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);
TQString person = loan_->borrower()->name();
TQString summary = i18n("Tellico: %1 is due to return \"%2\"").arg(person).arg(loan_->entry()->title());
todo_->setSummary(summary);
TQString 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(),
TQString(), 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
TQString CalendarHandler::timezone() {
TQString zone;
TDEConfig korgcfg(locate(TQString::fromLatin1("config"), TQString::fromLatin1("korganizerrc")));
korgcfg.setGroup("Time & Date");
TQString 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 = TQString::fromLocal8Bit(zonefilebuf, len);
zone = zone.mid(zone.find(TQString::fromLatin1("zoneinfo/")) + 9);
} else {
tzset();
zone = tzname[0];
}
}
return zone;
}
#endif