Bug 327890: Serialize exceptions to ics calendars. patch by michael.buettner@sun.com and daniel.boelzle@sun.com. r=mvl

This commit is contained in:
mvl%exedo.nl 2006-02-24 20:42:56 +00:00
parent 35d9b7048a
commit e7d07d5d0e
6 changed files with 72 additions and 13 deletions

View File

@ -119,6 +119,12 @@ interface calIIcalComponent : nsISupports
attribute calIDateTime completedTime;
attribute calIDateTime lastModified;
/**
* The recurrence ID, a.k.a. DTSTART-of-calculated-occurrence,
* or null if this isn't an occurrence.
*/
attribute calIDateTime recurrenceId;
AUTF8String serializeToICS();
/**

View File

@ -263,6 +263,8 @@ interface calIItemBase : nsISupports
/**
* The recurrence ID, a.k.a. DTSTART-of-calculated-occurrence,
* or null if this isn't an occurrence.
* Be conservative about setting this. It isn't marked as such, but
* consider it as readonly.
*/
attribute calIDateTime recurrenceId;

View File

@ -834,6 +834,7 @@ COMP_DATE_ATTRIBUTE(StampTime, DTSTAMP)
COMP_DATE_ATTRIBUTE(LastModified, LASTMODIFIED)
COMP_DATE_ATTRIBUTE(CreatedTime, CREATED)
COMP_DATE_ATTRIBUTE(CompletedTime, COMPLETED)
COMP_DATE_ATTRIBUTE(RecurrenceId, RECURRENCEID)
void
calIcalComponent::ClearAllProperties(icalproperty_kind kind)

View File

@ -464,7 +464,8 @@ calItemBase.prototype = {
{ cal: "SUMMARY", ics: "summary" },
{ cal: "PRIORITY", ics: "priority" },
{ cal: "STATUS", ics: "status" },
{ cal: "CLASS", ics: "icalClass" } ],
{ cal: "CLASS", ics: "icalClass" },
{ cal: "RECURRENCE-ID", ics: "recurrenceId" } ],
mapPropsFromICS: function(icalcomp, propmap) {
for (var i = 0; i < propmap.length; i++) {

View File

@ -223,6 +223,10 @@ calICSCalendar.prototype = {
calComp = rootComp.getFirstSubcomponent('VCALENDAR');
}
var unexpandedItems = [];
var uid2parent = {};
var excItems = [];
while (calComp) {
// Get unknown properties
var prop = calComp.getFirstProperty("ANY");
@ -239,30 +243,41 @@ calICSCalendar.prototype = {
// Place each subcomp in a try block, to hopefully get as
// much of a bad calendar as possible
try {
var item = null;
switch (subComp.componentType) {
case "VEVENT":
var event = Components.classes["@mozilla.org/calendar/event;1"]
.createInstance(Components.interfaces.calIEvent);
event.icalComponent = subComp;
this.mMemoryCalendar.adoptItem(event, null);
item = Components.classes["@mozilla.org/calendar/event;1"]
.createInstance(Components.interfaces.calIEvent);
break;
case "VTODO":
var todo = Components.classes["@mozilla.org/calendar/todo;1"]
.createInstance(Components.interfaces.calITodo);
todo.icalComponent = subComp;
this.mMemoryCalendar.adoptItem(todo, null);
item = Components.classes["@mozilla.org/calendar/todo;1"]
.createInstance(Components.interfaces.calITodo);
break;
case "VTIMEZONE":
// this should already be attached to the relevant
// events in the calendar, so there's no need to
// do anything with it here.
break;
default:
this.unmappedComponents.push(subComp);
dump(subComp.componentType+"\n");
}
if (item != null) {
item.icalComponent = subComp;
var rid = item.recurrenceId;
if (rid == null) {
unexpandedItems.push( item );
if (item.recurrenceInfo != null)
uid2parent[item.id] = item;
}
else {
item.calendar = this;
// force no recurrence info:
item.recurrenceInfo = null;
excItems.push(item);
}
}
}
catch(ex) {
this.mObserver.onError(ex.result, ex.toString());
@ -271,6 +286,23 @@ calICSCalendar.prototype = {
}
calComp = rootComp.getNextSubcomponent('VCALENDAR');
}
// tag "exceptions", i.e. items with rid:
for each (var item in excItems) {
var parent = uid2parent[item.id];
if (parent == null) {
debug( "no parent item for rid=" + item.recurrenceId );
}
else {
item.parentItem = parent;
parent.recurrenceInfo.modifyException(item);
}
}
for each (var item in unexpandedItems) {
this.mMemoryCalendar.adoptItem(item, null);
}
} catch(e) {
dump("Parsing the file failed:"+e+"\n");
this.mObserver.onError(e.result, e.toString());
@ -334,7 +366,18 @@ calICSCalendar.prototype = {
onGetResult: function(aCalendar, aStatus, aItemType, aDetail, aCount, aItems)
{
for (var i=0; i<aCount; i++) {
calComp.addSubcomponent(aItems[i].icalComponent);
var item = aItems[i];
calComp.addSubcomponent(item.icalComponent);
var rec = item.recurrenceInfo;
if (rec != null) {
var exceptions = rec.getExceptionIds({});
for each ( var exid in exceptions ) {
var ex = rec.getExceptionFor(exid, false);
if (ex != null) {
calComp.addSubcomponent(ex.icalComponent);
}
}
}
}
}
};

View File

@ -218,7 +218,13 @@ calMemoryCalendar.prototype = {
"item ID mismatch between old and new items");
return;
}
if (aNewItem.parentItem != aNewItem) {
aNewItem.parentItem.recurrenceInfo.modifyException(aNewItem);
aNewItem = aNewItem.parentItem;
}
aOldItem = aOldItem.parentItem;
if (aOldItem != this.mItems[aOldItem.id]) {
if (aListener)
aListener.onOperationComplete (this.calendarToReturn,