Back to index

lightning-sunbird  0.9+nobinonly
calRecurrenceRule.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Oracle Corporation code.
00015  *
00016  * The Initial Developer of the Original Code is
00017  *  Oracle Corporation
00018  * Portions created by the Initial Developer are Copyright (C) 2004
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
00023  *   Daniel Boelzle <daniel.boelzle@sun.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsCOMArray.h"
00040 
00041 #include "calRecurrenceRule.h"
00042 
00043 #include "calDateTime.h"
00044 #include "calIItemBase.h"
00045 #include "calIEvent.h"
00046 
00047 #include "calICSService.h"
00048 
00049 #ifndef MOZILLA_1_8_BRANCH
00050 #include "nsIClassInfoImpl.h"
00051 #endif
00052 
00053 #include <climits>
00054 
00055 NS_IMPL_ISUPPORTS2_CI(calRecurrenceRule, calIRecurrenceItem, calIRecurrenceRule)
00056 
00057 calRecurrenceRule::calRecurrenceRule()
00058     : mImmutable(PR_FALSE),
00059       mIsNegative(PR_FALSE),
00060       mIsByCount(PR_FALSE)
00061 {
00062     icalrecurrencetype_clear(&mIcalRecur);
00063 }
00064 
00065 NS_IMETHODIMP
00066 calRecurrenceRule::GetIsMutable(PRBool *aResult)
00067 {
00068     NS_ENSURE_ARG_POINTER(aResult);
00069     *aResult = !mImmutable;
00070     return NS_OK;
00071 }
00072 
00073 NS_IMETHODIMP
00074 calRecurrenceRule::MakeImmutable()
00075 {
00076     mImmutable = PR_TRUE;
00077     return NS_OK;
00078 }
00079 
00080 NS_IMETHODIMP
00081 calRecurrenceRule::Clone(calIRecurrenceItem **aResult)
00082 {
00083     calRecurrenceRule * const crc = new calRecurrenceRule();
00084     CAL_ENSURE_MEMORY(crc);
00085 
00086     crc->mIsNegative = mIsNegative;
00087     crc->mIsByCount = mIsByCount;
00088     crc->mIcalRecur = mIcalRecur;
00089 
00090     NS_ADDREF(*aResult = crc);
00091     return NS_OK;
00092 }
00093 
00094 /* attribute boolean isNegative; */
00095 NS_IMETHODIMP
00096 calRecurrenceRule::GetIsNegative(PRBool *_retval)
00097 {
00098     NS_ENSURE_ARG_POINTER(_retval);
00099     *_retval = mIsNegative;
00100     return NS_OK;
00101 }
00102 
00103 NS_IMETHODIMP
00104 calRecurrenceRule::SetIsNegative(PRBool aIsNegative)
00105 {
00106     if (mImmutable)
00107         return NS_ERROR_OBJECT_IS_IMMUTABLE;
00108     mIsNegative = aIsNegative;
00109     return NS_OK;
00110 }
00111 
00112 /* readonly attribute boolean isFinite; */
00113 NS_IMETHODIMP
00114 calRecurrenceRule::GetIsFinite(PRBool *_retval)
00115 {
00116     NS_ENSURE_ARG_POINTER(_retval);
00117 
00118     if ((mIsByCount && mIcalRecur.count == 0) ||
00119         (!mIsByCount && icaltime_is_null_time(mIcalRecur.until)))
00120     {
00121         *_retval = PR_FALSE;
00122     } else {
00123         *_retval = PR_TRUE;
00124     }
00125     return NS_OK;
00126 }
00127 
00128 /* attribute long type; */
00129 NS_IMETHODIMP
00130 calRecurrenceRule::GetType(nsACString &aType)
00131 {
00132     switch (mIcalRecur.freq) {
00133 #define RECUR_HELPER(x) \
00134         case ICAL_##x##_RECURRENCE: aType.AssignLiteral( #x ); break
00135         RECUR_HELPER(SECONDLY);
00136         RECUR_HELPER(MINUTELY);
00137         RECUR_HELPER(HOURLY);
00138         RECUR_HELPER(DAILY);
00139         RECUR_HELPER(WEEKLY);
00140         RECUR_HELPER(MONTHLY);
00141         RECUR_HELPER(YEARLY);
00142 #undef RECUR_HELPER
00143         default:
00144             aType.AssignLiteral("");
00145     }
00146 
00147     return NS_OK;
00148 }
00149 
00150 NS_IMETHODIMP
00151 calRecurrenceRule::SetType(const nsACString &aType)
00152 {
00153 #define RECUR_HELPER(x) \
00154     if (aType.EqualsLiteral( #x )) mIcalRecur.freq = ICAL_##x##_RECURRENCE
00155     RECUR_HELPER(SECONDLY);
00156     else RECUR_HELPER(MINUTELY);
00157     else RECUR_HELPER(HOURLY);
00158     else RECUR_HELPER(DAILY);
00159     else RECUR_HELPER(WEEKLY);
00160     else RECUR_HELPER(MONTHLY);
00161     else RECUR_HELPER(YEARLY);
00162 #undef RECUR_HELPER
00163     else if (aType.IsEmpty() || aType.EqualsLiteral(""))
00164         mIcalRecur.freq = ICAL_NO_RECURRENCE;
00165     else
00166         return NS_ERROR_FAILURE;
00167 
00168     return NS_OK;
00169 }
00170 
00171 /* attribute long count; */
00172 NS_IMETHODIMP
00173 calRecurrenceRule::GetCount(PRInt32 *aRecurCount)
00174 {
00175     NS_ENSURE_ARG_POINTER(aRecurCount);
00176 
00177     if (!mIsByCount)
00178         return NS_ERROR_FAILURE;
00179 
00180     if (mIcalRecur.count == 0 && icaltime_is_null_time(mIcalRecur.until)) {
00181         *aRecurCount = -1;
00182     } else if (mIcalRecur.count) {
00183         *aRecurCount = mIcalRecur.count;
00184     } else {
00185         // count wasn't set, so we don't know
00186         return NS_ERROR_FAILURE;
00187     }
00188 
00189     return NS_OK;
00190 }
00191 
00192 NS_IMETHODIMP
00193 calRecurrenceRule::SetCount(PRInt32 aRecurCount)
00194 {
00195     if (aRecurCount != -1) {
00196         if (aRecurCount < 0 || aRecurCount > INT_MAX)
00197             return NS_ERROR_ILLEGAL_VALUE;
00198         mIcalRecur.count = static_cast<int>(aRecurCount);
00199     } else {
00200         mIcalRecur.count = 0;
00201     }
00202 
00203     mIcalRecur.until = icaltime_null_time();
00204 
00205     mIsByCount = PR_TRUE;
00206 
00207     return NS_OK;
00208 }
00209 
00210 /* attribute calIDateTime endDate; */
00211 NS_IMETHODIMP
00212 calRecurrenceRule::GetEndDate(calIDateTime * *aRecurEnd)
00213 {
00214     NS_ENSURE_ARG_POINTER(aRecurEnd);
00215 
00216     if (mIsByCount)
00217         return NS_ERROR_FAILURE;
00218 
00219     if (!icaltime_is_null_time(mIcalRecur.until)) {
00220         *aRecurEnd = new calDateTime(&mIcalRecur.until, nsnull);
00221         CAL_ENSURE_MEMORY(*aRecurEnd);
00222         NS_ADDREF(*aRecurEnd);
00223     } else {
00224         // infinite recurrence
00225         *aRecurEnd = nsnull; 
00226     }
00227     return NS_OK;
00228 }
00229 
00230 NS_IMETHODIMP
00231 calRecurrenceRule::SetEndDate(calIDateTime * aRecurEnd)
00232 {
00233     if (aRecurEnd) {
00234         nsCOMPtr<calIDateTime> dt(aRecurEnd);
00235         nsCOMPtr<calITimezone> tz;
00236         aRecurEnd->GetTimezone(getter_AddRefs(tz));
00237         PRBool b;
00238         if (NS_SUCCEEDED(tz->GetIsUTC(&b)) && !b &&
00239             NS_SUCCEEDED(tz->GetIsFloating(&b)) && !b) {
00240             // convert to UTC:
00241             aRecurEnd->GetInTimezone(cal::UTC(), getter_AddRefs(dt));
00242         }
00243         struct icaltimetype itt;
00244         dt->ToIcalTime(&itt);
00245 
00246         mIcalRecur.until = itt;
00247     } else {
00248         mIcalRecur.until = icaltime_null_time();
00249     }
00250 
00251     mIcalRecur.count = 0;
00252 
00253     mIsByCount = PR_FALSE;
00254 
00255     return NS_OK;
00256 }
00257 
00258 /* readonly attribute boolean isByCount; */
00259 NS_IMETHODIMP
00260 calRecurrenceRule::GetIsByCount (PRBool *aIsByCount)
00261 {
00262     *aIsByCount = mIsByCount;
00263     return NS_OK;
00264 }
00265 
00266 /* attribute long interval; */
00267 NS_IMETHODIMP
00268 calRecurrenceRule::GetInterval(PRInt32 *aInterval)
00269 {
00270     NS_ENSURE_ARG_POINTER(aInterval);
00271     *aInterval = mIcalRecur.interval;
00272     return NS_OK;
00273 }
00274 
00275 NS_IMETHODIMP
00276 calRecurrenceRule::SetInterval(PRInt32 aInterval)
00277 {
00278     if (aInterval < 0 || aInterval > SHRT_MAX)
00279         return NS_ERROR_ILLEGAL_VALUE;
00280     mIcalRecur.interval = static_cast<short>(aInterval);
00281     return NS_OK;
00282 }
00283 
00284 /* void getComponent (in AUTF8String aComponentType, out unsigned long aCount, [array, size_is (aCount), retval] out long aValues); */
00285 NS_IMETHODIMP
00286 calRecurrenceRule::GetComponent(const nsACString &aComponentType, PRUint32 *aCount, PRInt16 **aValues)
00287 {
00288     NS_ENSURE_ARG_POINTER(aCount);
00289     NS_ENSURE_ARG_POINTER(aValues);
00290 
00291     // This little ugly macro counts the number of real entries
00292     // we have in the relevant array, and then clones it to the result.
00293 #define HANDLE_COMPONENT(_comptype,_icalvar,_icalmax)                   \
00294     if (aComponentType.EqualsLiteral( #_comptype )) {                    \
00295         int count;                                                      \
00296         for (count = 0; count < _icalmax; count++) {                    \
00297             if (mIcalRecur._icalvar[count] == ICAL_RECURRENCE_ARRAY_MAX) \
00298                 break;                                                  \
00299         }                                                               \
00300         if (count) {                                                    \
00301             *aValues = (PRInt16*) nsMemory::Clone(mIcalRecur._icalvar,  \
00302                                                   count * sizeof(PRInt16)); \
00303             if (!*aValues) return NS_ERROR_OUT_OF_MEMORY;               \
00304         } else {                                                        \
00305             *aValues = nsnull;                                          \
00306         }                                                               \
00307         *aCount = count;                                                \
00308     }
00309 
00310     HANDLE_COMPONENT(BYSECOND, by_second, ICAL_BY_SECOND_SIZE)
00311     else HANDLE_COMPONENT(BYMINUTE, by_minute, ICAL_BY_MINUTE_SIZE)
00312     else HANDLE_COMPONENT(BYHOUR, by_hour, ICAL_BY_HOUR_SIZE)
00313     else HANDLE_COMPONENT(BYDAY, by_day, ICAL_BY_DAY_SIZE) // special
00314     else HANDLE_COMPONENT(BYMONTHDAY, by_month_day, ICAL_BY_MONTHDAY_SIZE)
00315     else HANDLE_COMPONENT(BYYEARDAY, by_year_day, ICAL_BY_YEARDAY_SIZE)
00316     else HANDLE_COMPONENT(BYWEEKNO, by_week_no, ICAL_BY_WEEKNO_SIZE)
00317     else HANDLE_COMPONENT(BYMONTH, by_month, ICAL_BY_MONTH_SIZE)
00318     else HANDLE_COMPONENT(BYSETPOS, by_set_pos, ICAL_BY_SETPOS_SIZE)
00319     else {
00320         // invalid component; XXX - error code
00321         return NS_ERROR_FAILURE;
00322     }
00323 #undef HANDLE_COMPONENT
00324 
00325     return NS_OK;
00326 }
00327 
00328 /* void setComponent (in AUTF8String aComponentType, in unsigned long aCount, [array, size_is (aCount)] in long aValues); */
00329 NS_IMETHODIMP
00330 calRecurrenceRule::SetComponent(const nsACString& aComponentType, PRUint32 aCount, PRInt16 *aValues)
00331 {
00332     NS_ENSURE_ARG_POINTER(aValues);
00333 
00334     // Copy the passed-in array into the ical structure array
00335 #define HANDLE_COMPONENT(_comptype,_icalvar,_icalmax)                   \
00336     if (aComponentType.EqualsLiteral( #_comptype )) {                    \
00337         if (aCount > _icalmax)                                          \
00338             return NS_ERROR_FAILURE;                                    \
00339         memcpy(mIcalRecur._icalvar, aValues, aCount * sizeof(PRInt16)); \
00340         if (aCount < _icalmax)                                          \
00341             mIcalRecur._icalvar[aCount] = ICAL_RECURRENCE_ARRAY_MAX;    \
00342     }
00343 
00344     HANDLE_COMPONENT(BYSECOND, by_second, ICAL_BY_SECOND_SIZE)
00345     else HANDLE_COMPONENT(BYMINUTE, by_minute, ICAL_BY_MINUTE_SIZE)
00346     else HANDLE_COMPONENT(BYHOUR, by_hour, ICAL_BY_HOUR_SIZE)
00347     else HANDLE_COMPONENT(BYDAY, by_day, ICAL_BY_DAY_SIZE) // special
00348     else HANDLE_COMPONENT(BYMONTHDAY, by_month_day, ICAL_BY_MONTHDAY_SIZE)
00349     else HANDLE_COMPONENT(BYYEARDAY, by_year_day, ICAL_BY_YEARDAY_SIZE)
00350     else HANDLE_COMPONENT(BYWEEKNO, by_week_no, ICAL_BY_WEEKNO_SIZE)
00351     else HANDLE_COMPONENT(BYMONTH, by_month, ICAL_BY_MONTH_SIZE)
00352     else HANDLE_COMPONENT(BYSETPOS, by_set_pos, ICAL_BY_SETPOS_SIZE)
00353     else {
00354         // invalid component; XXX - error code
00355         return NS_ERROR_FAILURE;
00356     }
00357 #undef HANDLE_COMPONENT
00358 
00359     return NS_OK;
00360 }
00361 
00362 /* calIDateTime getNextOccurrence (in calIDateTime aStartTime, in calIDateTime aOccurrenceTime); */
00363 NS_IMETHODIMP
00364 calRecurrenceRule::GetNextOccurrence(calIDateTime *aStartTime,
00365                                      calIDateTime *aOccurrenceTime,
00366                                      calIDateTime **_retval)
00367 {
00368     NS_ENSURE_ARG_POINTER(aStartTime);
00369     NS_ENSURE_ARG_POINTER(aOccurrenceTime);
00370     NS_ENSURE_ARG_POINTER(_retval);
00371 
00372     struct icaltimetype dtstart;
00373     aStartTime->ToIcalTime(&dtstart);
00374 
00375     struct icaltimetype occurtime;
00376     aOccurrenceTime->ToIcalTime(&occurtime);
00377 
00378     icalrecur_iterator* recur_iter;
00379     recur_iter = icalrecur_iterator_new(mIcalRecur, dtstart);
00380     if (!recur_iter)
00381         return NS_ERROR_OUT_OF_MEMORY;
00382 
00383     struct icaltimetype next = icalrecur_iterator_next(recur_iter);
00384     while (!icaltime_is_null_time(next)) {
00385         if (icaltime_compare(next, occurtime) > 0)
00386             break;
00387 
00388         next = icalrecur_iterator_next(recur_iter);
00389     }
00390 
00391     icalrecur_iterator_free(recur_iter);
00392 
00393     if (icaltime_is_null_time(next)) {
00394         *_retval = nsnull;
00395         return NS_OK;
00396     }
00397 
00398     nsCOMPtr<calITimezone> tz;
00399     aStartTime->GetTimezone(getter_AddRefs(tz));
00400     *_retval = new calDateTime(&next, tz);
00401     CAL_ENSURE_MEMORY(*_retval);
00402     NS_ADDREF(*_retval);
00403     return NS_OK;
00404 }
00405 
00406 static inline icaltimetype ensureDateTime(icaltimetype const& icalt) {
00407     if (!icalt.is_date) {
00408         return icalt;
00409     } else {
00410         icaltimetype ret = icalt;
00411         ret.is_date = 0;
00412         ret.hour = 0;
00413         ret.minute = 0;
00414         ret.second = 0;
00415         return ret;
00416     }
00417 }
00418 
00419 NS_IMETHODIMP
00420 calRecurrenceRule::GetOccurrences(calIDateTime *aStartTime,
00421                                   calIDateTime *aRangeStart,
00422                                   calIDateTime *aRangeEnd,
00423                                   PRUint32 aMaxCount,
00424                                   PRUint32 *aCount, calIDateTime ***aDates)
00425 {
00426     NS_ENSURE_ARG_POINTER(aStartTime);
00427     NS_ENSURE_ARG_POINTER(aRangeStart);
00428     NS_ENSURE_ARG_POINTER(aCount);
00429     NS_ENSURE_ARG_POINTER(aDates);
00430 
00431     // make sure the request is sane; infinite recurrence
00432     // with no end time is bad times.
00433     if (!aMaxCount && !aRangeEnd && mIcalRecur.count == 0 && icaltime_is_null_time(mIcalRecur.until))
00434         return NS_ERROR_INVALID_ARG;
00435 
00436     nsCOMArray<calIDateTime> dates;
00437 
00438 #ifdef DEBUG_dbo
00439     {
00440         char const * const ss = icalrecurrencetype_as_string(&mIcalRecur);
00441         nsCAutoString tst, tend;
00442         aRangeStart->ToString(tst);
00443         aRangeEnd->ToString(tend);
00444         printf("RULE: [%s -> %s, %d]: %s\n", tst.get(), tend.get(), mIcalRecur.count, ss);
00445     }
00446 #endif
00447 
00448     struct icaltimetype rangestart, dtstart, dtend;
00449     aRangeStart->ToIcalTime(&rangestart);
00450     rangestart = ensureDateTime(rangestart);
00451     aStartTime->ToIcalTime(&dtstart);
00452     nsCOMPtr<calITimezone> tz;
00453     aStartTime->GetTimezone(getter_AddRefs(tz));
00454 
00455     if (aRangeEnd) {
00456         aRangeEnd->ToIcalTime(&dtend);
00457         dtend = ensureDateTime(dtend);
00458 
00459         // if the start of the recurrence is past the end,
00460         // we have no dates
00461         if (icaltime_compare (dtstart, dtend) >= 0) {
00462             *aDates = nsnull;
00463             *aCount = 0;
00464             return NS_OK;
00465         }
00466     }
00467 
00468     icalrecur_iterator* recur_iter;
00469     recur_iter = icalrecur_iterator_new(mIcalRecur, dtstart);
00470     if (!recur_iter)
00471         return NS_ERROR_OUT_OF_MEMORY;
00472 
00473     PRUint32 count = 0;
00474 
00475     for (icaltimetype next = icalrecur_iterator_next(recur_iter);
00476          !icaltime_is_null_time(next);
00477          next = icalrecur_iterator_next(recur_iter))
00478     {
00479         icaltimetype const dtNext(ensureDateTime(next));
00480 
00481         // if this thing is before the range start
00482         if (icaltime_compare(dtNext, rangestart) < 0) {
00483             continue;
00484         }
00485 
00486         if (aRangeEnd && icaltime_compare(dtNext, dtend) >= 0)
00487             break;
00488 
00489         calIDateTime * const cdt = new calDateTime(&next, tz);
00490         if (!cdt) {
00491             icalrecur_iterator_free(recur_iter);
00492             return NS_ERROR_OUT_OF_MEMORY;
00493         }
00494 
00495         dates.AppendObject(cdt);
00496 #ifdef DEBUG_dbo
00497         {
00498             nsCAutoString str;
00499             cdt->ToString(str);
00500             printf("  occ: %s\n", str.get());
00501         }
00502 #endif
00503         count++;
00504         if (aMaxCount && aMaxCount <= count)
00505             break;
00506     }
00507 
00508     icalrecur_iterator_free(recur_iter);
00509 
00510     if (count) {
00511         calIDateTime ** const dateArray =
00512             static_cast<calIDateTime **>(nsMemory::Alloc(sizeof(calIDateTime*) * count));
00513         CAL_ENSURE_MEMORY(dateArray);
00514         for (PRUint32 i = 0; i < count; ++i) {
00515             NS_ADDREF(dateArray[i] = dates[i]);
00516         }
00517         *aDates = dateArray;
00518     } else {
00519         *aDates = nsnull;
00520     }
00521 
00522     *aCount = count;
00523 
00524     return NS_OK;
00525 }
00526 
00530 NS_IMETHODIMP
00531 calRecurrenceRule::GetIcalProperty(calIIcalProperty **prop)
00532 {
00533     icalproperty * const rrule = icalproperty_new_rrule(mIcalRecur);
00534     CAL_ENSURE_MEMORY(rrule);
00535     *prop = new calIcalProperty(rrule, nsnull);
00536     if (!*prop) {
00537         icalproperty_free(rrule);
00538         return NS_ERROR_FAILURE;
00539     }
00540 
00541     NS_ADDREF(*prop);
00542     return NS_OK;
00543 }
00544 
00545 NS_IMETHODIMP
00546 calRecurrenceRule::SetIcalProperty(calIIcalProperty *aProp)
00547 {
00548     NS_ENSURE_ARG_POINTER(aProp);
00549 
00550     if (mImmutable)
00551         return NS_ERROR_OBJECT_IS_IMMUTABLE;
00552 
00553     nsCAutoString propname;
00554     nsresult rv = aProp->GetPropertyName(propname);
00555     NS_ENSURE_SUCCESS(rv, rv);
00556     if (propname.EqualsLiteral("RRULE"))
00557         mIsNegative = PR_FALSE;
00558     else if (propname.EqualsLiteral("EXRULE"))
00559         mIsNegative = PR_TRUE;
00560     else
00561         return NS_ERROR_INVALID_ARG;
00562 
00563     icalproperty *prop;
00564     struct icalrecurrencetype icalrecur;
00565 
00566     prop = aProp->GetIcalProperty();
00567 
00568     icalrecur = icalproperty_get_rrule(prop);
00569 
00570     // XXX Note that we ignore the dtstart and use the one from the
00571     // event, though I realize now that we shouldn't.  Ignoring
00572     // dtstart makes it impossible to have multiple RRULEs on one
00573     // event that start at different times (e.g. every day starting on
00574     // jan 1 for 2 weeks, every other day starting on feb 1 for 2
00575     // weeks).  Neither the server nor the UI supports this now,
00576     // but we really ought to!
00577     //struct icaltimetype icaldtstart;
00578     //icaldtstrat = icalproperty_get_dtstart(prop);
00579 
00580     if (icalrecur.count != 0)
00581         mIsByCount = PR_TRUE;
00582     else
00583         mIsByCount = PR_FALSE;
00584 
00585     mIcalRecur = icalrecur;
00586 
00587     return NS_OK;
00588 }