Merge branch 'HARMATTAN-1-3-1'
Fetched the code and its history from the 1.3.1 archives at: http://people.debian.org/~ovek/maemo/ http://people.debian.org/~ovek/harmattan/ Merged almost everything, except for Maemo/Harmattan specific build files: autogen-maemo.sh builddeb buildsrc debian The following changes were also removed, because they are either local workarounds or merge artifacts which probably also don't belong into the Maemo/Harmattan branch: diff --git a/configure.ac b/configure.ac index cb66617..2c4403c 100644 --- a/configure.ac +++ b/configure.ac @@ -44,7 +44,7 @@ if test "$enable_release_mode" = "yes"; then AC_DEFINE(SYNCEVOLUTION_STABLE_RELEASE, 1, [binary is meant for end-users]) fi -AM_INIT_AUTOMAKE([1.11.1 tar-ustar silent-rules subdir-objects -Wno-portability]) +AM_INIT_AUTOMAKE([subdir-objects -Wno-portability]) AM_PROG_CC_C_O diff --git a/src/backends/webdav/CalDAVSource.cpp b/src/backends/webdav/CalDAVSource.cpp index decd170..7d338ac 100644 --- a/src/backends/webdav/CalDAVSource.cpp +++ b/src/backends/webdav/CalDAVSource.cpp @@ -1282,6 +1282,7 @@ void CalDAVSource::Event::fixIncomingCalendar(icalcomponent *calendar) // time. bool ridInUTC = false; const icaltimezone *zone = NULL; + icalcomponent *parent = NULL; for (icalcomponent *comp = icalcomponent_get_first_component(calendar, ICAL_VEVENT_COMPONENT); comp; @@ -1295,6 +1296,7 @@ void CalDAVSource::Event::fixIncomingCalendar(icalcomponent *calendar) // is parent event? -> remember time zone unless it is UTC static const struct icaltimetype null = { 0 }; if (!memcmp(&rid, &null, sizeof(null))) { + parent = comp; struct icaltimetype dtstart = icalcomponent_get_dtstart(comp); if (!icaltime_is_utc(dtstart)) { zone = icaltime_get_timezone(dtstart); diff --git a/src/backends/webdav/CalDAVSource.h b/src/backends/webdav/CalDAVSource.h index 517ac2f..fa7c2ca 100644 --- a/src/backends/webdav/CalDAVSource.h +++ b/src/backends/webdav/CalDAVSource.h @@ -45,6 +45,10 @@ class CalDAVSource : public WebDAVSource, virtual void removeMergedItem(const std::string &luid); virtual void flushItem(const string &uid); virtual std::string getSubDescription(const string &uid, const string &subid); + virtual void updateSynthesisInfo(SynthesisInfo &info, + XMLConfigFragments &fragments) { + info.m_backendRule = "HAVE-SYNCEVOLUTION-EXDATE-DETACHED"; + } // implementation of SyncSourceLogging callback virtual std::string getDescription(const string &luid); Making SySync_ConsolePrintf a real instance inside SyncEvolution leads to link errors in other configurations. It really has to be extern. Added a comment to the master branch to make that more obvious: -extern "C" { // without curly braces, g++ 4.2 thinks the variable is extern - int (*SySync_ConsolePrintf)(FILE *stream, const char *format, ...); -} +// This is just the declaration. The actual function pointer instance +// is inside libsynthesis, which, for historic purposes, doesn't define +// it in its header files (yet). +extern "C" int (*SySync_ConsolePrintf)(FILE *stream, const char *format, ...);
This commit is contained in:
commit
340579cbdb
|
@ -23,6 +23,7 @@ Makefile.in
|
||||||
/config.sub
|
/config.sub
|
||||||
/configure
|
/configure
|
||||||
/depcomp
|
/depcomp
|
||||||
|
/INSTALL
|
||||||
/install-sh
|
/install-sh
|
||||||
/libtool
|
/libtool
|
||||||
/ltmain.sh
|
/ltmain.sh
|
||||||
|
@ -35,6 +36,9 @@ Makefile.in
|
||||||
/syncevolution.1
|
/syncevolution.1
|
||||||
/syncevolution-*.tar.gz
|
/syncevolution-*.tar.gz
|
||||||
|
|
||||||
|
# for Maemo build
|
||||||
|
/libsynthesis
|
||||||
|
|
||||||
# po
|
# po
|
||||||
/po/*.gmo
|
/po/*.gmo
|
||||||
/po/.intltool-merge-cache
|
/po/.intltool-merge-cache
|
||||||
|
|
|
@ -55,7 +55,8 @@ dnl Specify git revisions/branches without prefix, i.e., without 'origin'.
|
||||||
dnl We'll sort that out below.
|
dnl We'll sort that out below.
|
||||||
define([SYNTHESISSRC_REVISION], [syncevolution-0.9])
|
define([SYNTHESISSRC_REVISION], [syncevolution-0.9])
|
||||||
AC_CONFIG_HEADERS(config.h)
|
AC_CONFIG_HEADERS(config.h)
|
||||||
LT_INIT([dlopen])
|
AC_LIBTOOL_DLOPEN
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
|
|
||||||
dnl check for programs.
|
dnl check for programs.
|
||||||
AC_PROG_CXX
|
AC_PROG_CXX
|
||||||
|
@ -677,7 +678,11 @@ AC_SUBST(GUI_DESKTOP_FILES)
|
||||||
|
|
||||||
# C++ regular expression support is required often enough to make it
|
# C++ regular expression support is required often enough to make it
|
||||||
# mandatory.
|
# mandatory.
|
||||||
PKG_CHECK_MODULES(PCRECPP, libpcrecpp)
|
PKG_CHECK_MODULES(PCRECPP, libpcrecpp,,
|
||||||
|
AC_CHECK_LIB(pcrecpp,main,
|
||||||
|
AC_SUBST(PCRECPP_LIBS,-lpcrecpp),
|
||||||
|
AC_MSG_ERROR([pcrecpp not found])
|
||||||
|
))
|
||||||
|
|
||||||
# need rst2man for man pages
|
# need rst2man for man pages
|
||||||
AC_ARG_WITH(rst2man,
|
AC_ARG_WITH(rst2man,
|
||||||
|
|
|
@ -68,7 +68,10 @@ if test "$enable_evo" = "yes"; then
|
||||||
# Only the EClient code supports the API in EDS 3.5.x.
|
# Only the EClient code supports the API in EDS 3.5.x.
|
||||||
PKG_CHECK_MODULES(EDS_VERSION, [libedataserver-1.2 >= 3.5],
|
PKG_CHECK_MODULES(EDS_VERSION, [libedataserver-1.2 >= 3.5],
|
||||||
[AC_DEFINE(USE_EDS_CLIENT, 1, [use e_book/cal_client_* calls])],
|
[AC_DEFINE(USE_EDS_CLIENT, 1, [use e_book/cal_client_* calls])],
|
||||||
[true])
|
[CFLAGS_old="$CFLAGS"
|
||||||
|
CFLAGS="$CFLAGS $EPACKAGE_CFLAGS"
|
||||||
|
AC_CHECK_HEADERS(libedataserver/eds-version.h)
|
||||||
|
CFLAGS="$CFLAGS_old"])
|
||||||
else
|
else
|
||||||
EPACKAGE_CFLAGS=
|
EPACKAGE_CFLAGS=
|
||||||
EPACKAGE_LIBS=
|
EPACKAGE_LIBS=
|
||||||
|
|
|
@ -65,12 +65,26 @@ class KCalExtendedData
|
||||||
public:
|
public:
|
||||||
KCalExtendedData(KCalExtendedSource *parent,
|
KCalExtendedData(KCalExtendedSource *parent,
|
||||||
const QString ¬ebook,
|
const QString ¬ebook,
|
||||||
const KCalCore::IncidenceBase::IncidenceType &type) :
|
const KCalExtendedSource::Type &type) :
|
||||||
m_parent(parent),
|
m_parent(parent),
|
||||||
m_modified(false),
|
m_modified(false),
|
||||||
m_notebook(notebook),
|
m_notebook(notebook)
|
||||||
m_type(type)
|
|
||||||
{
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case KCalExtendedSource::Event:
|
||||||
|
m_type = KCalCore::IncidenceBase::TypeEvent;
|
||||||
|
break;
|
||||||
|
case KCalExtendedSource::Todo:
|
||||||
|
m_type = KCalCore::IncidenceBase::TypeTodo;
|
||||||
|
break;
|
||||||
|
case KCalExtendedSource::Journal:
|
||||||
|
m_type = KCalCore::IncidenceBase::TypeJournal;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_type = KCalCore::IncidenceBase::TypeUnknown;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!qApp) {
|
if (!qApp) {
|
||||||
static const char *argv[] = { "SyncEvolution" };
|
static const char *argv[] = { "SyncEvolution" };
|
||||||
static int argc = 1;
|
static int argc = 1;
|
||||||
|
@ -176,25 +190,36 @@ KCalExtendedData::ItemID KCalExtendedData::getItemID(const KCalCore::Incidence::
|
||||||
return ItemID(qstring2std(uid), ridStr);
|
return ItemID(qstring2std(uid), ridStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
KCalExtendedSource::KCalExtendedSource(const SyncSourceParams ¶ms) :
|
KCalExtendedSource::KCalExtendedSource(const SyncSourceParams ¶ms, Type type) :
|
||||||
TestingSyncSource(params)
|
TestingSyncSource(params)
|
||||||
{
|
{
|
||||||
SyncSourceRevisions::init(this, this, 0, m_operations);
|
SyncSourceRevisions::init(this, this, 0, m_operations);
|
||||||
SyncSourceLogging::init(InitList<std::string>("SUMMARY") + "LOCATION",
|
switch (type)
|
||||||
", ",
|
{
|
||||||
m_operations);
|
case Event:
|
||||||
#if 0
|
SyncSourceLogging::init(InitList<std::string>("SUMMARY") + "LOCATION",
|
||||||
// VTODO
|
", ",
|
||||||
SyncSourceLogging::init(InitList<std::string>("SUMMARY"),
|
m_operations);
|
||||||
", ",
|
break;
|
||||||
m_operations);
|
case Todo:
|
||||||
// VJOURNAL
|
SyncSourceLogging::init(InitList<std::string>("SUMMARY"),
|
||||||
SyncSourceLogging::init(InitList<std::string>("SUBJECT"),
|
", ",
|
||||||
", ",
|
m_operations);
|
||||||
m_operations);
|
break;
|
||||||
#endif
|
case Journal:
|
||||||
|
SyncSourceLogging::init(InitList<std::string>("SUBJECT"),
|
||||||
|
", ",
|
||||||
|
m_operations);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throwError("invalid calendar type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
m_data = NULL;
|
m_data = NULL;
|
||||||
|
m_type = type;
|
||||||
|
m_delete_run = 0;
|
||||||
|
m_insert_run = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
KCalExtendedSource::~KCalExtendedSource()
|
KCalExtendedSource::~KCalExtendedSource()
|
||||||
|
@ -202,14 +227,25 @@ KCalExtendedSource::~KCalExtendedSource()
|
||||||
delete m_data;
|
delete m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string KCalExtendedSource::getMimeType() const
|
||||||
|
{
|
||||||
|
return m_type == Journal ?
|
||||||
|
"text/calendar+plain" :
|
||||||
|
"text/calendar";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string KCalExtendedSource::getMimeVersion() const
|
||||||
|
{
|
||||||
|
return "2.0";
|
||||||
|
}
|
||||||
|
|
||||||
void KCalExtendedSource::open()
|
void KCalExtendedSource::open()
|
||||||
{
|
{
|
||||||
// read specified database name from "database" property
|
// read specified database name from "database" property
|
||||||
std::string databaseID = getDatabaseID();
|
std::string databaseID = getDatabaseID();
|
||||||
|
|
||||||
// TODO: also support todoType
|
// TODO: also support todoType
|
||||||
m_data = new KCalExtendedData(this, databaseID.c_str(),
|
m_data = new KCalExtendedData(this, databaseID.c_str(), m_type);
|
||||||
KCalCore::IncidenceBase::TypeEvent);
|
|
||||||
m_data->m_calendar = mKCal::ExtendedCalendar::Ptr(new mKCal::ExtendedCalendar(KDateTime::Spec::LocalZone()));
|
m_data->m_calendar = mKCal::ExtendedCalendar::Ptr(new mKCal::ExtendedCalendar(KDateTime::Spec::LocalZone()));
|
||||||
|
|
||||||
if (databaseID.empty() || boost::starts_with(databaseID, "file://") ) {
|
if (databaseID.empty() || boost::starts_with(databaseID, "file://") ) {
|
||||||
|
@ -227,11 +263,40 @@ void KCalExtendedSource::open()
|
||||||
if (!m_data->m_storage->open()) {
|
if (!m_data->m_storage->open()) {
|
||||||
throwError("failed to open storage");
|
throwError("failed to open storage");
|
||||||
}
|
}
|
||||||
|
#ifdef ENABLE_MAEMO
|
||||||
|
mKCal::Notebook::Ptr defaultNotebook;
|
||||||
|
// For notes, we need a different default database:
|
||||||
|
// Notes (uid:66666666-7777-8888-9999-000000000000)
|
||||||
|
if (databaseID.empty() && m_type == Journal)
|
||||||
|
{
|
||||||
|
defaultNotebook = m_data->m_storage->notebook("66666666-7777-8888-9999-000000000000");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
defaultNotebook = m_data->m_storage->defaultNotebook();
|
||||||
|
}
|
||||||
|
#else
|
||||||
mKCal::Notebook::Ptr defaultNotebook = m_data->m_storage->defaultNotebook();
|
mKCal::Notebook::Ptr defaultNotebook = m_data->m_storage->defaultNotebook();
|
||||||
|
#endif
|
||||||
if (!defaultNotebook) {
|
if (!defaultNotebook) {
|
||||||
throwError("no default Notebook");
|
throwError("no default Notebook");
|
||||||
}
|
}
|
||||||
m_data->m_notebookUID = defaultNotebook->uid();
|
m_data->m_notebookUID = defaultNotebook->uid();
|
||||||
|
#ifdef ENABLE_MAEMO
|
||||||
|
} else if (boost::starts_with(databaseID, "uid:")) {
|
||||||
|
// if databaseID has a "uid:" prefix, open existing notebook with given ID in default storage
|
||||||
|
m_data->m_storage = mKCal::ExtendedCalendar::defaultStorage(m_data->m_calendar);
|
||||||
|
if (!m_data->m_storage->open()) {
|
||||||
|
throwError("failed to open storage");
|
||||||
|
}
|
||||||
|
QString uid = databaseID.c_str() + strlen("uid:");
|
||||||
|
mKCal::Notebook::Ptr notebook = m_data->m_storage->notebook(uid);
|
||||||
|
|
||||||
|
if ( !notebook ) {
|
||||||
|
throwError(string("no such notebook with UID \"") + uid.toStdString() + string("\" in default storage"));
|
||||||
|
}
|
||||||
|
m_data->m_notebookUID = notebook->uid();
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
// use databaseID as notebook name to search for an existing notebook
|
// use databaseID as notebook name to search for an existing notebook
|
||||||
// if found use it, otherwise:
|
// if found use it, otherwise:
|
||||||
|
@ -270,14 +335,24 @@ void KCalExtendedSource::open()
|
||||||
// we are not currently using partial loading because there were
|
// we are not currently using partial loading because there were
|
||||||
// issues with it (BMC #6061); the load() calls elsewhere in this
|
// issues with it (BMC #6061); the load() calls elsewhere in this
|
||||||
// file are commented out
|
// file are commented out
|
||||||
if (!m_data->m_storage->load()) {
|
if (!m_data->m_storage->loadNotebookIncidences(m_data->m_notebookUID)) {
|
||||||
throwError("failed to load calendar");
|
throwError("failed to load calendar");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KCalExtendedSource::isEmpty()
|
bool KCalExtendedSource::isEmpty()
|
||||||
{
|
{
|
||||||
return false;
|
switch (m_data->m_type)
|
||||||
|
{
|
||||||
|
case KCalCore::IncidenceBase::TypeEvent:
|
||||||
|
return !m_data->m_calendar->eventCount();
|
||||||
|
case KCalCore::IncidenceBase::TypeTodo:
|
||||||
|
return !m_data->m_calendar->todoCount();
|
||||||
|
case KCalCore::IncidenceBase::TypeJournal:
|
||||||
|
return !m_data->m_calendar->journalCount();
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KCalExtendedSource::close()
|
void KCalExtendedSource::close()
|
||||||
|
@ -305,8 +380,7 @@ KCalExtendedSource::Databases KCalExtendedSource::getDatabases()
|
||||||
{
|
{
|
||||||
Databases result;
|
Databases result;
|
||||||
|
|
||||||
m_data = new KCalExtendedData(this, getDatabaseID().c_str(),
|
m_data = new KCalExtendedData(this, getDatabaseID().c_str(), m_type);
|
||||||
KCalCore::IncidenceBase::TypeEvent);
|
|
||||||
m_data->m_calendar = mKCal::ExtendedCalendar::Ptr(new mKCal::ExtendedCalendar(KDateTime::Spec::LocalZone()));
|
m_data->m_calendar = mKCal::ExtendedCalendar::Ptr(new mKCal::ExtendedCalendar(KDateTime::Spec::LocalZone()));
|
||||||
m_data->m_storage = mKCal::ExtendedCalendar::defaultStorage(m_data->m_calendar);
|
m_data->m_storage = mKCal::ExtendedCalendar::defaultStorage(m_data->m_calendar);
|
||||||
if (!m_data->m_storage->open()) {
|
if (!m_data->m_storage->open()) {
|
||||||
|
@ -315,10 +389,21 @@ KCalExtendedSource::Databases KCalExtendedSource::getDatabases()
|
||||||
mKCal::Notebook::List notebookList = m_data->m_storage->notebooks();
|
mKCal::Notebook::List notebookList = m_data->m_storage->notebooks();
|
||||||
mKCal::Notebook::List::Iterator it;
|
mKCal::Notebook::List::Iterator it;
|
||||||
for ( it = notebookList.begin(); it != notebookList.end(); ++it ) {
|
for ( it = notebookList.begin(); it != notebookList.end(); ++it ) {
|
||||||
|
#ifdef ENABLE_MAEMO
|
||||||
|
string name = (*it)->name().toStdString();
|
||||||
|
string uid = (*it)->uid().toStdString();
|
||||||
|
// For notes, we need a different default database:
|
||||||
|
// Notes (uid:66666666-7777-8888-9999-000000000000)
|
||||||
|
bool isDefault = (m_type != Journal) ?
|
||||||
|
(*it)->isDefault() :
|
||||||
|
(uid == "66666666-7777-8888-9999-000000000000");
|
||||||
|
result.push_back(Database( name, "uid:" + uid, isDefault ));
|
||||||
|
#else
|
||||||
bool isDefault = (*it)->isDefault();
|
bool isDefault = (*it)->isDefault();
|
||||||
result.push_back(Database( (*it)->name().toStdString(),
|
result.push_back(Database( (*it)->name().toStdString(),
|
||||||
(m_data->m_storage).staticCast<mKCal::SqliteStorage>()->databaseName().toStdString(),
|
(m_data->m_storage).staticCast<mKCal::SqliteStorage>()->databaseName().toStdString(),
|
||||||
isDefault));
|
isDefault));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
m_data->m_storage->close();
|
m_data->m_storage->close();
|
||||||
m_data->m_calendar->close();
|
m_data->m_calendar->close();
|
||||||
|
@ -330,9 +415,10 @@ void KCalExtendedSource::beginSync(const std::string &lastToken, const std::stri
|
||||||
const char *anchor = resumeToken.empty() ? lastToken.c_str() : resumeToken.c_str();
|
const char *anchor = resumeToken.empty() ? lastToken.c_str() : resumeToken.c_str();
|
||||||
KCalCore::Incidence::List incidences;
|
KCalCore::Incidence::List incidences;
|
||||||
// return all items
|
// return all items
|
||||||
if (!m_data->m_storage->allIncidences(&incidences, m_data->m_notebookUID)) {
|
incidences = m_data->m_calendar->incidences();
|
||||||
throwError("allIncidences() failed");
|
// if (!m_data->m_storage->allIncidences(&incidences, m_data->m_notebookUID)) {
|
||||||
}
|
// throwError("allIncidences() failed");
|
||||||
|
// }
|
||||||
m_data->extractIncidences(incidences, SyncSourceChanges::ANY, *this);
|
m_data->extractIncidences(incidences, SyncSourceChanges::ANY, *this);
|
||||||
if (*anchor) {
|
if (*anchor) {
|
||||||
SE_LOG_DEBUG(NULL, NULL, "checking for changes since %s UTC", anchor);
|
SE_LOG_DEBUG(NULL, NULL, "checking for changes since %s UTC", anchor);
|
||||||
|
@ -372,6 +458,8 @@ std::string KCalExtendedSource::endSync(bool success)
|
||||||
sleep(1 - (current - modtime));
|
sleep(1 - (current - modtime));
|
||||||
current = time(NULL);
|
current = time(NULL);
|
||||||
} while (current - modtime < 1);
|
} while (current - modtime < 1);
|
||||||
|
m_delete_run = 0;
|
||||||
|
m_insert_run = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDateTime now = QDateTime::currentDateTime().toUTC();
|
QDateTime now = QDateTime::currentDateTime().toUTC();
|
||||||
|
@ -393,6 +481,21 @@ void KCalExtendedSource::readItem(const string &uid, std::string &item)
|
||||||
|
|
||||||
TestingSyncSource::InsertItemResult KCalExtendedSource::insertItem(const string &uid, const std::string &item)
|
TestingSyncSource::InsertItemResult KCalExtendedSource::insertItem(const string &uid, const std::string &item)
|
||||||
{
|
{
|
||||||
|
if (m_delete_run > 0)
|
||||||
|
{
|
||||||
|
// Since the storage's save() might do deletes *after* inserts,
|
||||||
|
// the final save() could fail if we're doing a refresh-from-peer
|
||||||
|
// (where everything is first deleted and then reinserted), as
|
||||||
|
// the inserts will fail due to the existing entries not being
|
||||||
|
// deleted yet. To avoid the problem, make sure we save between
|
||||||
|
// the deletes and the inserts.
|
||||||
|
if (!m_data->m_storage->save()) {
|
||||||
|
throwError("could not save calendar");
|
||||||
|
}
|
||||||
|
m_delete_run = 0;
|
||||||
|
m_insert_run = 0;
|
||||||
|
}
|
||||||
|
|
||||||
KCalCore::Calendar::Ptr calendar(new KCalCore::MemoryCalendar(KDateTime::Spec::LocalZone()));
|
KCalCore::Calendar::Ptr calendar(new KCalCore::MemoryCalendar(KDateTime::Spec::LocalZone()));
|
||||||
KCalCore::ICalFormat parser;
|
KCalCore::ICalFormat parser;
|
||||||
if (!parser.fromString(calendar, std2qstring(item))) {
|
if (!parser.fromString(calendar, std2qstring(item))) {
|
||||||
|
@ -402,7 +505,7 @@ TestingSyncSource::InsertItemResult KCalExtendedSource::insertItem(const string
|
||||||
if (incidences.empty()) {
|
if (incidences.empty()) {
|
||||||
throwError("iCalendar 2.0 item empty?!");
|
throwError("iCalendar 2.0 item empty?!");
|
||||||
}
|
}
|
||||||
bool updated;
|
InsertItemResultState updated;
|
||||||
string newUID;
|
string newUID;
|
||||||
string oldUID = uid;
|
string oldUID = uid;
|
||||||
|
|
||||||
|
@ -437,7 +540,7 @@ TestingSyncSource::InsertItemResult KCalExtendedSource::insertItem(const string
|
||||||
if (oldUID.empty()) {
|
if (oldUID.empty()) {
|
||||||
KCalCore::Incidence::Ptr incidence = incidences[0];
|
KCalCore::Incidence::Ptr incidence = incidences[0];
|
||||||
|
|
||||||
updated = false;
|
updated = ITEM_OKAY;
|
||||||
if (!m_data->m_calendar->addIncidence(incidence)) {
|
if (!m_data->m_calendar->addIncidence(incidence)) {
|
||||||
throwError("could not add incidence");
|
throwError("could not add incidence");
|
||||||
}
|
}
|
||||||
|
@ -445,7 +548,7 @@ TestingSyncSource::InsertItemResult KCalExtendedSource::insertItem(const string
|
||||||
newUID = m_data->getItemID(incidence).getLUID();
|
newUID = m_data->getItemID(incidence).getLUID();
|
||||||
} else {
|
} else {
|
||||||
KCalCore::Incidence::Ptr incidence = incidences[0];
|
KCalCore::Incidence::Ptr incidence = incidences[0];
|
||||||
updated = true;
|
updated = uid.empty() ? ITEM_REPLACED : ITEM_OKAY;
|
||||||
newUID = oldUID;
|
newUID = oldUID;
|
||||||
KCalCore::Incidence::Ptr original = m_data->findIncidence(oldUID);
|
KCalCore::Incidence::Ptr original = m_data->findIncidence(oldUID);
|
||||||
if (!original) {
|
if (!original) {
|
||||||
|
@ -475,6 +578,7 @@ TestingSyncSource::InsertItemResult KCalExtendedSource::insertItem(const string
|
||||||
}
|
}
|
||||||
|
|
||||||
m_data->m_modified = true;
|
m_data->m_modified = true;
|
||||||
|
m_insert_run++;
|
||||||
|
|
||||||
return InsertItemResult(newUID,
|
return InsertItemResult(newUID,
|
||||||
"",
|
"",
|
||||||
|
@ -495,14 +599,16 @@ void KCalExtendedSource::deleteItem(const string &uid)
|
||||||
throwError(string("could not delete incidence") + uid);
|
throwError(string("could not delete incidence") + uid);
|
||||||
}
|
}
|
||||||
m_data->m_modified = true;
|
m_data->m_modified = true;
|
||||||
|
m_delete_run++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KCalExtendedSource::listAllItems(RevisionMap_t &revisions)
|
void KCalExtendedSource::listAllItems(RevisionMap_t &revisions)
|
||||||
{
|
{
|
||||||
KCalCore::Incidence::List incidences;
|
KCalCore::Incidence::List incidences;
|
||||||
if (!m_data->m_storage->allIncidences(&incidences, m_data->m_notebookUID)) {
|
incidences = m_data->m_calendar->incidences();
|
||||||
throwError("allIncidences() failed");
|
// if (!m_data->m_storage->allIncidences(&incidences, m_data->m_notebookUID)) {
|
||||||
}
|
// throwError("allIncidences() failed");
|
||||||
|
// }
|
||||||
foreach (KCalCore::Incidence::Ptr incidence, incidences) {
|
foreach (KCalCore::Incidence::Ptr incidence, incidences) {
|
||||||
if (incidence->type() == m_data->m_type) {
|
if (incidence->type() == m_data->m_type) {
|
||||||
revisions[m_data->getItemID(incidence).getLUID()] = "1";
|
revisions[m_data->getItemID(incidence).getLUID()] = "1";
|
||||||
|
|
|
@ -45,8 +45,14 @@ class KCalExtendedData;
|
||||||
*/
|
*/
|
||||||
class KCalExtendedSource : public TestingSyncSource, private SyncSourceAdmin, private SyncSourceBlob, private SyncSourceRevisions, public SyncSourceLogging, private boost::noncopyable
|
class KCalExtendedSource : public TestingSyncSource, private SyncSourceAdmin, private SyncSourceBlob, private SyncSourceRevisions, public SyncSourceLogging, private boost::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
KCalExtendedSource(const SyncSourceParams ¶ms);
|
enum Type {
|
||||||
|
Event = 0,
|
||||||
|
Todo = 1,
|
||||||
|
Journal = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
KCalExtendedSource(const SyncSourceParams ¶ms, Type type);
|
||||||
~KCalExtendedSource();
|
~KCalExtendedSource();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -57,7 +63,7 @@ class KCalExtendedSource : public TestingSyncSource, private SyncSourceAdmin, pr
|
||||||
virtual Databases getDatabases();
|
virtual Databases getDatabases();
|
||||||
virtual void enableServerMode();
|
virtual void enableServerMode();
|
||||||
virtual bool serverModeEnabled() const;
|
virtual bool serverModeEnabled() const;
|
||||||
virtual std::string getPeerMimeType() const { return "text/calendar"; }
|
virtual std::string getPeerMimeType() const { return getMimeType(); }
|
||||||
|
|
||||||
/* implementation of SyncSourceSession interface */
|
/* implementation of SyncSourceSession interface */
|
||||||
virtual void beginSync(const std::string &lastToken, const std::string &resumeToken);
|
virtual void beginSync(const std::string &lastToken, const std::string &resumeToken);
|
||||||
|
@ -67,8 +73,8 @@ class KCalExtendedSource : public TestingSyncSource, private SyncSourceAdmin, pr
|
||||||
virtual void deleteItem(const string &luid);
|
virtual void deleteItem(const string &luid);
|
||||||
|
|
||||||
/* implementation of SyncSourceSerialize interface */
|
/* implementation of SyncSourceSerialize interface */
|
||||||
virtual std::string getMimeType() const { return "text/calendar"; }
|
virtual std::string getMimeType() const;
|
||||||
virtual std::string getMimeVersion() const { return "2.0"; }
|
virtual std::string getMimeVersion() const;
|
||||||
virtual InsertItemResult insertItem(const std::string &luid, const std::string &item);
|
virtual InsertItemResult insertItem(const std::string &luid, const std::string &item);
|
||||||
virtual void readItem(const std::string &luid, std::string &item);
|
virtual void readItem(const std::string &luid, std::string &item);
|
||||||
|
|
||||||
|
@ -84,6 +90,9 @@ class KCalExtendedSource : public TestingSyncSource, private SyncSourceAdmin, pr
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KCalExtendedData *m_data;
|
KCalExtendedData *m_data;
|
||||||
|
Type m_type;
|
||||||
|
unsigned m_delete_run;
|
||||||
|
unsigned m_insert_run;
|
||||||
};
|
};
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
|
@ -27,7 +27,7 @@ SE_BEGIN_CXX
|
||||||
static SyncSource *createSource(const SyncSourceParams ¶ms)
|
static SyncSource *createSource(const SyncSourceParams ¶ms)
|
||||||
{
|
{
|
||||||
SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
|
SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
|
||||||
bool isMe = sourceType.m_backend == "mkcal";
|
bool isMe = sourceType.m_backend == "mkcal-events";
|
||||||
bool maybeMe = sourceType.m_backend == "calendar";
|
bool maybeMe = sourceType.m_backend == "calendar";
|
||||||
|
|
||||||
if (isMe || maybeMe) {
|
if (isMe || maybeMe) {
|
||||||
|
@ -37,11 +37,44 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
||||||
sourceType.m_format == "text/calendar") {
|
sourceType.m_format == "text/calendar") {
|
||||||
return
|
return
|
||||||
#ifdef ENABLE_KCALEXTENDED
|
#ifdef ENABLE_KCALEXTENDED
|
||||||
true ? new KCalExtendedSource(params) :
|
true ? new KCalExtendedSource(params, KCalExtendedSource::Event) :
|
||||||
#endif
|
#endif
|
||||||
isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isMe = sourceType.m_backend == "mkcal-todos";
|
||||||
|
maybeMe = sourceType.m_backend == "todo";
|
||||||
|
|
||||||
|
if (isMe || maybeMe) {
|
||||||
|
if (sourceType.m_format == "" ||
|
||||||
|
sourceType.m_format == "text/x-vcalendar" ||
|
||||||
|
sourceType.m_format == "text/x-calendar" ||
|
||||||
|
sourceType.m_format == "text/calendar") {
|
||||||
|
return
|
||||||
|
#ifdef ENABLE_KCALEXTENDED
|
||||||
|
true ? new KCalExtendedSource(params, KCalExtendedSource::Todo) :
|
||||||
|
#endif
|
||||||
|
isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isMe = sourceType.m_backend == "mkcal-notes";
|
||||||
|
maybeMe = sourceType.m_backend == "memo";
|
||||||
|
|
||||||
|
if (isMe || maybeMe) {
|
||||||
|
if (sourceType.m_format == "" ||
|
||||||
|
sourceType.m_format == "text/x-vcalendar" ||
|
||||||
|
sourceType.m_format == "text/x-calendar" ||
|
||||||
|
sourceType.m_format == "text/calendar") {
|
||||||
|
return
|
||||||
|
#ifdef ENABLE_KCALEXTENDED
|
||||||
|
true ? new KCalExtendedSource(params, KCalExtendedSource::Journal) :
|
||||||
|
#endif
|
||||||
|
isMe ? RegisterSyncSource::InactiveSource(params) : NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,16 +85,36 @@ static RegisterSyncSource registerMe("KCalExtended",
|
||||||
false,
|
false,
|
||||||
#endif
|
#endif
|
||||||
createSource,
|
createSource,
|
||||||
"mkcal = KCalExtended = calendar\n"
|
"mkcal-events = mkcal = KCalExtended = calendar\n"
|
||||||
" 'database' normally is the name of a calendar\n"
|
" 'database' normally is the name of a calendar\n"
|
||||||
" inside the default calendar storage. If it starts\n"
|
" inside the default calendar storage. If it starts\n"
|
||||||
" with the 'SyncEvolution_Test_' prefix, it will be\n"
|
" with the 'SyncEvolution_Test_' prefix, it will be\n"
|
||||||
" created as needed, otherwise it must exist.\n"
|
" created as needed, otherwise it must exist.\n"
|
||||||
|
#ifdef ENABLE_MAEMO
|
||||||
|
" If it starts with the 'uid:' prefix, the specified\n"
|
||||||
|
" calendar in the default SQLite storage file will\n"
|
||||||
|
" be used. It must exist.\n"
|
||||||
|
#endif
|
||||||
" If it starts with the 'file://' prefix, the default\n"
|
" If it starts with the 'file://' prefix, the default\n"
|
||||||
" calendar in the specified SQLite storage file will\n"
|
" calendar in the specified SQLite storage file will\n"
|
||||||
" created (if needed) and used.\n",
|
" created (if needed) and used.\n"
|
||||||
|
"mkcal-todos = todo\n"
|
||||||
|
" Same as above.\n"
|
||||||
|
"mkcal-notes = memo\n"
|
||||||
|
#ifdef ENABLE_MAEMO
|
||||||
|
" Same as above. Keep in mind that, by default, notes\n"
|
||||||
|
" are stored in their own database, separate from\n"
|
||||||
|
" events and todos. The name of this database is\n"
|
||||||
|
" hardcoded into the device's builtin Notes app.\n"
|
||||||
|
" Don't override the default unless you know what\n"
|
||||||
|
" you are doing.\n",
|
||||||
|
#else
|
||||||
|
" Same as above.\n",
|
||||||
|
#endif
|
||||||
Values() +
|
Values() +
|
||||||
(Aliases("mkcal") + "KCalExtended" + "MeeGo Calendar"));
|
(Aliases("mkcal-events") + "mkcal" + "KCalExtended" + "MeeGo Calendar") +
|
||||||
|
(Aliases("mkcal-todos") + "MeeGo Tasks") +
|
||||||
|
(Aliases("mkcal-notes") + "MeeGo Notes"));
|
||||||
|
|
||||||
#ifdef ENABLE_KCALEXTENDED
|
#ifdef ENABLE_KCALEXTENDED
|
||||||
#ifdef ENABLE_UNIT_TESTS
|
#ifdef ENABLE_UNIT_TESTS
|
||||||
|
|
|
@ -46,6 +46,26 @@ MaemoCalendarSource::MaemoCalendarSource(int EntryType, int EntryFormat,
|
||||||
TrackingSyncSource(params),
|
TrackingSyncSource(params),
|
||||||
entry_type(EntryType), entry_format(EntryFormat)
|
entry_type(EntryType), entry_format(EntryFormat)
|
||||||
{
|
{
|
||||||
|
switch (EntryType) {
|
||||||
|
case EVENT:
|
||||||
|
SyncSourceLogging::init(InitList<std::string>("SUMMARY") + "LOCATION",
|
||||||
|
", ",
|
||||||
|
m_operations);
|
||||||
|
break;
|
||||||
|
case TODO:
|
||||||
|
SyncSourceLogging::init(InitList<std::string>("SUMMARY"),
|
||||||
|
", ",
|
||||||
|
m_operations);
|
||||||
|
break;
|
||||||
|
case JOURNAL:
|
||||||
|
SyncSourceLogging::init(InitList<std::string>("SUBJECT"),
|
||||||
|
", ",
|
||||||
|
m_operations);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throwError("invalid calendar type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
mc = CMulticalendar::MCInstance();
|
mc = CMulticalendar::MCInstance();
|
||||||
cal = NULL;
|
cal = NULL;
|
||||||
if (!mc) {
|
if (!mc) {
|
||||||
|
@ -53,17 +73,19 @@ MaemoCalendarSource::MaemoCalendarSource(int EntryType, int EntryFormat,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *MaemoCalendarSource::getMimeType() const
|
std::string MaemoCalendarSource::getMimeType() const
|
||||||
{
|
{
|
||||||
switch (entry_format) {
|
switch (entry_format) {
|
||||||
case -1: return "text/plain";
|
case -1: return "text/plain";
|
||||||
case ICAL_TYPE: return "text/calendar";
|
case ICAL_TYPE: return entry_type == JOURNAL ?
|
||||||
|
"text/calendar+plain" :
|
||||||
|
"text/calendar";
|
||||||
case VCAL_TYPE: return "text/x-calendar";
|
case VCAL_TYPE: return "text/x-calendar";
|
||||||
default: return NULL;
|
default: return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *MaemoCalendarSource::getMimeVersion() const
|
std::string MaemoCalendarSource::getMimeVersion() const
|
||||||
{
|
{
|
||||||
switch (entry_format) {
|
switch (entry_format) {
|
||||||
case -1: return "1.0";
|
case -1: return "1.0";
|
||||||
|
@ -113,10 +135,13 @@ void MaemoCalendarSource::open()
|
||||||
|
|
||||||
bool MaemoCalendarSource::isEmpty()
|
bool MaemoCalendarSource::isEmpty()
|
||||||
{
|
{
|
||||||
// TODO: provide a real implementation. Always returning false
|
int id = cal->getCalendarId(), err;
|
||||||
// here disables the "allow slow sync when no local data" heuristic
|
switch (entry_type) {
|
||||||
// for preventSlowSync=1.
|
case EVENT: return !mc->getEventCount(id, err);
|
||||||
return false;
|
case TODO: return !mc->getTodoCount(id, err);
|
||||||
|
case JOURNAL: return !mc->getNoteCount(id, err);
|
||||||
|
default: return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaemoCalendarSource::close()
|
void MaemoCalendarSource::close()
|
||||||
|
@ -125,9 +150,6 @@ void MaemoCalendarSource::close()
|
||||||
conv = NULL;
|
conv = NULL;
|
||||||
delete cal;
|
delete cal;
|
||||||
cal = NULL;
|
cal = NULL;
|
||||||
// since timestamps are rounded down to nearest second,
|
|
||||||
// sleep until next second, just in case
|
|
||||||
sleep(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MaemoCalendarSource::Databases MaemoCalendarSource::getDatabases()
|
MaemoCalendarSource::Databases MaemoCalendarSource::getDatabases()
|
||||||
|
@ -159,7 +181,9 @@ void MaemoCalendarSource::listAllItems(RevisionMap_t &revisions)
|
||||||
#if 0 /* this code exposes a bug in calendar-backend, https://bugs.maemo.org/show_bug.cgi?id=8277 */
|
#if 0 /* this code exposes a bug in calendar-backend, https://bugs.maemo.org/show_bug.cgi?id=8277 */
|
||||||
// I've found no way to query the last modified time of a component
|
// I've found no way to query the last modified time of a component
|
||||||
// without getting the whole component.
|
// without getting the whole component.
|
||||||
// This limit should hopefully reduce memory usage of that a bit
|
// This limit should hopefully reduce memory usage of that a bit,
|
||||||
|
// though it could be bad if the database happens to change
|
||||||
|
// between getComponents() calls.
|
||||||
static const int limit = 1024;
|
static const int limit = 1024;
|
||||||
int ofs = 0, err;
|
int ofs = 0, err;
|
||||||
vector< CComponent * > comps;
|
vector< CComponent * > comps;
|
||||||
|
@ -180,14 +204,20 @@ void MaemoCalendarSource::listAllItems(RevisionMap_t &revisions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// this avoids the calendar-backend bug, but may use unlimited memory;
|
// Instead, get a full list of IDs from getIdList(), then
|
||||||
// hopefully the users aren't saving their entire life here!
|
// load each entry from the calendar one by one. The
|
||||||
|
// alternative would be to load the whole calendar into
|
||||||
|
// memory all at once, but that's probably not all that
|
||||||
|
// desirable, given the N900's limited memory.
|
||||||
int err;
|
int err;
|
||||||
vector< CComponent * > comps;
|
vector< string > ids = cal->getIdList(entry_type, err);
|
||||||
|
BOOST_FOREACH(std::string& id, ids) {
|
||||||
comps = cal->getComponents(entry_type, -1, -1, err);
|
CComponent *c = cal->getEntry(id, entry_type, err);
|
||||||
BOOST_FOREACH(CComponent * c, comps) {
|
if (!c)
|
||||||
revisions[c->getId()] = get_revision(c);
|
{
|
||||||
|
throwError(string("retrieving item: ") + id);
|
||||||
|
}
|
||||||
|
revisions[id] = get_revision(c);
|
||||||
delete c;
|
delete c;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -201,7 +231,7 @@ void MaemoCalendarSource::readItem(const string &uid, std::string &item, bool ra
|
||||||
throwError(string("retrieving item: ") + uid);
|
throwError(string("retrieving item: ") + uid);
|
||||||
}
|
}
|
||||||
if (entry_format == -1) {
|
if (entry_format == -1) {
|
||||||
item = c->getDescription();
|
item = c->getSummary();
|
||||||
err = CALENDAR_OPERATION_SUCCESSFUL;
|
err = CALENDAR_OPERATION_SUCCESSFUL;
|
||||||
} else {
|
} else {
|
||||||
item = conv->localToIcalVcal(c, FileType(entry_format), err);
|
item = conv->localToIcalVcal(c, FileType(entry_format), err);
|
||||||
|
@ -216,7 +246,8 @@ TrackingSyncSource::InsertItemResult MaemoCalendarSource::insertItem(const strin
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
CComponent *c;
|
CComponent *c;
|
||||||
bool r, u = false;
|
bool r;
|
||||||
|
InsertItemResultState u = ITEM_OKAY;
|
||||||
TrackingSyncSource::InsertItemResult result;
|
TrackingSyncSource::InsertItemResult result;
|
||||||
|
|
||||||
if (cal->getCalendarType() == BIRTHDAY_CALENDAR) {
|
if (cal->getCalendarType() == BIRTHDAY_CALENDAR) {
|
||||||
|
@ -275,7 +306,7 @@ TrackingSyncSource::InsertItemResult MaemoCalendarSource::insertItem(const strin
|
||||||
throwError(string("creating item "));
|
throwError(string("creating item "));
|
||||||
}
|
}
|
||||||
if (err == CALENDAR_ENTRY_DUPLICATED) {
|
if (err == CALENDAR_ENTRY_DUPLICATED) {
|
||||||
u = true;
|
u = ITEM_REPLACED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,6 +319,12 @@ TrackingSyncSource::InsertItemResult MaemoCalendarSource::insertItem(const strin
|
||||||
void MaemoCalendarSource::removeItem(const string &uid)
|
void MaemoCalendarSource::removeItem(const string &uid)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (cal->getCalendarType() == BIRTHDAY_CALENDAR) {
|
||||||
|
// stubbornly refuse to try this
|
||||||
|
throwError(string("can't sync smart calendar ") + cal->getCalendarName());
|
||||||
|
}
|
||||||
|
|
||||||
cal->deleteComponent(uid, err);
|
cal->deleteComponent(uid, err);
|
||||||
if (err != CALENDAR_OPERATION_SUCCESSFUL) {
|
if (err != CALENDAR_OPERATION_SUCCESSFUL) {
|
||||||
throwError(string("deleting item: ") + uid);
|
throwError(string("deleting item: ") + uid);
|
||||||
|
@ -304,6 +341,31 @@ string MaemoCalendarSource::get_revision(CComponent * c)
|
||||||
return revision.str();
|
return revision.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string MaemoCalendarSource::getDescription(const string &uid)
|
||||||
|
{
|
||||||
|
string ret;
|
||||||
|
int err;
|
||||||
|
CComponent * c = cal->getEntry(uid, entry_type, err);
|
||||||
|
if (c) {
|
||||||
|
list<string> parts;
|
||||||
|
string str;
|
||||||
|
str = c->getSummary();
|
||||||
|
if (!str.empty()) {
|
||||||
|
parts.push_back(str);
|
||||||
|
}
|
||||||
|
if (entry_type == EVENT)
|
||||||
|
{
|
||||||
|
str = c->getLocation();
|
||||||
|
if (!str.empty()) {
|
||||||
|
parts.push_back(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = boost::join(parts, ", ");
|
||||||
|
delete c;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
SE_END_CXX
|
SE_END_CXX
|
||||||
|
|
||||||
#endif /* ENABLE_MAEMO_CALENDAR */
|
#endif /* ENABLE_MAEMO_CALENDAR */
|
||||||
|
|
|
@ -35,13 +35,13 @@ SE_BEGIN_CXX
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implement access to Maemo calendar.
|
* Implement access to Maemo calendar.
|
||||||
* Change tracking is done by using the last-modified time.
|
* Change tracking is done by using the last-modified time
|
||||||
* It might be possible to improve on it by taking the last sync time
|
* as TrackingSyncSource revisions. While it might be possible
|
||||||
* and calling the getAllAdded/Modified/Deleted(...) methods provided by
|
* to improve performance by using the getAllAdded/Modified
|
||||||
* the CCalendar class, instead of comparing every single record in
|
* etc methods, it would make the change tracking less robust,
|
||||||
* the database like TrackingSyncSource probably needs to do otherwise.
|
* so it doesn't seem worth it.
|
||||||
*/
|
*/
|
||||||
class MaemoCalendarSource : public TrackingSyncSource, private boost::noncopyable
|
class MaemoCalendarSource : public TrackingSyncSource, public SyncSourceLogging, private boost::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MaemoCalendarSource(int EntryType, int EntryFormat,
|
MaemoCalendarSource(int EntryType, int EntryFormat,
|
||||||
|
@ -54,8 +54,8 @@ class MaemoCalendarSource : public TrackingSyncSource, private boost::noncopyabl
|
||||||
virtual bool isEmpty();
|
virtual bool isEmpty();
|
||||||
virtual void close();
|
virtual void close();
|
||||||
virtual Databases getDatabases();
|
virtual Databases getDatabases();
|
||||||
virtual const char *getMimeType() const;
|
virtual std::string getMimeType() const;
|
||||||
virtual const char *getMimeVersion() const;
|
virtual std::string getMimeVersion() const;
|
||||||
virtual void getSynthesisInfo(SynthesisInfo &info,
|
virtual void getSynthesisInfo(SynthesisInfo &info,
|
||||||
XMLConfigFragments &fragments);
|
XMLConfigFragments &fragments);
|
||||||
|
|
||||||
|
@ -63,8 +63,11 @@ class MaemoCalendarSource : public TrackingSyncSource, private boost::noncopyabl
|
||||||
virtual void listAllItems(RevisionMap_t &revisions);
|
virtual void listAllItems(RevisionMap_t &revisions);
|
||||||
virtual InsertItemResult insertItem(const string &luid, const std::string &item, bool raw);
|
virtual InsertItemResult insertItem(const string &luid, const std::string &item, bool raw);
|
||||||
void readItem(const std::string &luid, std::string &item, bool raw);
|
void readItem(const std::string &luid, std::string &item, bool raw);
|
||||||
virtual void removeItem(const string &uid);
|
virtual void removeItem(const string &luid);
|
||||||
|
|
||||||
|
/* implementation of SyncSourceLogging interface */
|
||||||
|
virtual std::string getDescription(const string &luid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CMulticalendar *mc; /**< multicalendar */
|
CMulticalendar *mc; /**< multicalendar */
|
||||||
CCalendar *cal; /**< calendar */
|
CCalendar *cal; /**< calendar */
|
||||||
|
|
|
@ -68,12 +68,12 @@ static SyncSource *createSource(const SyncSourceParams ¶ms)
|
||||||
maybeMe = sourceType.m_backend == "memo";
|
maybeMe = sourceType.m_backend == "memo";
|
||||||
|
|
||||||
if (isMe || maybeMe) {
|
if (isMe || maybeMe) {
|
||||||
if (sourceType.m_format == "" || sourceType.m_format == "text/plain") {
|
if (sourceType.m_format == "" || sourceType.m_format == "text/calendar") {
|
||||||
return new MaemoCalendarSource(JOURNAL, -1, params);
|
|
||||||
} else if (sourceType.m_format == "text/calendar") {
|
|
||||||
return new MaemoCalendarSource(JOURNAL, ICAL_TYPE, params);
|
return new MaemoCalendarSource(JOURNAL, ICAL_TYPE, params);
|
||||||
} else if (sourceType.m_format == "text/x-vcalendar") {
|
} else if (sourceType.m_format == "text/x-vcalendar") {
|
||||||
return new MaemoCalendarSource(JOURNAL, VCAL_TYPE, params);
|
return new MaemoCalendarSource(JOURNAL, VCAL_TYPE, params);
|
||||||
|
} else if (sourceType.m_format == "text/plain") {
|
||||||
|
return new MaemoCalendarSource(JOURNAL, -1, params);
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,8 @@
|
||||||
#include <QContactLocalIdFilter>
|
#include <QContactLocalIdFilter>
|
||||||
#include <QContactThumbnail>
|
#include <QContactThumbnail>
|
||||||
#include <QContactAvatar>
|
#include <QContactAvatar>
|
||||||
|
#include <QContactSyncTarget>
|
||||||
|
#include <QContactDetailFilter>
|
||||||
|
|
||||||
#include <QVersitContactExporter>
|
#include <QVersitContactExporter>
|
||||||
#include <QVersitContactImporter>
|
#include <QVersitContactImporter>
|
||||||
|
@ -422,17 +424,42 @@ QtContactsSource::Databases QtContactsSource::getDatabases()
|
||||||
{
|
{
|
||||||
Databases result;
|
Databases result;
|
||||||
QStringList availableManagers = QContactManager::availableManagers();
|
QStringList availableManagers = QContactManager::availableManagers();
|
||||||
|
bool isDefault = true;
|
||||||
|
|
||||||
|
#if 0
|
||||||
result.push_back(Database("select database via QtContacts Manager URL",
|
result.push_back(Database("select database via QtContacts Manager URL",
|
||||||
"qtcontacts:tracker:"));
|
"qtcontacts:tracker:"));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
foreach (QString manager, availableManagers) {
|
||||||
|
QMap<QString, QString> params;
|
||||||
|
QString uri = QContactManager::buildUri(manager, params);
|
||||||
|
result.push_back(Database(manager.toStdString(),
|
||||||
|
uri.toStdString(),
|
||||||
|
isDefault));
|
||||||
|
isDefault = false;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtContactsSource::listAllItems(RevisionMap_t &revisions)
|
void QtContactsSource::listAllItems(RevisionMap_t &revisions)
|
||||||
{
|
{
|
||||||
|
#ifdef ENABLE_MAEMO
|
||||||
|
QContactLocalId self_id = m_data->m_manager->selfContactId();
|
||||||
|
#endif
|
||||||
|
|
||||||
QContactFetchRequest fetch;
|
QContactFetchRequest fetch;
|
||||||
fetch.setManager(m_data->m_manager.get());
|
fetch.setManager(m_data->m_manager.get());
|
||||||
|
|
||||||
|
#ifdef ENABLE_MAEMO
|
||||||
|
// only sync contacts from addressbook, not from Telepathy or wherever
|
||||||
|
QContactDetailFilter filter;
|
||||||
|
filter.setDetailDefinitionName(QContactSyncTarget::DefinitionName, QContactSyncTarget::FieldSyncTarget);
|
||||||
|
filter.setValue("addressbook");
|
||||||
|
filter.setMatchFlags(QContactFilter::MatchExactly);
|
||||||
|
fetch.setFilter(filter);
|
||||||
|
#endif
|
||||||
|
|
||||||
// only need ID and time stamps
|
// only need ID and time stamps
|
||||||
QContactFetchHint hint;
|
QContactFetchHint hint;
|
||||||
hint.setOptimizationHints(QContactFetchHint::OptimizationHints(QContactFetchHint::NoRelationships|QContactFetchHint::NoBinaryBlobs));
|
hint.setOptimizationHints(QContactFetchHint::OptimizationHints(QContactFetchHint::NoRelationships|QContactFetchHint::NoBinaryBlobs));
|
||||||
|
@ -443,6 +470,13 @@ void QtContactsSource::listAllItems(RevisionMap_t &revisions)
|
||||||
fetch.waitForFinished();
|
fetch.waitForFinished();
|
||||||
m_data->checkError("read all items", fetch);
|
m_data->checkError("read all items", fetch);
|
||||||
foreach (const QContact &contact, fetch.contacts()) {
|
foreach (const QContact &contact, fetch.contacts()) {
|
||||||
|
#ifdef ENABLE_MAEMO
|
||||||
|
if (contact.localId() == self_id) {
|
||||||
|
// Do not synchronize "self" contact
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
string revision = QtContactsData::getRev(contact);
|
string revision = QtContactsData::getRev(contact);
|
||||||
string luid = QtContactsData::getLUID(contact);
|
string luid = QtContactsData::getLUID(contact);
|
||||||
if (luid == "2147483647" &&
|
if (luid == "2147483647" &&
|
||||||
|
@ -478,6 +512,10 @@ void QtContactsSource::readItem(const string &uid, std::string &item, bool raw)
|
||||||
thumbnail.setThumbnail(image);
|
thumbnail.setThumbnail(image);
|
||||||
contact.saveDetail(&thumbnail);
|
contact.saveDetail(&thumbnail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// foreach (const QContactSyncTarget &target, contact.details<QContactSyncTarget>()) {
|
||||||
|
// std::cout << " Sync Target: " << target.syncTarget().toUtf8().data() << std::endl;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList profiles;
|
QStringList profiles;
|
||||||
|
@ -559,7 +597,7 @@ TrackingSyncSource::InsertItemResult QtContactsSource::insertItem(const string &
|
||||||
|
|
||||||
return InsertItemResult(QtContactsData::getLUID(savedContact),
|
return InsertItemResult(QtContactsData::getLUID(savedContact),
|
||||||
QtContactsData::getRev(finalContact),
|
QtContactsData::getRev(finalContact),
|
||||||
false);
|
ITEM_OKAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#! /bin/bash
|
#! /bin/sh
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011 Intel Corporation
|
# Copyright (C) 2011 Intel Corporation
|
||||||
#
|
#
|
||||||
|
@ -49,7 +49,7 @@ trap "[ -s $LOG ] && ( echo $0 failed to find '$TYPE $DOMAIN':; cat $LOG >&2 );
|
||||||
|
|
||||||
# find one of the supported tools for DNS queries
|
# find one of the supported tools for DNS queries
|
||||||
TOOL=
|
TOOL=
|
||||||
ALTERNATIVES="adnshost host nslookup"
|
ALTERNATIVES="adnshost host /usr/lib/syncevolution/host nslookup"
|
||||||
for i in $ALTERNATIVES; do
|
for i in $ALTERNATIVES; do
|
||||||
if which $i >/dev/null; then
|
if which $i >/dev/null; then
|
||||||
TOOL=$i
|
TOOL=$i
|
||||||
|
@ -89,11 +89,12 @@ for type in ${TYPE}s ${TYPE}; do
|
||||||
PORT=`echo $res | sed -e 's;.*service = [^ ]* [^ ]* \([^ ]*\) \([^ ]*\)\.;\1;'`
|
PORT=`echo $res | sed -e 's;.*service = [^ ]* [^ ]* \([^ ]*\) \([^ ]*\)\.;\1;'`
|
||||||
HOSTNAME=`echo $res | sed -e 's;.*service = [^ ]* [^ ]* \([^ ]*\) \([^ ]*\)\.;\2;'`
|
HOSTNAME=`echo $res | sed -e 's;.*service = [^ ]* [^ ]* \([^ ]*\) \([^ ]*\)\.;\2;'`
|
||||||
;;
|
;;
|
||||||
host)
|
host|*/host)
|
||||||
res=`$TOOL -t srv _$type._tcp.$DOMAIN | tee -a $LOG | grep "has SRV record" | head -1`
|
res=`$TOOL -t srv _$type._tcp.$DOMAIN | tee -a $LOG | grep "\<SRV\>" | head -1`
|
||||||
# _caldavs._tcp.yahoo.com has SRV record 1 1 443 caldav.calendar.yahoo.com.
|
# _caldavs._tcp.yahoo.com has SRV record 1 1 443 caldav.calendar.yahoo.com.
|
||||||
PORT=`echo $res | sed -e 's;.* \([^ ]*\) \([^ ]*\)\.;\1;'`
|
# _caldavs._tcp.yahoo.com SRV 1 1 443 caldav.calendar.yahoo.com
|
||||||
HOSTNAME=`echo $res | sed -e 's;.* \([^ ]*\) \([^ ]*\)\.;\2;'`
|
PORT=`echo $res | sed -e 's;.* \([^ ]*\) \([^. ]\+\(\.[^. ]\+\)*\)\.\?;\1;'`
|
||||||
|
HOSTNAME=`echo $res | sed -e 's;.* \([^ ]*\) \([^. ]\+\(\.[^. ]\+\)*\)\.\?;\2;'`
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "unsupported tool $TOOL"
|
echo "unsupported tool $TOOL"
|
||||||
|
|
|
@ -18,7 +18,7 @@ CLEANFILES += src/backends/webdav/syncevo-webdav-lookup
|
||||||
|
|
||||||
src/backends/webdav/syncevo-webdav-lookup: $(srcdir)/src/backends/webdav/syncevo-webdav-lookup.sh
|
src/backends/webdav/syncevo-webdav-lookup: $(srcdir)/src/backends/webdav/syncevo-webdav-lookup.sh
|
||||||
$(AM_V_GEN)rm -f $@ ; \
|
$(AM_V_GEN)rm -f $@ ; \
|
||||||
ln -s $< $@
|
cd src/backends/webdav && ln -s $(notdir $<) $(notdir $@)
|
||||||
|
|
||||||
src_backends_webdav_src = \
|
src_backends_webdav_src = \
|
||||||
src/backends/webdav/CalDAVSource.h \
|
src/backends/webdav/CalDAVSource.h \
|
||||||
|
|
|
@ -39,6 +39,9 @@ CurlTransportAgent::CurlTransportAgent() :
|
||||||
m_replyLen(0),
|
m_replyLen(0),
|
||||||
m_replySize(0)
|
m_replySize(0)
|
||||||
{
|
{
|
||||||
|
#ifdef ENABLE_MAEMO /* hack because Maemo doesn't support IPv6 yet */
|
||||||
|
curl_easy_setopt(m_easyHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* set up for post where message is pushed into curl via
|
* set up for post where message is pushed into curl via
|
||||||
* its read callback and reply is stored in write callback
|
* its read callback and reply is stored in write callback
|
||||||
|
|
|
@ -873,7 +873,7 @@ public:
|
||||||
// for a password. However, that does not cover failures
|
// for a password. However, that does not cover failures
|
||||||
// like the parent not asking us to sync in the first place
|
// like the parent not asking us to sync in the first place
|
||||||
// and also does not work with libdbus (https://bugs.freedesktop.org/show_bug.cgi?id=49728).
|
// and also does not work with libdbus (https://bugs.freedesktop.org/show_bug.cgi?id=49728).
|
||||||
m_forkexec->m_onQuit.connect(onParentQuit);
|
m_forkexec->m_onQuit.connect(&onParentQuit);
|
||||||
|
|
||||||
m_forkexec->connect();
|
m_forkexec->connect();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2815,6 +2815,9 @@ void SyncContext::initEngine(bool logXML)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is just the declaration. The actual function pointer instance
|
||||||
|
// is inside libsynthesis, which, for historic purposes, doesn't define
|
||||||
|
// it in its header files (yet).
|
||||||
extern "C" int (*SySync_ConsolePrintf)(FILE *stream, const char *format, ...);
|
extern "C" int (*SySync_ConsolePrintf)(FILE *stream, const char *format, ...);
|
||||||
|
|
||||||
static int nopPrintf(FILE *stream, const char *format, ...) { return 0; }
|
static int nopPrintf(FILE *stream, const char *format, ...) { return 0; }
|
||||||
|
|
|
@ -55,7 +55,9 @@
|
||||||
#if defined(USE_EDS_CLIENT)
|
#if defined(USE_EDS_CLIENT)
|
||||||
#include <libedataserver/libedataserver.h>
|
#include <libedataserver/libedataserver.h>
|
||||||
#else
|
#else
|
||||||
|
#ifdef HAVE_LIBEDATASERVER_EDS_VERSION_H
|
||||||
#include <libedataserver/eds-version.h>
|
#include <libedataserver/eds-version.h>
|
||||||
|
#endif
|
||||||
#include <libedataserver/e-source.h>
|
#include <libedataserver/e-source.h>
|
||||||
#include <libedataserver/e-source-list.h>
|
#include <libedataserver/e-source-list.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1758,6 +1758,24 @@ void LocalTests::testLinkedItemsParentChild() {
|
||||||
CT_ASSERT_MESSAGE(exdate + " not found in:\n" + parentDataEngine, pos != parentDataEngine.npos);
|
CT_ASSERT_MESSAGE(exdate + " not found in:\n" + parentDataEngine, pos != parentDataEngine.npos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.m_supportsReccurenceEXDates) {
|
||||||
|
TestingSyncSourcePtr source;
|
||||||
|
SOURCE_ASSERT_NO_FAILURE(source.get(), source.reset(createSourceA()));
|
||||||
|
CLIENT_TEST_LOG("retrieve parent as reported to the Synthesis engine, check for X-SYNCEVOLUTION-EXDATE-DETACHED");
|
||||||
|
std::string parentDataEngine;
|
||||||
|
CT_ASSERT_NO_THROW(source->readItem(parent, parentDataEngine));
|
||||||
|
size_t pos = childData.find("RECURRENCE-ID");
|
||||||
|
CT_ASSERT(pos != childData.npos);
|
||||||
|
size_t end = childData.find_first_of("\r\n", pos);
|
||||||
|
CT_ASSERT(end != childData.npos);
|
||||||
|
std::string exdate = childData.substr(pos, end - pos);
|
||||||
|
boost::replace_first(exdate, "RECURRENCE-ID", "X-SYNCEVOLUTION-EXDATE-DETACHED");
|
||||||
|
// not generated because not needed by Synthesis engine
|
||||||
|
boost::replace_first(exdate, ";VALUE=DATE", "");
|
||||||
|
pos = parentDataEngine.find(exdate);
|
||||||
|
CT_ASSERT_MESSAGE(exdate + " not found in:\n" + parentDataEngine, pos != parentDataEngine.npos);
|
||||||
|
}
|
||||||
|
|
||||||
if (getenv("CLIENT_TEST_LINKED_ITEMS_NO_DELETE")) {
|
if (getenv("CLIENT_TEST_LINKED_ITEMS_NO_DELETE")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue