|
|
|
/* KPilot
|
|
|
|
**
|
|
|
|
** Copyright (C) 2001 by Dan Pilone
|
|
|
|
** Copyright (C) 2002,2003,2004 by Adriaan de Groot
|
|
|
|
**
|
|
|
|
** This file defines the SyncAction for the knotes-conduit plugin.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
** 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 <tqmap.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
|
|
|
|
#include <kapplication.h>
|
|
|
|
|
|
|
|
#include <kurl.h>
|
|
|
|
#include <libkcal/calendarlocal.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include <kconfig.h>
|
|
|
|
//#include <dcopclient.h>
|
|
|
|
|
|
|
|
#include <time.h> // required by pilot-link includes
|
|
|
|
|
|
|
|
#include <pi-memo.h>
|
|
|
|
|
|
|
|
#include "pilotMemo.h"
|
|
|
|
#include "pilotSerialDatabase.h"
|
|
|
|
|
|
|
|
//#include "KNotesIface_stub.h"
|
|
|
|
|
|
|
|
#include "knotes-factory.h"
|
|
|
|
|
|
|
|
#include "knotes-action.moc"
|
|
|
|
#include "knotesconduitSettings.h"
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
|
|
|
|
unsigned long version_conduit_knotes = Pilot::PLUGIN_API;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef TQString KNoteID_t;
|
|
|
|
typedef const TQString &KNoteID_pt;
|
|
|
|
|
|
|
|
class NoteAndMemo
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
NoteAndMemo() : noteId(),memoId(-1) { } ;
|
|
|
|
NoteAndMemo(KNoteID_pt noteid,int memoid) : noteId(noteid),memoId(memoid) { } ;
|
|
|
|
bool operator ==(const NoteAndMemo &p) const
|
|
|
|
{
|
|
|
|
return (p.memo()==memoId) && (p.note()==noteId);
|
|
|
|
}
|
|
|
|
|
|
|
|
int memo() const { return memoId; } ;
|
|
|
|
KNoteID_t note() const { return noteId; } ;
|
|
|
|
inline bool valid() const { return (memoId>0) && (!noteId.isEmpty()) ; } ;
|
|
|
|
TQString toString() const { return CSL1("<%1,%2>").arg(noteId).arg(memoId); } ;
|
|
|
|
|
|
|
|
static NoteAndMemo findNote(const TQValueList<NoteAndMemo> &,KNoteID_pt note);
|
|
|
|
static NoteAndMemo findMemo(const TQValueList<NoteAndMemo> &,int memo);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
KNoteID_t noteId;
|
|
|
|
int memoId;
|
|
|
|
} ;
|
|
|
|
|
|
|
|
NoteAndMemo NoteAndMemo::findNote(const TQValueList<NoteAndMemo> &l ,KNoteID_pt note)
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
|
|
|
|
for (TQValueList<NoteAndMemo>::ConstIterator it = l.begin();
|
|
|
|
it != l.end();
|
|
|
|
++it)
|
|
|
|
{
|
|
|
|
if ((*it).note()==note) return *it;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NoteAndMemo();
|
|
|
|
}
|
|
|
|
|
|
|
|
NoteAndMemo NoteAndMemo::findMemo(const TQValueList<NoteAndMemo> &l , int memo)
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
|
|
|
|
for (TQValueList<NoteAndMemo>::ConstIterator it =l.begin();
|
|
|
|
it != l.end();
|
|
|
|
++it)
|
|
|
|
{
|
|
|
|
if ((*it).memo()==memo) return *it;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NoteAndMemo();
|
|
|
|
}
|
|
|
|
|
|
|
|
class KNotesAction::KNotesActionPrivate
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
KNotesActionPrivate() :
|
|
|
|
fNotesResource(0L),
|
|
|
|
fTimer(0L),
|
|
|
|
fDeleteCounter(0),
|
|
|
|
fModifiedNotesCounter(0),
|
|
|
|
fModifiedMemosCounter(0),
|
|
|
|
fAddedNotesCounter(0),
|
|
|
|
fAddedMemosCounter(0),
|
|
|
|
fDeletedNotesCounter(0),
|
|
|
|
fDeletedMemosCounter(0),
|
|
|
|
fDeleteNoteForMemo(false)
|
|
|
|
{ } ;
|
|
|
|
~KNotesActionPrivate()
|
|
|
|
{
|
|
|
|
fNotesResource->save();
|
|
|
|
|
|
|
|
KPILOT_DELETE(fNotesResource);
|
|
|
|
KPILOT_DELETE(fTimer);
|
|
|
|
}
|
|
|
|
|
|
|
|
// The record index we're dealing with. Used by
|
|
|
|
// CopyHHToPC sync only.
|
|
|
|
int fRecordIndex;
|
|
|
|
|
|
|
|
KCal::CalendarLocal *fNotesResource;
|
|
|
|
// This is the collection of notes held by KNotes and
|
|
|
|
KCal::Journal::List fNotes;
|
|
|
|
|
|
|
|
// This iterates through that list; it's in here because
|
|
|
|
// we use slots to process one item at a time and need
|
|
|
|
// to keep track of where we are between slot calls.
|
|
|
|
KCal::Journal::List::ConstIterator fIndex;
|
|
|
|
|
|
|
|
// The DCOP client for this application, and the KNotes stub.
|
|
|
|
// DCOPClient *fDCOP;
|
|
|
|
//KNotesIface_stub *fKNotes;
|
|
|
|
|
|
|
|
// The timer for invoking process() to do some more work.
|
|
|
|
TQTimer *fTimer;
|
|
|
|
|
|
|
|
// The database we're working with (MemoDB)
|
|
|
|
// PilotSerialDatabase *fDatabase;
|
|
|
|
// Some counter that needs to be preserved between calls to
|
|
|
|
// process(). Typically used to note how much work is done.
|
|
|
|
int fDeleteCounter; // Count deleted memos as well.
|
|
|
|
unsigned int fModifiedNotesCounter; // Count modified KNotes.
|
|
|
|
unsigned int fModifiedMemosCounter;
|
|
|
|
unsigned int fAddedNotesCounter;
|
|
|
|
unsigned int fAddedMemosCounter;
|
|
|
|
unsigned int fDeletedNotesCounter;
|
|
|
|
unsigned int fDeletedMemosCounter;
|
|
|
|
|
|
|
|
// We need to translate between the ids that KNotes uses and
|
|
|
|
// Pilot id's, so we make a list of pairs.
|
|
|
|
//
|
|
|
|
TQValueList<NoteAndMemo> fIdList;
|
|
|
|
|
|
|
|
// Setting to delete a KNote when the corresponding memo
|
|
|
|
// has been deleted.
|
|
|
|
bool fDeleteNoteForMemo;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
KNotesAction::KNotesAction(KPilotLink *o,
|
|
|
|
const char *n, const TQStringList &a) :
|
|
|
|
ConduitAction(o,n ? n : "knotes-conduit",a),
|
|
|
|
fP(new KNotesActionPrivate)
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
|
|
|
|
/*
|
|
|
|
if (fP) fP->fDCOP = TDEApplication::kApplication()->dcopClient();
|
|
|
|
|
|
|
|
if (fP && !fP->fDCOP)
|
|
|
|
{
|
|
|
|
WARNINGKPILOT << "Can't get DCOP client." << endl;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
/* virtual */ KNotesAction::~KNotesAction()
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
|
|
|
|
KPILOT_DELETE(fP);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* virtual */ bool KNotesAction::exec()
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
DEBUGKPILOT << fname << ": Starting knotes conduit." << endl;
|
|
|
|
|
|
|
|
if (syncMode().isTest())
|
|
|
|
{
|
|
|
|
test();
|
|
|
|
delayDone();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString e;
|
|
|
|
if (!openKNotesResource()) return false;
|
|
|
|
|
|
|
|
// Database names seem to be latin1
|
|
|
|
if (!openDatabases(CSL1("MemoDB")))
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
DEBUGKPILOT << fname << "Can not open databases." << endl;
|
|
|
|
#endif
|
|
|
|
emit logError(i18n("Could not open MemoDB on the handheld."));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
fP->fTimer = new TQTimer(this);
|
|
|
|
fActionStatus = Init;
|
|
|
|
|
|
|
|
// this is not needed. As it is done in the initstate in process();
|
|
|
|
// resetIndexes();
|
|
|
|
|
|
|
|
connect(fP->fTimer,TQT_SIGNAL(timeout()),TQT_SLOT(process()));
|
|
|
|
fP->fTimer->start(0,false);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KNotesAction::test()
|
|
|
|
{
|
|
|
|
if (!openKNotesResource()) return;
|
|
|
|
listNotes();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KNotesAction::openKNotesResource()
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
|
|
|
|
KConfig korgcfg( locate( "config", CSL1("korganizerrc") ) );
|
|
|
|
korgcfg.setGroup( "Time & Date" );
|
|
|
|
TQString tz(korgcfg.readEntry( "TimeZoneId" ) );
|
|
|
|
|
|
|
|
fP->fNotesResource = new KCal::CalendarLocal(tz);
|
|
|
|
KURL mURL = KGlobal::dirs()->saveLocation( "data", "knotes/" ) + "notes.ics";
|
|
|
|
|
|
|
|
if( fP->fNotesResource->load( mURL.path() ) )
|
|
|
|
{
|
|
|
|
fP->fNotes = fP->fNotesResource->journals();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
emit logError( i18n("Could not load the resource at: %1").arg(mURL.path()) );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KNotesAction::resetIndexes()
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
|
|
|
|
fP->fRecordIndex = 0;
|
|
|
|
fP->fIndex = fP->fNotes.begin();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KNotesAction::listNotes()
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
|
|
|
|
KCal::Journal::List notes = fP->fNotesResource->journals();
|
|
|
|
DEBUGKPILOT << fname << ": the resource contains " << notes.size()
|
|
|
|
<< " note(s)." << endl;
|
|
|
|
|
|
|
|
KCal::Journal::List::ConstIterator it;
|
|
|
|
int i = 1;
|
|
|
|
for ( it = notes.begin(); it != notes.end(); ++it )
|
|
|
|
{
|
|
|
|
DEBUGKPILOT << fname << ": note " << i << " has id " << (*it)->uid()
|
|
|
|
<< endl;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUGKPILOT << fname << ": "
|
|
|
|
<< "Sync direction: " << syncMode().name() << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* slot */ void KNotesAction::process()
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
|
|
|
|
DEBUGKPILOT << fname << ": Now in state " << fActionStatus << endl;
|
|
|
|
|
|
|
|
switch(fActionStatus)
|
|
|
|
{
|
|
|
|
case Init:
|
|
|
|
resetIndexes();
|
|
|
|
getAppInfo();
|
|
|
|
getConfigInfo();
|
|
|
|
switch(syncMode().mode())
|
|
|
|
{
|
|
|
|
case SyncAction::SyncMode::eBackup:
|
|
|
|
case SyncAction::SyncMode::eRestore:
|
|
|
|
// Impossible!
|
|
|
|
fActionStatus = Done;
|
|
|
|
break;
|
|
|
|
case SyncAction::SyncMode::eCopyHHToPC :
|
|
|
|
listNotes(); // Debugging
|
|
|
|
fActionStatus = MemosToKNotes;
|
|
|
|
break;
|
|
|
|
case SyncAction::SyncMode::eHotSync:
|
|
|
|
case SyncAction::SyncMode::eFullSync:
|
|
|
|
case SyncAction::SyncMode::eCopyPCToHH:
|
|
|
|
fActionStatus = ModifiedNotesToPilot;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ModifiedNotesToPilot:
|
|
|
|
if (modifyNoteOnPilot())
|
|
|
|
{
|
|
|
|
resetIndexes();
|
|
|
|
fActionStatus = DeleteNotesOnPilot;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DeleteNotesOnPilot:
|
|
|
|
if (deleteNoteOnPilot())
|
|
|
|
{
|
|
|
|
resetIndexes();
|
|
|
|
fActionStatus = NewNotesToPilot;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NewNotesToPilot :
|
|
|
|
if (addNewNoteToPilot())
|
|
|
|
{
|
|
|
|
resetIndexes();
|
|
|
|
fDatabase->resetDBIndex();
|
|
|
|
switch(syncMode().mode())
|
|
|
|
{
|
|
|
|
case SyncAction::SyncMode::eBackup:
|
|
|
|
case SyncAction::SyncMode::eRestore:
|
|
|
|
case SyncAction::SyncMode::eCopyHHToPC :
|
|
|
|
// Impossible!
|
|
|
|
fActionStatus = Done;
|
|
|
|
break;
|
|
|
|
case SyncAction::SyncMode::eHotSync:
|
|
|
|
case SyncAction::SyncMode::eFullSync:
|
|
|
|
fActionStatus = MemosToKNotes;
|
|
|
|
break;
|
|
|
|
case SyncAction::SyncMode::eCopyPCToHH:
|
|
|
|
fActionStatus = Cleanup;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MemosToKNotes :
|
|
|
|
if (syncMemoToKNotes())
|
|
|
|
{
|
|
|
|
fActionStatus=Cleanup;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Cleanup :
|
|
|
|
cleanupMemos();
|
|
|
|
break;
|
|
|
|
default :
|
|
|
|
if (fP->fTimer) fP->fTimer->stop();
|
|
|
|
delayDone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KNotesAction::getConfigInfo()
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
|
|
|
|
KNotesConduitSettings::self()->readConfig();
|
|
|
|
|
|
|
|
fP->fDeleteNoteForMemo = KNotesConduitSettings::deleteNoteForMemo();
|
|
|
|
|
|
|
|
TQValueList<KNoteID_t> notes;
|
|
|
|
TQValueList<int> memos;
|
|
|
|
|
|
|
|
// Make this match the type of KNoteID_t !
|
|
|
|
notes=KNotesConduitSettings::noteIds();
|
|
|
|
memos=KNotesConduitSettings::memoIds();
|
|
|
|
|
|
|
|
if (notes.count() != memos.count())
|
|
|
|
{
|
|
|
|
WARNINGKPILOT
|
|
|
|
<< ": Notes and memo id lists don't match ("
|
|
|
|
<< notes.count()
|
|
|
|
<< ","
|
|
|
|
<< memos.count()
|
|
|
|
<< ")"
|
|
|
|
<< endl;
|
|
|
|
notes.clear();
|
|
|
|
memos.clear();
|
|
|
|
setFirstSync( true );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQValueList<KNoteID_t>::ConstIterator iNotes = notes.begin();
|
|
|
|
TQValueList<int>::ConstIterator iMemos = memos.begin();
|
|
|
|
|
|
|
|
while((iNotes != notes.end()) && (iMemos != memos.end()))
|
|
|
|
{
|
|
|
|
fP->fIdList.append(NoteAndMemo(*iNotes,*iMemos));
|
|
|
|
++iNotes;
|
|
|
|
++iMemos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KNotesAction::getAppInfo()
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
|
|
|
|
resetIndexes();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool KNotesAction::modifyNoteOnPilot()
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
return true;
|
|
|
|
/*
|
|
|
|
if (fP->fIndex == fP->fNotes.end())
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
//TODO DCOP_REMOVAL
|
|
|
|
/*
|
|
|
|
if (fP->fKNotes->isModified(CSL1("kpilot"),fP->fIndex.key()))
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
DEBUGKPILOT << fname
|
|
|
|
<< ": The note #"
|
|
|
|
<< fP->fIndex.key()
|
|
|
|
<< " with name "
|
|
|
|
<< fP->fIndex.data()
|
|
|
|
<< " is modified in KNotes."
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
NoteAndMemo nm = NoteAndMemo::findNote(fP->fIdList,
|
|
|
|
fP->fIndex.key());
|
|
|
|
|
|
|
|
if (nm.valid())
|
|
|
|
{
|
|
|
|
TQString text,title,body;
|
|
|
|
title = fP->fIndex.data();
|
|
|
|
body = fP->fKNotes->text(fP->fIndex.key());
|
|
|
|
if (body.startsWith(title))
|
|
|
|
{
|
|
|
|
text = body;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
text = title + CSL1("\n") + body;
|
|
|
|
}
|
|
|
|
|
|
|
|
PilotMemo *a = new PilotMemo(text);
|
|
|
|
PilotRecord *r = a->pack();
|
|
|
|
r->setID(nm.memo());
|
|
|
|
|
|
|
|
int newid = fDatabase->writeRecord(r);
|
|
|
|
fLocalDatabase->writeRecord(r);
|
|
|
|
|
|
|
|
if (newid != nm.memo())
|
|
|
|
{
|
|
|
|
WARNINGKPILOT
|
|
|
|
<< ": Memo id changed during write? "
|
|
|
|
<< "From "
|
|
|
|
<< nm.memo()
|
|
|
|
<< " to "
|
|
|
|
<< newid
|
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
WARNINGKPILOT << "Modified note unknown to Pilot" << endl;
|
|
|
|
// Add it anyway, with new PilotID.
|
|
|
|
int newid = addNoteToPilot();
|
|
|
|
fP->fIdList.remove(nm);
|
|
|
|
fP->fIdList.append(NoteAndMemo(fP->fIndex.key(),newid));
|
|
|
|
}
|
|
|
|
|
|
|
|
++(fP->fModifiedMemosCounter);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
//++(fP->fIndex);
|
|
|
|
//return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KNotesAction::deleteNoteOnPilot()
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
|
|
|
|
/*
|
|
|
|
TQValueList<NoteAndMemo>::Iterator i = fP->fIdList.begin();
|
|
|
|
while ( i != fP->fIdList.end() )
|
|
|
|
{
|
|
|
|
// TODO DCOP_REMOVE
|
|
|
|
if (fP->fNotes.contains((*i).note()))
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
DEBUGKPILOT << fname << ": Note " << (*i).note() << " still exists." << endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
DEBUGKPILOT << fname << ": Note " << (*i).note() << " is deleted." << endl;
|
|
|
|
#endif
|
|
|
|
fDatabase->deleteRecord((*i).memo());
|
|
|
|
fLocalDatabase->deleteRecord((*i).memo());
|
|
|
|
i = fP->fIdList.remove(i);
|
|
|
|
fP->fDeletedMemosCounter++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KNotesAction::addNewNoteToPilot()
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
|
|
|
|
if (fP->fIndex == fP->fNotes.end())
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
KCal::Journal *j = (*fP->fIndex);
|
|
|
|
|
|
|
|
if( j->pilotId() == 0 )
|
|
|
|
{
|
|
|
|
DEBUGKPILOT << fname << ": Adding note with id " << j->uid()
|
|
|
|
<< " to pilot." << endl;
|
|
|
|
|
|
|
|
int newid = addNoteToPilot();
|
|
|
|
|
|
|
|
++(fP->fAddedMemosCounter);
|
|
|
|
}
|
|
|
|
//TODO DCOP_REMOVAL
|
|
|
|
/*
|
|
|
|
if (fP->fKNotes->isNew(CSL1("kpilot"),fP->fIndex.key()))
|
|
|
|
{
|
|
|
|
int newid = addNoteToPilot();
|
|
|
|
fP->fIdList.append(NoteAndMemo(fP->fIndex.key(),newid));
|
|
|
|
++(fP->fAddedMemosCounter);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
++(fP->fIndex);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KNotesAction::syncMemoToKNotes()
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
|
|
|
|
PilotRecord *rec = 0L;
|
|
|
|
|
|
|
|
if ( syncMode() == SyncAction::SyncMode::eCopyHHToPC )
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
DEBUGKPILOT << fname << ": Read record " << fP->fRecordIndex << endl;
|
|
|
|
#endif
|
|
|
|
rec = fDatabase->readRecordByIndex(fP->fRecordIndex);
|
|
|
|
fP->fRecordIndex++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rec = fDatabase->readNextModifiedRec();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!rec)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
PilotMemo *memo = new PilotMemo(rec);
|
|
|
|
NoteAndMemo m = NoteAndMemo::findMemo(fP->fIdList,memo->id());
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
DEBUGKPILOT << fname << ": Looking at memo "
|
|
|
|
<< memo->id()
|
|
|
|
<< " which was found "
|
|
|
|
<< m.toString()
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (memo->isDeleted())
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
DEBUGKPILOT << fname << ": It's been deleted." << endl;
|
|
|
|
#endif
|
|
|
|
if (m.valid())
|
|
|
|
{
|
|
|
|
// We knew about the note already, but it
|
|
|
|
// has changed on the Pilot.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
if (fP->fDeleteNoteForMemo)
|
|
|
|
{
|
|
|
|
//TODO DCOP_REMOVAL
|
|
|
|
//fP->fKNotes->killNote(m.note(),KNotesConduitSettings::suppressKNotesConfirm()
|
|
|
|
//) ;
|
|
|
|
fP->fDeletedNotesCounter++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
DEBUGKPILOT << fname << ": It's new and deleted." << endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
fLocalDatabase->deleteRecord(rec->id());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (m.valid())
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
DEBUGKPILOT << fname << ": It's just modified." << endl;
|
|
|
|
DEBUGKPILOT << fname << ": <"
|
|
|
|
// << fP->fNotes[m.note()]
|
|
|
|
<< "> <"
|
|
|
|
<< memo->shortTitle()
|
|
|
|
<< ">"
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
// Check if KNotes still knows about this note
|
|
|
|
//TODO DCOP_REMOVAL
|
|
|
|
/*
|
|
|
|
if (!(fP->fKNotes->name(m.note()).isEmpty()))
|
|
|
|
{
|
|
|
|
updateNote(m,memo);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uint c = fP->fIdList.remove(m);
|
|
|
|
if (!c)
|
|
|
|
{
|
|
|
|
WARNINGKPILOT
|
|
|
|
<< "Tried to remove valid note and failed."
|
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
addMemoToKNotes(memo);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
addMemoToKNotes(memo);
|
|
|
|
}
|
|
|
|
fLocalDatabase->writeRecord(rec);
|
|
|
|
}
|
|
|
|
|
|
|
|
KPILOT_DELETE(memo);
|
|
|
|
KPILOT_DELETE(rec);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KNotesAction::updateNote(const NoteAndMemo &m, const PilotMemo *memo)
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
//TODO DCOP_REMOVAL
|
|
|
|
if (true/*fP->fNotes[m.note()] != memo->shortTitle()*/)
|
|
|
|
{
|
|
|
|
// Name changed. KNotes might complain though.
|
|
|
|
//TODO DCOP_REMOVAL
|
|
|
|
//fP->fKNotes->setName(m.note(), memo->shortTitle());
|
|
|
|
}
|
|
|
|
//TODO DCOP_REMOVAL
|
|
|
|
//fP->fKNotes->setText(m.note(),memo->text());
|
|
|
|
fP->fModifiedNotesCounter++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KNotesAction::addMemoToKNotes(const PilotMemo *memo)
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
// This note is new to KNotes
|
|
|
|
//TODO DCOP_REMOVAL
|
|
|
|
//KNoteID_t i = fP->fKNotes->newNote(memo->shortTitle(), memo->text());
|
|
|
|
//fP->fIdList.append(NoteAndMemo(i,memo->id()));
|
|
|
|
//fP->fAddedNotesCounter++;
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
//TODO DCOP_REMOVAL
|
|
|
|
//DEBUGKPILOT << fname << ": It's new with knote id " << i << endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
int KNotesAction::addNoteToPilot()
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
|
|
|
|
KCal::Journal *j = (*fP->fIndex);
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
DEBUGKPILOT << fname
|
|
|
|
<< ": The note #"
|
|
|
|
<< j->uid()
|
|
|
|
<< " with name "
|
|
|
|
<< j->summary()
|
|
|
|
<< " is new to the Pilot."
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
TQString text = j->summary() + CSL1("\n");
|
|
|
|
text.append( j->description() );
|
|
|
|
//TODO DCOP_REMOVAL
|
|
|
|
//text.append(fP->fKNotes->text(fP->fIndex.key()));
|
|
|
|
|
|
|
|
PilotMemo *a = new PilotMemo(text);
|
|
|
|
PilotRecord *r = a->pack();
|
|
|
|
|
|
|
|
int newid = fDatabase->writeRecord(r);
|
|
|
|
fLocalDatabase->writeRecord(r);
|
|
|
|
|
|
|
|
j->setPilotId( newid );
|
|
|
|
|
|
|
|
delete r;
|
|
|
|
delete a;
|
|
|
|
delete j;
|
|
|
|
|
|
|
|
fP->fAddedMemosCounter++;
|
|
|
|
|
|
|
|
return newid;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KNotesAction::cleanupMemos()
|
|
|
|
{
|
|
|
|
FUNCTIONSETUP;
|
|
|
|
|
|
|
|
// Tell KNotes we're up-to-date
|
|
|
|
//TODO DCOP_REMOVAL
|
|
|
|
//fP->fKNotes->sync(CSL1("kpilot"));
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
DEBUGKPILOT << fname
|
|
|
|
<< ": Writing "
|
|
|
|
<< fP->fIdList.count()
|
|
|
|
<< " pairs to the config file."
|
|
|
|
<< endl;
|
|
|
|
DEBUGKPILOT << fname
|
|
|
|
<< ": The config file is read-only: "
|
|
|
|
<< KNotesConduitSettings::self()->config()->isReadOnly()
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
TQValueList<KNoteID_t> notes;
|
|
|
|
TQValueList<int> memos;
|
|
|
|
|
|
|
|
for (TQValueList<NoteAndMemo>::ConstIterator i =
|
|
|
|
fP->fIdList.begin();
|
|
|
|
i!=fP->fIdList.end();
|
|
|
|
++i)
|
|
|
|
{
|
|
|
|
notes.append((*i).note());
|
|
|
|
memos.append((*i).memo());
|
|
|
|
}
|
|
|
|
|
|
|
|
KNotesConduitSettings::setNoteIds(notes);
|
|
|
|
KNotesConduitSettings::setMemoIds(memos);
|
|
|
|
KNotesConduitSettings::self()->writeConfig();
|
|
|
|
|
|
|
|
fActionStatus=Done;
|
|
|
|
fDatabase->cleanup();
|
|
|
|
fDatabase->resetSyncFlags();
|
|
|
|
fLocalDatabase->cleanup();
|
|
|
|
fLocalDatabase->resetSyncFlags();
|
|
|
|
|
|
|
|
// Tell the user what happened. If no changes were
|
|
|
|
// made, spoke remains false and we'll tack a
|
|
|
|
// message on to the end saying so, so that
|
|
|
|
// the user always gets at least one message.
|
|
|
|
bool spoke = false;
|
|
|
|
if (fP->fAddedMemosCounter)
|
|
|
|
{
|
|
|
|
addSyncLogEntry(i18n("Added one new memo.",
|
|
|
|
"Added %n new memos.",
|
|
|
|
fP->fAddedMemosCounter));
|
|
|
|
}
|
|
|
|
if (fP->fModifiedMemosCounter)
|
|
|
|
{
|
|
|
|
addSyncLogEntry(i18n("Modified one memo.",
|
|
|
|
"Modified %n memos.",
|
|
|
|
fP->fModifiedMemosCounter));
|
|
|
|
spoke = true;
|
|
|
|
}
|
|
|
|
if (fP->fDeletedMemosCounter)
|
|
|
|
{
|
|
|
|
addSyncLogEntry(i18n("Deleted one memo.",
|
|
|
|
"Deleted %n memos.",fP->fDeletedMemosCounter));
|
|
|
|
spoke = true;
|
|
|
|
}
|
|
|
|
if (fP->fAddedNotesCounter)
|
|
|
|
{
|
|
|
|
addSyncLogEntry(i18n("Added one note to KNotes.",
|
|
|
|
"Added %n notes to KNotes.",fP->fAddedNotesCounter));
|
|
|
|
spoke = true;
|
|
|
|
}
|
|
|
|
if (fP->fModifiedNotesCounter)
|
|
|
|
{
|
|
|
|
addSyncLogEntry(i18n("Modified one note in KNotes.",
|
|
|
|
"Modified %n notes in KNotes.",fP->fModifiedNotesCounter));
|
|
|
|
spoke = true;
|
|
|
|
}
|
|
|
|
if (fP->fDeletedNotesCounter)
|
|
|
|
{
|
|
|
|
addSyncLogEntry(i18n("Deleted one note from KNotes.",
|
|
|
|
"Deleted %n notes from KNotes.",fP->fDeletedNotesCounter));
|
|
|
|
spoke = true;
|
|
|
|
}
|
|
|
|
if (!spoke)
|
|
|
|
{
|
|
|
|
addSyncLogEntry(i18n("No change to KNotes."));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* virtual */ TQString KNotesAction::statusString() const
|
|
|
|
{
|
|
|
|
switch(fActionStatus)
|
|
|
|
{
|
|
|
|
case Init : return CSL1("Init");
|
|
|
|
case NewNotesToPilot :
|
|
|
|
return CSL1("NewNotesToPilot key=%1");
|
|
|
|
// TODO DCOP_REMOVAL .arg(fP->fIndex.key());
|
|
|
|
case ModifiedNotesToPilot :
|
|
|
|
return CSL1("ModifiedNotesToPilot key=%1");
|
|
|
|
//TODO DCOP_REMOVAL .arg(fP->fIndex.key());
|
|
|
|
case MemosToKNotes :
|
|
|
|
return CSL1("MemosToKNotes rec=%1")
|
|
|
|
.arg(fP->fRecordIndex);
|
|
|
|
case Cleanup : return CSL1("Cleanup");
|
|
|
|
case Done :
|
|
|
|
return CSL1("Done");
|
|
|
|
default :
|
|
|
|
return CSL1("Unknown (%1)").arg(fActionStatus);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|