зеркало из https://github.com/mozilla/pjs.git
Bug 400950 - Change calDatetime to reference its timezone definition; r=ctalbert, r=mickey, r=philipp
This commit is contained in:
Родитель
b746ea872b
Коммит
a450d66132
|
@ -46,28 +46,37 @@
|
|||
#include "calDuration.h"
|
||||
#include "calPeriod.h"
|
||||
#include "calICSService.h"
|
||||
#include "calTimezoneService.h"
|
||||
#include "calRecurrenceRule.h"
|
||||
#include "calRecurrenceDate.h"
|
||||
#include "calRecurrenceDateSet.h"
|
||||
|
||||
#include "calBaseCID.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(calDateTime)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(calDuration)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(calPeriod)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(calICSService)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(calRecurrenceRule)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(calRecurrenceDate)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(calRecurrenceDateSet)
|
||||
|
||||
NS_DECL_CLASSINFO(calDateTime)
|
||||
NS_DECL_CLASSINFO(calDuration)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(calPeriod)
|
||||
NS_DECL_CLASSINFO(calPeriod)
|
||||
NS_DECL_CLASSINFO(calICSService)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(calRecurrenceRule)
|
||||
NS_DECL_CLASSINFO(calRecurrenceRule)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(calRecurrenceDate)
|
||||
NS_DECL_CLASSINFO(calRecurrenceDate)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(calRecurrenceDateSet)
|
||||
NS_DECL_CLASSINFO(calRecurrenceDateSet)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(calDateTime)
|
||||
NS_DECL_CLASSINFO(calDateTime)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(calICSService)
|
||||
NS_DECL_CLASSINFO(calICSService)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(calTimezoneService)
|
||||
NS_DECL_CLASSINFO(calTimezoneService)
|
||||
|
||||
static const nsModuleComponentInfo components[] =
|
||||
{
|
||||
{ "Calendar DateTime Object",
|
||||
|
@ -114,6 +123,17 @@ static const nsModuleComponentInfo components[] =
|
|||
NULL,
|
||||
&NS_CLASSINFO_NAME(calICSService)
|
||||
},
|
||||
{ "Timezone Service",
|
||||
CAL_TIMEZONESERVICE_CID,
|
||||
CAL_TIMEZONESERVICE_CONTRACTID,
|
||||
calTimezoneServiceConstructor,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NS_CI_INTERFACE_GETTER_NAME(calTimezoneService),
|
||||
NULL,
|
||||
&NS_CLASSINFO_NAME(calTimezoneService)
|
||||
},
|
||||
{ "Calendar Recurrence Rule",
|
||||
CAL_RECURRENCERULE_CID,
|
||||
CAL_RECURRENCERULE_CONTRACTID,
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
this.calView.goToDay(this.calView.selectedDay);
|
||||
break;
|
||||
case "calendar.timezone.local":
|
||||
this.calView.viewElem.timezone = subj.getCharPref(pref);
|
||||
this.calView.viewElem.timezone = calendarDefaultTimezone();
|
||||
if (!this.calView.startDay || !this.calView.endDay) {
|
||||
// Don't refresh if we're not initialized
|
||||
return;
|
||||
|
|
|
@ -163,7 +163,7 @@
|
|||
break;
|
||||
|
||||
case "calendar.timezone.local":
|
||||
this.viewElem.timezone = aSubject.getCharPref(aPreference);
|
||||
this.viewElem.timezone = calendarDefaultTimezone();
|
||||
if (!this.startDay || !this.endDay) {
|
||||
// don't refresh if we're not initialized
|
||||
return;
|
||||
|
|
|
@ -132,7 +132,7 @@
|
|||
this.calView.goToDay(this.calView.selectedDay);
|
||||
break;
|
||||
case "calendar.timezone.local":
|
||||
this.calView.viewElem.timezone = subj.getCharPref(pref);
|
||||
this.calView.viewElem.timezone = calendarDefaultTimezone();
|
||||
if (!this.calView.startDay || !this.calView.endDay) {
|
||||
// Don't refresh if we're not initialized
|
||||
return;
|
||||
|
|
|
@ -71,7 +71,7 @@ var calendarDNDObserver = {
|
|||
case "text/calendar":
|
||||
var parser = Components.classes["@mozilla.org/calendar/ics-parser;1"]
|
||||
.createInstance(Components.interfaces.calIIcsParser);
|
||||
parser.parseString(data);
|
||||
parser.parseString(data, null);
|
||||
startBatchTransaction();
|
||||
try {
|
||||
for each (var item in parser.getItems({})) {
|
||||
|
@ -150,7 +150,7 @@ var calendarDNDObserver = {
|
|||
}
|
||||
var parser = Components.classes["@mozilla.org/calendar/ics-parser;1"]
|
||||
.createInstance(Components.interfaces.calIIcsParser);
|
||||
parser.parseString(str);
|
||||
parser.parseString(str, null);
|
||||
startBatchTransaction();
|
||||
try {
|
||||
for each (var item in parser.getItems({})) {
|
||||
|
|
|
@ -836,6 +836,7 @@
|
|||
hdr.index = i;
|
||||
}
|
||||
|
||||
this.mTimezone = floating();
|
||||
var alarmService = Components.classes['@mozilla.org/calendar/alarm-service;1']
|
||||
.getService(Components.interfaces.calIAlarmService);
|
||||
alarmService.addObserver(this.mObserver);
|
||||
|
@ -857,7 +858,7 @@
|
|||
<field name="mStartDate">null</field>
|
||||
<field name="mEndDate">null</field>
|
||||
<field name="mDateBoxes">null</field>
|
||||
<field name="mTimezone">"floating"</field>
|
||||
<field name="mTimezone">null</field>
|
||||
|
||||
<field name="mSelectedItems">[]</field>
|
||||
<field name="mSelectedDayBox">null</field>
|
||||
|
|
|
@ -265,6 +265,7 @@
|
|||
<implementation>
|
||||
<constructor><![CDATA[
|
||||
this.mEvents = Array();
|
||||
this.mTimezone = UTC();
|
||||
]]></constructor>
|
||||
|
||||
<!-- fields -->
|
||||
|
@ -277,7 +278,7 @@
|
|||
<field name="mEventMap">null</field>
|
||||
<field name="mCalendarView">null</field>
|
||||
<field name="mDate">null</field>
|
||||
<field name="mTimezone">"UTC"</field>
|
||||
<field name="mTimezone">null</field>
|
||||
<field name="mDragState">null</field>
|
||||
<field name="mLayoutBatchCount">0</field>
|
||||
<!-- Since we'll often be getting many events in rapid succession, this
|
||||
|
@ -339,7 +340,7 @@
|
|||
<setter><![CDATA[
|
||||
this.mDate = val;
|
||||
|
||||
if (val.timezone != this.mTimezone) {
|
||||
if (!compareObjects(val.timezone, this.mTimezone)) {
|
||||
//dump ("++ column tz: " + val.timezone + "\n");
|
||||
this.mTimezone = val.timezone;
|
||||
if (!this.mLayoutBatchCount) {
|
||||
|
@ -540,11 +541,11 @@
|
|||
var stdate = aOccurrence.startDate || aOccurrence.entryDate;
|
||||
var enddate = aOccurrence.endDate || aOccurrence.dueDate;
|
||||
|
||||
if (stdate.timezone != this.mTimezone) {
|
||||
if (!compareObjects(stdate.timezone, this.mTimezone)) {
|
||||
stdate = stdate.getInTimezone (this.mTimezone);
|
||||
}
|
||||
|
||||
if (enddate.timezone != this.mTimezone) {
|
||||
if (!compareObjects(enddate.timezone, this.mTimezone)) {
|
||||
enddate = enddate.getInTimezone (this.mTimezone);
|
||||
}
|
||||
|
||||
|
@ -1151,7 +1152,7 @@
|
|||
// that's why i'm clipping the start- and end-time to the
|
||||
// timespan of this column.
|
||||
var start = data.item.startDate || data.item.entryDate;
|
||||
if (start.timezone != this.mTimezone) {
|
||||
if (!compareObjects(start.timezone, this.mTimezone)) {
|
||||
start = start.getInTimezone(this.mTimezone);
|
||||
}
|
||||
if (start.year != this.date.year ||
|
||||
|
@ -1165,7 +1166,7 @@
|
|||
start.timezone);
|
||||
}
|
||||
var end = data.item.endDate || data.item.dueDate;
|
||||
if (end.timezone != this.mTimezone) {
|
||||
if (!compareObjects(end.timezone, this.mTimezone)) {
|
||||
end = end.getInTimezone(this.mTimezone);
|
||||
}
|
||||
if (end.year != this.date.year ||
|
||||
|
@ -1189,7 +1190,7 @@
|
|||
prevEnd.hour = 0;
|
||||
prevEnd.minute = this.mStartMin;
|
||||
}
|
||||
prevEnd.timezone = "floating";
|
||||
prevEnd.timezone = floating();
|
||||
// the reason why we need to calculate time durations
|
||||
// based on floating timezones is that we need avoid
|
||||
// dst gaps in this case. converting the date/times to
|
||||
|
@ -1197,13 +1198,13 @@
|
|||
// we explicitly don't use getInTimezone() as it would
|
||||
// be slightly more expensive in terms of performance.
|
||||
var floatstart = start.clone();
|
||||
floatstart.timezone = "floating";
|
||||
floatstart.timezone = floating();
|
||||
var dur = floatstart.subtractDate(prevEnd);
|
||||
if (dur.inSeconds) {
|
||||
col.push({duration: dur});
|
||||
}
|
||||
var floatend = end.clone();
|
||||
floatend.timezone = "floating";
|
||||
floatend.timezone = floating();
|
||||
col.push({event: data.item,
|
||||
endDate: end,
|
||||
duration: floatend.subtractDate(floatstart)});
|
||||
|
@ -2190,6 +2191,7 @@
|
|||
<field name="mResizeHandler">null</field>
|
||||
<constructor><![CDATA[
|
||||
var self = this;
|
||||
this.mTimezone = UTC();
|
||||
this.mResizeHandler = function resizeHandler() { self.onResize(); };
|
||||
window.addEventListener("resize", this.mResizeHandler, true);
|
||||
this.mScrollHandler = function scrollHandler() { self.onScroll(); };
|
||||
|
@ -2300,7 +2302,7 @@
|
|||
<field name="mShowCompleted">false</field>
|
||||
<field name="mDisplayDaysOff">true</field>
|
||||
<field name="mDaysOffArray">[0,6]</field>
|
||||
<field name="mTimezone">"UTC"</field>
|
||||
<field name="mTimezone">null</field>
|
||||
<field name="mFlashingEvents">new Object()</field>
|
||||
|
||||
<field name="mObserver"><![CDATA[
|
||||
|
|
|
@ -45,7 +45,7 @@ var gTimezonesPane = {
|
|||
|
||||
if (!prefValue) {
|
||||
prefValue = calendarDefaultTimezone();
|
||||
tzMenuList.value = prefValue;
|
||||
tzMenuList.value = prefValue.tzid;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -82,6 +82,7 @@ XPIDLSRCS = calIAlarmService.idl \
|
|||
calIOperation.idl \
|
||||
calIFreeBusyProvider.idl \
|
||||
calICalendarSearchProvider.idl \
|
||||
calITimezoneProvider.idl \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = calBaseCID.h
|
||||
|
|
|
@ -61,6 +61,11 @@
|
|||
#define CAL_ICSSERVICE_CONTRACTID \
|
||||
"@mozilla.org/calendar/ics-service;1"
|
||||
|
||||
#define CAL_TIMEZONESERVICE_CID \
|
||||
{ 0x1a23ace4, 0xa0dd, 0x43b4, { 0x96, 0xa8, 0xb3, 0xcd, 0x41, 0x9a, 0x14, 0xa5 } }
|
||||
#define CAL_TIMEZONESERVICE_CONTRACTID \
|
||||
"@mozilla.org/calendar/timezone-service;1"
|
||||
|
||||
#define CAL_RECURRENCERULE_CID \
|
||||
{ 0xd9560bf9, 0x3065, 0x404a, { 0x90, 0x4c, 0xc8, 0x82, 0xfc, 0x9c, 0x9b, 0x74 } }
|
||||
#define CAL_RECURRENCERULE_CONTRACTID \
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
interface calIItemBase;
|
||||
interface calICalendar;
|
||||
interface calIDuration;
|
||||
interface calITimezone;
|
||||
|
||||
[scriptable,uuid(c9c97643-db45-4790-9441-05384ae5c272)]
|
||||
interface calIAlarmServiceObserver : nsISupports
|
||||
|
@ -70,7 +71,7 @@ interface calIAlarmService : nsISupports
|
|||
* This is the timezone that all-day events will be converted to in order to
|
||||
* determine when their alarms should fire.
|
||||
*/
|
||||
attribute AUTF8String timezone;
|
||||
attribute calITimezone timezone;
|
||||
|
||||
/**
|
||||
* Cause the alarm service to start up, create a list of upcoming
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "nsISupports.idl"
|
||||
|
||||
interface calIDuration;
|
||||
interface calITimezone;
|
||||
[ptr] native icaltimetypeptr(struct icaltimetype);
|
||||
|
||||
[scriptable, uuid(5678d4a3-2543-4ece-afbb-079292f2866e)]
|
||||
|
@ -120,21 +121,11 @@ interface calIDateTime : nsISupports
|
|||
/**
|
||||
* Gets or sets the timezone of this calIDateTime instance.
|
||||
* Setting the timezone does not change the actual date/time components;
|
||||
* to convert between timezones, use getInTimezone().
|
||||
* to convert between timezones, use getInTimezone().
|
||||
*
|
||||
* Valid values are:
|
||||
*
|
||||
* - "UTC" (or "utc", "UTC" preferred)
|
||||
* - the object refers to a time in UTC.
|
||||
* - a TZID string, understood by the ICS Service
|
||||
* - the object refers to a time in that tz
|
||||
* - "floating"
|
||||
* - the object is in floating time and does not have an
|
||||
* associated timezone.
|
||||
*
|
||||
* @throws NS_ERROR_INVALID_ARG if an invalid timezone is passed in.
|
||||
* @throws NS_ERROR_INVALID_ARG if null is passed in.
|
||||
*/
|
||||
attribute AUTF8String timezone;
|
||||
attribute calITimezone timezone;
|
||||
|
||||
/**
|
||||
* Resets the datetime object.
|
||||
|
@ -145,12 +136,12 @@ interface calIDateTime : nsISupports
|
|||
* @param hour hour, 0-23
|
||||
* @param minute minute, 0-59
|
||||
* @param second decond, 0-59
|
||||
* @param timezone timezone, e.g. "UTC", "floating", "Europe/Berlin"
|
||||
* @param timezone timezone
|
||||
*
|
||||
* The passed datetime will be normalized, e.g. a minute value of 60 will
|
||||
* increase the hour.
|
||||
*
|
||||
* @throws NS_ERROR_INVALID_ARG if an invalid timezone is passed in.
|
||||
* @throws NS_ERROR_INVALID_ARG if no timezone is passed in.
|
||||
*/
|
||||
void resetTo(in short year,
|
||||
in short month,
|
||||
|
@ -158,7 +149,7 @@ interface calIDateTime : nsISupports
|
|||
in short hour,
|
||||
in short minute,
|
||||
in short second,
|
||||
in AUTF8String timezone);
|
||||
in calITimezone timezone);
|
||||
|
||||
/**
|
||||
* The offset of the timezone this datetime is in, relative to UTC, in
|
||||
|
@ -205,11 +196,9 @@ interface calIDateTime : nsISupports
|
|||
/**
|
||||
* Set the value of this calIDateTime instance
|
||||
* to aTime milliseconds since the epoch in the
|
||||
* given timezone. Valid values for the aTimezone
|
||||
* are either a known TZID or "UTC"; null/empty string
|
||||
* is not valid.
|
||||
* given timezone.
|
||||
*/
|
||||
void setTimeInTimezone (in PRTime aTime, in AUTF8String aTimezone);
|
||||
void setTimeInTimezone(in PRTime aTime, in calITimezone aTimezone);
|
||||
|
||||
/**
|
||||
* Return a new calIDateTime instance that's the result of
|
||||
|
@ -218,7 +207,7 @@ interface calIDateTime : nsISupports
|
|||
* the "floating" timezone is given, then this object
|
||||
* is just cloned, and the timezone is set to floating.
|
||||
*/
|
||||
calIDateTime getInTimezone (in AUTF8String aTimezone);
|
||||
calIDateTime getInTimezone(in calITimezone aTimezone);
|
||||
|
||||
// add the given calIDateTime, treating it as a duration, to
|
||||
// this item.
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Mike Shaver <shaver@off.net>
|
||||
* Daniel Boelzle <daniel.boelzle@sun.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -44,6 +45,8 @@
|
|||
interface calIItemBase;
|
||||
interface calIDateTime;
|
||||
interface calIDuration;
|
||||
interface calITimezone;
|
||||
interface calITimezoneProvider;
|
||||
|
||||
interface calIIcalProperty;
|
||||
interface nsIUTF8StringEnumerator;
|
||||
|
@ -51,6 +54,7 @@ interface nsIInputStream;
|
|||
|
||||
[ptr] native icalpropertyptr(struct icalproperty_impl);
|
||||
[ptr] native icalcomponentptr(struct icalcomponent_impl);
|
||||
[ptr] native icaltimezoneptr(struct _icaltimezone);
|
||||
|
||||
/**
|
||||
* General notes:
|
||||
|
@ -127,6 +131,11 @@ interface calIIcalComponent : nsISupports
|
|||
|
||||
AUTF8String serializeToICS();
|
||||
|
||||
/**
|
||||
* Return a string representation of this instance.
|
||||
*/
|
||||
AUTF8String toString();
|
||||
|
||||
/**
|
||||
* Serializes this component (and subcomponents) directly to an
|
||||
* input stream. Typically used for performance to avoid
|
||||
|
@ -140,7 +149,9 @@ interface calIIcalComponent : nsISupports
|
|||
nsIInputStream serializeToICSStream();
|
||||
|
||||
void addSubcomponent(in calIIcalComponent comp);
|
||||
void removeSubcomponent(in calIIcalComponent comp);
|
||||
// If you add then remove a property/component, the referenced
|
||||
// timezones won't get purged out. There's currently no client code.
|
||||
// void removeSubcomponent(in calIIcalComponent comp);
|
||||
|
||||
/**
|
||||
* @param kind ANY, ATTENDEE, X-WHATEVER, etc.
|
||||
|
@ -148,36 +159,35 @@ interface calIIcalComponent : nsISupports
|
|||
calIIcalProperty getFirstProperty(in AUTF8String kind);
|
||||
calIIcalProperty getNextProperty(in AUTF8String kind);
|
||||
void addProperty(in calIIcalProperty prop);
|
||||
void removeProperty(in calIIcalProperty prop);
|
||||
// If you add then remove a property/component, the referenced
|
||||
// timezones won't get purged out. There's currently no client code.
|
||||
// void removeProperty(in calIIcalProperty prop);
|
||||
|
||||
/**
|
||||
* Timezones need special handling, as they must be
|
||||
* emitted as children of VCALENDAR, but can be referenced by
|
||||
* any sub component. The components this expects to receive
|
||||
* are VCALENDAR components with a single VTIMEZONE child.
|
||||
* Adding the same TZID twice will cause the second and later
|
||||
* adds to be ignored. Appropriate calIIcalComponents can
|
||||
* be obtained via the calIICSService.
|
||||
* any sub component.
|
||||
* Adding a second timezone (of the same TZID) will remove the
|
||||
* first one.
|
||||
*/
|
||||
void addTimezoneReference(in calIIcalComponent aTimezone);
|
||||
void addTimezoneReference(in calITimezone aTimezone);
|
||||
|
||||
/**
|
||||
* Returns an array of VCALENDAR components, each with a single
|
||||
* VTIMEZONE. These are the timezones that are in use by this
|
||||
* component and its children. Child timezones are only added
|
||||
* at addSubcomponent time.
|
||||
* Returns an array of VTIMEZONE components.
|
||||
* These are the timezones that are in use by this
|
||||
* component and its children.
|
||||
*/
|
||||
void getReferencedTimezones(out PRUint32 aCount,
|
||||
[array,size_is(aCount),retval] out calIIcalComponent aTimezones);
|
||||
[array,size_is(aCount),retval] out calITimezone aTimezones);
|
||||
|
||||
/**
|
||||
* Clones the component. The cloned component is decoupled from any parent.
|
||||
* @return cloned component
|
||||
*/
|
||||
calIIcalComponent clone();
|
||||
|
||||
|
||||
[noscript,notxpcom] icalcomponentptr getIcalComponent();
|
||||
[noscript, notxpcom] nsresult addTimezoneReferenceById(in ACStringPtr tzid);
|
||||
[noscript,notxpcom] icaltimezoneptr getIcalTimezone();
|
||||
};
|
||||
|
||||
[scriptable,uuid(17349a10-5d80-47fa-9bea-f22957357675)]
|
||||
|
@ -188,6 +198,11 @@ interface calIIcalProperty : nsISupports
|
|||
* @exception Any libical error will be thrown as an calIError::ICS_ error.
|
||||
*/
|
||||
readonly attribute AUTF8String icalString;
|
||||
|
||||
/**
|
||||
* Return a string representation of this instance.
|
||||
*/
|
||||
AUTF8String toString();
|
||||
|
||||
/**
|
||||
* The value of the property as string.
|
||||
|
@ -204,8 +219,7 @@ interface calIIcalProperty : nsISupports
|
|||
|
||||
/**
|
||||
* The value of the property as date/datetime value, keeping
|
||||
* track of the used timezone being resolvable and referenced in the
|
||||
* owning component.
|
||||
* track of the used timezone referenced in the owning component.
|
||||
*/
|
||||
attribute calIDateTime valueAsDatetime;
|
||||
|
||||
|
@ -237,51 +251,23 @@ interface calIIcalProperty : nsISupports
|
|||
[scriptable,uuid(ae4ca6c3-981b-4f66-a0ce-2f2c218ad9e3)]
|
||||
interface calIICSService : nsISupports
|
||||
{
|
||||
calIIcalComponent parseICS(in AUTF8String serialized);
|
||||
/**
|
||||
* Parses an ICS string and uses the passed tzProvider instance to
|
||||
* resolve timezones not contained withing the VCALENDAR.
|
||||
*
|
||||
* @param serialized an ICS string
|
||||
* @param tzProvider timezone provider used to resolve TZIDs
|
||||
* not contained within the VCALENDAR;
|
||||
* if null is passed, parsing falls back to
|
||||
* using the timezone service
|
||||
*/
|
||||
calIIcalComponent parseICS(in AUTF8String serialized,
|
||||
in calITimezoneProvider tzProvider);
|
||||
|
||||
calIIcalComponent createIcalComponent(in AUTF8String kind);
|
||||
calIIcalProperty createIcalProperty(in AUTF8String kind);
|
||||
/* I wish I could write this function atop libical!
|
||||
boolean isLegalParameterValue(in AUTF8String paramKind,
|
||||
in AUTF8String paramValue);
|
||||
*/
|
||||
|
||||
/* Return a calIIcalComponent for the given timezone. Note that
|
||||
* the component returned is a VCALENDAR with a VTIMEZONE child,
|
||||
* not the VTIMEZONE itself.
|
||||
*/
|
||||
calIIcalComponent getTimezone(in AUTF8String tzid);
|
||||
AUTF8String getTimezoneLatitude(in AUTF8String tzid);
|
||||
AUTF8String getTimezoneLongitude(in AUTF8String tzid);
|
||||
|
||||
/**
|
||||
* Adds and takes over ownership of a timezone record.
|
||||
* Record will be ignored if there is already an existing one with the
|
||||
* same id.
|
||||
*
|
||||
* @param tzCal VCALENDAR with a VTIMEZONE child
|
||||
* @param tzLatitude timzeone latitude, empty string if unknown
|
||||
* @param tzLongitude timzeone longitude, empty string if unknown
|
||||
* @return present VCALENDAR with a VTIMEZONE child
|
||||
*/
|
||||
calIIcalComponent addTimezone(in calIIcalComponent tzCal,
|
||||
in AUTF8String tzLatitude,
|
||||
in AUTF8String tzLongitude);
|
||||
|
||||
readonly attribute nsIUTF8StringEnumerator timezoneIds;
|
||||
|
||||
/**
|
||||
* This is the string that is used to prefix all tzIds that come from our
|
||||
* local tzid database. This includes a trailing slash character.
|
||||
*/
|
||||
readonly attribute AUTF8String tzIdPrefix;
|
||||
|
||||
/**
|
||||
* Takes a tzId, and if it's an old version of one of ours, returns
|
||||
* the current version of that tzId. Otherwise returns the empty string.
|
||||
*
|
||||
* @param aTzId the tzid to check
|
||||
*
|
||||
* @return updated version of the same tzid or ""
|
||||
*/
|
||||
AUTF8String latestTzId(in AUTF8String tzId);
|
||||
};
|
||||
|
|
|
@ -41,6 +41,7 @@ interface calIIcalProperty;
|
|||
interface calIIcalComponent;
|
||||
interface calIItemBase;
|
||||
interface nsIInputStream;
|
||||
interface calITimezoneProvider;
|
||||
|
||||
/**
|
||||
* An interface for parsing an ics string or stream into its items.
|
||||
|
@ -56,8 +57,12 @@ interface calIIcsParser : nsISupports
|
|||
*
|
||||
* @param aICSString
|
||||
* The ICS string to parse
|
||||
* @param aTzProvider
|
||||
* The timezone provider used to resolve timezones not contained in the
|
||||
* parent VCALENDAR or null (falls back to timezone service)
|
||||
*/
|
||||
void parseString(in AString aICSString);
|
||||
void parseString(in AString aICSString,
|
||||
in calITimezoneProvider aTzProvider);
|
||||
|
||||
/**
|
||||
* Parse an input stream.
|
||||
|
@ -65,8 +70,12 @@ interface calIIcsParser : nsISupports
|
|||
* @see parseString
|
||||
* @param aICSString
|
||||
* The stream to parse
|
||||
* @param aTzProvider
|
||||
* The timezone provider used to resolve timezones not contained in the
|
||||
* parent VCALENDAR or null (falls back to timezone service)
|
||||
*/
|
||||
void parseFromStream(in nsIInputStream aStream);
|
||||
void parseFromStream(in nsIInputStream aStream,
|
||||
in calITimezoneProvider aTzProvider);
|
||||
|
||||
/**
|
||||
* Get the items that were in the string or stream
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Sun Microsystems code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Sun Microsystems, Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Boelzle <daniel.boelzle@sun.com>
|
||||
* Clint Talbert <ctalbert@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface calIIcalComponent;
|
||||
interface nsIUTF8StringEnumerator;
|
||||
interface calITimezoneProvider;
|
||||
|
||||
[scriptable, uuid(D79161E7-0DB9-427d-A0C3-27E0DB3B030F)]
|
||||
interface calITimezone : nsISupports
|
||||
{
|
||||
/**
|
||||
* The timezone provider this timezone belongs to.
|
||||
*/
|
||||
readonly attribute calITimezoneProvider provider;
|
||||
|
||||
/**
|
||||
* VTIMEZONE ical component, null if floating.
|
||||
*/
|
||||
readonly attribute calIIcalComponent component;
|
||||
|
||||
/**
|
||||
* The TZID of this timezone.
|
||||
*/
|
||||
readonly attribute AUTF8String tzid;
|
||||
|
||||
/**
|
||||
* Whether this timezone is the "floating" timezone.
|
||||
*/
|
||||
readonly attribute boolean isFloating;
|
||||
|
||||
/**
|
||||
* Whether this is the "UTC" timezone.
|
||||
*/
|
||||
readonly attribute boolean isUTC;
|
||||
|
||||
/**
|
||||
* Latitude of timezone or empty string if unknown.
|
||||
*/
|
||||
readonly attribute AUTF8String latitude;
|
||||
|
||||
/**
|
||||
* Longitude of timezone or empty string if unknown.
|
||||
*/
|
||||
readonly attribute AUTF8String longitude;
|
||||
|
||||
/**
|
||||
* For debugging purposes.
|
||||
*
|
||||
* @return "UTC", "floating" or component's ical representation
|
||||
*/
|
||||
AUTF8String toString();
|
||||
};
|
||||
|
||||
[scriptable, uuid(0E502BF5-4FD3-4090-9122-F1EC3CA701BB)]
|
||||
interface calITimezoneProvider : nsISupports
|
||||
{
|
||||
readonly attribute nsIUTF8StringEnumerator timezoneIds;
|
||||
|
||||
/**
|
||||
* Gets a timezone defintion passing a TZID.
|
||||
* Returns null in case of an unknown TZID.
|
||||
*
|
||||
* @param tzid a TZID to be resolved
|
||||
* @return a timezone object or null
|
||||
*/
|
||||
calITimezone getTimezone(in AUTF8String tzid);
|
||||
};
|
||||
|
||||
/**
|
||||
* This service acts as a central access point for the up to date set
|
||||
* of Olson timezone definitions.
|
||||
*/
|
||||
[scriptable, uuid(AB1BFE6A-EE95-4038-B594-34AEEDA9911A)]
|
||||
interface calITimezoneService : calITimezoneProvider
|
||||
{
|
||||
readonly attribute calITimezone floating;
|
||||
readonly attribute calITimezone UTC;
|
||||
|
||||
/**
|
||||
* This is the string that is used to prefix all tzIds that come from our
|
||||
* local tzid database. This includes a trailing slash character.
|
||||
*/
|
||||
readonly attribute AUTF8String tzidPrefix;
|
||||
};
|
|
@ -69,6 +69,7 @@ CPPSRCS = calDateTime.cpp \
|
|||
calDuration.cpp \
|
||||
calPeriod.cpp \
|
||||
calICSService.cpp \
|
||||
calTimezoneService.cpp \
|
||||
calRecurrenceRule.cpp \
|
||||
calRecurrenceDate.cpp \
|
||||
calRecurrenceDateSet.cpp \
|
||||
|
|
|
@ -39,6 +39,10 @@
|
|||
|
||||
const kHoursBetweenUpdates = 6;
|
||||
|
||||
function nowUTC() {
|
||||
return jsDateToDateTime(new Date()).getInTimezone(UTC());
|
||||
}
|
||||
|
||||
function newTimerWithCallback(callback, delay, repeating)
|
||||
{
|
||||
var timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
|
||||
|
@ -198,7 +202,7 @@ calAlarmService.prototype = {
|
|||
},
|
||||
|
||||
set timezone(aTimezone) {
|
||||
this.mTimezone = aTimezone;
|
||||
return (this.mTimezone = aTimezone);
|
||||
},
|
||||
|
||||
snoozeAlarm: function cas_snoozeAlarm(event, duration) {
|
||||
|
@ -206,7 +210,7 @@ calAlarmService.prototype = {
|
|||
// Make sure we're working with the parent, otherwise we'll accidentally
|
||||
// create an exception
|
||||
var newEvent = event.parentItem.clone();
|
||||
var alarmTime = jsDateToDateTime((new Date())).getInTimezone("UTC");
|
||||
var alarmTime = nowUTC();
|
||||
|
||||
// Set the last acknowledged time to now.
|
||||
newEvent.alarmLastAck = alarmTime;
|
||||
|
@ -230,7 +234,7 @@ calAlarmService.prototype = {
|
|||
},
|
||||
|
||||
dismissAlarm: function cas_dismissAlarm(item) {
|
||||
var now = jsDateToDateTime(new Date()).getInTimezone("UTC");
|
||||
var now = nowUTC();
|
||||
// We want the parent item, otherwise we're going to accidentally create an
|
||||
// exception. We've relnoted (for 0.1) the slightly odd behavior this can
|
||||
// cause if you move an event after dismissing an alarm
|
||||
|
@ -296,7 +300,7 @@ calAlarmService.prototype = {
|
|||
var timerCallback = {
|
||||
alarmService: this,
|
||||
notify: function timer_notify() {
|
||||
var now = jsDateToDateTime((new Date())).getInTimezone("UTC");
|
||||
var now = nowUTC();
|
||||
var start;
|
||||
if (!this.alarmService.mRangeEnd) {
|
||||
// This is our first search for alarms. We're going to look for
|
||||
|
@ -315,7 +319,7 @@ calAlarmService.prototype = {
|
|||
// We don't set timers for every future alarm, only those within 6 hours
|
||||
var end = now.clone();
|
||||
end.hour += kHoursBetweenUpdates;
|
||||
this.alarmService.mRangeEnd = end.getInTimezone("UTC");
|
||||
this.alarmService.mRangeEnd = end.getInTimezone(UTC());
|
||||
|
||||
this.alarmService.findAlarms(this.alarmService.calendarManager.getCalendars({}),
|
||||
start, until);
|
||||
|
@ -400,14 +404,14 @@ calAlarmService.prototype = {
|
|||
// a well defined startTime. We just consider the start/end to be
|
||||
// midnight in the user's timezone.
|
||||
if (alarmDate.isDate) {
|
||||
alarmDate = alarmDate.getInTimezone(this.mTimezone);
|
||||
alarmDate = alarmDate.getInTimezone(this.timezone);
|
||||
alarmDate.isDate = false;
|
||||
}
|
||||
|
||||
var offset = aItem.alarmOffset || aItem.parentItem.alarmOffset;
|
||||
|
||||
alarmDate.addDuration(offset);
|
||||
alarmDate = alarmDate.getInTimezone("UTC");
|
||||
alarmDate = alarmDate.getInTimezone(UTC());
|
||||
|
||||
return alarmDate;
|
||||
},
|
||||
|
@ -439,12 +443,12 @@ calAlarmService.prototype = {
|
|||
// If the alarm was snoozed, the snooze time is more important.
|
||||
alarmTime = snoozeTime || alarmTime;
|
||||
|
||||
var now = jsDateToDateTime((new Date()));
|
||||
if (alarmTime.timezone == "floating") {
|
||||
var now = jsDateToDateTime(new Date());
|
||||
if (alarmTime.timezone.isFloating) {
|
||||
now = now.getInTimezone(calendarDefaultTimezone());
|
||||
now.timezone = "floating";
|
||||
now.timezone = floating();
|
||||
} else {
|
||||
now = now.getInTimezone("UTC");
|
||||
now = now.getInTimezone(UTC());
|
||||
}
|
||||
LOG("[calAlarmService] now is " + now);
|
||||
var callbackObj = {
|
||||
|
@ -514,7 +518,7 @@ calAlarmService.prototype = {
|
|||
cal[aItem.id] = itemTimers;
|
||||
}
|
||||
var rid = aItem.recurrenceId;
|
||||
itemTimers[rid ? rid.getInTimezone("UTC").icalString : "mTimer"] = aTimer;
|
||||
itemTimers[rid ? rid.getInTimezone(UTC()).icalString : "mTimer"] = aTimer;
|
||||
++itemTimers.mCount;
|
||||
},
|
||||
|
||||
|
@ -525,7 +529,7 @@ calAlarmService.prototype = {
|
|||
if (itemTimers) {
|
||||
var rid = aItem.recurrenceId;
|
||||
if (rid) {
|
||||
rid = rid.getInTimezone("UTC").icalString;
|
||||
rid = rid.getInTimezone(UTC()).icalString;
|
||||
var timer = itemTimers[rid];
|
||||
if (timer) {
|
||||
delete itemTimers[rid];
|
||||
|
@ -580,7 +584,7 @@ calAlarmService.prototype = {
|
|||
// alarms +/- 1 month from now. If someone sets an alarm more than
|
||||
// a month ahead of an event, or doesn't start Sunbird/Lightning
|
||||
// for a month, they'll miss some, but that's a slim chance
|
||||
var start = jsDateToDateTime((new Date())).getInTimezone("UTC");
|
||||
var start = nowUTC();
|
||||
var until = start.clone();
|
||||
start.month -= 1;
|
||||
until.month += 1;
|
||||
|
|
|
@ -39,8 +39,12 @@
|
|||
#ifndef CALATTRIBUTEHELPERS_H_
|
||||
#define CALATTRIBUTEHELPERS_H_
|
||||
|
||||
#ifndef UPDATE_LAST_MODIFIED
|
||||
#define UPDATE_LAST_MODIFIED /**/
|
||||
#ifndef CAL_ATTR_SET_PRE
|
||||
#define CAL_ATTR_SET_PRE /**/
|
||||
#endif
|
||||
|
||||
#ifndef CAL_ATTR_SET_POST
|
||||
#define CAL_ATTR_SET_POST /**/
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -59,9 +63,9 @@ cname::Get##name (mtype &_retval) { \
|
|||
#define CAL_STRINGTYPE_ATTR_SETTER(cname,mtype,name) \
|
||||
NS_IMETHODIMP \
|
||||
cname::Set##name (const mtype &aValue) { \
|
||||
if (mImmutable) return NS_ERROR_OBJECT_IS_IMMUTABLE; \
|
||||
CAL_ATTR_SET_PRE; \
|
||||
m##name.Assign(aValue); \
|
||||
UPDATE_LAST_MODIFIED; \
|
||||
CAL_ATTR_SET_POST; \
|
||||
return NS_OK; \
|
||||
}
|
||||
|
||||
|
@ -73,6 +77,7 @@ cname::Set##name (const mtype &aValue) { \
|
|||
#define CAL_VALUETYPE_ATTR_GETTER(cname,mtype,name) \
|
||||
NS_IMETHODIMP \
|
||||
cname::Get##name (mtype *_retval) { \
|
||||
NS_ENSURE_ARG_POINTER(_retval); \
|
||||
*_retval = m##name; \
|
||||
return NS_OK; \
|
||||
}
|
||||
|
@ -80,10 +85,10 @@ cname::Get##name (mtype *_retval) { \
|
|||
#define CAL_VALUETYPE_ATTR_SETTER(cname,mtype,name) \
|
||||
NS_IMETHODIMP \
|
||||
cname::Set##name (mtype aValue) { \
|
||||
if (mImmutable) return NS_ERROR_OBJECT_IS_IMMUTABLE; \
|
||||
CAL_ATTR_SET_PRE; \
|
||||
if (m##name != aValue) { \
|
||||
m##name = aValue; \
|
||||
UPDATE_LAST_MODIFIED; \
|
||||
CAL_ATTR_SET_POST; \
|
||||
} \
|
||||
return NS_OK; \
|
||||
}
|
||||
|
@ -96,6 +101,7 @@ cname::Set##name (mtype aValue) { \
|
|||
#define CAL_ISUPPORTS_ATTR_GETTER(cname,mtype,name) \
|
||||
NS_IMETHODIMP \
|
||||
cname::Get##name (mtype **_retval) { \
|
||||
NS_ENSURE_ARG_POINTER(_retval); \
|
||||
NS_IF_ADDREF (*_retval = m##name); \
|
||||
return NS_OK; \
|
||||
}
|
||||
|
@ -103,10 +109,10 @@ cname::Get##name (mtype **_retval) { \
|
|||
#define CAL_ISUPPORTS_ATTR_SETTER(cname,mtype,name) \
|
||||
NS_IMETHODIMP \
|
||||
cname::Set##name (mtype *aValue) { \
|
||||
if (mImmutable) return NS_ERROR_OBJECT_IS_IMMUTABLE; \
|
||||
CAL_ATTR_SET_PRE; \
|
||||
if (m##name != aValue) { \
|
||||
m##name = aValue; \
|
||||
UPDATE_LAST_MODIFIED; \
|
||||
CAL_ATTR_SET_POST; \
|
||||
} \
|
||||
return NS_OK; \
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -48,7 +47,6 @@
|
|||
#include "nsIClassInfoImpl.h"
|
||||
#endif
|
||||
|
||||
#include "calIICSService.h"
|
||||
#include "calIErrors.h"
|
||||
#include "calDuration.h"
|
||||
|
||||
|
@ -56,41 +54,25 @@
|
|||
#include "prprf.h"
|
||||
|
||||
extern "C" {
|
||||
#include "ical.h"
|
||||
#include "ical.h"
|
||||
}
|
||||
|
||||
#define UPDATE_LAST_MODIFIED normalize()
|
||||
#define CAL_ATTR_SET_PRE NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE)
|
||||
#define CAL_ATTR_SET_POST Normalize()
|
||||
#include "calAttributeHelpers.h"
|
||||
|
||||
static NS_DEFINE_CID(kCalICSService, CAL_ICSSERVICE_CID);
|
||||
|
||||
NS_IMPL_ISUPPORTS2_CI(calDateTime, calIDateTime, nsIXPCScriptable)
|
||||
|
||||
calDateTime::calDateTime() : mImmutable(PR_FALSE)
|
||||
calDateTime::calDateTime()
|
||||
: mImmutable(PR_FALSE)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
calDateTime::calDateTime(struct icaltimetype const* atimeptr) : mImmutable(PR_FALSE)
|
||||
{
|
||||
FromIcalTime(atimeptr);
|
||||
}
|
||||
|
||||
calDateTime::calDateTime(const calDateTime& cdt)
|
||||
: mImmutable(PR_FALSE),
|
||||
mIsValid(cdt.mIsValid),
|
||||
mNativeTime(cdt.mNativeTime),
|
||||
mYear(cdt.mYear),
|
||||
mMonth(cdt.mMonth),
|
||||
mDay(cdt.mDay),
|
||||
mHour(cdt.mHour),
|
||||
mMinute(cdt.mMinute),
|
||||
mSecond(cdt.mSecond),
|
||||
mWeekday(cdt.mWeekday),
|
||||
mYearday(cdt.mYearday),
|
||||
mIsDate(cdt.mIsDate),
|
||||
mTimezone(cdt.mTimezone)
|
||||
calDateTime::calDateTime(icaltimetype const* atimeptr, calITimezone *tz)
|
||||
: mImmutable(PR_FALSE)
|
||||
{
|
||||
FromIcalTime(atimeptr, tz);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -112,9 +94,10 @@ NS_IMETHODIMP
|
|||
calDateTime::Clone(calIDateTime **aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
calDateTime *cdt = new calDateTime(*this);
|
||||
if (!cdt)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
icaltimetype itt;
|
||||
ToIcalTime(&itt);
|
||||
calDateTime * const cdt = new calDateTime(&itt, mTimezone);
|
||||
CAL_ENSURE_MEMORY(cdt);
|
||||
NS_ADDREF(*aResult = cdt);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -126,28 +109,26 @@ calDateTime::ResetTo(PRInt16 year,
|
|||
PRInt16 hour,
|
||||
PRInt16 minute,
|
||||
PRInt16 second,
|
||||
nsACString const& timezone)
|
||||
calITimezone * tz)
|
||||
{
|
||||
nsresult rc = SetTimezone(timezone);
|
||||
if (NS_SUCCEEDED(rc)) {
|
||||
mYear = year;
|
||||
mMonth = month;
|
||||
mDay = day;
|
||||
mHour = hour;
|
||||
mMinute = minute;
|
||||
mSecond = second;
|
||||
mIsDate = PR_FALSE;
|
||||
normalize();
|
||||
}
|
||||
return rc;
|
||||
NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE);
|
||||
NS_ENSURE_ARG_POINTER(tz);
|
||||
mYear = year;
|
||||
mMonth = month;
|
||||
mDay = day;
|
||||
mHour = hour;
|
||||
mMinute = minute;
|
||||
mSecond = second;
|
||||
mIsDate = PR_FALSE;
|
||||
mTimezone = tz;
|
||||
Normalize();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::Reset()
|
||||
{
|
||||
if (mImmutable)
|
||||
return NS_ERROR_OBJECT_IS_IMMUTABLE;
|
||||
|
||||
NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE);
|
||||
mYear = 1970;
|
||||
mMonth = 0;
|
||||
mDay = 1;
|
||||
|
@ -157,123 +138,56 @@ calDateTime::Reset()
|
|||
mWeekday = 4;
|
||||
mYearday = 1;
|
||||
mIsDate = PR_FALSE;
|
||||
mTimezone.AssignLiteral("UTC");
|
||||
cal::getTimezoneService()->GetUTC(getter_AddRefs(mTimezone));
|
||||
mNativeTime = 0;
|
||||
|
||||
mIsValid = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
CAL_VALUETYPE_ATTR_GETTER(calDateTime, PRBool, IsValid)
|
||||
|
||||
CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Year)
|
||||
CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Month)
|
||||
CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Day)
|
||||
CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Hour)
|
||||
CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Minute)
|
||||
CAL_VALUETYPE_ATTR(calDateTime, PRInt16, Second)
|
||||
|
||||
CAL_VALUETYPE_ATTR(calDateTime, PRBool, IsDate)
|
||||
CAL_ISUPPORTS_ATTR(calDateTime, calITimezone, Timezone)
|
||||
CAL_VALUETYPE_ATTR_GETTER(calDateTime, PRBool, IsValid)
|
||||
CAL_VALUETYPE_ATTR_GETTER(calDateTime, PRTime, NativeTime)
|
||||
CAL_VALUETYPE_ATTR_GETTER(calDateTime, PRInt16, Weekday)
|
||||
CAL_VALUETYPE_ATTR_GETTER(calDateTime, PRInt16, Yearday)
|
||||
|
||||
CAL_STRINGTYPE_ATTR_GETTER(calDateTime, nsACString, Timezone)
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::SetIsDate(PRBool aIsDate)
|
||||
{
|
||||
if (mImmutable)
|
||||
return NS_ERROR_OBJECT_IS_IMMUTABLE;
|
||||
|
||||
if (mIsDate != aIsDate) {
|
||||
mIsDate = aIsDate;
|
||||
if (aIsDate) {
|
||||
mHour = 0;
|
||||
mMinute = 0;
|
||||
mSecond = 0;
|
||||
}
|
||||
normalize();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::GetIsDate(PRBool *aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = mIsDate;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::SetTimezone(const nsACString& aTimezone)
|
||||
{
|
||||
if (mImmutable)
|
||||
return NS_ERROR_OBJECT_IS_IMMUTABLE;
|
||||
if (aTimezone.EqualsLiteral("UTC") || aTimezone.EqualsLiteral("utc")) {
|
||||
mTimezone.AssignLiteral("UTC");
|
||||
} else if (aTimezone.EqualsLiteral("floating")) {
|
||||
mTimezone.AssignLiteral("floating");
|
||||
} else {
|
||||
icaltimezone const* tz = nsnull;
|
||||
nsresult rv = GetIcalTZ(aTimezone, &tz);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
mTimezone.Assign(aTimezone);
|
||||
}
|
||||
normalize();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::GetTimezoneOffset(PRInt32 *aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
struct icaltimetype icalt;
|
||||
icaltimetype icalt;
|
||||
ToIcalTime(&icalt);
|
||||
int dst;
|
||||
*aResult = icaltimezone_get_utc_offset(
|
||||
const_cast<icaltimezone *>(icalt.zone), &icalt, &dst);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::GetNativeTime(PRTime *aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = mNativeTime;
|
||||
*aResult = icaltimezone_get_utc_offset(const_cast<icaltimezone *>(icalt.zone), &icalt, &dst);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::SetNativeTime(PRTime aNativeTime)
|
||||
{
|
||||
return SetTimeInTimezone (aNativeTime, NS_LITERAL_CSTRING("UTC"));
|
||||
}
|
||||
|
||||
// internal normalize():
|
||||
void calDateTime::normalize()
|
||||
{
|
||||
struct icaltimetype icalt;
|
||||
ToIcalTime(&icalt);
|
||||
FromIcalTime(&icalt);
|
||||
return SetTimeInTimezone(aNativeTime, cal::UTC());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::AddDuration(calIDuration *aDuration)
|
||||
{
|
||||
NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE);
|
||||
NS_ENSURE_ARG_POINTER(aDuration);
|
||||
if (mImmutable)
|
||||
return NS_ERROR_OBJECT_IS_IMMUTABLE;
|
||||
|
||||
struct icaldurationtype idt;
|
||||
icaldurationtype idt;
|
||||
aDuration->ToIcalDuration(&idt);
|
||||
|
||||
struct icaltimetype itt;
|
||||
icaltimetype itt;
|
||||
ToIcalTime(&itt);
|
||||
|
||||
struct icaltimetype newitt;
|
||||
newitt = icaltime_add(itt, idt);
|
||||
FromIcalTime(&newitt);
|
||||
icaltimetype const newitt = icaltime_add(itt, idt);
|
||||
FromIcalTime(&newitt, mTimezone);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -292,217 +206,174 @@ calDateTime::SubtractDate(calIDateTime *aDate, calIDuration **aDuration)
|
|||
icaldurationtype const idt = icaldurationtype_from_int(
|
||||
static_cast<int>((mNativeTime - t2t) / PRInt64(PR_USEC_PER_SEC)));
|
||||
|
||||
nsCOMPtr<calIDuration> const result(new calDuration(&idt));
|
||||
if (!result)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
*aDuration = result;
|
||||
NS_ADDREF(*aDuration);
|
||||
|
||||
calDuration * const dur = new calDuration(&idt);
|
||||
CAL_ENSURE_MEMORY(dur);
|
||||
NS_ADDREF(*aDuration = dur);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::ToString(nsACString& aResult)
|
||||
calDateTime::ToString(nsACString & aResult)
|
||||
{
|
||||
nsCAutoString tzid;
|
||||
mTimezone->GetTzid(tzid);
|
||||
char buffer[256];
|
||||
PRUint32 const length = PR_snprintf(
|
||||
buffer, sizeof(buffer), "%04hd/%02hd/%02hd %02hd:%02hd:%02hd %s isDate=%01hd",
|
||||
mYear, mMonth + 1, mDay, mHour, mMinute, mSecond,
|
||||
mTimezone.get(), static_cast<PRInt16>(mIsDate));
|
||||
tzid.get(), static_cast<PRInt16>(mIsDate));
|
||||
if (length != static_cast<PRUint32>(-1))
|
||||
aResult.Assign(buffer, length);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::SetTimeInTimezone(PRTime aTime, const nsACString& aTimezone)
|
||||
calDateTime::SetTimeInTimezone(PRTime aTime, calITimezone * aTimezone)
|
||||
{
|
||||
if (mImmutable)
|
||||
return NS_ERROR_OBJECT_IS_IMMUTABLE;
|
||||
if (aTimezone.IsEmpty())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
icaltimezone const* tz = nsnull;
|
||||
nsresult rv = GetIcalTZ(aTimezone, &tz);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
struct icaltimetype icalt = icaltime_null_time();
|
||||
PRTimeToIcaltime(aTime, PR_FALSE, tz, &icalt);
|
||||
|
||||
FromIcalTime(&icalt);
|
||||
|
||||
NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE);
|
||||
NS_ENSURE_ARG_POINTER(aTimezone);
|
||||
icaltimetype icalt;
|
||||
PRTimeToIcaltime(aTime, PR_FALSE, cal::getIcalTimezone(aTimezone), &icalt);
|
||||
FromIcalTime(&icalt, aTimezone);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::GetInTimezone(const nsACString& aTimezone, calIDateTime **aResult)
|
||||
calDateTime::GetInTimezone(calITimezone * aTimezone, calIDateTime ** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTimezone);
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
calDateTime *cdt = nsnull;
|
||||
|
||||
if (mIsDate) {
|
||||
// if it's a date, we really just want to make a copy of this
|
||||
// and set the timezone.
|
||||
cdt = new calDateTime(*this);
|
||||
cdt->mTimezone.Assign(aTimezone);
|
||||
} else if (mTimezone.Equals(aTimezone)) {
|
||||
cdt = new calDateTime(*this);
|
||||
nsresult rv = Clone(aResult);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = (*aResult)->SetTimezone(aTimezone);
|
||||
}
|
||||
return rv;
|
||||
} else {
|
||||
struct icaltimetype icalt;
|
||||
icaltimezone const* tz = nsnull;
|
||||
|
||||
icaltimetype icalt;
|
||||
ToIcalTime(&icalt);
|
||||
|
||||
// Get the latest version of aTimezone.
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<calIICSService> const icsSvc(do_GetService(kCalICSService, &rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
icaltimezone * tz = cal::getIcalTimezone(aTimezone);
|
||||
if (icalt.zone == tz) {
|
||||
return Clone(aResult);
|
||||
}
|
||||
|
||||
nsCAutoString newTimezone;
|
||||
rv = icsSvc->LatestTzId(aTimezone, newTimezone);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (newTimezone.Length() == 0) {
|
||||
newTimezone = aTimezone;
|
||||
}
|
||||
|
||||
rv = GetIcalTZ(newTimezone, &tz);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
/* If there's a zone, we need to convert; otherwise, we just
|
||||
* assign, since this item is floating */
|
||||
if (icalt.zone && tz) {
|
||||
icaltimezone_convert_time(&icalt,
|
||||
const_cast<icaltimezone *>(icalt.zone),
|
||||
const_cast<icaltimezone *>(tz));
|
||||
icaltimezone_convert_time(&icalt, const_cast<icaltimezone *>(icalt.zone), tz);
|
||||
}
|
||||
if (tz == icaltimezone_get_utc_timezone())
|
||||
icalt.is_utc = 1;
|
||||
else
|
||||
icalt.is_utc = 0;
|
||||
icalt.zone = tz;
|
||||
icalt.is_utc = (tz && tz == icaltimezone_get_utc_timezone());
|
||||
|
||||
cdt = new calDateTime(&icalt);
|
||||
calDateTime * cdt = new calDateTime(&icalt, aTimezone);
|
||||
CAL_ENSURE_MEMORY(cdt);
|
||||
NS_ADDREF (*aResult = cdt);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!cdt)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF (*aResult = cdt);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::GetStartOfWeek(calIDateTime **aResult)
|
||||
calDateTime::GetStartOfWeek(calIDateTime ** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
struct icaltimetype icalt;
|
||||
icaltimetype icalt;
|
||||
ToIcalTime(&icalt);
|
||||
int day_of_week = icaltime_day_of_week(icalt);
|
||||
if (day_of_week > 1)
|
||||
icaltime_adjust(&icalt, - (day_of_week - 1), 0, 0, 0);
|
||||
icalt.is_date = 1;
|
||||
|
||||
calDateTime *cdt = new calDateTime(&icalt);
|
||||
if (!cdt)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
calDateTime * const cdt = new calDateTime(&icalt, mTimezone);
|
||||
CAL_ENSURE_MEMORY(cdt);
|
||||
NS_ADDREF(*aResult = cdt);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::GetEndOfWeek(calIDateTime **aResult)
|
||||
calDateTime::GetEndOfWeek(calIDateTime ** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
struct icaltimetype icalt;
|
||||
icaltimetype icalt;
|
||||
ToIcalTime(&icalt);
|
||||
int day_of_week = icaltime_day_of_week(icalt);
|
||||
if (day_of_week < 7)
|
||||
icaltime_adjust(&icalt, 7 - day_of_week, 0, 0, 0);
|
||||
icalt.is_date = 1;
|
||||
|
||||
calDateTime *cdt = new calDateTime(&icalt);
|
||||
if (!cdt)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
calDateTime * const cdt = new calDateTime(&icalt, mTimezone);
|
||||
CAL_ENSURE_MEMORY(cdt);
|
||||
NS_ADDREF(*aResult = cdt);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::GetStartOfMonth(calIDateTime **aResult)
|
||||
calDateTime::GetStartOfMonth(calIDateTime ** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
struct icaltimetype icalt;
|
||||
icaltimetype icalt;
|
||||
ToIcalTime(&icalt);
|
||||
icalt.day = 1;
|
||||
icalt.is_date = 1;
|
||||
|
||||
calDateTime *cdt = new calDateTime(&icalt);
|
||||
if (!cdt)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
calDateTime * const cdt = new calDateTime(&icalt, mTimezone);
|
||||
CAL_ENSURE_MEMORY(cdt);
|
||||
NS_ADDREF(*aResult = cdt);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::GetEndOfMonth(calIDateTime **aResult)
|
||||
calDateTime::GetEndOfMonth(calIDateTime ** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
struct icaltimetype icalt;
|
||||
icaltimetype icalt;
|
||||
ToIcalTime(&icalt);
|
||||
icalt.day = icaltime_days_in_month(icalt.month, icalt.year);
|
||||
icalt.is_date = 1;
|
||||
|
||||
calDateTime *cdt = new calDateTime(&icalt);
|
||||
if (!cdt)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
calDateTime * const cdt = new calDateTime(&icalt, mTimezone);
|
||||
CAL_ENSURE_MEMORY(cdt);
|
||||
NS_ADDREF(*aResult = cdt);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::GetStartOfYear(calIDateTime **aResult)
|
||||
calDateTime::GetStartOfYear(calIDateTime ** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
struct icaltimetype icalt;
|
||||
icaltimetype icalt;
|
||||
ToIcalTime(&icalt);
|
||||
icalt.month = 1;
|
||||
icalt.day = 1;
|
||||
icalt.is_date = 1;
|
||||
|
||||
calDateTime *cdt = new calDateTime(&icalt);
|
||||
if (!cdt)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
calDateTime * const cdt = new calDateTime(&icalt, mTimezone);
|
||||
CAL_ENSURE_MEMORY(cdt);
|
||||
NS_ADDREF(*aResult = cdt);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::GetEndOfYear(calIDateTime **aResult)
|
||||
calDateTime::GetEndOfYear(calIDateTime ** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
struct icaltimetype icalt;
|
||||
icaltimetype icalt;
|
||||
ToIcalTime(&icalt);
|
||||
icalt.month = 12;
|
||||
icalt.day = 31;
|
||||
icalt.is_date = 1;
|
||||
|
||||
calDateTime *cdt = new calDateTime(&icalt);
|
||||
if (!cdt)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
calDateTime * const cdt = new calDateTime(&icalt, mTimezone);
|
||||
CAL_ENSURE_MEMORY(cdt);
|
||||
NS_ADDREF(*aResult = cdt);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -514,27 +385,22 @@ calDateTime::GetIcalString(nsACString& aResult)
|
|||
ToIcalTime(&t);
|
||||
|
||||
// note that ics is owned by libical, so we don't need to free
|
||||
const char *ics = icaltime_as_ical_string(t);
|
||||
|
||||
if (ics) {
|
||||
aResult.Assign(ics);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
char const * const ics = icaltime_as_ical_string(t);
|
||||
CAL_ENSURE_MEMORY(ics);
|
||||
aResult.Assign(ics);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::SetIcalString(const nsACString& aIcalString)
|
||||
calDateTime::SetIcalString(nsACString const& aIcalString)
|
||||
{
|
||||
if (mImmutable)
|
||||
return NS_ERROR_OBJECT_IS_IMMUTABLE;
|
||||
struct icaltimetype icalt;
|
||||
icalt = icaltime_from_string(nsPromiseFlatCString(aIcalString).get());
|
||||
NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE);
|
||||
icaltimetype icalt;
|
||||
icalt = icaltime_from_string(PromiseFlatCString(aIcalString).get());
|
||||
if (icaltime_is_null_time(icalt)) {
|
||||
return calIErrors::ICS_ERROR_BASE + icalerrno;
|
||||
}
|
||||
FromIcalTime(&icalt);
|
||||
FromIcalTime(&icalt, mTimezone);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -542,8 +408,16 @@ calDateTime::SetIcalString(const nsACString& aIcalString)
|
|||
** utility/protected methods
|
||||
**/
|
||||
|
||||
// internal Normalize():
|
||||
void calDateTime::Normalize()
|
||||
{
|
||||
icaltimetype icalt;
|
||||
ToIcalTime(&icalt);
|
||||
FromIcalTime(&icalt, mTimezone);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
calDateTime::ToIcalTime(icaltimetype *icalt)
|
||||
calDateTime::ToIcalTime(struct icaltimetype * icalt)
|
||||
{
|
||||
icalt->year = mYear;
|
||||
icalt->month = mMonth + 1;
|
||||
|
@ -555,25 +429,17 @@ calDateTime::ToIcalTime(icaltimetype *icalt)
|
|||
icalt->is_date = mIsDate ? 1 : 0;
|
||||
icalt->is_daylight = 0;
|
||||
|
||||
icaltimezone const* tz = nsnull;
|
||||
nsresult rv = GetIcalTZ(mTimezone, &tz);
|
||||
// this will always succeed, because
|
||||
// mTimezone can't be set without GetIcalTZ
|
||||
// succeeding.
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("calDateTime::ToIcalTime: GetIcalTZ failed!");
|
||||
}
|
||||
|
||||
icaltimezone * tz = cal::getIcalTimezone(mTimezone);
|
||||
icalt->zone = tz;
|
||||
|
||||
if (icalt->zone == icaltimezone_get_utc_timezone())
|
||||
icalt->is_utc = 1;
|
||||
else
|
||||
icalt->is_utc = 0;
|
||||
icalt->is_utc = (tz && tz == icaltimezone_get_utc_timezone());
|
||||
icalt->is_daylight = 0;
|
||||
// xxx todo: discuss/investigate is_daylight
|
||||
// if (tz) {
|
||||
// icaltimezone_get_utc_offset(tz, icalt, &icalt->is_daylight);
|
||||
// }
|
||||
}
|
||||
|
||||
void
|
||||
calDateTime::FromIcalTime(icaltimetype const* icalt)
|
||||
void calDateTime::FromIcalTime(icaltimetype const* icalt, calITimezone * tz)
|
||||
{
|
||||
icaltimetype t = *icalt;
|
||||
mIsValid = (icaltime_is_null_time(t) ||
|
||||
|
@ -597,18 +463,31 @@ calDateTime::FromIcalTime(icaltimetype const* icalt)
|
|||
mMinute = t.minute;
|
||||
mSecond = t.second;
|
||||
|
||||
if (t.is_utc || t.zone == icaltimezone_get_utc_timezone()) {
|
||||
mTimezone.AssignLiteral("UTC");
|
||||
} else if (t.zone) {
|
||||
mTimezone.Assign(icaltimezone_get_tzid(
|
||||
const_cast<icaltimezone *>(t.zone)));
|
||||
if (tz) {
|
||||
mTimezone = tz;
|
||||
} else {
|
||||
mTimezone.AssignLiteral("floating");
|
||||
mTimezone = cal::detectTimezone(t, nsnull);
|
||||
}
|
||||
#if defined(DEBUG)
|
||||
if (mTimezone) {
|
||||
if (t.is_utc) {
|
||||
NS_ASSERTION(cal::sameXpcomObject(mTimezone, cal::UTC()),
|
||||
"UTC mismatch!");
|
||||
} else if (!t.zone) {
|
||||
NS_ASSERTION(cal::sameXpcomObject(mTimezone, cal::floating()),
|
||||
"floating mismatch!");
|
||||
} else {
|
||||
nsCAutoString tzid;
|
||||
mTimezone->GetTzid(tzid);
|
||||
NS_ASSERTION(tzid.Equals(icaltimezone_get_tzid(const_cast<icaltimezone *>(t.zone))),
|
||||
"tzid mismatch!");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
mWeekday = icaltime_day_of_week(t) - 1;
|
||||
mYearday = icaltime_day_of_year(t);
|
||||
|
||||
|
||||
// mNativeTime: not moving the existing date to UTC,
|
||||
// but merely representing it a UTC-based way.
|
||||
t.is_date = 0;
|
||||
|
@ -617,8 +496,8 @@ calDateTime::FromIcalTime(icaltimetype const* icalt)
|
|||
|
||||
PRTime calDateTime::IcaltimeToPRTime(icaltimetype const* icalt, icaltimezone const* tz)
|
||||
{
|
||||
struct icaltimetype tt;
|
||||
struct PRExplodedTime et;
|
||||
icaltimetype tt;
|
||||
PRExplodedTime et;
|
||||
|
||||
/* If the time is the special null time, return 0. */
|
||||
if (icaltime_is_null_time(*icalt)) {
|
||||
|
@ -653,11 +532,9 @@ PRTime calDateTime::IcaltimeToPRTime(icaltimetype const* icalt, icaltimezone con
|
|||
|
||||
void calDateTime::PRTimeToIcaltime(PRTime time, PRBool isdate,
|
||||
icaltimezone const* tz,
|
||||
icaltimetype *icalt)
|
||||
icaltimetype * icalt)
|
||||
{
|
||||
icaltimezone *utc_zone;
|
||||
|
||||
struct PRExplodedTime et;
|
||||
PRExplodedTime et;
|
||||
PR_ExplodeTime(time, PR_GMTParameters, &et);
|
||||
|
||||
icalt->year = et.tm_year;
|
||||
|
@ -665,24 +542,28 @@ void calDateTime::PRTimeToIcaltime(PRTime time, PRBool isdate,
|
|||
icalt->day = et.tm_mday;
|
||||
|
||||
if (isdate) {
|
||||
icalt->hour = 0;
|
||||
icalt->minute = 0;
|
||||
icalt->second = 0;
|
||||
icalt->is_date = 1;
|
||||
return;
|
||||
} else {
|
||||
icalt->hour = et.tm_hour;
|
||||
icalt->minute = et.tm_min;
|
||||
icalt->second = et.tm_sec;
|
||||
icalt->is_date = 0;
|
||||
}
|
||||
|
||||
icalt->hour = et.tm_hour;
|
||||
icalt->minute = et.tm_min;
|
||||
icalt->second = et.tm_sec;
|
||||
|
||||
/* Only do conversion when not in floating timezone */
|
||||
if (tz) {
|
||||
utc_zone = icaltimezone_get_utc_timezone();
|
||||
icalt->is_utc = (tz == utc_zone) ? 1 : 0;
|
||||
icalt->zone = tz;
|
||||
}
|
||||
icalt->zone = tz;
|
||||
icalt->is_utc = ((tz && tz == icaltimezone_get_utc_timezone()) ? 1 : 0);
|
||||
icalt->is_daylight = 0;
|
||||
// xxx todo: discuss/investigate is_daylight
|
||||
// if (tz) {
|
||||
// icaltimezone_get_utc_offset(tz, icalt, &icalt->is_daylight);
|
||||
// }
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calDateTime::Compare(calIDateTime *aOther, PRInt32 *aResult)
|
||||
calDateTime::Compare(calIDateTime * aOther, PRInt32 * aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aOther);
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
@ -704,13 +585,7 @@ calDateTime::Compare(calIDateTime *aOther, PRInt32 *aResult)
|
|||
}
|
||||
|
||||
if (mIsDate || otherIsDate) {
|
||||
icaltimezone const* tz;
|
||||
nsresult rv = GetIcalTZ(mTimezone, &tz);
|
||||
if (NS_FAILED(rv))
|
||||
return calIErrors::INVALID_TIMEZONE;
|
||||
|
||||
*aResult = icaltime_compare_date_only(a, b,
|
||||
const_cast<icaltimezone *>(tz));
|
||||
*aResult = icaltime_compare_date_only(a, b, cal::getIcalTimezone(mTimezone));
|
||||
} else {
|
||||
*aResult = icaltime_compare(a, b);
|
||||
}
|
||||
|
@ -718,62 +593,23 @@ calDateTime::Compare(calIDateTime *aOther, PRInt32 *aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult calDateTime::GetIcalTZ(nsACString const& tzid, icaltimezone const** tzp)
|
||||
{
|
||||
if (tzid.IsEmpty()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (tzid.EqualsLiteral("floating")) {
|
||||
*tzp = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (tzid.EqualsLiteral("UTC") || tzid.EqualsLiteral("utc")) {
|
||||
*tzp = icaltimezone_get_utc_timezone();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<calIICSService> const ics(do_GetService(kCalICSService));
|
||||
nsCOMPtr<calIIcalComponent> tz;
|
||||
|
||||
nsresult rv = ics->GetTimezone(tzid, getter_AddRefs(tz));
|
||||
if (NS_FAILED(rv) || !tz) {
|
||||
// No timezone was found. To prevent the app from dying,
|
||||
// pretent that there is no timezone, ie return floating.
|
||||
// See bug 335879
|
||||
*tzp = nsnull;
|
||||
return NS_OK;
|
||||
// We should return an error, but don't:
|
||||
//return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (tzp) {
|
||||
icalcomponent *zonecomp = tz->GetIcalComponent();
|
||||
*tzp = icalcomponent_get_timezone(zonecomp, nsPromiseFlatCString(tzid).get());
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* nsIXPCScriptable impl
|
||||
*/
|
||||
|
||||
/* readonly attribute string className; */
|
||||
NS_IMETHODIMP
|
||||
calDateTime::GetClassName(char * *aClassName)
|
||||
calDateTime::GetClassName(char ** aClassName)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aClassName);
|
||||
*aClassName = static_cast<char *>(nsMemory::Clone("calDateTime", 12));
|
||||
if (!*aClassName)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
*aClassName = static_cast<char *>(nsMemory::Clone(CAL_STRLEN_ARGS("calDateTime") +1));
|
||||
CAL_ENSURE_MEMORY(*aClassName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute PRUint32 scriptableFlags; */
|
||||
NS_IMETHODIMP
|
||||
calDateTime::GetScriptableFlags(PRUint32 *aScriptableFlags)
|
||||
calDateTime::GetScriptableFlags(PRUint32 * aScriptableFlags)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aScriptableFlags);
|
||||
*aScriptableFlags = nsIXPCScriptable::WANT_GETPROPERTY |
|
||||
|
@ -783,7 +619,6 @@ calDateTime::GetScriptableFlags(PRUint32 *aScriptableFlags)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
inline
|
||||
/* PRBool getProperty (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in JSVal id, in JSValPtr vp); */
|
||||
NS_IMETHODIMP
|
||||
calDateTime::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
|
||||
|
@ -805,7 +640,8 @@ calDateTime::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
|
|||
LL_L2D(msec, tmp);
|
||||
|
||||
JSObject *obj;
|
||||
if (mTimezone.EqualsLiteral("floating"))
|
||||
PRBool b;
|
||||
if (NS_SUCCEEDED(mTimezone->GetIsFloating(&b)) && b)
|
||||
obj = js_NewDateObject(cx, mYear, mMonth, mDay, mHour, mMinute, mSecond);
|
||||
else
|
||||
obj = js_NewDateObjectMsec(cx, msec);
|
||||
|
@ -953,8 +789,7 @@ calDateTime::Convert(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
|
|||
|
||||
/* void finalize (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); */
|
||||
NS_IMETHODIMP
|
||||
calDateTime::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
|
||||
JSObject * obj)
|
||||
calDateTime::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
@ -999,8 +834,7 @@ calDateTime::Mark(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
|
|||
#else
|
||||
/* void trace (in nsIXPConnectWrappedNative wrapper, in JSTracePtr trc, in JSObjectPtr obj); */
|
||||
NS_IMETHODIMP
|
||||
calDateTime::Trace(nsIXPConnectWrappedNative *wrapper, JSTracer *trc,
|
||||
JSObject *obj)
|
||||
calDateTime::Trace(nsIXPConnectWrappedNative *wrapper, JSTracer *trc, JSObject *obj)
|
||||
#endif
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
@ -1029,25 +863,3 @@ calDateTime::InnerObject(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* We are subclassing nsCString for mTimezone so we can check the tzid of all
|
||||
* calIDateTimes as they go by.
|
||||
*/
|
||||
void calTzId::Assign(char const* c)
|
||||
{
|
||||
this->Assign(nsDependentCString(c));
|
||||
}
|
||||
|
||||
void calTzId::Assign(nsACString const& aStr)
|
||||
{
|
||||
nsCString _retVal;
|
||||
nsCOMPtr<calIICSService> const icsSvc(do_GetService(kCalICSService));
|
||||
icsSvc->LatestTzId(aStr, _retVal);
|
||||
|
||||
if (_retVal.Length() != 0) {
|
||||
nsCString::Assign(_retVal);
|
||||
} else {
|
||||
nsCString::Assign(aStr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -21,6 +20,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
|
||||
* Daniel Boelzle <daniel.boelzle@sun.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -35,52 +35,34 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef CALDATETIME_H_
|
||||
#define CALDATETIME_H_
|
||||
#if !defined(INCLUDED_CALDATETIME_H)
|
||||
#define INCLUDED_CALDATETIME_H
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "nsIXPCScriptable.h"
|
||||
#include "calIDateTime.h"
|
||||
#include "calITimezoneProvider.h"
|
||||
#include "calUtils.h"
|
||||
|
||||
struct icaltimetype;
|
||||
typedef struct _icaltimezone icaltimezone;
|
||||
|
||||
/* This class subclasses nsCString so we can check tzids for "freshness". */
|
||||
class calTzId : public nsCString
|
||||
{
|
||||
public:
|
||||
/* Used by AssignLiteral when we set the tzid to "utc" or "floating". */
|
||||
void Assign(char const* c);
|
||||
/* Used by mTimezone.Assign as our hook to check the tzid's "freshness". */
|
||||
void Assign(nsACString const& aStr);
|
||||
};
|
||||
|
||||
class calDateTime : public calIDateTime,
|
||||
public nsIXPCScriptable
|
||||
public nsIXPCScriptable,
|
||||
public cal::XpcomBase
|
||||
{
|
||||
public:
|
||||
calDateTime ();
|
||||
explicit calDateTime (struct icaltimetype const* timeptr);
|
||||
calDateTime (const calDateTime& cdt);
|
||||
calDateTime();
|
||||
calDateTime(icaltimetype const* icalt, calITimezone * tz);
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// calIDateTime interface
|
||||
NS_DECL_CALIDATETIME
|
||||
|
||||
// nsIXPCScriptable interface
|
||||
NS_DECL_NSIXPCSCRIPTABLE
|
||||
|
||||
protected:
|
||||
calDateTime const& operator=(calDateTime const&);
|
||||
|
||||
PRBool mImmutable;
|
||||
|
||||
PRBool mIsValid;
|
||||
|
||||
PRTime mNativeTime;
|
||||
PRBool mIsDate;
|
||||
|
||||
PRInt16 mYear;
|
||||
PRInt16 mMonth;
|
||||
|
@ -88,21 +70,18 @@ protected:
|
|||
PRInt16 mHour;
|
||||
PRInt16 mMinute;
|
||||
PRInt16 mSecond;
|
||||
|
||||
PRBool mIsDate;
|
||||
calTzId mTimezone;
|
||||
|
||||
PRInt16 mWeekday;
|
||||
PRInt16 mYearday;
|
||||
|
||||
void normalize();
|
||||
void FromIcalTime(icaltimetype const* icalt);
|
||||
PRTime mNativeTime;
|
||||
nsCOMPtr<calITimezone> mTimezone;
|
||||
|
||||
static nsresult GetIcalTZ(nsACString const& tzid, icaltimezone const** tzp);
|
||||
void Normalize();
|
||||
void FromIcalTime(icaltimetype const* icalt, calITimezone *tz);
|
||||
|
||||
static PRTime IcaltimeToPRTime(icaltimetype const* icalt, icaltimezone const* tz);
|
||||
static void PRTimeToIcaltime(PRTime time, PRBool isdate,
|
||||
icaltimezone const* tz, icaltimetype *icalt);
|
||||
};
|
||||
|
||||
#endif /* CALDATETIME_H_ */
|
||||
#endif // INCLUDED_CALDATETIME_H
|
||||
|
|
|
@ -60,7 +60,7 @@ function calDateTimeFormatter() {
|
|||
var probeDate =
|
||||
Components.classes["@mozilla.org/calendar/datetime;1"]
|
||||
.createInstance(Components.interfaces.calIDateTime);
|
||||
probeDate.timezone = "UTC";
|
||||
probeDate.timezone = UTC();
|
||||
probeDate.year = 2002;
|
||||
probeDate.month = 3;
|
||||
probeDate.day = 5;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,4 +1,3 @@
|
|||
/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -21,6 +20,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Mike Shaver <mike.x.shaver@oracle.com>
|
||||
* Daniel Boelzle <daniel.boelzle@sun.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -35,69 +35,128 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#if !defined(INCLUDED_CALICSSERVICE_H)
|
||||
#define INCLUDED_CALICSSERVICE_H
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "calIICSService.h"
|
||||
|
||||
#include "nsClassHashtable.h"
|
||||
#include "calITimezoneProvider.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "calUtils.h"
|
||||
|
||||
extern "C" {
|
||||
# include "ical.h"
|
||||
#include "ical.h"
|
||||
}
|
||||
|
||||
class calIIcalComponent;
|
||||
class calIcalComponent;
|
||||
|
||||
struct TimezoneEntry
|
||||
{
|
||||
nsCString const mLatitude;
|
||||
nsCString const mLongitude;
|
||||
nsCOMPtr<calIIcalComponent> const mTzCal;
|
||||
|
||||
TimezoneEntry(nsACString const& latitude,
|
||||
nsACString const& longitude,
|
||||
nsCOMPtr<calIIcalComponent> const& tzCal)
|
||||
: mLatitude(latitude), mLongitude(longitude), mTzCal(tzCal) {}
|
||||
};
|
||||
|
||||
class calICSService : public calIICSService
|
||||
class calICSService : public calIICSService,
|
||||
public cal::XpcomBase
|
||||
{
|
||||
public:
|
||||
calICSService();
|
||||
virtual ~calICSService() { }
|
||||
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_CALIICSSERVICE
|
||||
protected:
|
||||
nsClassHashtable<nsCStringHashKey, TimezoneEntry> mTzHash;
|
||||
TimezoneEntry const* getTimezoneEntry(nsACString const& tzid);
|
||||
};
|
||||
|
||||
class calIcalProperty : public calIIcalProperty
|
||||
class calIcalComponent;
|
||||
|
||||
class calIcalProperty : public calIIcalProperty,
|
||||
public cal::XpcomBase
|
||||
{
|
||||
friend class calIcalComponent;
|
||||
public:
|
||||
calIcalProperty(icalproperty *prop, calIIcalComponent *parent) :
|
||||
mProperty(prop), mParent(parent) { }
|
||||
virtual ~calIcalProperty()
|
||||
{
|
||||
if (!mParent)
|
||||
icalproperty_free(mProperty);
|
||||
}
|
||||
|
||||
icalproperty * getIcalProperty() const { return mProperty; }
|
||||
|
||||
static nsresult getDatetime_(calIIcalComponent *comp,
|
||||
icalproperty *prop,
|
||||
calIDateTime **dtp);
|
||||
static nsresult setDatetime_(calIIcalComponent *comp,
|
||||
icalproperty *prop,
|
||||
calIDateTime *dt);
|
||||
calIcalProperty(icalproperty * prop, calIIcalComponent * parent)
|
||||
: mProperty(prop), mParent(parent) {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_CALIICALPROPERTY
|
||||
|
||||
friend class calIcalComponent;
|
||||
protected:
|
||||
icalproperty *mProperty;
|
||||
virtual ~calIcalProperty();
|
||||
|
||||
static nsresult getDatetime_(calIcalComponent *parent,
|
||||
icalproperty *prop,
|
||||
calIDateTime **dtp);
|
||||
static nsresult setDatetime_(calIcalComponent *parent,
|
||||
icalproperty *prop,
|
||||
calIDateTime *dt);
|
||||
|
||||
icalproperty * mProperty;
|
||||
nsCOMPtr<calIIcalComponent> mParent;
|
||||
};
|
||||
|
||||
class calIcalComponent : public calIIcalComponent,
|
||||
public cal::XpcomBase
|
||||
{
|
||||
friend class calIcalProperty;
|
||||
public:
|
||||
calIcalComponent(icalcomponent *ical, calIIcalComponent *parent,
|
||||
calITimezoneProvider *tzProvider = nsnull)
|
||||
: mComponent(ical), mParent(parent), mTimezone(nsnull), mTzProvider(tzProvider)
|
||||
{
|
||||
mReferencedTimezones.Init();
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_CALIICALCOMPONENT
|
||||
|
||||
protected:
|
||||
virtual ~calIcalComponent();
|
||||
|
||||
calITimezoneProvider * getTzProvider() const {
|
||||
// walk up the parents to find a tz provider:
|
||||
calIcalComponent const * that = this;
|
||||
while (that) {
|
||||
calITimezoneProvider * const ret = that->mTzProvider;
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
calIIcalComponent * const p = that->mParent;
|
||||
that = static_cast<calIcalComponent const *>(p);
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
calIcalComponent * getParentVCalendarOrThis() {
|
||||
// walk up the parents to find a VCALENDAR:
|
||||
calIcalComponent * that = this;
|
||||
while (that && icalcomponent_isa(that->mComponent) != ICAL_VCALENDAR_COMPONENT) {
|
||||
calIIcalComponent * const p = that->mParent;
|
||||
that = static_cast<calIcalComponent *>(p);
|
||||
}
|
||||
if (!that)
|
||||
that = this;
|
||||
return that;
|
||||
}
|
||||
|
||||
nsresult GetDateTimeAttribute(icalproperty_kind kind, calIDateTime ** dtp);
|
||||
nsresult SetDateTimeAttribute(icalproperty_kind kind, calIDateTime * dt);
|
||||
|
||||
nsresult SetPropertyValue(icalproperty_kind kind, icalvalue *val);
|
||||
nsresult SetProperty(icalproperty_kind kind, icalproperty *prop);
|
||||
|
||||
nsresult GetStringProperty(icalproperty_kind kind, nsACString &str);
|
||||
nsresult SetStringProperty(icalproperty_kind kind, const nsACString &str);
|
||||
|
||||
nsresult GetIntProperty(icalproperty_kind kind, PRInt32 *valp);
|
||||
nsresult SetIntProperty(icalproperty_kind kind, PRInt32 i);
|
||||
|
||||
void ClearAllProperties(icalproperty_kind kind);
|
||||
|
||||
nsresult Serialize(char ** icalstr);
|
||||
|
||||
nsInterfaceHashtable<nsCStringHashKey, calITimezone> mReferencedTimezones;
|
||||
icalcomponent * mComponent;
|
||||
icaltimezone * mTimezone; // set iff VTIMEZONE
|
||||
nsCOMPtr<calIIcalComponent> mParent;
|
||||
nsCOMPtr<calITimezoneProvider> const mTzProvider;
|
||||
};
|
||||
|
||||
inline calIcalProperty * toIcalProperty(calIIcalProperty * p) {
|
||||
return static_cast<calIcalProperty *>(p);
|
||||
}
|
||||
inline calIcalComponent * toIcalComponent(calIIcalComponent * p) {
|
||||
return static_cast<calIcalComponent *>(p);
|
||||
}
|
||||
|
||||
#endif // INCLUDED_CALICSSERVICE_H
|
||||
|
|
|
@ -53,11 +53,11 @@ function QueryInterface(aIID) {
|
|||
};
|
||||
|
||||
calIcsParser.prototype.parseString =
|
||||
function ip_parseString(aICSString) {
|
||||
function ip_parseString(aICSString, aTzProvider) {
|
||||
icsSvc = Components.classes["@mozilla.org/calendar/ics-service;1"]
|
||||
.getService(Components.interfaces.calIICSService);
|
||||
|
||||
var rootComp = icsSvc.parseICS(aICSString);
|
||||
var rootComp = icsSvc.parseICS(aICSString, aTzProvider);
|
||||
var calComp;
|
||||
// libical returns the vcalendar component if there is just one vcalendar.
|
||||
// If there are multiple vcalendars, it returns an xroot component, with
|
||||
|
@ -95,14 +95,12 @@ function ip_parseString(aICSString) {
|
|||
var item = null;
|
||||
switch (subComp.componentType) {
|
||||
case "VEVENT":
|
||||
var event = Components.classes["@mozilla.org/calendar/event;1"]
|
||||
.createInstance(Components.interfaces.calIEvent);
|
||||
item = event;
|
||||
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);
|
||||
item = todo;
|
||||
item = Components.classes["@mozilla.org/calendar/todo;1"]
|
||||
.createInstance(Components.interfaces.calITodo);
|
||||
break;
|
||||
case "VTIMEZONE":
|
||||
// this should already be attached to the relevant
|
||||
|
@ -155,7 +153,7 @@ function ip_parseString(aICSString) {
|
|||
};
|
||||
|
||||
calIcsParser.prototype.parseFromStream =
|
||||
function ip_parseFromStream(aStream) {
|
||||
function ip_parseFromStream(aStream, aTzProvider) {
|
||||
// Read in the string. Note that it isn't a real string at this point,
|
||||
// because likely, the file is utf8. The multibyte chars show up as multiple
|
||||
// 'chars' in this string. So call it an array of octets for now.
|
||||
|
@ -186,7 +184,7 @@ function ip_parseFromStream(aStream) {
|
|||
// ICS files are always UTF8
|
||||
unicodeConverter.charset = "UTF-8";
|
||||
var str = unicodeConverter.convertFromByteArray(octetArray, octetArray.length);
|
||||
return this.parseString(str);
|
||||
return this.parseString(str, aTzProvider);
|
||||
}
|
||||
|
||||
calIcsParser.prototype.getItems =
|
||||
|
|
|
@ -74,7 +74,7 @@ calItemBase.prototype = {
|
|||
var cal = this.calendar;
|
||||
// some unused delim character:
|
||||
this.mHashId = [encodeURIComponent(this.id),
|
||||
rid ? rid.getInTimezone("UTC").icalString : "",
|
||||
rid ? rid.getInTimezone(UTC()).icalString : "",
|
||||
cal ? encodeURIComponent(cal.id) : ""].join("#");
|
||||
}
|
||||
return this.mHashId;
|
||||
|
@ -808,7 +808,7 @@ function icalFromString(str)
|
|||
{
|
||||
const icssvc = Components.classes["@mozilla.org/calendar/ics-service;1"].
|
||||
getService(Components.interfaces.calIICSService);
|
||||
return icssvc.parseICS(str);
|
||||
return icssvc.parseICS(str, null);
|
||||
}
|
||||
|
||||
function icalProp(kind)
|
||||
|
|
|
@ -165,7 +165,7 @@ calItipItem.prototype = {
|
|||
init: function ciiI(aIcalString) {
|
||||
var parser = Components.classes["@mozilla.org/calendar/ics-parser;1"].
|
||||
createInstance(Components.interfaces.calIIcsParser);
|
||||
parser.parseString(aIcalString);
|
||||
parser.parseString(aIcalString, null);
|
||||
this.mItemList = parser.getItems({});
|
||||
this.mPropertiesList = parser.getProperties({});
|
||||
|
||||
|
|
|
@ -109,8 +109,7 @@ NS_IMETHODIMP calPeriod::SetStart(calIDateTime *aValue)
|
|||
return NS_ERROR_OBJECT_IS_IMMUTABLE;
|
||||
// rfc2445 says that periods are always in utc. libical ignore that,
|
||||
// so we need the conversion here.
|
||||
nsresult const rv = aValue->GetInTimezone(
|
||||
NS_LITERAL_CSTRING("UTC"), getter_AddRefs(mStart));
|
||||
nsresult const rv = aValue->GetInTimezone(cal::UTC(), getter_AddRefs(mStart));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return mStart->MakeImmutable();
|
||||
}
|
||||
|
@ -127,8 +126,7 @@ NS_IMETHODIMP calPeriod::SetEnd(calIDateTime *aValue)
|
|||
NS_ENSURE_ARG_POINTER(aValue);
|
||||
if (mImmutable)
|
||||
return NS_ERROR_OBJECT_IS_IMMUTABLE;
|
||||
nsresult const rv = aValue->GetInTimezone(
|
||||
NS_LITERAL_CSTRING("UTC"), getter_AddRefs(mEnd));
|
||||
nsresult const rv = aValue->GetInTimezone(cal::UTC(), getter_AddRefs(mEnd));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return mEnd->MakeImmutable();
|
||||
}
|
||||
|
@ -163,9 +161,9 @@ calPeriod::ToIcalPeriod(struct icalperiodtype *icalp)
|
|||
void
|
||||
calPeriod::FromIcalPeriod(struct icalperiodtype const* icalp)
|
||||
{
|
||||
mStart = new calDateTime(&(icalp->start));
|
||||
mStart = new calDateTime(&(icalp->start), nsnull);
|
||||
mStart->MakeImmutable();
|
||||
mEnd = new calDateTime(&(icalp->end));
|
||||
mEnd = new calDateTime(&(icalp->end), nsnull);
|
||||
mEnd->MakeImmutable();
|
||||
return;
|
||||
}
|
||||
|
@ -196,7 +194,7 @@ calPeriod::SetIcalString(const nsACString& aIcalString)
|
|||
ip = icalperiodtype_from_string(nsPromiseFlatCString(aIcalString).get());
|
||||
//XXX Shortcut. Assumes nobody tried to overrule our impl. of calIDateTime
|
||||
// Should use NS_NEWXPCOM()
|
||||
mStart = new calDateTime(&ip.start);
|
||||
mEnd = new calDateTime(&ip.end);
|
||||
mStart = new calDateTime(&ip.start, nsnull);
|
||||
mEnd = new calDateTime(&ip.end, nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -720,8 +720,8 @@ calRecurrenceInfo.prototype = {
|
|||
}
|
||||
|
||||
// convert both dates to UTC since subtractDate is not timezone aware.
|
||||
aOldStartTime = aOldStartTime.getInTimezone("UTC");
|
||||
aNewStartTime = aNewStartTime.getInTimezone("UTC");
|
||||
aOldStartTime = aOldStartTime.getInTimezone(UTC());
|
||||
aNewStartTime = aNewStartTime.getInTimezone(UTC());
|
||||
var timeDiff = aNewStartTime.subtractDate(aOldStartTime);
|
||||
var exceptions = this.getExceptionIds({});
|
||||
var modifiedExceptions = [];
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -51,10 +50,6 @@
|
|||
#include "nsIClassInfoImpl.h"
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
#include "ical.h"
|
||||
}
|
||||
|
||||
#include <climits>
|
||||
|
||||
NS_IMPL_ISUPPORTS2_CI(calRecurrenceRule, calIRecurrenceItem, calIRecurrenceRule)
|
||||
|
@ -64,20 +59,13 @@ calRecurrenceRule::calRecurrenceRule()
|
|||
mIsNegative(PR_FALSE),
|
||||
mIsByCount(PR_FALSE)
|
||||
{
|
||||
mIcalRecur = new struct icalrecurrencetype;
|
||||
icalrecurrencetype_clear(mIcalRecur);
|
||||
}
|
||||
|
||||
calRecurrenceRule::~calRecurrenceRule()
|
||||
{
|
||||
delete mIcalRecur;
|
||||
icalrecurrencetype_clear(&mIcalRecur);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calRecurrenceRule::GetIsMutable(PRBool *aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
*aResult = !mImmutable;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -85,9 +73,6 @@ calRecurrenceRule::GetIsMutable(PRBool *aResult)
|
|||
NS_IMETHODIMP
|
||||
calRecurrenceRule::MakeImmutable()
|
||||
{
|
||||
if (mImmutable)
|
||||
return NS_ERROR_FAILURE; // XXX another error code
|
||||
|
||||
mImmutable = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -95,13 +80,12 @@ calRecurrenceRule::MakeImmutable()
|
|||
NS_IMETHODIMP
|
||||
calRecurrenceRule::Clone(calIRecurrenceItem **aResult)
|
||||
{
|
||||
calRecurrenceRule *crc = new calRecurrenceRule;
|
||||
if (!crc)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
calRecurrenceRule * const crc = new calRecurrenceRule();
|
||||
CAL_ENSURE_MEMORY(crc);
|
||||
|
||||
crc->mIsNegative = mIsNegative;
|
||||
crc->mIsByCount = mIsByCount;
|
||||
*(crc->mIcalRecur) = *mIcalRecur;
|
||||
crc->mIcalRecur = mIcalRecur;
|
||||
|
||||
NS_ADDREF(*aResult = crc);
|
||||
return NS_OK;
|
||||
|
@ -112,7 +96,6 @@ NS_IMETHODIMP
|
|||
calRecurrenceRule::GetIsNegative(PRBool *_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
*_retval = mIsNegative;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -121,8 +104,7 @@ NS_IMETHODIMP
|
|||
calRecurrenceRule::SetIsNegative(PRBool aIsNegative)
|
||||
{
|
||||
if (mImmutable)
|
||||
return NS_ERROR_FAILURE; // XXX CAL_ERROR_ITEM_IS_IMMUTABLE
|
||||
|
||||
return NS_ERROR_OBJECT_IS_IMMUTABLE;
|
||||
mIsNegative = aIsNegative;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -133,8 +115,8 @@ calRecurrenceRule::GetIsFinite(PRBool *_retval)
|
|||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
if ((mIsByCount && mIcalRecur->count == 0) ||
|
||||
(!mIsByCount && icaltime_is_null_time(mIcalRecur->until)))
|
||||
if ((mIsByCount && mIcalRecur.count == 0) ||
|
||||
(!mIsByCount && icaltime_is_null_time(mIcalRecur.until)))
|
||||
{
|
||||
*_retval = PR_FALSE;
|
||||
} else {
|
||||
|
@ -147,7 +129,7 @@ calRecurrenceRule::GetIsFinite(PRBool *_retval)
|
|||
NS_IMETHODIMP
|
||||
calRecurrenceRule::GetType(nsACString &aType)
|
||||
{
|
||||
switch (mIcalRecur->freq) {
|
||||
switch (mIcalRecur.freq) {
|
||||
#define RECUR_HELPER(x) \
|
||||
case ICAL_##x##_RECURRENCE: aType.AssignLiteral( #x ); break
|
||||
RECUR_HELPER(SECONDLY);
|
||||
|
@ -169,7 +151,7 @@ NS_IMETHODIMP
|
|||
calRecurrenceRule::SetType(const nsACString &aType)
|
||||
{
|
||||
#define RECUR_HELPER(x) \
|
||||
if (aType.EqualsLiteral( #x )) mIcalRecur->freq = ICAL_##x##_RECURRENCE
|
||||
if (aType.EqualsLiteral( #x )) mIcalRecur.freq = ICAL_##x##_RECURRENCE
|
||||
RECUR_HELPER(SECONDLY);
|
||||
else RECUR_HELPER(MINUTELY);
|
||||
else RECUR_HELPER(HOURLY);
|
||||
|
@ -179,7 +161,7 @@ calRecurrenceRule::SetType(const nsACString &aType)
|
|||
else RECUR_HELPER(YEARLY);
|
||||
#undef RECUR_HELPER
|
||||
else if (aType.IsEmpty() || aType.EqualsLiteral(""))
|
||||
mIcalRecur->freq = ICAL_NO_RECURRENCE;
|
||||
mIcalRecur.freq = ICAL_NO_RECURRENCE;
|
||||
else
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -195,10 +177,10 @@ calRecurrenceRule::GetCount(PRInt32 *aRecurCount)
|
|||
if (!mIsByCount)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (mIcalRecur->count == 0 && icaltime_is_null_time(mIcalRecur->until)) {
|
||||
if (mIcalRecur.count == 0 && icaltime_is_null_time(mIcalRecur.until)) {
|
||||
*aRecurCount = -1;
|
||||
} else if (mIcalRecur->count) {
|
||||
*aRecurCount = mIcalRecur->count;
|
||||
} else if (mIcalRecur.count) {
|
||||
*aRecurCount = mIcalRecur.count;
|
||||
} else {
|
||||
// count wasn't set, so we don't know
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -213,12 +195,12 @@ calRecurrenceRule::SetCount(PRInt32 aRecurCount)
|
|||
if (aRecurCount != -1) {
|
||||
if (aRecurCount < 0 || aRecurCount > INT_MAX)
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
mIcalRecur->count = static_cast<int>(aRecurCount);
|
||||
mIcalRecur.count = static_cast<int>(aRecurCount);
|
||||
} else {
|
||||
mIcalRecur->count = 0;
|
||||
mIcalRecur.count = 0;
|
||||
}
|
||||
|
||||
mIcalRecur->until = icaltime_null_time();
|
||||
mIcalRecur.until = icaltime_null_time();
|
||||
|
||||
mIsByCount = PR_TRUE;
|
||||
|
||||
|
@ -234,12 +216,10 @@ calRecurrenceRule::GetEndDate(calIDateTime * *aRecurEnd)
|
|||
if (mIsByCount)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!icaltime_is_null_time(mIcalRecur->until)) {
|
||||
calDateTime *cdt = new calDateTime(&mIcalRecur->until);
|
||||
if (!cdt)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF (*aRecurEnd = cdt);
|
||||
if (!icaltime_is_null_time(mIcalRecur.until)) {
|
||||
*aRecurEnd = new calDateTime(&mIcalRecur.until, nsnull);
|
||||
CAL_ENSURE_MEMORY(*aRecurEnd);
|
||||
NS_ADDREF(*aRecurEnd);
|
||||
} else {
|
||||
// infinite recurrence
|
||||
*aRecurEnd = nsnull;
|
||||
|
@ -250,16 +230,26 @@ calRecurrenceRule::GetEndDate(calIDateTime * *aRecurEnd)
|
|||
NS_IMETHODIMP
|
||||
calRecurrenceRule::SetEndDate(calIDateTime * aRecurEnd)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRecurEnd);
|
||||
if (aRecurEnd) {
|
||||
nsCOMPtr<calIDateTime> dt(aRecurEnd);
|
||||
nsCOMPtr<calITimezone> tz;
|
||||
aRecurEnd->GetTimezone(getter_AddRefs(tz));
|
||||
PRBool b;
|
||||
if (NS_SUCCEEDED(tz->GetIsUTC(&b)) && !b &&
|
||||
NS_SUCCEEDED(tz->GetIsFloating(&b)) && !b) {
|
||||
// convert to UTC:
|
||||
aRecurEnd->GetInTimezone(cal::UTC(), getter_AddRefs(dt));
|
||||
}
|
||||
struct icaltimetype itt;
|
||||
aRecurEnd->ToIcalTime(&itt);
|
||||
dt->ToIcalTime(&itt);
|
||||
|
||||
mIcalRecur->until = itt;
|
||||
mIcalRecur.until = itt;
|
||||
} else {
|
||||
mIcalRecur->until = icaltime_null_time();
|
||||
mIcalRecur.until = icaltime_null_time();
|
||||
}
|
||||
|
||||
mIcalRecur->count = 0;
|
||||
mIcalRecur.count = 0;
|
||||
|
||||
mIsByCount = PR_FALSE;
|
||||
|
||||
|
@ -279,7 +269,7 @@ NS_IMETHODIMP
|
|||
calRecurrenceRule::GetInterval(PRInt32 *aInterval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aInterval);
|
||||
*aInterval = mIcalRecur->interval;
|
||||
*aInterval = mIcalRecur.interval;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -288,7 +278,7 @@ calRecurrenceRule::SetInterval(PRInt32 aInterval)
|
|||
{
|
||||
if (aInterval < 0 || aInterval > SHRT_MAX)
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
mIcalRecur->interval = static_cast<short>(aInterval);
|
||||
mIcalRecur.interval = static_cast<short>(aInterval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -305,11 +295,11 @@ calRecurrenceRule::GetComponent(const nsACString &aComponentType, PRUint32 *aCou
|
|||
if (aComponentType.EqualsLiteral( #_comptype )) { \
|
||||
int count; \
|
||||
for (count = 0; count < _icalmax; count++) { \
|
||||
if (mIcalRecur->_icalvar[count] == ICAL_RECURRENCE_ARRAY_MAX) \
|
||||
if (mIcalRecur._icalvar[count] == ICAL_RECURRENCE_ARRAY_MAX) \
|
||||
break; \
|
||||
} \
|
||||
if (count) { \
|
||||
*aValues = (PRInt16*) nsMemory::Clone(mIcalRecur->_icalvar, \
|
||||
*aValues = (PRInt16*) nsMemory::Clone(mIcalRecur._icalvar, \
|
||||
count * sizeof(PRInt16)); \
|
||||
if (!*aValues) return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} else { \
|
||||
|
@ -347,9 +337,9 @@ calRecurrenceRule::SetComponent(const nsACString& aComponentType, PRUint32 aCoun
|
|||
if (aComponentType.EqualsLiteral( #_comptype )) { \
|
||||
if (aCount > _icalmax) \
|
||||
return NS_ERROR_FAILURE; \
|
||||
memcpy(mIcalRecur->_icalvar, aValues, aCount * sizeof(PRInt16)); \
|
||||
memcpy(mIcalRecur._icalvar, aValues, aCount * sizeof(PRInt16)); \
|
||||
if (aCount < _icalmax) \
|
||||
mIcalRecur->_icalvar[aCount] = ICAL_RECURRENCE_ARRAY_MAX; \
|
||||
mIcalRecur._icalvar[aCount] = ICAL_RECURRENCE_ARRAY_MAX; \
|
||||
}
|
||||
|
||||
HANDLE_COMPONENT(BYSECOND, by_second, ICAL_BY_SECOND_SIZE)
|
||||
|
@ -387,8 +377,7 @@ calRecurrenceRule::GetNextOccurrence(calIDateTime *aStartTime,
|
|||
aOccurrenceTime->ToIcalTime(&occurtime);
|
||||
|
||||
icalrecur_iterator* recur_iter;
|
||||
recur_iter = icalrecur_iterator_new (*mIcalRecur,
|
||||
dtstart);
|
||||
recur_iter = icalrecur_iterator_new(mIcalRecur, dtstart);
|
||||
if (!recur_iter)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
@ -407,8 +396,11 @@ calRecurrenceRule::GetNextOccurrence(calIDateTime *aStartTime,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<calIDateTime> cdt = new calDateTime(&next);
|
||||
NS_ADDREF(*_retval = cdt);
|
||||
nsCOMPtr<calITimezone> tz;
|
||||
aStartTime->GetTimezone(getter_AddRefs(tz));
|
||||
*_retval = new calDateTime(&next, tz);
|
||||
CAL_ENSURE_MEMORY(*_retval);
|
||||
NS_ADDREF(*_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -439,18 +431,18 @@ calRecurrenceRule::GetOccurrences(calIDateTime *aStartTime,
|
|||
|
||||
// make sure the request is sane; infinite recurrence
|
||||
// with no end time is bad times.
|
||||
if (!aMaxCount && !aRangeEnd && mIcalRecur->count == 0 && icaltime_is_null_time(mIcalRecur->until))
|
||||
if (!aMaxCount && !aRangeEnd && mIcalRecur.count == 0 && icaltime_is_null_time(mIcalRecur.until))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCOMArray<calIDateTime> dates;
|
||||
|
||||
#ifdef DEBUG_dbo
|
||||
{
|
||||
char* ss = icalrecurrencetype_as_string(mIcalRecur);
|
||||
char const * const ss = icalrecurrencetype_as_string(&mIcalRecur);
|
||||
nsCAutoString tst, tend;
|
||||
aRangeStart->ToString(tst);
|
||||
aRangeEnd->ToString(tend);
|
||||
printf("RULE: [%s -> %s, %d]: %s\n", tst.get(), tend.get(), mIcalRecur->count, ss);
|
||||
printf("RULE: [%s -> %s, %d]: %s\n", tst.get(), tend.get(), mIcalRecur.count, ss);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -458,6 +450,9 @@ calRecurrenceRule::GetOccurrences(calIDateTime *aStartTime,
|
|||
aRangeStart->ToIcalTime(&rangestart);
|
||||
rangestart = ensureDateTime(rangestart);
|
||||
aStartTime->ToIcalTime(&dtstart);
|
||||
nsCOMPtr<calITimezone> tz;
|
||||
aStartTime->GetTimezone(getter_AddRefs(tz));
|
||||
|
||||
if (aRangeEnd) {
|
||||
aRangeEnd->ToIcalTime(&dtend);
|
||||
dtend = ensureDateTime(dtend);
|
||||
|
@ -472,7 +467,7 @@ calRecurrenceRule::GetOccurrences(calIDateTime *aStartTime,
|
|||
}
|
||||
|
||||
icalrecur_iterator* recur_iter;
|
||||
recur_iter = icalrecur_iterator_new (*mIcalRecur, dtstart);
|
||||
recur_iter = icalrecur_iterator_new(mIcalRecur, dtstart);
|
||||
if (!recur_iter)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
@ -492,7 +487,7 @@ calRecurrenceRule::GetOccurrences(calIDateTime *aStartTime,
|
|||
if (aRangeEnd && icaltime_compare(dtNext, dtend) >= 0)
|
||||
break;
|
||||
|
||||
nsCOMPtr<calIDateTime> cdt = new calDateTime(&next);
|
||||
calIDateTime * const cdt = new calDateTime(&next, tz);
|
||||
if (!cdt) {
|
||||
icalrecur_iterator_free(recur_iter);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -536,9 +531,8 @@ calRecurrenceRule::GetOccurrences(calIDateTime *aStartTime,
|
|||
NS_IMETHODIMP
|
||||
calRecurrenceRule::GetIcalProperty(calIIcalProperty **prop)
|
||||
{
|
||||
icalproperty* rrule = icalproperty_new_rrule(*mIcalRecur);
|
||||
if (!rrule)
|
||||
return NS_ERROR_OUT_OF_MEMORY; // XXX map error code
|
||||
icalproperty * const rrule = icalproperty_new_rrule(mIcalRecur);
|
||||
CAL_ENSURE_MEMORY(rrule);
|
||||
*prop = new calIcalProperty(rrule, nsnull);
|
||||
if (!*prop) {
|
||||
icalproperty_free(rrule);
|
||||
|
@ -555,15 +549,10 @@ calRecurrenceRule::SetIcalProperty(calIIcalProperty *aProp)
|
|||
NS_ENSURE_ARG_POINTER(aProp);
|
||||
|
||||
if (mImmutable)
|
||||
return NS_ERROR_FAILURE;
|
||||
return NS_ERROR_OBJECT_IS_IMMUTABLE;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// XXX we really should do some CID checking here
|
||||
calIcalProperty *cprop = static_cast<calIcalProperty *>(aProp);
|
||||
nsCAutoString propname;
|
||||
|
||||
rv = cprop->GetPropertyName(propname);
|
||||
nsresult rv = aProp->GetPropertyName(propname);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (propname.EqualsLiteral("RRULE"))
|
||||
mIsNegative = PR_FALSE;
|
||||
|
@ -575,7 +564,7 @@ calRecurrenceRule::SetIcalProperty(calIIcalProperty *aProp)
|
|||
icalproperty *prop;
|
||||
struct icalrecurrencetype icalrecur;
|
||||
|
||||
prop = cprop->getIcalProperty();
|
||||
prop = aProp->GetIcalProperty();
|
||||
|
||||
icalrecur = icalproperty_get_rrule(prop);
|
||||
|
||||
|
@ -594,7 +583,7 @@ calRecurrenceRule::SetIcalProperty(calIIcalProperty *aProp)
|
|||
else
|
||||
mIsByCount = PR_FALSE;
|
||||
|
||||
*mIcalRecur = icalrecur;
|
||||
mIcalRecur = icalrecur;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -21,6 +20,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
|
||||
* Daniel Boelzle <daniel.boelzle@sun.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -35,31 +35,31 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef CALRECURRENCERULE_H_
|
||||
#define CALRECURRENCERULE_H_
|
||||
#if !defined(INCLUDED_CAL_RECURRENCERULE_H)
|
||||
#define INCLUDED_CAL_RECURRENCERULE_H
|
||||
|
||||
#include "calIRecurrenceRule.h"
|
||||
#include "calUtils.h"
|
||||
|
||||
struct icalrecurrencetype;
|
||||
extern "C" {
|
||||
#include "ical.h"
|
||||
}
|
||||
|
||||
class calRecurrenceRule : public calIRecurrenceRule
|
||||
class calRecurrenceRule : public calIRecurrenceRule,
|
||||
public cal::XpcomBase
|
||||
{
|
||||
public:
|
||||
calRecurrenceRule();
|
||||
~calRecurrenceRule();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_DECL_CALIRECURRENCEITEM
|
||||
|
||||
NS_DECL_CALIRECURRENCERULE
|
||||
protected:
|
||||
icalrecurrencetype mIcalRecur;
|
||||
|
||||
PRBool mImmutable;
|
||||
PRBool mIsNegative;
|
||||
|
||||
PRBool mIsByCount;
|
||||
struct icalrecurrencetype *mIcalRecur;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // INCLUDED_CAL_RECURRENCERULE_H
|
||||
|
|
|
@ -0,0 +1,233 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Sun Microsystems code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Sun Microsystems, Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Boelzle <daniel.boelzle@sun.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#ifndef MOZILLA_1_8_BRANCH
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#endif
|
||||
#include "calTimezoneService.h"
|
||||
#include "calUtils.h"
|
||||
#include "calIErrors.h"
|
||||
#include "calAttributeHelpers.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(calTimezone, calITimezone)
|
||||
|
||||
CAL_ISUPPORTS_ATTR_GETTER(calTimezone, calIIcalComponent, Component)
|
||||
CAL_STRINGTYPE_ATTR_GETTER(calTimezone, nsACString, Tzid)
|
||||
CAL_STRINGTYPE_ATTR_GETTER(calTimezone, nsACString, Latitude)
|
||||
CAL_STRINGTYPE_ATTR_GETTER(calTimezone, nsACString, Longitude)
|
||||
CAL_VALUETYPE_ATTR_GETTER(calTimezone, PRBool, IsFloating)
|
||||
CAL_VALUETYPE_ATTR_GETTER(calTimezone, PRBool, IsUTC)
|
||||
|
||||
NS_IMETHODIMP
|
||||
calTimezone::GetProvider(calITimezoneProvider ** _retval) {
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
NS_ADDREF(*_retval = cal::getTimezoneService());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calTimezone::ToString(nsACString & aResult) {
|
||||
// xxx todo remove: for some time, we want to know if a calITimezone object
|
||||
// is treated as a string...
|
||||
NS_WARNING("calTimezone::ToString called!");
|
||||
|
||||
if (mIsUTC || mIsFloating) {
|
||||
aResult = mTzid;
|
||||
return NS_OK;
|
||||
}
|
||||
return mComponent->ToString(aResult);
|
||||
}
|
||||
|
||||
calTimezoneService::calTimezoneService()
|
||||
: mUTC(new calTimezone(nsnull, NS_LITERAL_CSTRING("UTC"), PR_TRUE)),
|
||||
mFloating(new calTimezone(nsnull, NS_LITERAL_CSTRING("floating"), PR_FALSE, PR_TRUE))
|
||||
{
|
||||
mTzHash.Init();
|
||||
mTzHash.Put(NS_LITERAL_CSTRING("UTC"), mUTC);
|
||||
mTzHash.Put(NS_LITERAL_CSTRING("utc"), mUTC);
|
||||
mTzHash.Put(NS_LITERAL_CSTRING("floating"), mFloating);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS2_CI(calTimezoneService, calITimezoneProvider, calITimezoneService)
|
||||
|
||||
CAL_ISUPPORTS_ATTR_GETTER(calTimezoneService, calITimezone, UTC)
|
||||
CAL_ISUPPORTS_ATTR_GETTER(calTimezoneService, calITimezone, Floating)
|
||||
|
||||
// include tzdata, to get ical_timezone_data_struct
|
||||
#include "tzdata.c"
|
||||
|
||||
static nsDependentCString sTzIdPrefix(kTzIdPrefix);
|
||||
|
||||
NS_IMETHODIMP
|
||||
calTimezoneService::GetTimezone(nsACString const& tzid_, calITimezone ** _retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
*_retval = nsnull;
|
||||
|
||||
if (!mTzHash.Get(tzid_, _retval) || !*_retval) {
|
||||
nsCAutoString tzid;
|
||||
if (NS_SUCCEEDED(LatestTzId(tzid_, tzid)) && StringBeginsWith(tzid, sTzIdPrefix)) {
|
||||
// not found, look up in static tab:
|
||||
for (PRUint32 i = 0; ical_timezone_data[i].tzid; ++i) {
|
||||
if (tzid.Equals(ical_timezone_data[i].tzid)) {
|
||||
ical_timezone_data_struct const& tzdata = ical_timezone_data[i];
|
||||
nsCOMPtr<calIIcalComponent> icalComp, vtimezone;
|
||||
if (NS_FAILED(cal::getICSService()->ParseICS(nsDependentCString(tzdata.icstimezone),
|
||||
nsnull,
|
||||
getter_AddRefs(icalComp))) ||
|
||||
NS_FAILED(icalComp->GetFirstSubcomponent(NS_LITERAL_CSTRING("VTIMEZONE"),
|
||||
getter_AddRefs(vtimezone))) ||
|
||||
!vtimezone) {
|
||||
NS_WARNING(ical_timezone_data[i].tzid);
|
||||
break;
|
||||
}
|
||||
nsCOMPtr<calITimezone> const tz(new calTimezone(vtimezone, tzid, PR_FALSE, PR_FALSE,
|
||||
nsDependentCString(tzdata.latitude),
|
||||
nsDependentCString(tzdata.longitude)));
|
||||
if (!mTzHash.Put(tzid, tz)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (tzid_ != tzid) { // tzid has been updated by LatestTzId
|
||||
if (!mTzHash.Put(tzid_, tz)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
NS_ADDREF(*_retval = tz);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(*_retval, PromiseFlatCString(tzid_).get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calTimezoneService::GetTimezoneIds(nsIUTF8StringEnumerator ** aTzids)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTzids);
|
||||
PRUint32 const arlen = sizeof(ical_timezone_data) / sizeof(ical_timezone_data[0]);
|
||||
nsAutoPtr<nsCStringArray> pArray(new nsCStringArray(mTzHash.Count() + arlen));
|
||||
CAL_ENSURE_MEMORY(pArray);
|
||||
pArray->AppendCString(NS_LITERAL_CSTRING("UTC"));
|
||||
for (PRUint32 i = 0; ical_timezone_data[i].tzid; ++i) {
|
||||
pArray->AppendCString(nsDependentCString(ical_timezone_data[i].tzid));
|
||||
}
|
||||
pArray->Sort();
|
||||
return cal::createUTF8StringEnumerator(pArray, aTzids);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
calTimezoneService::GetTzidPrefix(nsACString & _retval)
|
||||
{
|
||||
_retval = sTzIdPrefix;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* LatestTzId
|
||||
* Gets updated timezone ID (tzId) for a given tzId.
|
||||
* - If this isn't a mozilla.org tzId:
|
||||
* return nothing
|
||||
* - If the tzId name was changed or the tzId was deleted:
|
||||
* return updated tzId
|
||||
* - If the tzId's dtstamp is different from our current dtstamp:
|
||||
* return updated tzId
|
||||
* - Otherwise, don't change the tzId.
|
||||
*/
|
||||
nsresult calTimezoneService::LatestTzId(const nsACString& tzid, nsACString& _retval) {
|
||||
// Ensure _retval is both initialized and empty.
|
||||
_retval.Truncate();
|
||||
|
||||
// If it doesn't start with "/mozilla.org/" then it isn't ours.
|
||||
if (!StringBeginsWith(tzid, NS_LITERAL_CSTRING("/mozilla.org/"))) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// We know that our tzids look like "/mozilla.org/<dtstamp>/continent/..."
|
||||
// The ending of the mozilla prefix is the index of that slash before the
|
||||
// continent. Therefore, we start looking for the prefix-ending slash
|
||||
// after position 13.
|
||||
PRInt32 prefixEnd = tzid.FindChar('/', 13);
|
||||
PRInt32 continentEnd = tzid.FindChar('/', prefixEnd + 1);
|
||||
|
||||
// Go through our list of deletions and changes in Olsen, and update
|
||||
// these to entirely new zones.
|
||||
nsCAutoString continent(Substring(tzid, prefixEnd + 1,
|
||||
continentEnd - (prefixEnd + 1)));
|
||||
|
||||
// XXX We want to make this table-driven at some point in the future.
|
||||
// xxx todo => tz db generation code!
|
||||
|
||||
if (continent.EqualsLiteral("Africa")) {
|
||||
if (tzid.EqualsLiteral("/mozilla.org/20050126_1/Africa/Asmera")) {
|
||||
_retval.AssignLiteral("/mozilla.org/20070129_1/Africa/Asmara");
|
||||
} else if (tzid.EqualsLiteral("/mozilla.org/20050126_1/Africa/Timbuktu")) {
|
||||
_retval.AssignLiteral("/mozilla.org/20070129_1/Africa/Bamako");
|
||||
}
|
||||
} else if (continent.EqualsLiteral("Atlantic")) {
|
||||
if (tzid.EqualsLiteral("/mozilla.org/20050126_1/Atlantic/Faeroe")) {
|
||||
_retval.AssignLiteral("/mozilla.org/20070129_1/Atlantic/Faroe");
|
||||
}
|
||||
} else if (continent.EqualsLiteral("America")) {
|
||||
if (tzid.EqualsLiteral("/mozilla.org/20050126_1/America/Argentina/ComodRivadavia")) {
|
||||
_retval.AssignLiteral("/mozilla.org/20070129_1/America/Argentina/Catamarca");
|
||||
} else if (tzid.EqualsLiteral("/mozilla.org/20050126_1/America/Louisville")) {
|
||||
_retval.AssignLiteral("/mozilla.org/20070129_1/America/Kentucky/Louisville");
|
||||
}
|
||||
} else if (continent.EqualsLiteral("Europe")) {
|
||||
if (tzid.EqualsLiteral("/mozilla.org/20050126_1/Europe/Belfast")) {
|
||||
_retval.AssignLiteral("/mozilla.org/20070129_1/Europe/London");
|
||||
}
|
||||
} else if (continent.EqualsLiteral("Pacific")) {
|
||||
if (tzid.EqualsLiteral("/mozilla.org/20050126_1/Pacific/Yap")) {
|
||||
_retval.AssignLiteral("/mozilla.org/20070129_1/Pacific/Truk");
|
||||
}
|
||||
}
|
||||
|
||||
if (_retval.IsEmpty()) {
|
||||
if (sTzIdPrefix != Substring(tzid, 0, prefixEnd + 1)) {
|
||||
// TODO: This assumes that new zones will always be later. If we are
|
||||
// ever going to support mixing our TZID headers, then this needs to
|
||||
// be a date comparison.
|
||||
_retval = sTzIdPrefix;
|
||||
_retval += Substring(tzid, prefixEnd + 1, tzid.Length() - (prefixEnd + 1));
|
||||
} else {
|
||||
_retval = tzid;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Sun Microsystems code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Sun Microsystems, Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Boelzle <daniel.boelzle@sun.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#if !defined(INCLUDED_CAL_TIMEZONESERVIC_H)
|
||||
#define INCLUDED_CAL_TIMEZONESERVIC_H
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "calITimezoneProvider.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "calUtils.h"
|
||||
|
||||
extern "C" {
|
||||
#include "ical.h"
|
||||
}
|
||||
|
||||
class calTimezone : public calITimezone,
|
||||
public cal::XpcomBase
|
||||
{
|
||||
public:
|
||||
calTimezone(calIIcalComponent * component,
|
||||
nsCString const& tzid,
|
||||
PRBool isUTC = PR_FALSE,
|
||||
PRBool isFloating = PR_FALSE,
|
||||
nsCString const& latitude = nsCString(),
|
||||
nsCString const& longitude = nsCString())
|
||||
: mComponent(component),
|
||||
mTzid(tzid),
|
||||
mLatitude(latitude),
|
||||
mLongitude(longitude),
|
||||
mIsFloating(isFloating),
|
||||
mIsUTC(isUTC) {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_CALITIMEZONE
|
||||
|
||||
private:
|
||||
nsCOMPtr<calIIcalComponent> const mComponent;
|
||||
nsCString const mTzid;
|
||||
nsCString const mLatitude;
|
||||
nsCString const mLongitude;
|
||||
PRBool const mIsFloating;
|
||||
PRBool const mIsUTC;
|
||||
};
|
||||
|
||||
class calTimezoneService : public calITimezoneService,
|
||||
public cal::XpcomBase
|
||||
{
|
||||
public:
|
||||
calTimezoneService();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_CALITIMEZONEPROVIDER
|
||||
NS_DECL_CALITIMEZONESERVICE
|
||||
|
||||
private:
|
||||
nsresult LatestTzId(const nsACString& tzid, nsACString& _retval);
|
||||
|
||||
nsInterfaceHashtable<nsCStringHashKey, calITimezone> mTzHash;
|
||||
nsCOMPtr<calITimezone> const mUTC;
|
||||
nsCOMPtr<calITimezone> const mFloating;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_CAL_TIMEZONESERVIC_H
|
|
@ -34,15 +34,21 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef MOZILLA_1_8_BRANCH
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#endif
|
||||
#include "nsServiceManagerUtils.h"
|
||||
// #ifndef MOZILLA_1_8_BRANCH
|
||||
// #include "nsIClassInfoImpl.h"
|
||||
// #endif
|
||||
#include "calBaseCID.h"
|
||||
#include "calUtils.h"
|
||||
|
||||
extern "C" {
|
||||
#include "ical.h"
|
||||
}
|
||||
|
||||
namespace cal {
|
||||
|
||||
class UTF8StringEnumerator : public nsIUTF8StringEnumerator
|
||||
class UTF8StringEnumerator : public nsIUTF8StringEnumerator,
|
||||
public XpcomBase
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -51,17 +57,10 @@ public:
|
|||
explicit UTF8StringEnumerator(nsAutoPtr<nsCStringArray> & takeOverArray)
|
||||
: mArray(takeOverArray), mPos(0) {}
|
||||
private:
|
||||
UTF8StringEnumerator const& operator=(UTF8StringEnumerator const&);
|
||||
virtual ~UTF8StringEnumerator();
|
||||
|
||||
nsAutoPtr<nsCStringArray> const mArray;
|
||||
PRInt32 mPos;
|
||||
};
|
||||
|
||||
UTF8StringEnumerator::~UTF8StringEnumerator()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(UTF8StringEnumerator, nsIUTF8StringEnumerator)
|
||||
|
||||
NS_IMETHODIMP UTF8StringEnumerator::HasMore(PRBool *_retval)
|
||||
|
@ -88,10 +87,85 @@ nsresult createUTF8StringEnumerator(nsAutoPtr<nsCStringArray> & takeOverArray,
|
|||
NS_ENSURE_ARG_POINTER(takeOverArray.get());
|
||||
NS_ENSURE_ARG_POINTER(ppRet);
|
||||
*ppRet = new UTF8StringEnumerator(takeOverArray);
|
||||
if (!*ppRet)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
CAL_ENSURE_MEMORY(*ppRet);
|
||||
NS_ADDREF(*ppRet);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<calIICSService> const& getICSService() {
|
||||
static nsCOMPtr<calIICSService> sIcsService;
|
||||
if (!sIcsService) {
|
||||
sIcsService = do_GetService(CAL_ICSSERVICE_CONTRACTID);
|
||||
NS_ASSERTION(sIcsService, "Could not init ics service! Will crash now...");
|
||||
}
|
||||
return sIcsService;
|
||||
}
|
||||
|
||||
nsCOMPtr<calITimezoneService> const& getTimezoneService() {
|
||||
static nsCOMPtr<calITimezoneService> sTzService;
|
||||
if (!sTzService) {
|
||||
sTzService = do_GetService(CAL_TIMEZONESERVICE_CONTRACTID);
|
||||
NS_ASSERTION(sTzService, "Could not init timezone service! Will crash now...");
|
||||
}
|
||||
return sTzService;
|
||||
}
|
||||
|
||||
nsCOMPtr<calITimezone> const& floating() {
|
||||
static nsCOMPtr<calITimezone> sFloating;
|
||||
if (!sFloating) {
|
||||
getTimezoneService()->GetFloating(getter_AddRefs(sFloating));
|
||||
}
|
||||
return sFloating;
|
||||
}
|
||||
|
||||
nsCOMPtr<calITimezone> const& UTC() {
|
||||
static nsCOMPtr<calITimezone> sUTC;
|
||||
if (!sUTC) {
|
||||
getTimezoneService()->GetUTC(getter_AddRefs(sUTC));
|
||||
}
|
||||
return sUTC;
|
||||
}
|
||||
|
||||
nsCOMPtr<calITimezone> detectTimezone(icaltimetype const& icalt,
|
||||
calITimezoneProvider * tzProvider)
|
||||
{
|
||||
if (!tzProvider) {
|
||||
tzProvider = getTimezoneService();
|
||||
}
|
||||
if (icalt.is_utc) {
|
||||
return UTC();
|
||||
}
|
||||
if (icalt.zone) {
|
||||
char const* const tzid = icaltimezone_get_tzid(const_cast<icaltimezone *>(icalt.zone));
|
||||
if (tzid) {
|
||||
nsCOMPtr<calITimezone> tz;
|
||||
tzProvider->GetTimezone(nsDependentCString(tzid), getter_AddRefs(tz));
|
||||
if (tz) {
|
||||
return tz;
|
||||
}
|
||||
NS_ASSERTION(tz, "no timezone found, falling back to floating!");
|
||||
}
|
||||
}
|
||||
return floating();
|
||||
}
|
||||
|
||||
icaltimezone * getIcalTimezone(calITimezone * tz) {
|
||||
icaltimezone * icaltz = nsnull;
|
||||
PRBool b;
|
||||
tz->GetIsUTC(&b);
|
||||
if (b) {
|
||||
icaltz = icaltimezone_get_utc_timezone();
|
||||
} else {
|
||||
nsCOMPtr<calIIcalComponent> tzComp;
|
||||
tz->GetComponent(getter_AddRefs(tzComp));
|
||||
if (tzComp) {
|
||||
icaltz = tzComp->GetIcalTimezone();
|
||||
} // else floating
|
||||
}
|
||||
return icaltz;
|
||||
}
|
||||
|
||||
XpcomBase::~XpcomBase() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,13 +51,95 @@
|
|||
#include "nsVoidArray.h"
|
||||
#include "nsIStringEnumerator.h"
|
||||
|
||||
#include "calITimezoneProvider.h"
|
||||
#include "calIICSService.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#define CAL_STRLEN_ARGS(x) x, sizeof(x)-1
|
||||
#define CAL_ENSURE_MEMORY(p) NS_ENSURE_TRUE(p, NS_ERROR_OUT_OF_MEMORY)
|
||||
|
||||
typedef struct _icaltimezone icaltimezone;
|
||||
typedef struct icaltimetype icaltimetype;
|
||||
|
||||
namespace cal {
|
||||
|
||||
/**
|
||||
* Creates a UTF8 string enumerator.
|
||||
*
|
||||
* @param takeOverArray a C string array that is taken over by the resulting
|
||||
* string enumerator object (nsAutoPtr passes over ownership)
|
||||
* @param ppRet returned enumerator object
|
||||
*/
|
||||
nsresult createUTF8StringEnumerator(nsAutoPtr<nsCStringArray> & takeOverArray,
|
||||
nsIUTF8StringEnumerator ** ppRet);
|
||||
|
||||
// some static timezone helpers, we leak those, but this is ok since the
|
||||
// underlying service leaks those anyway until process termination
|
||||
|
||||
/**
|
||||
* Gets the global ICS service.
|
||||
*/
|
||||
nsCOMPtr<calIICSService> const& getICSService();
|
||||
|
||||
/**
|
||||
* Gets the global timezone service.
|
||||
*/
|
||||
nsCOMPtr<calITimezoneService> const& getTimezoneService();
|
||||
|
||||
/**
|
||||
* Gets the "floating" timezone
|
||||
*/
|
||||
nsCOMPtr<calITimezone> const& floating();
|
||||
|
||||
/**
|
||||
* Gets the "UTC" timezone.
|
||||
*/
|
||||
nsCOMPtr<calITimezone> const& UTC();
|
||||
|
||||
/**
|
||||
* Returns the libical VTIMEZONE component, null if floating.
|
||||
*
|
||||
* @attention
|
||||
* Every timezone provider needs to use calICSService for
|
||||
* creating its timezone components since we need to stick to the
|
||||
* same libical.
|
||||
*/
|
||||
icaltimezone * getIcalTimezone(calITimezone * tz);
|
||||
|
||||
/**
|
||||
* Detects the timezone icalt refers to, either using the
|
||||
* passed timezone provider or the global timezone service.
|
||||
*
|
||||
* @param icalt an icaltime
|
||||
* @param tzProvider timezone provider or null which
|
||||
* defaults to the timezone service
|
||||
*/
|
||||
nsCOMPtr<calITimezone> detectTimezone(icaltimetype const& icalt,
|
||||
calITimezoneProvider * tzProvider);
|
||||
|
||||
/**
|
||||
* Tests whether two interface pointers refer to the same object.
|
||||
*/
|
||||
inline NSCAP_BOOL sameXpcomObject(nsISupports * i1_, nsISupports * i2_) {
|
||||
nsCOMPtr<nsISupports> const i1 = do_QueryInterface(i1_);
|
||||
nsCOMPtr<nsISupports> const i2 = do_QueryInterface(i2_);
|
||||
return i1 == i2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Common base class for XPCOM object implementations:
|
||||
* - disallows public deletion (virtual protected dtor)
|
||||
* - disallows copy semantics (no assignment, no copy ctor)
|
||||
*/
|
||||
class XpcomBase {
|
||||
protected:
|
||||
XpcomBase() {}
|
||||
virtual ~XpcomBase();
|
||||
private:
|
||||
XpcomBase(XpcomBase const&); // left unimplemented
|
||||
XpcomBase const& operator=(XpcomBase const&); // left unimplemented
|
||||
};
|
||||
|
||||
} // namespace cal
|
||||
|
||||
#endif // !defined(INCLUDED_CAL_UTILS_H)
|
||||
|
|
|
@ -81,8 +81,36 @@ function createAttendee() {
|
|||
|
||||
/* Shortcut to the calendar-manager service */
|
||||
function getCalendarManager() {
|
||||
return Components.classes["@mozilla.org/calendar/manager;1"].
|
||||
getService(Components.interfaces.calICalendarManager);
|
||||
if (getCalendarManager.mObject === undefined) {
|
||||
getCalendarManager.mObject = Components.classes["@mozilla.org/calendar/manager;1"]
|
||||
.getService(Components.interfaces.calICalendarManager);
|
||||
}
|
||||
return getCalendarManager.mObject;
|
||||
}
|
||||
|
||||
/* Shortcut to the timezone service */
|
||||
function getTimezoneService() {
|
||||
if (getTimezoneService.mObject === undefined) {
|
||||
getTimezoneService.mObject = Components.classes["@mozilla.org/calendar/timezone-service;1"]
|
||||
.getService(Components.interfaces.calITimezoneService);
|
||||
}
|
||||
return getTimezoneService.mObject;
|
||||
}
|
||||
|
||||
/// @return the UTC timezone.
|
||||
function UTC() {
|
||||
if (UTC.mObject === undefined) {
|
||||
UTC.mObject = getTimezoneService().UTC;
|
||||
}
|
||||
return UTC.mObject;
|
||||
}
|
||||
|
||||
/// @return the floating timezone.
|
||||
function floating() {
|
||||
if (floating.mObject === undefined) {
|
||||
floating.mObject = getTimezoneService().floating;
|
||||
}
|
||||
return floating.mObject;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -90,26 +118,23 @@ function getCalendarManager() {
|
|||
* use the value of the calendar.timezone.local preference, if it exists. If
|
||||
* not, we'll do our best guess.
|
||||
*
|
||||
* @returns a string of the Mozilla TZID for the user's default timezone.
|
||||
* @return user's default timezone.
|
||||
*/
|
||||
var gDefaultTimezone;
|
||||
function calendarDefaultTimezone() {
|
||||
if (!gDefaultTimezone) {
|
||||
gDefaultTimezone = getPrefSafe("calendar.timezone.local", null);
|
||||
if (!gDefaultTimezone) {
|
||||
gDefaultTimezone = guessSystemTimezone();
|
||||
} else {
|
||||
var icsSvc = Components.classes["@mozilla.org/calendar/ics-service;1"].
|
||||
getService(Components.interfaces.calIICSService);
|
||||
|
||||
// Update this tzid if necessary.
|
||||
if (icsSvc.latestTzId(gDefaultTimezone).length) {
|
||||
gDefaultTimezone = icsSvc.latestTzId(gDefaultTimezone);
|
||||
setPref("calendar.timezone.local", "CHAR", gDefaultTimezone);
|
||||
}
|
||||
if (calendarDefaultTimezone.mTz === undefined) {
|
||||
var prefTzid = getPrefSafe("calendar.timezone.local", null);
|
||||
var tzid = prefTzid;
|
||||
if (!tzid) {
|
||||
tzid = guessSystemTimezone();
|
||||
}
|
||||
calendarDefaultTimezone.mTz = getTimezoneService().getTimezone(tzid);
|
||||
ASSERT(calendarDefaultTimezone.mTz, "timezone not found: " + tzid);
|
||||
// Update prefs if necessary:
|
||||
if (calendarDefaultTimezone.mTz && calendarDefaultTimezone.mTz.tzid != prefTzid) {
|
||||
setPref("calendar.timezone.local", "CHAR", calendarDefaultTimezone.mTz.tzid);
|
||||
}
|
||||
}
|
||||
return gDefaultTimezone;
|
||||
return calendarDefaultTimezone.mTz;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,14 +182,11 @@ function guessSystemTimezone() {
|
|||
dump("TZname1: " + TZname1 + "\nTZname2: " + TZname2 + "\n");
|
||||
}
|
||||
|
||||
var icsSvc = Components.classes["@mozilla.org/calendar/ics-service;1"].
|
||||
getService(Components.interfaces.calIICSService);
|
||||
|
||||
// returns 0=definitely not, 1=maybe, 2=likely
|
||||
function checkTZ(someTZ)
|
||||
{
|
||||
var comp = icsSvc.getTimezone(someTZ);
|
||||
var subComp = comp.getFirstSubcomponent("VTIMEZONE");
|
||||
var tz = getTimezoneService().getTimezone(someTZ);
|
||||
var subComp = tz.component;
|
||||
var standard = subComp.getFirstSubcomponent("STANDARD");
|
||||
var standardTZOffset = standard.getFirstProperty("TZOFFSETTO").valueAsIcalString;
|
||||
var standardNameProp = standard.getFirstProperty("TZNAME");
|
||||
|
@ -223,8 +245,7 @@ function guessSystemTimezone() {
|
|||
// This happens if the l10n team didn't know how to get a time from
|
||||
// tzdata.c. To convert an Olson time to a ics-timezone-string we
|
||||
// need to append this prefix.
|
||||
// XXX Get this prefix from calIICSService.tzIdPrefix
|
||||
stringBundleTZ = "/mozilla.org/20070129_1/" + stringBundleTZ;
|
||||
stringBundleTZ = getTimezoneService().tzidPrefix + stringBundleTZ;
|
||||
}
|
||||
|
||||
switch (checkTZ(stringBundleTZ)) {
|
||||
|
@ -241,7 +262,7 @@ function guessSystemTimezone() {
|
|||
catch (ex) { // Oh well, this didn't work, next option...
|
||||
}
|
||||
|
||||
var tzIDs = icsSvc.timezoneIds;
|
||||
var tzIDs = getTimezoneService().timezoneIds;
|
||||
while (tzIDs.hasMore()) {
|
||||
var theTZ = tzIDs.getNext();
|
||||
try {
|
||||
|
@ -558,9 +579,18 @@ function compareItems(aItem, aOtherItem) {
|
|||
*
|
||||
* @param aObject first object to be compared
|
||||
* @param aOtherObject second object to be compared
|
||||
* @param aIID IID to use in comparison
|
||||
* @param aIID IID to use in comparison, undefined/null defaults to nsISupports
|
||||
*/
|
||||
function compareObjects(aObject, aOtherObject, aIID) {
|
||||
// xxx todo: seems to work fine e.g. for WCAP, but I still mistrust this trickery...
|
||||
// Anybody knows an official API that could be used for this purpose?
|
||||
// For what reason do clients need to pass aIID since
|
||||
// every XPCOM object has to implement nsISupports?
|
||||
// XPCOM (like COM, like UNO, ...) defines that QueryInterface *only* needs to return
|
||||
// the very same pointer for nsISupports during its lifetime.
|
||||
if (!aIID) {
|
||||
aIID = Components.interfaces.nsISupports;
|
||||
}
|
||||
var sip1 = Components.classes["@mozilla.org/supports-interface-pointer;1"].
|
||||
createInstance(Components.interfaces.nsISupportsInterfacePointer);
|
||||
sip1.data = aObject;
|
||||
|
@ -1297,9 +1327,6 @@ function sendMailTo(aRecipient, aSubject, aBody) {
|
|||
}
|
||||
}
|
||||
|
||||
var gOpGroupPrefix;
|
||||
var gOpGroupId = 0;
|
||||
|
||||
/**
|
||||
* This object implements calIOperation and could group multiple sub
|
||||
* operations into one. You can pass a cancel function which is called once
|
||||
|
@ -1312,12 +1339,14 @@ var gOpGroupId = 0;
|
|||
*/
|
||||
function calOperationGroup(cancelFunc) {
|
||||
this.wrappedJSObject = this;
|
||||
if (!gOpGroupPrefix) {
|
||||
gOpGroupPrefix = (getUUID() + "-");
|
||||
if (calOperationGroup.mOpGroupId === undefined) {
|
||||
calOperationGroup.mOpGroupId = 0;
|
||||
}
|
||||
if (calOperationGroup.mOpGroupPrefix === undefined) {
|
||||
calOperationGroup.mOpGroupPrefix = (getUUID() + "-");
|
||||
}
|
||||
this.mCancelFunc = cancelFunc;
|
||||
this.mId = (gOpGroupPrefix + gOpGroupId);
|
||||
++gOpGroupId;
|
||||
this.mId = (calOperationGroup.mOpGroupPrefix + calOperationGroup.mOpGroupId++);
|
||||
this.mSubOperations = [];
|
||||
}
|
||||
calOperationGroup.prototype = {
|
||||
|
|
|
@ -66,7 +66,7 @@ calIcsImporter.prototype.importFromStream =
|
|||
function ics_importFromStream(aStream, aCount) {
|
||||
var parser = Components.classes["@mozilla.org/calendar/ics-parser;1"].
|
||||
createInstance(Components.interfaces.calIIcsParser);
|
||||
parser.parseFromStream(aStream);
|
||||
parser.parseFromStream(aStream, null);
|
||||
return parser.getItems(aCount);
|
||||
};
|
||||
|
||||
|
|
|
@ -326,7 +326,7 @@ function parseDateTime(aDate, aTime, aLocale)
|
|||
.createInstance(Components.interfaces.calIDateTime);
|
||||
|
||||
//XXX Can we do better?
|
||||
date.timezone = "floating";
|
||||
date.timezone = floating();
|
||||
|
||||
var rd = aLocale.dateRe.exec(aDate);
|
||||
var rt = aLocale.timeRe.exec(aTime);
|
||||
|
|
|
@ -139,7 +139,6 @@ function onLoad() {
|
|||
}
|
||||
|
||||
function onAccept() {
|
||||
var kDefaultTimezone = calendarDefaultTimezone();
|
||||
var attendees = document.getElementById("attendees-list");
|
||||
window.arguments[0].onOk(
|
||||
attendees.attendees,
|
||||
|
@ -235,8 +234,8 @@ function updateDateTime() {
|
|||
// the timezone of the endtime is "UTC", we convert
|
||||
// the endtime into the timezone of the starttime.
|
||||
if (startTime && endTime) {
|
||||
if (startTime.timezone != endTime.timezone) {
|
||||
if (endTime.timezone == "UTC") {
|
||||
if (!compareObjects(startTime.timezone, endTime.timezone)) {
|
||||
if (endTime.timezone.isUTC) {
|
||||
endTime = endTime.getInTimezone(startTime.timezone);
|
||||
}
|
||||
}
|
||||
|
@ -245,8 +244,8 @@ function updateDateTime() {
|
|||
// Before feeding the date/time value into the control we need
|
||||
// to set the timezone to 'floating' in order to avoid the
|
||||
// automatic conversion back into the OS timezone.
|
||||
startTime.timezone = "floating";
|
||||
endTime.timezone = "floating";
|
||||
startTime.timezone = floating();
|
||||
endTime.timezone = floating();
|
||||
|
||||
document.getElementById("event-starttime").value = startTime.jsDate;
|
||||
document.getElementById("event-endtime").value = endTime.jsDate;
|
||||
|
@ -264,8 +263,8 @@ function updateDateTime() {
|
|||
// Before feeding the date/time value into the control we need
|
||||
// to set the timezone to 'floating' in order to avoid the
|
||||
// automatic conversion back into the OS timezone.
|
||||
startTime.timezone = "floating";
|
||||
endTime.timezone = "floating";
|
||||
startTime.timezone = floating();
|
||||
endTime.timezone = floating();
|
||||
|
||||
document.getElementById("event-starttime").value = startTime.jsDate;
|
||||
document.getElementById("event-endtime").value = endTime.jsDate;
|
||||
|
@ -275,13 +274,13 @@ function updateDateTime() {
|
|||
updateAllDay();
|
||||
}
|
||||
|
||||
function timezoneString(date) {
|
||||
var fragments = date.split('/');
|
||||
var num = fragments.length;
|
||||
if (num <= 1) {
|
||||
return fragments[0];
|
||||
function timezoneString(tz) {
|
||||
var tzid = tz.tzid;
|
||||
var prefix = getTimezoneService().tzidPrefix;
|
||||
if (tzid.indexOf(prefix) == 0) {
|
||||
tzid = tzid.substring(prefix.length);
|
||||
}
|
||||
return fragments[num - 2] + '/' + fragments[num - 1];
|
||||
return tzid;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -302,7 +301,7 @@ function updateTimezone() {
|
|||
var endTimezone = gEndTimezone;
|
||||
var equalTimezones = false;
|
||||
if (startTimezone && endTimezone &&
|
||||
(startTimezone == endTimezone || endTimezone == "UTC")) {
|
||||
(compareObjects(startTimezone, endTimezone) || endTimezone.isUTC)) {
|
||||
equalTimezones = true;
|
||||
}
|
||||
|
||||
|
@ -381,9 +380,9 @@ function updateEndTime() {
|
|||
gDisplayTimezone ? gStartTimezone : calendarDefaultTimezone());
|
||||
|
||||
var timezone = gEndTimezone;
|
||||
if (timezone == "UTC" &&
|
||||
if (timezone.isUTC &&
|
||||
gStartDate &&
|
||||
gStartTimezone != gEndTimezone) {
|
||||
!compareObjects(gStartTimezone, gEndTimezone)) {
|
||||
timezone = gStartTimezone;
|
||||
}
|
||||
gEndDate = jsDateToDateTime(endWidget.value,
|
||||
|
@ -436,13 +435,13 @@ function editStartTimezone() {
|
|||
args.time = gStartDate.getInTimezone(gStartTimezone);
|
||||
args.onOk = function(datetime) {
|
||||
var equalTimezones = false;
|
||||
if (self.mStartTimezone && self.mEndTimezone &&
|
||||
self.mStartTimezone == self.mEndTimezone) {
|
||||
if (gStartTimezone && gEndTimezone &&
|
||||
compareObjects(gStartTimezone, gEndTimezone)) {
|
||||
equalTimezones = true;
|
||||
}
|
||||
self.mStartTimezone = datetime.timezone;
|
||||
gStartTimezone = datetime.timezone;
|
||||
if (equalTimezones) {
|
||||
self.mEndTimezone = datetime.timezone;
|
||||
gEndTimezone = datetime.timezone;
|
||||
}
|
||||
self.propagateDateTime();
|
||||
};
|
||||
|
@ -465,15 +464,11 @@ function editEndTimezone() {
|
|||
var args = new Object();
|
||||
args.time = gEndTime.getInTimezone(gEndTimezone);
|
||||
args.onOk = function(datetime) {
|
||||
var equalTimezones = false;
|
||||
if (self.mStartTimezone && self.mEndTimezone &&
|
||||
self.mStartTimezone == self.mEndTimezone) {
|
||||
equalTimezones = true;
|
||||
if (gStartTimezone && gEndTimezone &&
|
||||
compareObjects(gStartTimezone, gEndTimezone)) {
|
||||
gStartTimezone = datetime.timezone;
|
||||
}
|
||||
if (equalTimezones) {
|
||||
self.mStartTimezone = datetime.timezone;
|
||||
}
|
||||
self.mEndTimezone = datetime.timezone;
|
||||
gEndTimezone = datetime.timezone;
|
||||
self.propagateDateTime();
|
||||
};
|
||||
|
||||
|
|
|
@ -39,13 +39,11 @@ function onLoad() {
|
|||
window.time = args.time;
|
||||
window.onAcceptCallback = args.onOk;
|
||||
|
||||
var tzname = timezoneString(window.time.timezone);
|
||||
var tzname = timezoneString(window.time.timezone.tzid);
|
||||
var menulist = document.getElementById("timezone-menulist");
|
||||
var index = findTimezone(tzname);
|
||||
if (index < 0) {
|
||||
var kDefaultTimezone = calendarDefaultTimezone();
|
||||
var tzstring = window.time.getInTimezone(kDefaultTimezone).timezone;
|
||||
tzname = timezoneString(tzstring);
|
||||
tzname = timezoneString(calendarDefaultTimezone().tzid);
|
||||
index = findTimezone(tzname);
|
||||
}
|
||||
|
||||
|
@ -69,19 +67,19 @@ function findTimezone(timezone) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
function timezoneString(timezone) {
|
||||
var fragments = timezone.split('/');
|
||||
var num = fragments.length;
|
||||
if (num <= 1) {
|
||||
return fragments[0];
|
||||
function timezoneString(tzid) {
|
||||
var prefix = getTimezoneService().tzidPrefix;
|
||||
if (tzid.indexOf(prefix) == 0) {
|
||||
tzid = tzid.substring(prefix.length);
|
||||
}
|
||||
return fragments[num-2] + '/' + fragments[num - 1];
|
||||
return tzid;
|
||||
}
|
||||
|
||||
function updateTimezone() {
|
||||
var menulist = document.getElementById("timezone-menulist");
|
||||
var menuitem = menulist.selectedItem;
|
||||
var someTZ = menuitem.getAttribute("value");
|
||||
var tz = getTimezoneService().getTimezone(someTZ);
|
||||
|
||||
// convert the date/time to the currently selected timezone
|
||||
// and display the result in the appropriate control.
|
||||
|
@ -89,15 +87,11 @@ function updateTimezone() {
|
|||
// to set the timezone to 'floating' in order to avoid the
|
||||
// automatic conversion back into the OS timezone.
|
||||
var datetime = document.getElementById("timezone-time");
|
||||
var time = window.time.getInTimezone(someTZ);
|
||||
time.timezone = "floating";
|
||||
var time = window.time.getInTimezone(tz);
|
||||
time.timezone = floating();
|
||||
datetime.value = time.jsDate;
|
||||
|
||||
var icssrv = Components.classes["@mozilla.org/calendar/ics-service;1"]
|
||||
.getService(Components.interfaces.calIICSService);
|
||||
|
||||
var comp = icssrv.getTimezone(someTZ);
|
||||
var subComp = comp.getFirstSubcomponent("VTIMEZONE");
|
||||
var subComp = tz.component;
|
||||
var standard = subComp.getFirstSubcomponent("STANDARD");
|
||||
var standardTZOffset = standard.getFirstProperty("TZOFFSETTO").valueAsIcalString;
|
||||
|
||||
|
@ -120,7 +114,8 @@ function onAccept() {
|
|||
var menulist = document.getElementById("timezone-menulist");
|
||||
var menuitem = menulist.selectedItem;
|
||||
var timezone = menuitem.getAttribute("value");
|
||||
var datetime = window.time.getInTimezone(timezone);
|
||||
var tz = getTimezoneService().getTimezone(timezone);
|
||||
var datetime = window.time.getInTimezone(tz);
|
||||
window.onAcceptCallback(datetime);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -271,13 +271,13 @@ function onCancel() {
|
|||
return result;
|
||||
}
|
||||
|
||||
function timezoneString(aDate) {
|
||||
var fragments = aDate.split('/');
|
||||
var num = fragments.length;
|
||||
if (num <= 1) {
|
||||
return fragments[0];
|
||||
function timezoneString(tz) {
|
||||
var tzid = tz.tzid;
|
||||
var prefix = getTimezoneService().tzidPrefix;
|
||||
if (tzid.indexOf(prefix) == 0) {
|
||||
tzid = tzid.substring(prefix.length);
|
||||
}
|
||||
return fragments[num-2] + '/'+fragments[num - 1];
|
||||
return tzid;
|
||||
}
|
||||
|
||||
function loadDialog(item) {
|
||||
|
@ -448,6 +448,7 @@ function loadDialog(item) {
|
|||
}
|
||||
|
||||
function loadDateTime(item) {
|
||||
var kDefaultTimezone = calendarDefaultTimezone();
|
||||
if (isEvent(item)) {
|
||||
var startTime = item.startDate;
|
||||
var endTime = item.endDate;
|
||||
|
@ -465,7 +466,6 @@ function loadDateTime(item) {
|
|||
// store the start/end-times as calIDateTime-objects
|
||||
// converted to the default timezone. store the timezones
|
||||
// separately.
|
||||
var kDefaultTimezone = calendarDefaultTimezone();
|
||||
gStartTimezone = startTime.timezone;
|
||||
gEndTimezone = endTime.timezone;
|
||||
gStartTime = startTime.getInTimezone(kDefaultTimezone);
|
||||
|
@ -478,7 +478,6 @@ function loadDateTime(item) {
|
|||
var endTime = null;
|
||||
var duration = null;
|
||||
|
||||
var kDefaultTimezone = calendarDefaultTimezone();
|
||||
var hasEntryDate = (item.entryDate != null);
|
||||
if (hasEntryDate) {
|
||||
startTime = item.entryDate;
|
||||
|
@ -550,8 +549,8 @@ function dateTimeControls2State(aKeepDuration) {
|
|||
}
|
||||
} else {
|
||||
var timezone = gEndTimezone;
|
||||
if (timezone == "UTC") {
|
||||
if (gStartTime && gStartTimezone != gEndTimezone) {
|
||||
if (timezone.isUTC) {
|
||||
if (gStartTime && !compareObjects(gStartTimezone, gEndTimezone)) {
|
||||
timezone = gStartTimezone;
|
||||
}
|
||||
}
|
||||
|
@ -953,8 +952,8 @@ function updateAccept() {
|
|||
if (menuItem.getAttribute('checked') == 'true') {
|
||||
var startTimezone = gStartTimezone;
|
||||
var endTimezone = gEndTimezone;
|
||||
if (endTimezone == "UTC") {
|
||||
if (gStartTimezone != gEndTimezone) {
|
||||
if (endTimezone.isUTC) {
|
||||
if (!compareObjects(gStartTimezone, gEndTimezone)) {
|
||||
endTimezone = gStartTimezone;
|
||||
}
|
||||
}
|
||||
|
@ -1318,7 +1317,7 @@ function setItemProperty(item, propertyName, value) {
|
|||
case "startDate":
|
||||
if (value.isDate && !item.startDate.isDate ||
|
||||
!value.isDate && item.startDate.isDate ||
|
||||
value.timezone != item.startDate.timezone ||
|
||||
!compareObjects(value.timezone, item.startDate.timezone) ||
|
||||
value.compare(item.startDate) != 0) {
|
||||
item.startDate = value;
|
||||
}
|
||||
|
@ -1326,7 +1325,7 @@ function setItemProperty(item, propertyName, value) {
|
|||
case "endDate":
|
||||
if (value.isDate && !item.endDate.isDate ||
|
||||
!value.isDate && item.endDate.isDate ||
|
||||
value.timezone != item.endDate.timezone ||
|
||||
!compareObjects(value.timezone, item.endDate.timezone) ||
|
||||
value.compare(item.endDate) != 0) {
|
||||
item.endDate = value;
|
||||
}
|
||||
|
@ -1338,7 +1337,7 @@ function setItemProperty(item, propertyName, value) {
|
|||
if (value && !item.entryDate ||
|
||||
!value && item.entryDate ||
|
||||
value.isDate != item.entryDate.isDate ||
|
||||
value.timezone != item.entryDate.timezone ||
|
||||
!compareObjects(value.timezone, item.entryDate.timezone) ||
|
||||
value.compare(item.entryDate) != 0) {
|
||||
item.entryDate = value;
|
||||
}
|
||||
|
@ -1350,7 +1349,7 @@ function setItemProperty(item, propertyName, value) {
|
|||
if (value && !item.dueDate ||
|
||||
!value && item.dueDate ||
|
||||
value.isDate != item.dueDate.isDate ||
|
||||
value.timezone != item.dueDate.timezone ||
|
||||
!compareObjects(value.timezone, item.dueDate.timezone) ||
|
||||
value.compare(item.dueDate) != 0) {
|
||||
item.dueDate = value;
|
||||
}
|
||||
|
@ -1871,7 +1870,7 @@ function editEndTimezone() {
|
|||
function(datetime) {
|
||||
var equalTimezones = false;
|
||||
if (gStartTimezone && gEndTimezone) {
|
||||
if (gStartTimezone == gEndTimezone) {
|
||||
if (compareObjects(gStartTimezone, gEndTimezone)) {
|
||||
equalTimezones = true;
|
||||
}
|
||||
}
|
||||
|
@ -1937,8 +1936,8 @@ function updateDateTime() {
|
|||
// the timezone of the endtime is "UTC", we convert
|
||||
// the endtime into the timezone of the starttime.
|
||||
if (startTime && endTime) {
|
||||
if (startTime.timezone != endTime.timezone) {
|
||||
if (endTime.timezone == "UTC") {
|
||||
if (!compareObjects(startTime.timezone, endTime.timezone)) {
|
||||
if (endTime.timezone.isUTC) {
|
||||
endTime = endTime.getInTimezone(startTime.timezone);
|
||||
}
|
||||
}
|
||||
|
@ -1947,8 +1946,8 @@ function updateDateTime() {
|
|||
// before feeding the date/time value into the control we need
|
||||
// to set the timezone to 'floating' in order to avoid the
|
||||
// automatic conversion back into the OS timezone.
|
||||
startTime.timezone = "floating";
|
||||
endTime.timezone = "floating";
|
||||
startTime.timezone = floating();
|
||||
endTime.timezone = floating();
|
||||
|
||||
setElementValue("event-starttime", startTime.jsDate);
|
||||
setElementValue("event-endtime", endTime.jsDate);
|
||||
|
@ -1962,25 +1961,25 @@ function updateDateTime() {
|
|||
|
||||
if (hasEntryDate && hasDueDate) {
|
||||
setElementValue("todo-has-entrydate", hasEntryDate, "checked");
|
||||
startTime.timezone = "floating";
|
||||
startTime.timezone = floating();
|
||||
setElementValue("todo-entrydate", startTime.jsDate);
|
||||
|
||||
setElementValue("todo-has-duedate", hasDueDate, "checked");
|
||||
endTime.timezone = "floating";
|
||||
endTime.timezone = floating();
|
||||
setElementValue("todo-duedate", endTime.jsDate);
|
||||
} else if (hasEntryDate) {
|
||||
setElementValue("todo-has-entrydate", hasEntryDate, "checked");
|
||||
startTime.timezone = "floating";
|
||||
startTime.timezone = floating();
|
||||
setElementValue("todo-entrydate", startTime.jsDate);
|
||||
|
||||
startTime.timezone = "floating";
|
||||
startTime.timezone = floating();
|
||||
setElementValue("todo-duedate", startTime.jsDate);
|
||||
} else if (hasDueDate) {
|
||||
endTime.timezone = "floating";
|
||||
endTime.timezone = floating();
|
||||
setElementValue("todo-entrydate", endTime.jsDate);
|
||||
|
||||
setElementValue("todo-has-duedate", hasDueDate, "checked");
|
||||
endTime.timezone = "floating";
|
||||
endTime.timezone = floating();
|
||||
setElementValue("todo-duedate", endTime.jsDate);
|
||||
}
|
||||
}
|
||||
|
@ -1995,8 +1994,8 @@ function updateDateTime() {
|
|||
// before feeding the date/time value into the control we need
|
||||
// to set the timezone to 'floating' in order to avoid the
|
||||
// automatic conversion back into the OS timezone.
|
||||
startTime.timezone = "floating";
|
||||
endTime.timezone = "floating";
|
||||
startTime.timezone = floating();
|
||||
endTime.timezone = floating();
|
||||
setElementValue("event-starttime", startTime.jsDate);
|
||||
setElementValue("event-endtime", endTime.jsDate);
|
||||
}
|
||||
|
@ -2010,25 +2009,25 @@ function updateDateTime() {
|
|||
|
||||
if (hasEntryDate && hasDueDate) {
|
||||
setElementValue("todo-has-entrydate", hasEntryDate, "checked");
|
||||
startTime.timezone = "floating";
|
||||
startTime.timezone = floating();
|
||||
setElementValue("todo-entrydate", startTime.jsDate);
|
||||
|
||||
setElementValue("todo-has-duedate", hasDueDate, "checked");
|
||||
endTime.timezone = "floating";
|
||||
endTime.timezone = floating();
|
||||
setElementValue("todo-duedate", endTime.jsDate);
|
||||
} else if (hasEntryDate) {
|
||||
setElementValue("todo-has-entrydate", hasEntryDate, "checked");
|
||||
startTime.timezone = "floating";
|
||||
startTime.timezone = floating();
|
||||
setElementValue("todo-entrydate", startTime.jsDate);
|
||||
|
||||
startTime.timezone = "floating";
|
||||
startTime.timezone = floating();
|
||||
setElementValue("todo-duedate", startTime.jsDate);
|
||||
} else if (hasDueDate) {
|
||||
endTime.timezone = "floating";
|
||||
endTime.timezone = floating();
|
||||
setElementValue("todo-entrydate", endTime.jsDate);
|
||||
|
||||
setElementValue("todo-has-duedate", hasDueDate, "checked");
|
||||
endTime.timezone = "floating";
|
||||
endTime.timezone = floating();
|
||||
setElementValue("todo-duedate", endTime.jsDate);
|
||||
}
|
||||
}
|
||||
|
@ -2058,7 +2057,7 @@ function updateTimezone() {
|
|||
|
||||
var equalTimezones = false;
|
||||
if (startTimezone && endTimezone) {
|
||||
if (startTimezone == endTimezone || endTimezone == "UTC") {
|
||||
if (compareObjects(startTimezone, endTimezone) || endTimezone.isUTC) {
|
||||
equalTimezones = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -904,7 +904,7 @@ calDavCalendar.prototype = {
|
|||
thisCalendar.mICSService = Components.classes["@mozilla.org/calendar/ics-service;1"].
|
||||
getService(Components.interfaces.calIICSService);
|
||||
}
|
||||
var rootComp = thisCalendar.mICSService.parseICS(calData);
|
||||
var rootComp = thisCalendar.mICSService.parseICS(calData, null);
|
||||
|
||||
var calComp;
|
||||
if (rootComp.componentType == 'VCALENDAR') {
|
||||
|
@ -1222,8 +1222,8 @@ calDavCalendar.prototype = {
|
|||
queryRangeEnd.day++;
|
||||
queryRangeEnd.isDate = false;
|
||||
}
|
||||
var rangeXml = <time-range start={queryRangeStart.getInTimezone("UTC").icalString}
|
||||
end={queryRangeEnd.getInTimezone("UTC").icalString}/>;
|
||||
var rangeXml = <time-range start={queryRangeStart.getInTimezone(UTC()).icalString}
|
||||
end={queryRangeEnd.getInTimezone(UTC()).icalString}/>;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1671,9 +1671,9 @@ calDavCalendar.prototype = {
|
|||
|
||||
var organizer = this.mMailToUrl;
|
||||
|
||||
var dtstamp = now().getInTimezone("UTC").icalString;
|
||||
var dtstart = aRangeStart.getInTimezone("UTC").icalString;
|
||||
var dtend = aRangeEnd.getInTimezone("UTC").icalString;
|
||||
var dtstamp = now().getInTimezone(UTC()).icalString;
|
||||
var dtstart = aRangeStart.getInTimezone(UTC()).icalString;
|
||||
var dtend = aRangeEnd.getInTimezone(UTC()).icalString;
|
||||
var uuid = getUUID();
|
||||
|
||||
var fbQuery = "BEGIN:VCALENDAR\n";
|
||||
|
|
|
@ -677,7 +677,7 @@ calGoogleCalendar.prototype = {
|
|||
var xml = new XML(aItemString.substring(38));
|
||||
|
||||
// Get the local timezone from the preferences
|
||||
var timezone = getPrefSafe("calendar.timezone.local");
|
||||
var timezone = calendarDefaultTimezone().tzid;
|
||||
|
||||
// Parse the Item with the given timezone
|
||||
var item = XMLEntryToItem(xml, timezone, this.superCalendar);
|
||||
|
|
|
@ -74,7 +74,7 @@ function ComponentsUtilsImport(aFile) {
|
|||
var scriptUri = iosvc.newFileURI(aFile);
|
||||
loader.loadSubScript(scriptUri.spec, null);
|
||||
} catch (e) {
|
||||
Components.utils.reportError("Error while loading " + fileurl.spec);
|
||||
Components.utils.reportError("Error while loading " + aFile.path);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -210,29 +210,30 @@ function getCalendarCredentials(aCalendarName,
|
|||
* @return The same string including /mozilla.org/<date>/
|
||||
*/
|
||||
function getMozillaTimezone(aICALTimezone) {
|
||||
|
||||
if (!aICALTimezone ||
|
||||
aICALTimezone == "UTC" ||
|
||||
aICALTimezone == "floating") {
|
||||
return aICALTimezone;
|
||||
ASSERT(aICALTimezone, "No timezone passed", true);
|
||||
if (aICALTimezone == "floating") {
|
||||
return floating();
|
||||
} else if (aICALTimezone == "UTC") {
|
||||
return UTC();
|
||||
}
|
||||
|
||||
// TODO A patch to Bug 363191 should make this more efficient.
|
||||
// For now we need to go through all timezones and see which timezone
|
||||
// ends with aICALTimezone.
|
||||
|
||||
var icsSvc = Components.classes["@mozilla.org/calendar/ics-service;1"].
|
||||
getService(Components.interfaces.calIICSService);
|
||||
|
||||
var tzService = getTimezoneService();
|
||||
// Enumerate timezones, set them, check their offset
|
||||
var enumerator = icsSvc.timezoneIds;
|
||||
var enumerator = tzService.timezoneIds;
|
||||
var id = null;
|
||||
while (enumerator.hasMore()) {
|
||||
var id = enumerator.getNext();
|
||||
id = enumerator.getNext();
|
||||
|
||||
if (id.substr(-aICALTimezone.length) == aICALTimezone) {
|
||||
return id;
|
||||
return tzService.getTimezone(id);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
return floating();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -257,7 +258,7 @@ function fromRFC3339(aStr, aTimezone) {
|
|||
"(([Zz]|([+-])([0-9]{2}):([0-9]{2})))?");
|
||||
|
||||
var matches = re.exec(aStr);
|
||||
var moztz = getMozillaTimezone(aTimezone) || "UTC";
|
||||
var moztz = getMozillaTimezone(aTimezone);
|
||||
|
||||
if (!matches) {
|
||||
return null;
|
||||
|
@ -280,7 +281,7 @@ function fromRFC3339(aStr, aTimezone) {
|
|||
if (matches[9] == "Z") {
|
||||
// If the dates timezone is "Z", then this is UTC, no matter
|
||||
// what timezone was passed
|
||||
dateTime.timezone = "UTC";
|
||||
dateTime.timezone = UTC();
|
||||
|
||||
} else if (matches[9] == null) {
|
||||
// We have no timezone info, only a date. We have no way to
|
||||
|
@ -302,21 +303,19 @@ function fromRFC3339(aStr, aTimezone) {
|
|||
if (dateTime.timezoneOffset != offset_in_s) {
|
||||
// TODO A patch to Bug 363191 should make this more efficient.
|
||||
|
||||
var icsSvc = Components.classes["@mozilla.org/calendar/ics-service;1"].
|
||||
getService(Components.interfaces.calIICSService);
|
||||
|
||||
var tzService = getTimezoneService();
|
||||
// Enumerate timezones, set them, check their offset
|
||||
var enumerator = icsSvc.timezoneIds;
|
||||
var enumerator = tzService.timezoneIds;
|
||||
while (enumerator.hasMore()) {
|
||||
var id = enumerator.getNext();
|
||||
dateTime.timezone = id;
|
||||
dateTime.timezone = tzService.getTimezone(id);
|
||||
if (dateTime.timezoneOffset == offset_in_s) {
|
||||
// This is our last step, so go ahead and return
|
||||
return dateTime;
|
||||
}
|
||||
}
|
||||
// We are still here: no timezone was found
|
||||
dateTime.timezone = "UTC";
|
||||
dateTime.timezone = UTC();
|
||||
if (!dateTime.isDate) {
|
||||
dateTime.hour += (matches[11] == "-" ? -1 : 1) * matches[12];
|
||||
dateTime.minute += (matches[11] == "-" ? -1 : 1) * matches[13];
|
||||
|
@ -358,7 +357,7 @@ function toRFC3339(aDateTime) {
|
|||
str += (tzoffset_hr < 0 ? "-" : "+") +
|
||||
("00" + Math.abs(tzoffset_hr)).substr(-2) + ":" +
|
||||
("00" + Math.abs(tzoffset_mn)).substr(-2);
|
||||
} else if (aDateTime.timezone == "floating") {
|
||||
} else if (aDateTime.timezone.isFloating) {
|
||||
// RFC3339 Section 4.3 Unknown Local Offset Convention
|
||||
str += "-00:00";
|
||||
} else {
|
||||
|
@ -1037,7 +1036,6 @@ function XMLEntryToItem(aXMLEntry, aTimezone, aCalendar) {
|
|||
// those recurrence events.
|
||||
// XXX This code is somewhat preliminary
|
||||
|
||||
var timezone;
|
||||
var startDate = createDateTime();
|
||||
var endDate;
|
||||
for each (var line in lines) {
|
||||
|
|
|
@ -228,7 +228,7 @@ calICSCalendar.prototype = {
|
|||
try {
|
||||
var parser = Components.classes["@mozilla.org/calendar/ics-parser;1"].
|
||||
createInstance(Components.interfaces.calIIcsParser);
|
||||
parser.parseString(str);
|
||||
parser.parseString(str, null);
|
||||
var items = parser.getItems({});
|
||||
|
||||
for each (var item in items) {
|
||||
|
|
|
@ -148,12 +148,12 @@ function textToDate(d) {
|
|||
function dateToText(d) {
|
||||
var datestr;
|
||||
var tz = null;
|
||||
if (d.timezone != "floating") {
|
||||
if (d.timezone == "UTC") {
|
||||
if (!d.timezone.isFloating) {
|
||||
if (d.timezone.isUTC) {
|
||||
datestr = "U";
|
||||
} else {
|
||||
datestr = "Z";
|
||||
tz = d.timezone;
|
||||
tz = d.timezone.tzid;
|
||||
}
|
||||
} else {
|
||||
datestr = "L";
|
||||
|
@ -183,10 +183,11 @@ function dateToText(d) {
|
|||
function newDateTime(aNativeTime, aTimezone) {
|
||||
var t = createDateTime();
|
||||
t.nativeTime = aNativeTime;
|
||||
if (aTimezone && aTimezone != "floating") {
|
||||
t = t.getInTimezone(aTimezone);
|
||||
if (aTimezone) {
|
||||
var tz = getTimezoneService().getTimezone(aTimezone);
|
||||
t = t.getInTimezone(tz);
|
||||
} else {
|
||||
t.timezone = "floating";
|
||||
t.timezone = floating();
|
||||
}
|
||||
|
||||
return t;
|
||||
|
@ -1756,7 +1757,7 @@ calStorageCalendar.prototype = {
|
|||
setDateParamHelper: function (params, entryname, cdt) {
|
||||
if (cdt) {
|
||||
params[entryname] = cdt.nativeTime;
|
||||
params[entryname + "_tz"] = cdt.timezone;
|
||||
params[entryname + "_tz"] = cdt.timezone.tzid;
|
||||
} else {
|
||||
params[entryname] = null;
|
||||
params[entryname + "_tz"] = null;
|
||||
|
|
|
@ -396,15 +396,19 @@ calWcapCalendar.prototype = {
|
|||
return tzid[0];
|
||||
},
|
||||
|
||||
getAlignedTimezone: function calWcapCalendar_getAlignedTimezone(tzid) {
|
||||
// check whether it is one of cs:
|
||||
if (tzid.indexOf("/mozilla.org/") == 0) {
|
||||
// cut mozilla prefix: assuming that the latter string portion
|
||||
// semantically equals the demanded timezone
|
||||
tzid = tzid.substring( // next slash after "/mozilla.org/"
|
||||
tzid.indexOf("/", "/mozilla.org/".length) + 1);
|
||||
getAlignedTzid: function calWcapCalendar_getAlignedTzid(tz) {
|
||||
var tzid = tz.tzid;
|
||||
// check whether it is one cs supports:
|
||||
if (!tz.isUTC && !tz.isFloating && !compareObjects(tz.provider, this.session)) {
|
||||
log("not a server timezone: " + tzid);
|
||||
var prefix = getTimezoneService().tzidPrefix;
|
||||
if (tzid.indexOf(prefix) == 0) {
|
||||
// cut mozilla prefix: assuming that the latter string portion
|
||||
// semantically equals the demanded timezone
|
||||
tzid = tzid.substring(prefix.length);
|
||||
}
|
||||
}
|
||||
if (!this.session.isSupportedTimezone(tzid)) {
|
||||
if (!this.session.getTimezone(tzid)) {
|
||||
// xxx todo: we could further on search for a matching region,
|
||||
// e.g. CET (in TZNAME), but for now stick to
|
||||
// user's default if not supported directly
|
||||
|
@ -413,8 +417,7 @@ calWcapCalendar.prototype = {
|
|||
log(tzid + " not supported, falling back to default: " + ret, this);
|
||||
return ret;
|
||||
}
|
||||
else // is ok (supported):
|
||||
return tzid;
|
||||
return tzid;
|
||||
},
|
||||
|
||||
checkAccess: function calWcapCalendar_checkAccess(accessControlBits)
|
||||
|
|
|
@ -68,10 +68,10 @@ calWcapCalendar.prototype.encodeNscpTzid =
|
|||
function calWcapCalendar_encodeNscpTzid(dateTime)
|
||||
{
|
||||
var params = "X-NSCP-ORIGINAL-OPERATION=X-NSCP-WCAP-PROPERTY-";
|
||||
if (!dateTime || !dateTime.isValid || (dateTime.timezone == "floating")) {
|
||||
if (!dateTime || !dateTime.isValid || dateTime.timezone.isUTC || dateTime.timezone.isFloating) {
|
||||
params += "DELETE^";
|
||||
} else {
|
||||
params += ("REPLACE^" + encodeURIComponent(this.getAlignedTimezone(dateTime.timezone)));
|
||||
params += ("REPLACE^" + encodeURIComponent(this.getAlignedTzid(dateTime.timezone)));
|
||||
}
|
||||
return params;
|
||||
};
|
||||
|
@ -277,7 +277,7 @@ function equalDatetimes(one, two) {
|
|||
function identicalDatetimes(one, two) {
|
||||
return ((!one && !two) ||
|
||||
(equalDatetimes(one, two) &&
|
||||
(one.timezone == two.timezone)));
|
||||
compareObjects(one.timezone, two.timezone)));
|
||||
}
|
||||
|
||||
// @return null if nothing has changed else value to be written
|
||||
|
@ -564,11 +564,13 @@ function calWcapCalendar_storeItem(bAddItem, item, oldItem, request, netRespFunc
|
|||
else {
|
||||
var someDate = (item.startDate || item.entryDate || item.dueDate);
|
||||
if (someDate) {
|
||||
// provide some date: eMail notification dates are influenced by this parameter...
|
||||
params += ("&tzid=" + encodeURIComponent(
|
||||
this.getAlignedTimezone(someDate.timezone)));
|
||||
someTz = someDate.timezone;
|
||||
if (!someTz.isUTC && !someTz.isFloating) {
|
||||
// provide some tzid: eMail notification dates are influenced by this parameter
|
||||
params += ("&tzid=" + encodeURIComponent(this.getAlignedTzid(someTz)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (item.id)
|
||||
params += ("&uid=" + encodeURIComponent(item.id));
|
||||
|
||||
|
@ -836,11 +838,15 @@ calWcapCalendar.prototype.parseItems = function calWcapCalendar_parseItems(
|
|||
log(attr + " is " + dt, this_);
|
||||
}
|
||||
var tzid = subComp.getFirstProperty(xprop);
|
||||
if (tzid != null) {
|
||||
subComp[attr] = dt.getInTimezone(tzid.value);
|
||||
if (LOG_LEVEL > 2) {
|
||||
log("patching " + xprop + ": from " +
|
||||
dt + " to " + subComp[attr], this_);
|
||||
if (tzid) {
|
||||
var tz = this_.session.getTimezone(tzid.value);
|
||||
ASSERT(tz, "timezone not found: " + tzid);
|
||||
if (tz) {
|
||||
subComp[attr] = dt.getInTimezone(tz);
|
||||
if (LOG_LEVEL > 2) {
|
||||
log("patching " + xprop + ": from " +
|
||||
dt + " to " + subComp[attr], this_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -409,7 +409,7 @@ function getWcapRequestStatusString(xml)
|
|||
return str;
|
||||
}
|
||||
|
||||
function stringToIcal(data, expectedErrno)
|
||||
function stringToIcal(session, data, expectedErrno)
|
||||
{
|
||||
if (!data || data.length == 0) { // assuming time-out; WTF.
|
||||
throw new Components.Exception(
|
||||
|
@ -418,7 +418,7 @@ function stringToIcal(data, expectedErrno)
|
|||
}
|
||||
var icalRootComp;
|
||||
try {
|
||||
icalRootComp = getIcsService().parseICS(data);
|
||||
icalRootComp = getIcsService().parseICS(data, session /*implements calITimezoneProvider*/);
|
||||
}
|
||||
catch (exc) { // map into more useful error string:
|
||||
throw new Components.Exception("error parsing ical data!",
|
||||
|
@ -428,7 +428,7 @@ function stringToIcal(data, expectedErrno)
|
|||
return icalRootComp;
|
||||
}
|
||||
|
||||
function stringToXml(data, expectedErrno)
|
||||
function stringToXml(session, data, expectedErrno)
|
||||
{
|
||||
if (!data || data.length == 0) { // assuming time-out
|
||||
throw new Components.Exception(
|
||||
|
|
|
@ -54,6 +54,25 @@ function getWcapSessionFor(cal, uri) {
|
|||
return session;
|
||||
}
|
||||
|
||||
function calWcapTimezone(tzProvider, tzid_, component_) {
|
||||
this.wrappedJSObject = this;
|
||||
this.provider = tzProvider;
|
||||
this.component = component_;
|
||||
this.tzid = tzid_;
|
||||
this.isUTC = false;
|
||||
this.isFloating = false;
|
||||
this.latitude = "";
|
||||
this.longitude = "";
|
||||
}
|
||||
calWcapTimezone.prototype = {
|
||||
toString: function() {
|
||||
// xxx todo remove: for some time, we want to know if a calITimezone object
|
||||
// is handled as string...
|
||||
ASSERT(false, "calWcapTimezone.toString!");
|
||||
return this.component.toString();
|
||||
}
|
||||
};
|
||||
|
||||
function calWcapSession(contextId, thatUri) {
|
||||
this.wrappedJSObject = this;
|
||||
this.m_contextId = contextId;
|
||||
|
@ -78,6 +97,7 @@ calWcapSession.prototype = {
|
|||
m_ifaces: [ calIWcapSession,
|
||||
calIFreeBusyProvider,
|
||||
calICalendarSearchProvider,
|
||||
Components.interfaces.calITimezoneProvider,
|
||||
Components.interfaces.calICalendarManagerObserver,
|
||||
Components.interfaces.nsIInterfaceRequestor,
|
||||
Components.interfaces.nsIClassInfo,
|
||||
|
@ -145,18 +165,44 @@ calWcapSession.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
// calITimezoneProvider:
|
||||
m_serverTimezones: null,
|
||||
isSupportedTimezone: function calWcapSession_isSupportedTimezone(tzid)
|
||||
{
|
||||
if (!this.m_serverTimezones) {
|
||||
throw new Components.Exception(
|
||||
"early run into getSupportedTimezones()!",
|
||||
Components.results.NS_ERROR_NOT_AVAILABLE);
|
||||
get timezoneIds() {
|
||||
var tzids = [];
|
||||
tzids.push("floating");
|
||||
tzids.push("UTC");
|
||||
for (var tz in this.m_serverTimezones) {
|
||||
tzids.push(tz.tzid);
|
||||
}
|
||||
return this.m_serverTimezones.some(
|
||||
function someFunc(id) { return tzid == id; } );
|
||||
return {
|
||||
// nsIUTF8StringEnumerator:
|
||||
m_index: 0,
|
||||
getNext: function() {
|
||||
if (this.m_index >= tzids) {
|
||||
ASSERT(false, "calWcapSession::timezoneIds enumerator!");
|
||||
throw Components.results.NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return tzids[this.m_index++];
|
||||
},
|
||||
hasMoreElements: function() {
|
||||
return (this.m_index < tzids);
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
getTimezone: function calWcapSession_getTimezone(tzid) {
|
||||
switch (tzid) {
|
||||
case "floating":
|
||||
return floating();
|
||||
case "UTC":
|
||||
return UTC();
|
||||
default:
|
||||
if (this.m_serverTimezones) {
|
||||
return this.m_serverTimezones[tzid];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
m_serverTimeDiff: null,
|
||||
getServerTime: function calWcapSession_getServerTime(localTime)
|
||||
{
|
||||
|
@ -374,7 +420,7 @@ calWcapSession.prototype = {
|
|||
// currently, xml parsing at an early stage during
|
||||
// process startup does not work reliably, so use
|
||||
// libical parsing for now:
|
||||
var icalRootComp = stringToIcal(str);
|
||||
var icalRootComp = stringToIcal(this_, str);
|
||||
var prop = icalRootComp.getFirstProperty("X-NSCP-WCAP-SESSION-ID");
|
||||
if (!prop) {
|
||||
throw new Components.Exception(
|
||||
|
@ -438,7 +484,7 @@ calWcapSession.prototype = {
|
|||
function netResp(err, str) {
|
||||
if (err)
|
||||
throw err;
|
||||
stringToXml(str, -1 /* logout successfull */);
|
||||
stringToXml(this_, str, -1 /* logout successfull */);
|
||||
}, url);
|
||||
}
|
||||
else {
|
||||
|
@ -460,7 +506,7 @@ calWcapSession.prototype = {
|
|||
var icalRootComp;
|
||||
if (!err) {
|
||||
try {
|
||||
icalRootComp = stringToIcal(str);
|
||||
icalRootComp = stringToIcal(this_, str);
|
||||
}
|
||||
catch (exc) {
|
||||
err = exc;
|
||||
|
@ -726,7 +772,7 @@ calWcapSession.prototype = {
|
|||
installServerTimezones:
|
||||
function calWcapSession_installServerTimezones(sessionId, request)
|
||||
{
|
||||
this.m_serverTimezones = [];
|
||||
this.m_serverTimezones = {};
|
||||
var this_ = this;
|
||||
this_.issueNetworkRequest_(
|
||||
request,
|
||||
|
@ -734,17 +780,12 @@ calWcapSession.prototype = {
|
|||
if (err)
|
||||
throw err;
|
||||
var tzids = [];
|
||||
var icsService = getIcsService();
|
||||
forEachIcalComponent(
|
||||
data, "VTIMEZONE",
|
||||
function eachComp(subComp) {
|
||||
try {
|
||||
var tzCal = icsService.createIcalComponent("VCALENDAR");
|
||||
subComp = subComp.clone();
|
||||
tzCal.addSubcomponent(subComp);
|
||||
icsService.addTimezone(tzCal, "", "");
|
||||
this_.m_serverTimezones.push(
|
||||
subComp.getFirstProperty("TZID").value);
|
||||
var tzid = subComp.getFirstProperty("TZID").value;
|
||||
this_.m_serverTimezones[tzid] = new calWcapTimezone(this_, tzid, subComp);
|
||||
}
|
||||
catch (exc) { // ignore but errors:
|
||||
logError(exc, this_);
|
||||
|
@ -798,6 +839,7 @@ calWcapSession.prototype = {
|
|||
request, respFunc, dataConvFunc, wcapCommand, params, sessionId)
|
||||
{
|
||||
var url = this.getCommandUrl(wcapCommand, params, sessionId);
|
||||
var this_ = this;
|
||||
issueNetworkRequest(
|
||||
request,
|
||||
function netResp(err, str) {
|
||||
|
@ -805,7 +847,7 @@ calWcapSession.prototype = {
|
|||
if (!err) {
|
||||
try {
|
||||
if (dataConvFunc)
|
||||
data = dataConvFunc(str);
|
||||
data = dataConvFunc(this_, str);
|
||||
else
|
||||
data = str;
|
||||
}
|
||||
|
@ -1040,13 +1082,13 @@ calWcapSession.prototype = {
|
|||
|
||||
// cannot use stringToXml here, because cs 6.3 returns plain nothing
|
||||
// on invalid user freebusy requests. WTF.
|
||||
function stringToXml_(data) {
|
||||
function stringToXml_(session, data) {
|
||||
if (!data || data.length == 0) { // assuming invalid user
|
||||
throw new Components.Exception(
|
||||
wcapErrorToString(calIWcapErrors.WCAP_CALENDAR_DOES_NOT_EXIST),
|
||||
calIWcapErrors.WCAP_CALENDAR_DOES_NOT_EXIST);
|
||||
}
|
||||
return stringToXml(data);
|
||||
return stringToXml(session, data);
|
||||
}
|
||||
this.issueNetworkRequest(
|
||||
request,
|
||||
|
|
|
@ -43,8 +43,7 @@ var g_logPrefObserver = null;
|
|||
|
||||
function initLogging()
|
||||
{
|
||||
g_logTimezone = getPref("calendar.timezone.local", null);
|
||||
|
||||
g_logTimezone = calendarDefaultTimezone();
|
||||
if (g_logFilestream) {
|
||||
try {
|
||||
g_logFilestream.close();
|
||||
|
@ -306,10 +305,10 @@ function getIcalUTC(dt) {
|
|||
return "0";
|
||||
else {
|
||||
var dtz = dt.timezone;
|
||||
if (dtz == "UTC" || dtz == "floating")
|
||||
if (dtz.isUTC || dtz.isFloating)
|
||||
return dt.icalString;
|
||||
else
|
||||
return dt.getInTimezone("UTC").icalString;
|
||||
return dt.getInTimezone(UTC()).icalString;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ function CalendarWindow( )
|
|||
CalendarWindow.prototype.pickAndGoToDate = function calWin_pickAndGoToDate( )
|
||||
{
|
||||
var args = new Object();
|
||||
args.initialDate = currentView().selectedDay.getInTimezone("floating").jsDate;
|
||||
args.initialDate = currentView().selectedDay.getInTimezone(floating()).jsDate;
|
||||
args.onOk = function receiveAndGoToDate( pickedDate ) {
|
||||
currentView().goToDay( jsDateToDateTime(pickedDate) );
|
||||
document.getElementById( "lefthandcalendar" ).value = pickedDate;
|
||||
|
|
|
@ -216,7 +216,7 @@ function pasteFromClipboard()
|
|||
case "text/unicode":
|
||||
var icssrv = Components.classes["@mozilla.org/calendar/ics-service;1"]
|
||||
.getService(Components.interfaces.calIICSService);
|
||||
var calComp = icssrv.parseICS(data);
|
||||
var calComp = icssrv.parseICS(data, null);
|
||||
var subComp = calComp.getFirstSubcomponent("ANY");
|
||||
while (subComp) {
|
||||
switch (subComp.componentType) {
|
||||
|
|
|
@ -15,7 +15,7 @@ var str = "BEGIN:VCALENDAR\n";
|
|||
var icsServ = Components.classes["@mozilla.org/calendar/ics-service;1"]
|
||||
.getService(Components.interfaces.calIICSService);
|
||||
|
||||
var calComp = icsServ.parseICS(str);
|
||||
var calComp = icsServ.parseICS(str, null);
|
||||
var subComp = calComp.getFirstSubcomponent("VEVENT");
|
||||
var event = Components.classes["@mozilla.org/calendar/event;1"]
|
||||
.createInstance(Components.interfaces.calIEvent);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Boelzle <daniel.boelzle@sun.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -37,10 +38,35 @@
|
|||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
/* Shortcut to the timezone service */
|
||||
function getTimezoneService() {
|
||||
if (getTimezoneService.mObject === undefined) {
|
||||
getTimezoneService.mObject = Components.classes["@mozilla.org/calendar/timezone-service;1"]
|
||||
.getService(Components.interfaces.calITimezoneService);
|
||||
}
|
||||
return getTimezoneService.mObject;
|
||||
}
|
||||
|
||||
/// @return the UTC timezone.
|
||||
function UTC() {
|
||||
if (UTC.mObject === undefined) {
|
||||
UTC.mObject = getTimezoneService().UTC;
|
||||
}
|
||||
return UTC.mObject;
|
||||
}
|
||||
|
||||
/// @return the floating timezone.
|
||||
function floating() {
|
||||
if (floating.mObject === undefined) {
|
||||
floating.mObject = getTimezoneService().floating;
|
||||
}
|
||||
return floating.mObject;
|
||||
}
|
||||
|
||||
function createDate(aYear, aMonth, aDay) {
|
||||
var cd = Cc["@mozilla.org/calendar/datetime;1"].
|
||||
createInstance(Ci.calIDateTime);
|
||||
cd.resetTo(aYear, aMonth, aDay, 0, 0, 0, "UTC");
|
||||
cd.resetTo(aYear, aMonth, aDay, 0, 0, 0, UTC());
|
||||
cd.isDate = true;
|
||||
return cd;
|
||||
}
|
||||
|
|
|
@ -35,22 +35,23 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
function run_test() {
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
function getMozTimezone(tzid) {
|
||||
return getTimezoneService().getTimezone(tzid);
|
||||
}
|
||||
|
||||
var cd = Cc["@mozilla.org/calendar/datetime;1"].
|
||||
createInstance(Ci.calIDateTime);
|
||||
cd.resetTo(2005, 10, 13,
|
||||
10, 0, 0,
|
||||
"/mozilla.org/20050126_1/America/Bogota");
|
||||
getMozTimezone("/mozilla.org/20050126_1/America/Bogota"));
|
||||
|
||||
do_check_eq(cd.hour, 10);
|
||||
do_check_eq(cd.icalString, "20051113T100000");
|
||||
|
||||
var cd_floating = cd.getInTimezone("floating");
|
||||
var cd_floating = cd.getInTimezone(floating());
|
||||
do_check_eq(cd_floating.hour, 10);
|
||||
|
||||
var cd_utc = cd.getInTimezone("UTC");
|
||||
var cd_utc = cd.getInTimezone(UTC());
|
||||
do_check_eq(cd_utc.hour, 15);
|
||||
do_check_eq(cd_utc.icalString, "20051113T150000Z");
|
||||
|
||||
|
@ -70,7 +71,7 @@ function run_test() {
|
|||
// Daylight savings test
|
||||
cd.resetTo(2006, 2, 26,
|
||||
1, 0, 0,
|
||||
"/mozilla.org/20050126_1/Europe/Amsterdam");
|
||||
getMozTimezone("/mozilla.org/20050126_1/Europe/Amsterdam"));
|
||||
|
||||
do_check_eq(cd.weekday, 0);
|
||||
do_check_eq(cd.timezoneOffset, 1*3600);
|
||||
|
@ -81,24 +82,24 @@ function run_test() {
|
|||
// Bug 398724 – Problems with floating all-day items
|
||||
var event = Cc["@mozilla.org/calendar/event;1"].createInstance(Ci.calIEvent);
|
||||
event.icalString = "BEGIN:VEVENT\nUID:45674d53-229f-48c6-9f3b-f2b601e7ae4d\nSUMMARY:New Event\nDTSTART;VALUE=DATE:20071003\nDTEND;VALUE=DATE:20071004\nEND:VEVENT";
|
||||
do_check_eq(event.startDate.timezone, "floating");
|
||||
do_check_eq(event.endDate.timezone, "floating");
|
||||
do_check_eq(event.startDate.timezone.isFloating, true);
|
||||
do_check_eq(event.endDate.timezone.isFloating, true);
|
||||
|
||||
// Bug 392853 - Same times, different timezones, but subtractDate says times are PT0S apart
|
||||
const zeroLength = Cc["@mozilla.org/calendar/duration;1"].createInstance(Ci.calIDuration);
|
||||
const a = Cc["@mozilla.org/calendar/datetime;1"].createInstance(Ci.calIDateTime);
|
||||
a.jsDate = new Date();
|
||||
a.timezone = "/mozilla.org/20070129_1/Europe/Berlin";
|
||||
a.timezone = getMozTimezone("/mozilla.org/20070129_1/Europe/Berlin");
|
||||
|
||||
var b = a.clone();
|
||||
b.timezone = "/mozilla.org/20070129_1/America/New_York";
|
||||
b.timezone = getMozTimezone("/mozilla.org/20070129_1/America/New_York");
|
||||
|
||||
var duration = a.subtractDate(b);
|
||||
do_check_neq(duration.compare(zeroLength), 0);
|
||||
do_check_neq(a.compare(b), 0);
|
||||
|
||||
// Should lead to zero length duration
|
||||
b = a.getInTimezone("/mozilla.org/20070129_1/America/New_York");
|
||||
b = a.getInTimezone(getMozTimezone("/mozilla.org/20070129_1/America/New_York"));
|
||||
duration = a.subtractDate(b);
|
||||
do_check_eq(duration.compare(zeroLength), 0);
|
||||
do_check_eq(a.compare(b), 0);
|
||||
|
|
Загрузка…
Ссылка в новой задаче