Bug 400950 - Change calDatetime to reference its timezone definition; r=ctalbert, r=mickey, r=philipp

This commit is contained in:
daniel.boelzle%sun.com 2007-12-03 14:42:49 +00:00
Родитель b746ea872b
Коммит a450d66132
56 изменённых файлов: 1783 добавлений и 1521 удалений

Просмотреть файл

@ -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)]
@ -122,19 +123,9 @@ interface calIDateTime : nsISupports
* Setting the timezone does not change the actual date/time components;
* 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,27 +159,26 @@ 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.
@ -177,7 +187,7 @@ interface calIIcalComponent : nsISupports
calIIcalComponent clone();
[noscript,notxpcom] icalcomponentptr getIcalComponent();
[noscript, notxpcom] nsresult addTimezoneReferenceById(in ACStringPtr tzid);
[noscript,notxpcom] icaltimezoneptr getIcalTimezone();
};
[scriptable,uuid(17349a10-5d80-47fa-9bea-f22957357675)]
@ -189,6 +199,11 @@ interface calIIcalProperty : nsISupports
*/
readonly attribute AUTF8String icalString;
/**
* Return a string representation of this instance.
*/
AUTF8String toString();
/**
* The value of the property as string.
* The exception for properties of TEXT or X- type, those will be unescaped
@ -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,14 +463,27 @@ 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);
@ -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,9 +564,11 @@ 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)
@ -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,16 +165,42 @@ 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 {
// 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;
}
return this.m_serverTimezones.some(
function someFunc(id) { return tzid == id; } );
},
m_serverTimeDiff: null,
@ -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);