Fix bug 362648. r=dbo

git-svn-id: svn://10.0.0.236/trunk@225088 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mozilla%kewis.ch
2007-04-26 13:38:26 +00:00
parent c7e1160f28
commit e0f26d60fc
2 changed files with 159 additions and 9 deletions

View File

@@ -84,6 +84,7 @@ calGoogleCalendar.prototype = {
},
/* Member Variables */
mID: null,
mSession: null,
mObservers: null,
mReadOnly: false,
@@ -104,6 +105,19 @@ calGoogleCalendar.prototype = {
return this.mCalendarName;
},
/**
* readonly attribute isDefaultCalendar
* Returns true if this is the default calendar of the user.
*/
get isDefaultCalendar() {
// If there is no session, use the non-default calendar identifier as a
// fallback.
return ((this.mSession &&
this.mCalendarName == this.mSession.googleUser) ||
(!this.mSession &&
this.mCalendarName.indexOf("group.calendar.google.com") < 0));
},
/**
* attribute session
* An calGoogleSession Object that handles the session requests.
@@ -178,13 +192,13 @@ calGoogleCalendar.prototype = {
* implement calICalendar
*/
// attribute AUTF8String id;
mID: null,
get id() {
return this.mID;
},
set id(id) {
if (this.mID)
throw Components.results.NS_ERROR_ALREADY_INITIALIZED;
throw Cr.NS_ERROR_ALREADY_INITIALIZED;
return (this.mID = id);
},
@@ -678,7 +692,7 @@ calGoogleCalendar.prototype = {
// Parse all <entry> tags
for each (var entry in xml.entry) {
var item = XMLEntryToItem(entry, timezone);
var item = XMLEntryToItem(entry, timezone, this);
if (item) {
var itemReturnOccurrences =
@@ -765,7 +779,7 @@ calGoogleCalendar.prototype = {
var timezone = getPrefSafe("calendar.timezone.local");
// Parse the Item with the given timezone
var item = XMLEntryToItem(xml, timezone);
var item = XMLEntryToItem(xml, timezone, this);
LOGitem(item);
item.calendar = this;

View File

@@ -489,6 +489,74 @@ function ItemToXMLEntry(aItem, aAuthorEmail, aAuthorName) {
entry.gd::when.@endTime = toRFC3339(aItem.endDate);
}
// gd:reminder
if (aItem.alarmOffset) {
var gdReminder = <gd:reminder xmlns:gd={gd}/>;
var alarmOffset = aItem.alarmOffset.clone();
if (aItem.alarmRelated == Ci.calIItemBase.ALARM_RELATED_END) {
// Google always uses an alarm offset related to the start time
alarmOffset.addDuration(duration);
}
// Google only accepts certain alarm values. Snap to them. See
// http://code.google.com/p/google-gdata/issues/detail?id=55
var alarmValues = [ 300, 600, 900, 1200, 1500, 1800, 2700, 3600, 7200,
10800, 86400, 172800, 604800 ];
var discreteValue = alarmValues[alarmValues.length - 1] / 60;
for (var i = 0; i < alarmValues.length; i++) {
if (-aItem.alarmOffset.inSeconds <= alarmValues[i]) {
discreteValue = alarmValues[i] / 60;
break;
}
}
gdReminder.@minutes = discreteValue;
entry.gd::when.gd::reminder += gdReminder;
if (!aItem.calendar.isDefaultCalendar) {
// On non-default calendars, alarms do not work as expected. This is
// an error on Google's side. We are going to work around with an
// extended property. After Google crippled alarm support,
// non-default calendars will work even better regarding alarms - at
// least in sunbird/lightning. See
// http://code.google.com/p/google-gdata/issues/detail?id=20
var gdExtendedReminder = <gd:extendedProperty xmlns:gd={gd}/>;
var alarmTime = aItem.startDate.clone();
alarmTime.addDuration(aItem.alarmOffset);
gdExtendedReminder.@name = "X-MOZ-ALARM-WORKAROUND";
gdExtendedReminder.@value = toRFC3339(alarmTime);
entry.gd::extendedProperty += gdExtendedReminder;
}
}
// XXX Google currently only supports one reminder. Nevertheless, according
// to the Google Calendar API docs, snoozed events should be implemented by
// a second gd:reminder element with an absolute time. This issue is tracked
// at http://code.google.com/p/google-gdata/issues/detail?id=44
// gd:extendedProperty (alarmLastAck)
var gdAlarmLastAck = <gd:extendedProperty xmlns:gd={gd}/>;
gdAlarmLastAck.@name = "X-MOZ-LASTACK";
gdAlarmLastAck.@value = toRFC3339(aItem.alarmLastAck);
entry.gd::extendedProperty += gdAlarmLastAck;
// gd:extendedProperty (snooze time)
var gdAlarmSnoozeTime = <gd:extendedProperty xmlns:gd={gd}/>;
var itemSnoozeTime = aItem.getProperty("X-MOZ-SNOOZE-TIME");
var icalSnoozeTime = createDateTime();
if (itemSnoozeTime) {
// The propery is saved as a string, translate back to calIDateTime.
icalSnoozeTime.icalString = itemSnoozeTime;
icalSnoozeTime.normalize();
}
gdAlarmSnoozeTime.@name = "X-MOZ-SNOOZE-TIME";
gdAlarmSnoozeTime.@value = toRFC3339(icalSnoozeTime);
entry.gd::extendedProperty += gdAlarmSnoozeTime;
// gd:visibility
var privacy = aItem.privacy || "default";
entry.gd::visibility.@value = kEVENT_SCHEMA + privacy.toLowerCase();
@@ -504,7 +572,6 @@ function ItemToXMLEntry(aItem, aAuthorEmail, aAuthorName) {
// TODO gd:recurrenceException: Enhancement tracked in bug 362650
// TODO gd:comments: Enhancement tracked in bug 362653
// TODO gd:who Enhancement tracked in bug 355226
// TODO gd:reminder: Enhancement tracked in bug 362648
// XXX Google currently has no priority support. See
// http://code.google.com/p/google-gdata/issues/detail?id=52
@@ -531,8 +598,16 @@ function relevantFieldsMatch(a, b) {
return false;
}
function compareNotNull(prop) {
var ap = a[prop];
var bp = b[prop];
return (ap && !bp || !ap && bp || ap && bp && ap.compare(bp));
}
// Object flat values
if (
if (compareNotNull("alarmOffset") ||
compareNotNull("alarmLastAck") ||
/* Compare startDate and endDate */
(a.startDate && a.startDate.compare(b.startDate)) ||
(a.endDate && a.endDate.compare(b.endDate)) ||
(a.startDate.isDate != b.startDate.isDate) ||
@@ -542,7 +617,7 @@ function relevantFieldsMatch(a, b) {
// Properties
const kPROPERTIES = ["DESCRIPTION", "TRANSP", "X-GOOGLE-EDITURL",
"LOCATION", "CATEGORIES"];
"LOCATION", "CATEGORIES", "X-MOZ-SNOOZE-TIME"];
for each (var p in kPROPERTIES) {
// null and an empty string should be handled as non-relevant
@@ -578,9 +653,10 @@ function getItemEditURI(aItem) {
*
* @param aXMLEntry The xml data of the item
* @param aTimezone The timezone the event is most likely in
* @param aCalendar The calendar the event will be added to. Can be null.
* @return The calIEvent with the item data.
*/
function XMLEntryToItem(aXMLEntry, aTimezone) {
function XMLEntryToItem(aXMLEntry, aTimezone, aCalendar) {
if (aXMLEntry == null) {
throw new Components.Exception("", Cr.NS_ERROR_DOM_SYNTAX_ERR);
@@ -647,8 +723,66 @@ function XMLEntryToItem(aXMLEntry, aTimezone) {
item.endDate = item.startDate.clone();
}
}
// gd:reminder
var alarmOffset = Cc["@mozilla.org/calendar/duration;1"]
.createInstance(Ci.calIDuration);
if (aXMLEntry.gd::originalEvent.toString().length > 0) {
// If the item is an occurrence, we cannot change it until bug
// 362650 has been fixed. For now, don't set alarms on
// occurrences.
continue;
} else if (when.gd::reminder.@absoluteTime.toString()) {
var absolute = fromRFC3339(when.gd::reminder.@absoluteTime,
aTimezone);
alarmOffset = startDate.subtractDate(absolute);
} else if (when.gd::reminder.@days.toString()) {
alarmOffset.days = -when.gd::reminder.@days;
} else if (when.gd::reminder.@hours.toString()) {
alarmOffset.hours = -when.gd::reminder.@hours;
} else if (when.gd::reminder.@minutes.toString()) {
// There is a bug in the Google API that always sets an alarm,
// even if you didn't specify it. The value is always -1. See
// http://code.google.com/p/google-gdata/issues/detail?id=43
// As a workaround, ignore such reminders
if (when.gd::reminder.@minutes == "-1") {
continue;
}
alarmOffset.minutes = -when.gd::reminder.@minutes;
} else {
continue;
}
alarmOffset.normalize();
item.alarmOffset = alarmOffset;
item.alarmRelated = Ci.calIItemBase.ALARM_RELATED_START;
}
// gd:extendedProperty (alarm workaround)
if (!aCalendar.isDefaultCalendar) {
var alarmTime = fromRFC3339(aXMLEntry.gd::extendedProperty
.(@name == "X-MOZ-ALARM-WORKAROUND")
.@value.toString(), aTimezone);
if (alarmTime) {
item.alarmOffset = alarmTime.subtractDate(item.startDate);
item.alarmRelated = Ci.calIItemBase.ALARM_RELATED_START;
} else {
item.alarmOffset = null;
}
}
// gd:extendedProperty (alarmLastAck)
var alarmLastAck = aXMLEntry.gd::extendedProperty
.(@name == "X-MOZ-LASTACK")
.@value.toString();
item.alarmLastAck = fromRFC3339(alarmLastAck, aTimezone);
// gd:extendedProperty (snooze time)
var xmlSnoozeTime = aXMLEntry.gd::extendedProperty
.(@name == "X-MOZ-SNOOZE-TIME").@value.toString();
var dtSnoozeTime = fromRFC3339(xmlSnoozeTime, aTimezone);
var snoozeProperty = (dtSnoozeTime ? dtSnoozeTime.icalString : null);
item.setProperty("X-MOZ-SNOOZE-TIME", snoozeProperty);
// gd:where
item.setProperty("LOCATION",
aXMLEntry.gd::where.@valueString.toString());
@@ -743,7 +877,6 @@ function XMLEntryToItem(aXMLEntry, aTimezone) {
// TODO gd:recurrenceException: Enhancement tracked in bug 362650
// TODO gd:comments: Enhancement tracked in bug 362653
// TODO gd:who Enhancement tracked in bug 355226
// TODO gd:reminder: Enhancement tracked in bug 362648
// XXX Google currently has no priority support. See
// http://code.google.com/p/google-gdata/issues/detail?id=52
@@ -774,6 +907,9 @@ function LOGitem(item) {
"\n\tendTime:" + item.endDate.toString() +
"\n\tlocation:" + item.getProperty("LOCATION") +
"\n\tprivacy:" + item.privacy +
"\n\talarmOffset:" + item.alarmOffset +
"\n\talarmLastAck:" + item.alarmLastAck +
"\n\tsnoozeTime:" + item.getProperty("X-MOZ-SNOOZE-TIME") +
"\n\tisOccurrence:" +
item.getProperty("x-GOOGLE-ITEM-IS-OCCURRENCE"));
}