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.
kpilot/conduits/vcalconduit/todo-conduit.cpp

374 lines
8.3 KiB

/* Todo-Conduit for syncing KPilot and KOrganizer
**
** Copyright (C) 2002-2003 Reinhold Kainhofer
** Copyright (C) 1998-2001 Dan Pilone
** Copyright (C) 1998-2000 Preston Brown <pbrown@kde.org>
** Copyright (C) 1998 Herwin-Jan Steehouwer
** Copyright (C) 2001 Cornelius Schumacher
**
** This file is part of the todo conduit, a conduit for KPilot that
** synchronises the Pilot's todo application with the outside world,
** which currently means KOrganizer.
*/
/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program 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 General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/
/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/
#include "options.h"
#include <tqdatetime.h>
#include <tqtextcodec.h>
#include <libkcal/calendar.h>
#include <libkcal/todo.h>
#include <pilotLocalDatabase.h>
#include "todo-conduit.moc"
#include "vcalconduitSettings.h"
#include "todo-factory.h"
#include "kcalRecord.h"
#include "todoRecord.h"
// define conduit versions, one for the version when categories were synced for the first time, and the current version number
#define CONDUIT_VERSION_CATEGORYSYNC 10
#define CONDUIT_VERSION 10
extern "C"
{
unsigned long version_conduit_todo = Pilot::PLUGIN_API;
}
TodoConduitPrivate::TodoConduitPrivate(KCal::Calendar *b) :
VCalConduitPrivateBase(b)
{
fAllTodos.setAutoDelete(false);
}
void TodoConduitPrivate::addIncidence(KCal::Incidence*e)
{
fAllTodos.append(static_cast<KCal::Todo*>(e));
fCalendar->addTodo(static_cast<KCal::Todo*>(e));
}
int TodoConduitPrivate::updateIncidences()
{
fAllTodos = fCalendar->todos();
fAllTodos.setAutoDelete(false);
return fAllTodos.count();
}
void TodoConduitPrivate::removeIncidence(KCal::Incidence *e)
{
fAllTodos.remove(static_cast<KCal::Todo*>(e));
if (!fCalendar) return;
fCalendar->deleteTodo(static_cast<KCal::Todo*>(e));
// now just in case we're in the middle of reading through our list
// and we delete something, set reading to false so we start at the
// top again next time and don't have problems with our iterator
reading = false;
}
KCal::Incidence *TodoConduitPrivate::findIncidence(recordid_t id)
{
KCal::Todo::List::ConstIterator it;
for( it = fAllTodos.begin(); it != fAllTodos.end(); ++it ) {
KCal::Todo *todo = *it;
if ((recordid_t)(todo->pilotId()) == id) return todo;
}
return 0L;
}
KCal::Incidence *TodoConduitPrivate::findIncidence(PilotRecordBase *tosearch)
{
PilotTodoEntry*entry=dynamic_cast<PilotTodoEntry*>(tosearch);
if (!entry) return 0L;
TQString title=entry->getDescription();
TQDateTime dt=readTm( entry->getDueDate() );
KCal::Todo::List::ConstIterator it;
for( it = fAllTodos.begin(); it != fAllTodos.end(); ++it ) {
KCal::Todo *event = *it;
if ( (event->dtDue().date() == dt.date()) && (event->summary() == title) ) return event;
}
return 0L;
}
KCal::Incidence *TodoConduitPrivate::getNextIncidence()
{
FUNCTIONSETUP;
if (reading) {
++fAllTodosIterator;
}
else {
reading=true;
fAllTodosIterator = fAllTodos.begin();
}
return(fAllTodosIterator == fAllTodos.end()) ? 0L : *fAllTodosIterator;
}
KCal::Incidence *TodoConduitPrivate::getNextModifiedIncidence()
{
FUNCTIONSETUP;
KCal::Todo*e=0L;
if (!reading)
{
reading=true;
fAllTodosIterator = fAllTodos.begin();
}
else
{
++fAllTodosIterator;
}
if ( fAllTodosIterator != fAllTodos.end() ) e=*fAllTodosIterator;
while (fAllTodosIterator != fAllTodos.end() &&
e && e->syncStatus()!=KCal::Incidence::SYNCMOD && e->pilotId())
{
e = (++fAllTodosIterator != fAllTodos.end()) ? *fAllTodosIterator : 0L;
#ifdef DEBUG
if(e)
DEBUGKPILOT<< e->summary()<<" had SyncStatus="<<e->syncStatus()<<endl;
#endif
}
return (fAllTodosIterator == fAllTodos.end()) ? 0L : *fAllTodosIterator;
}
/****************************************************************************
* TodoConduit class *
****************************************************************************/
TodoConduit::TodoConduit(KPilotLink *d,
const char *n,
const TQStringList &a) : VCalConduitBase(d,n,a),
fTodoAppInfo( 0L )
{
FUNCTIONSETUP;
fConduitName=i18n("To-do");
}
TodoConduit::~TodoConduit()
{
// FUNCTIONSETUP;
}
void TodoConduit::_setAppInfo()
{
FUNCTIONSETUP;
// get the address application header information
if( !fTodoAppInfo )
{
DEBUGKPILOT << fname << ": fTodoAppInfo is NULL" << endl;
return;
}
if( !fDatabase )
{
DEBUGKPILOT << fname << ": fDatabase is NULL" << endl;
return;
}
fTodoAppInfo->writeTo(fDatabase);
}
void TodoConduit::_getAppInfo()
{
FUNCTIONSETUP;
// get the address application header information
KPILOT_DELETE( fTodoAppInfo );
fTodoAppInfo = new PilotToDoInfo(fDatabase);
fTodoAppInfo->dump();
}
const TQString TodoConduit::getTitle(PilotRecordBase *de)
{
PilotTodoEntry*d=dynamic_cast<PilotTodoEntry*>(de);
if (d)
{
return TQString(d->getDescription());
}
return TQString();
}
void TodoConduit::readConfig()
{
FUNCTIONSETUP;
VCalConduitBase::readConfig();
// determine if the categories have ever been synce. Needed to prevent loosing
// the categories on the desktop. Also use a full sync for the first time to
// make sure the palm categories are really transferred to the desktop.
//
categoriesSynced = config()->conduitVersion()>=CONDUIT_VERSION_CATEGORYSYNC;
if (!categoriesSynced && !isFullSync() )
{
changeSync(SyncMode::eFullSync);
}
DEBUGKPILOT<<"categoriesSynced=" << categoriesSynced << endl;
}
void TodoConduit::preSync()
{
FUNCTIONSETUP;
VCalConduitBase::preSync();
_getAppInfo();
}
void TodoConduit::postSync()
{
FUNCTIONSETUP;
VCalConduitBase::postSync();
// after this successful sync the categories have been synced for sure
config()->setConduitVersion( CONDUIT_VERSION );
config()->writeConfig();
_setAppInfo();
}
PilotRecord *TodoConduit::recordFromIncidence(PilotRecordBase *de, const KCal::Incidence *e)
{
FUNCTIONSETUP;
if (!de || !e)
{
DEBUGKPILOT << fname
<< ": got NULL entry or NULL incidence." << endl;
return 0L;
}
PilotTodoEntry *todoEntry = dynamic_cast<PilotTodoEntry*>(de);
if (!todoEntry)
{
// Secretly wasn't a todo entry after all
return 0L;
}
const KCal::Todo *todo = dynamic_cast<const KCal::Todo *>(e);
if (!todo)
{
DEBUGKPILOT << fname << ": Incidence is not a todo." << endl;
return 0L;
}
// don't need to check for null pointers here, the recordFromIncidence(PTE*, KCal::Todo*) will do that.
if (KCalSync::setTodoEntry(todoEntry,todo,*fTodoAppInfo->categoryInfo()))
{
return todoEntry->pack();
}
else
{
return 0L;
}
}
KCal::Incidence *TodoConduit::incidenceFromRecord(KCal::Incidence *e, const PilotRecordBase *de)
{
FUNCTIONSETUP;
if (!de || !e)
{
DEBUGKPILOT << fname
<< ": Got NULL entry or NULL incidence." << endl;
return 0L;
}
const PilotTodoEntry *todoEntry = dynamic_cast<const PilotTodoEntry *>(de);
if (!todoEntry)
{
DEBUGKPILOT << fname << ": HH record not a todo entry." << endl;
return 0L;
}
KCal::Todo *todo = dynamic_cast<KCal::Todo *>(e);
if (!todo)
{
DEBUGKPILOT << fname << ": Incidence is not a todo." << endl;
return 0L;
}
KCalSync::setTodo(todo, todoEntry,*fTodoAppInfo->categoryInfo());
return e;
}
void TodoConduit::preRecord(PilotRecord*r)
{
FUNCTIONSETUP;
if (!categoriesSynced && r)
{
const PilotRecordBase *de = newPilotEntry(r);
KCal::Incidence *e = fP->findIncidence(r->id());
KCalSync::setCategory(dynamic_cast<KCal::Todo*>(e),
dynamic_cast<const PilotTodoEntry*>(de),
*fTodoAppInfo->categoryInfo());
}
}
static VCalConduitSettings *config_vcal = 0L;
VCalConduitSettings *TodoConduit::theConfig() {
if (!config_vcal)
{
config_vcal = new VCalConduitSettings(CSL1("Calendar"));
}
return config_vcal;
}
VCalConduitSettings *TodoConduit::config() {
return theConfig();
}