bool NotebookSyncAgent::discardRemoteChanges(KCalCore::Incidence::List *localInserted, KCalCore::Incidence::List *localModified, KCalCore::Incidence::List *localDeleted) { NOTEBOOK_FUNCTION_CALL_TRACE; // Go through the local inserted, modified and deletions list and: // - Discard from them respectively the additions, modifications and deletions that were // created as a result of the last remote sync. // - Discard any incidences that have already been deleted on the server. (These will be // deleted locally when the current sync finishes.) // - Discard any local modifications that were modified on the server, as the server // modifications take precedence. if (!mNotebook) { LOG_CRITICAL("no notebook"); return false; } bool ok = false; QSet<QString> remoteDeletedIncidences = QSet<QString>::fromList(mIncidenceUidsToDelete); QStringList additions = mDatabase->additions(mNotebook->uid(), &ok); if (!ok) { LOG_CRITICAL("Unable to look up last sync additions for notebook:" << mNotebook->uid()); return false; } QHash<QString,QString> modifications = mDatabase->modifications(mNotebook->uid(), &ok); if (!ok) { LOG_CRITICAL("Unable to look up last sync modifications for notebook:" << mNotebook->uid()); return false; } for (KCalCore::Incidence::List::iterator it = localInserted->begin(); it != localInserted->end();) { const KCalCore::Incidence::Ptr &incidence = *it; const QString &uid = incidence->uid(); if (remoteDeletedIncidences.contains(uid)) { LOG_DEBUG("Discarding addition deleted on server:" << uid); it = localInserted->erase(it); } else if (additions.indexOf(uid) >= 0) { if (incidence->lastModified().isValid() && incidence->lastModified() > incidence->created()) { // This incidence has been modified since it was added from the server in the last sync, // so it's a modification rather than an addition. LOG_DEBUG("Moving to modified:" << uid); KCalCore::Incidence::Ptr savedIncidence = fetchIncidence(mCalendar, uid); if (savedIncidence) { localModified->append(savedIncidence); it = localInserted->erase(it); } else { ++it; } } else { LOG_DEBUG("Discarding addition from previous sync:" << uid); it = localInserted->erase(it); } } else { ++it; } } QSet<QString> serverModifiedUids; for (int i=0; i<mReceivedCalendarResources.count(); i++) { serverModifiedUids.insert(Reader::hrefToUid(mReceivedCalendarResources[i].href)); } for (KCalCore::Incidence::List::iterator it = localModified->begin(); it != localModified->end();) { KCalCore::Incidence::Ptr sourceIncidence = *it; const QString &uid = sourceIncidence->uid(); if (remoteDeletedIncidences.contains(uid) || serverModifiedUids.contains(uid)) { LOG_DEBUG("Discarding modification," << (remoteDeletedIncidences.contains(uid) ? "was already deleted on server" : "") << (serverModifiedUids.contains(uid) ? "was already modified on server": "")); it = localModified->erase(it); continue; } else if (modifications.contains(uid)) { KCalCore::ICalFormat iCalFormat; KCalCore::Incidence::Ptr receivedIncidence = iCalFormat.fromString(modifications[uid]); if (receivedIncidence.isNull()) { LOG_WARNING("Not sending modification, cannot parse the received incidence:" << modifications[uid]); it = localModified->erase(it); continue; } // If incidences are the same, then we assume the local incidence was not changed after // the remote incidence was received, and thus there are no modifications to report. IncidenceHandler::prepareImportedIncidence(receivedIncidence); // ensure fields are updated as per imported incidences if (IncidenceHandler::copiedPropertiesAreEqual(sourceIncidence, receivedIncidence)) { LOG_DEBUG("Discarding modification" << uid); it = localModified->erase(it); continue; } } // The default storage implementation applies the organizer as an attendee by default. Don't do this // as it turns the incidence into a scheduled event requiring acceptance/rejection/etc. const KCalCore::Person::Ptr organizer = sourceIncidence->organizer(); if (organizer) { Q_FOREACH (const KCalCore::Attendee::Ptr &attendee, sourceIncidence->attendees()) { if (attendee->email() == organizer->email() && attendee->fullName() == organizer->fullName()) { LOG_DEBUG("Discarding organizer as attendee" << attendee->fullName()); sourceIncidence->deleteAttendee(attendee); break; } } } ++it; } QStringList deletions = mDatabase->deletions(mNotebook->uid(), &ok); if (!ok) { LOG_CRITICAL("Unable to look up last sync deletions for notebook:" << mNotebook->uid()); return false; } for (KCalCore::Incidence::List::iterator it = localDeleted->begin(); it != localDeleted->end();) { const QString &uid = (*it)->uid(); mLocalDeletedUids.insert(uid); if (remoteDeletedIncidences.contains(uid) || deletions.indexOf(uid) >= 0) { LOG_DEBUG("Discarding deletion" << uid); it = localDeleted->erase(it); } else { ++it; } } return true; }
QString timetrackerstorage::load(TaskView* view, const QString &fileName) // loads data from filename into view. If no filename is given, filename from preferences is used. // filename might be of use if this program is run as embedded konqueror plugin. { Q_UNUSED(fileName); // TODO: receive changes from akonadi kDebug(5970) << "Entering function"; QString err; KEMailSettings settings; // If file doesn't exist, create a blank one to avoid ResourceLocal load // error. We make it user and group read/write, others read. This is // masked by the users umask. (See man creat) if ( d->mCalendar ) closeStorage(); // Create local file resource and add to resources d->mICalFile = ""; d->mCalendar = KTTCalendar::createInstance(); QObject::connect( d->mCalendar.data(), SIGNAL(calendarChanged()), view, SLOT(iCalFileModified()) ); d->mCalendar->setTimeSpec( KSystemTimeZones::local() ); d->mCalendar->reload(); // Claim ownership of iCalendar file if no one else has. KCalCore::Person::Ptr owner = d->mCalendar->owner(); if ( owner && owner->isEmpty() ) { // TODO d->mCalendar->setOwner( KCalCore::Person::Ptr( new KCalCore::Person( settings.getSetting( KEMailSettings::RealName ), settings.getSetting( KEMailSettings::EmailAddress ) ) ) ); } // TODO // Build task view from iCal data if (!err.isEmpty()) { KCalCore::Todo::List todoList; KCalCore::Todo::List::ConstIterator todo; QMultiHash< QString, Task* > map; // Build dictionary to look up Task object from Todo uid. Each task is a // QListViewItem, and is initially added with the view as the parent. todoList = d->mCalendar->rawTodos(); kDebug(5970) << "timetrackerstorage::load" << "rawTodo count (includes completed todos) =" << todoList.count(); for (todo = todoList.constBegin(); todo != todoList.constEnd(); ++todo) { Task* task = new Task(*todo, view); map.insert( (*todo)->uid(), task ); view->setRootIsDecorated(true); task->setPixmapProgress(); } // Load each task under it's parent task. for (todo = todoList.constBegin(); todo != todoList.constEnd(); ++todo) { Task* task = map.value( (*todo)->uid() ); // No relatedTo incident just means this is a top-level task. if ( !(*todo)->relatedTo().isEmpty() ) { Task *newParent = map.value( (*todo)->relatedTo() ); // Complete the loading but return a message if ( !newParent ) err = i18n("Error loading \"%1\": could not find parent (uid=%2)", task->name(), (*todo)->relatedTo() ); if (!err.isEmpty()) task->move( newParent ); } } kDebug(5970) << "timetrackerstorage::load - loaded" << view->count() << "tasks from" << d->mICalFile; } if ( view ) buildTaskView(d->mCalendar->weakPointer(), view); this->save(view); // FIXME ? return err; }
<< attendee->d->mCustomProperties; } QDataStream &KCalCore::operator>>( QDataStream &stream, KCalCore::Attendee::Ptr &attendee ) { bool RSVP; Attendee::Role role; Attendee::PartStat status; QString uid; QString delegate; QString delegator; CustomProperties customProperties; uint role_int; uint status_int; KCalCore::Person::Ptr person( new Person() ); stream >> person; stream >> RSVP >> role_int >> status_int >> uid >> delegate >> delegator >> customProperties; role = Attendee::Role( role_int ); status = Attendee::PartStat( status_int ); Attendee::Ptr att_temp( new KCalCore::Attendee( person->name(), person->email(), RSVP, status, role, uid ) ); att_temp->setDelegate( delegate );