/* 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 ** 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 #include #include #include #include #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(e)); fCalendar->addTodo(static_cast(e)); } int TodoConduitPrivate::updateIncidences() { fAllTodos = fCalendar->todos(); fAllTodos.setAutoDelete(false); return fAllTodos.count(); } void TodoConduitPrivate::removeIncidence(KCal::Incidence *e) { fAllTodos.remove(static_cast(e)); if (!fCalendar) return; fCalendar->deleteTodo(static_cast(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(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="<syncStatus()<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(de); if (d) { return TQString(d->getDescription()); } return TQString::null; } 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(de); if (!todoEntry) { // Secretly wasn't a todo entry after all return 0L; } const KCal::Todo *todo = dynamic_cast(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(de); if (!todoEntry) { DEBUGKPILOT << fname << ": HH record not a todo entry." << endl; return 0L; } KCal::Todo *todo = dynamic_cast(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(e), dynamic_cast(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(); }