engine: tell peers about detached recurrence exceptions

The Maemo 5 calendar backend does not support UID/RECURRENCE-ID
semantic. This is problematic in combination with peers which rely on
that to override the main recurring event on specific recurrences,
because the Maemo 5 calendar will show duplicates.

Fixing this inside the calendar backend is hard because it doesn't get
to see all related events at once. The engine has the same
problem. Therefore a workaround is used:
- backends which have that unified access to all related events
  add special X-SYNCEVOLUTION-EXDATE-DETACHED properties to the
  main event which correspond to the exceptions represented by
  detached recurrences, in addition to the regular EXDATE; the
  backend must set the HAVE-SYNCEVOLUTION-EXDATE-DETACHED rule when
  using PARSETEXTWITHPROFILE()
- the engine parses the special property (only if the
  HAVE-SYNCEVOLUTION-EXDATE-DETACHED rule is active!) and stores
  the values in the EXDATES_DETACHED field
- this gets passed between SyncEvolution instances in a local
  or SyncML sync
- another SyncEvolution backend can request to get either
  X-SYNCEVOLUTION-EXDATE-DETACHED or regular EXDATE properties
  by setting the HAVE-[SYNCEVOLUTION-]EXDATE-DETACHED rules

The Maemo 5 backend needs to set HAVE-EXDATE-DETACHED. This means that
importing events will add additional EXDATEs which will be sent back
when updating events inside the calendar app, but that is okay. They
are merely redundant.
This commit is contained in:
Patrick Ohly 2011-10-18 09:40:58 +02:00
parent 33bbf5df57
commit fe1f5b6aac
6 changed files with 48 additions and 0 deletions

View File

@ -184,6 +184,12 @@ class SubSyncSource : virtual public SyncSourceBase
*/
virtual std::string getSubDescription(const string &mainid, const string &subid) = 0;
/**
* Called after MapSyncSource already populated the info structure.
*/
virtual void updateSynthesisInfo(SynthesisInfo &info,
XMLConfigFragments &fragments) {}
private:
MapSyncSource *m_parent;
};
@ -273,6 +279,13 @@ class MapSyncSource :
/* TestingSyncSource */
virtual void removeAllItems();
protected:
virtual void getSynthesisInfo(SynthesisInfo &info,
XMLConfigFragments &fragments) {
TestingSyncSource::getSynthesisInfo(info, fragments);
m_sub->updateSynthesisInfo(info, fragments);
}
private:
boost::shared_ptr<SubSyncSource> m_sub;
/** escape / in uid with %2F, so that splitMainIDValue() and splitLUID() can use / as separator */

View File

@ -56,6 +56,20 @@
<!-- for events -->
<field name="EXDATES" array="yes" type="timestamp" compare="never"/>
<!-- EXDATEs for detached recurrences: meant to be used for the
RECURRENCE-IDs of all detached recurrences.
Can be ignored when dealing with only iCalendar 2.0 aware
peers, because these EXDATEs are implied for detached
recurrences and don't have to be specified explicitly. Can
be used to create additional EXDATEs for non-iCalendar 2.0
peers. For that, EXDATES_DETACHED must be populated by the
backend creating the parent event, because the engine
itself doesn't have the necessary
information. X-SYNCEVOLUTION-EXDATE-DETACHED can be used
for that in serialized calendar events. -->
<field name="EXDATES_DETACHED" array="yes" type="timestamp" compare="never"/>
<field name="ORIGSTART" array="no" type="timestamp" compare="never"/>
<field name="SEQNO" array="no" type="integer" compare="never"/>

View File

@ -394,6 +394,23 @@
<position field="EXDATES" repeat="array" increment="1" minshow="0"/>
</property>
<!-- parse X-SYNCEVOLUTION-EXDATE-DETACHED, but never encode it like this except internally -->
<property name="X-SYNCEVOLUTION-EXDATE-DETACHED" delayedparsing="1" mandatory="no"
show="no" rule="HAVE-SYNCEVOLUTION-EXDATE-DETACHED">
<value field="EXDATES_DETACHED"/>
<parameter name="TZID" default="no" show="yes">
<value field="EXDATES_DETACHED" conversion="TZID"/>
</parameter>
<position field="EXDATES_DETACHED" repeat="array" increment="1" minshow="0"/>
</property>
<!-- encode as normal EXDATE when backend asks for it -->
<property name="EXDATE" show="no" rule="HAVE-EXDATE-DETACHED" mandatory="no">
<value field="EXDATES_DETACHED"/>
<parameter name="TZID" default="no" show="yes">
<value field="EXDATES_DETACHED" conversion="TZID"/>
</parameter>
<position field="EXDATES_DETACHED" repeat="array" increment="1" minshow="0"/>
</property>
<property name="DTEND" suppressempty="yes" delayedparsing="1">
<value field="DTEND" conversion="autoenddate"/>

View File

@ -0,0 +1 @@
<subrule name="HAVE-EXDATE-DETACHED"/>

View File

@ -0,0 +1 @@
<subrule name="HAVE-SYNCEVOLUTION-EXDATE-DETACHED"/>

View File

@ -2,6 +2,8 @@
<manufacturer>Patrick Ohly</manufacturer>
<model>SyncEvolution</model>
<include rule="HAVE-SYNCEVOLUTION-EXDATE-DETACHED"/>
<include rule="HAVE-EVOLUTION-UI-SLOT"/>
<!-- Merging between SyncEvolution instances is expected to work
well, so allow the engine to update items on both