/* ***** 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 OEone Calendar Code, released October 31st, 2001. * * The Initial Developer of the Original Code is * OEone Corporation. * Portions created by the Initial Developer are Copyright (C) 2001 * the Initial Developer. All Rights Reserved. * * Contributor(s): Mostafa Hosseini * * 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 WIN32 #include #endif #include "oeICalEventImpl.h" #include "nsMemory.h" #include "nsCOMPtr.h" #define strcasecmp strcmp #define RECUR_NONE 0 #define RECUR_DAILY 1 #define RECUR_WEEKLY 2 #define RECUR_MONTHLY_MDAY 3 #define RECUR_MONTHLY_WDAY 4 #define RECUR_YEARLY 5 char *EmptyReturn() { return (char*) nsMemory::Clone( "", 1 ); } icaltimetype ConvertFromPrtime( PRTime indate ) { icaltimetype outdate = icaltime_null_time(); PRExplodedTime ext; PRInt64 indateinusec, usecpermsec; LL_I2L( usecpermsec, PR_USEC_PER_MSEC ); LL_MUL( indateinusec, indate, usecpermsec ); PR_ExplodeTime( indateinusec, PR_LocalTimeParameters, &ext); outdate.year = ext.tm_year; outdate.month = ext.tm_month + 1; outdate.day = ext.tm_mday; outdate.hour = ext.tm_hour; outdate.minute = ext.tm_min; outdate.second = ext.tm_sec; return outdate; } PRTime ConvertToPrtime ( icaltimetype indate ) { PRExplodedTime ext; ext.tm_year = indate.year; ext.tm_month = indate.month - 1; ext.tm_mday = indate.day; ext.tm_hour = indate.hour; ext.tm_min = indate.minute; ext.tm_sec = indate.second; ext.tm_usec = 0; ext.tm_params.tp_gmt_offset = 0; ext.tm_params.tp_dst_offset = 0; PRTime result = PR_ImplodeTime( &ext ); PR_ExplodeTime( result, PR_LocalTimeParameters, &ext); ext.tm_year = indate.year; ext.tm_month = indate.month - 1; ext.tm_mday = indate.day; ext.tm_hour = indate.hour; ext.tm_min = indate.minute; ext.tm_sec = indate.second; ext.tm_usec = 0; result = PR_ImplodeTime( &ext ); PRInt64 usecpermsec; LL_I2L( usecpermsec, PR_USEC_PER_MSEC ); LL_DIV( result, result, usecpermsec ); return result; } ////////////////////////////////////////////////// // ICalEvent Factory ////////////////////////////////////////////////// /* Implementation file */ NS_IMPL_ISUPPORTS1(oeICalEventImpl, oeIICalEvent) nsresult NS_NewICalEvent( oeIICalEvent** inst ) { NS_PRECONDITION(inst != nsnull, "null ptr"); if (! inst) return NS_ERROR_NULL_POINTER; *inst = new oeICalEventImpl(); if (! *inst) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(*inst); return NS_OK; } oeICalEventImpl::oeICalEventImpl() { #ifdef ICAL_DEBUG printf( "oeICalEventImpl::oeICalEventImpl()\n" ); #endif NS_INIT_ISUPPORTS(); /* member initializers and constructor code */ nsresult rv; if( NS_FAILED( rv = NS_NewDateTime((oeIDateTime**) &m_start ))) { m_start = nsnull; } if( NS_FAILED( rv = NS_NewDateTime((oeIDateTime**) &m_end ))) { m_end = nsnull; } if( NS_FAILED( rv = NS_NewDateTime((oeIDateTime**) &m_recurend ))) { m_recurend = nsnull; } m_id = nsnull; m_title = nsnull; m_description = nsnull; m_location = nsnull; m_category = nsnull; m_isprivate = true; m_syncid = nsnull; m_allday = false; m_hasalarm = false; m_alarmlength = 0; m_alarmemail = nsnull; m_inviteemail = nsnull; m_recurinterval = 1; m_recur = false; m_recurforever = true; m_alarmunits = nsnull; m_recurunits = nsnull; m_recurweekdays = 0; m_recurweeknumber = 0; m_lastalarmack = icaltime_null_time(); SetAlarmUnits( "minutes" ); SetRecurUnits( "weeks" ); SetSyncId( "" ); } oeICalEventImpl::~oeICalEventImpl() { #ifdef ICAL_DEBUG printf( "oeICalEventImpl::~oeICalEventImpl( %d )\n", mRefCnt ); #endif /* destructor code */ if( m_id ) nsMemory::Free( m_id ); if( m_title ) nsMemory::Free( m_title ); if( m_description ) nsMemory::Free( m_description ); if( m_location ) nsMemory::Free( m_location ); if( m_category ) nsMemory::Free( m_category ); if( m_alarmunits ) nsMemory::Free( m_alarmunits ); if( m_alarmemail ) nsMemory::Free( m_alarmemail ); if( m_inviteemail ) nsMemory::Free( m_inviteemail ); if( m_recurunits ) nsMemory::Free( m_recurunits ); if( m_syncid ) nsMemory::Free( m_syncid ); if( m_start ) m_start->Release(); if( m_end ) m_end->Release(); if( m_recurend ) m_recurend->Release(); } /* attribute string Id; */ NS_IMETHODIMP oeICalEventImpl::GetId(char **aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetId() = " ); #endif if( m_id ) { *aRetVal= (char*) nsMemory::Clone( m_id, strlen(m_id)+1); if( *aRetVal == nsnull ) return NS_ERROR_OUT_OF_MEMORY; } else *aRetVal= nsnull; #ifdef ICAL_DEBUG_ALL printf( "\"%s\"\n", *aRetVal ); #endif return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetId(const char *aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetId( %s )\n", aNewVal ); #endif if( m_id ) nsMemory::Free( m_id ); if( aNewVal ) m_id= (char*) nsMemory::Clone( aNewVal, strlen(aNewVal)+1); else m_id = nsnull; return NS_OK; } bool oeICalEventImpl::matchId( const char *id ) { if( m_id ) return ( strcmp( m_id, id ) == 0 ); else return false; } /* attribute string Title; */ NS_IMETHODIMP oeICalEventImpl::GetTitle(char **aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetTitle() = " ); #endif if( m_title ) { *aRetVal= (char*) nsMemory::Clone( m_title, strlen(m_title)+1); if( *aRetVal == nsnull ) return NS_ERROR_OUT_OF_MEMORY; } else *aRetVal= EmptyReturn(); #ifdef ICAL_DEBUG_ALL printf( "\"%s\"\n", *aRetVal ); #endif return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetTitle(const char * aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetTitle( %s )\n", aNewVal ); #endif if( m_title ) nsMemory::Free( m_title ); if( aNewVal ) m_title= (char*) nsMemory::Clone( aNewVal, strlen(aNewVal)+1); else m_title = nsnull; return NS_OK; } /* attribute string Description; */ NS_IMETHODIMP oeICalEventImpl::GetDescription(char * *aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetDescription() = " ); #endif if( m_description ) { *aRetVal= (char*) nsMemory::Clone( m_description , strlen(m_description)+1); if( *aRetVal == nsnull ) return NS_ERROR_OUT_OF_MEMORY; } else *aRetVal= EmptyReturn(); #ifdef ICAL_DEBUG_ALL printf( "\"%s\"\n", *aRetVal ); #endif return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetDescription(const char * aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetDescription( %s )\n", aNewVal ); #endif if( m_description ) nsMemory::Free( m_description ); if( aNewVal ) m_description= (char*) nsMemory::Clone( aNewVal, strlen(aNewVal)+1); else m_description = nsnull; return NS_OK; } /* attribute string Location; */ NS_IMETHODIMP oeICalEventImpl::GetLocation(char **aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetLocation() = " ); #endif if( m_location ) { *aRetVal= (char*) nsMemory::Clone( m_location , strlen(m_location)+1); if( *aRetVal == nsnull ) return NS_ERROR_OUT_OF_MEMORY; } else *aRetVal= EmptyReturn(); #ifdef ICAL_DEBUG_ALL printf( "\"%s\"\n", *aRetVal ); #endif return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetLocation(const char * aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetLocation( %s )\n", aNewVal ); #endif if( m_location ) nsMemory::Free( m_location ); if( aNewVal ) m_location= (char*) nsMemory::Clone( aNewVal, strlen(aNewVal)+1); else m_location = nsnull; return NS_OK; } /* attribute string Category; */ NS_IMETHODIMP oeICalEventImpl::GetCategory(char **aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetCategory() = " ); #endif if( m_category ) { *aRetVal= (char*) nsMemory::Clone( m_category , strlen(m_category)+1); if( *aRetVal == nsnull ) return NS_ERROR_OUT_OF_MEMORY; } else *aRetVal= EmptyReturn(); #ifdef ICAL_DEBUG_ALL printf( "\"%s\"\n", *aRetVal ); #endif return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetCategory(const char * aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetCategory( %s )\n", aNewVal ); #endif if( m_category ) nsMemory::Free( m_category ); if( aNewVal ) m_category= (char*) nsMemory::Clone( aNewVal, strlen(aNewVal)+1); else m_category = nsnull; return NS_OK; } /* attribute boolean PrivateEvent; */ NS_IMETHODIMP oeICalEventImpl::GetPrivateEvent(PRBool *aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetPrivateEvent( ) = " ); #endif *aRetVal = m_isprivate; #ifdef ICAL_DEBUG_ALL printf( "%d\n", *aRetVal ); #endif return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetPrivateEvent(PRBool aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetPrivateEvent( %d )\n", aNewVal ); #endif m_isprivate = aNewVal; return NS_OK; } /* attribute string SyncId; */ NS_IMETHODIMP oeICalEventImpl::GetSyncId(char * *aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetSyncId()\n" ); #endif if( m_syncid ) { *aRetVal= (char*) nsMemory::Clone( m_syncid, strlen(m_syncid)+1); if( *aRetVal == nsnull ) return NS_ERROR_OUT_OF_MEMORY; } else *aRetVal= EmptyReturn(); return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetSyncId(const char * aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetSyncId( %s )\n", aNewVal ); #endif if( m_syncid ) nsMemory::Free( m_syncid ); if( aNewVal ) m_syncid= (char*) nsMemory::Clone( aNewVal, strlen(aNewVal)+1); else m_syncid = nsnull; return NS_OK; } /* attribute boolean AllDay; */ NS_IMETHODIMP oeICalEventImpl::GetAllDay(PRBool *aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetAllDay()\n" ); #endif *aRetVal = m_allday; return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetAllDay(PRBool aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetAllDay( %d )\n", aNewVal ); #endif m_allday = aNewVal; return NS_OK; } /* attribute boolean Alarm; */ NS_IMETHODIMP oeICalEventImpl::GetAlarm(PRBool *aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetAlarm()\n" ); #endif *aRetVal = m_hasalarm; return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetAlarm(PRBool aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetAlarm()\n" ); #endif m_hasalarm = aNewVal; return NS_OK; } /* attribute string AlarmUnits; */ NS_IMETHODIMP oeICalEventImpl::GetAlarmUnits(char * *aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetAlarmUnits()\n" ); #endif if( m_alarmunits ) { *aRetVal= (char*) nsMemory::Clone( m_alarmunits, strlen(m_alarmunits)+1); if( *aRetVal == nsnull ) return NS_ERROR_OUT_OF_MEMORY; } else *aRetVal= EmptyReturn(); return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetAlarmUnits(const char * aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetAlarmUnits( %s )\n", aNewVal ); #endif if( m_alarmunits ) nsMemory::Free( m_alarmunits ); if( aNewVal ) m_alarmunits= (char*) nsMemory::Clone( aNewVal, strlen(aNewVal)+1); else m_alarmunits = nsnull; return NS_OK; } /* attribute long AlarmLength; */ NS_IMETHODIMP oeICalEventImpl::GetAlarmLength(PRUint32 *aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetAlarmLength()\n" ); #endif *aRetVal = m_alarmlength; return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetAlarmLength(PRUint32 aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetAlarmLength(%lu)\n", aNewVal ); #endif m_alarmlength = aNewVal; return NS_OK; } /* attribute string AlarmEmailAddress; */ NS_IMETHODIMP oeICalEventImpl::GetAlarmEmailAddress(char * *aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetAlarmEmailAddres()\n" ); #endif if( m_alarmemail ) { *aRetVal= (char*) nsMemory::Clone( m_alarmemail, strlen(m_alarmemail)+1); if( *aRetVal == nsnull ) return NS_ERROR_OUT_OF_MEMORY; } else *aRetVal= EmptyReturn(); return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetAlarmEmailAddress(const char * aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetAlarmEmailAddres()\n" ); #endif if( m_alarmemail ) nsMemory::Free( m_alarmemail ); if( aNewVal ) m_alarmemail= (char*) nsMemory::Clone( aNewVal, strlen(aNewVal)+1); else m_alarmemail = nsnull; return NS_OK; } /* attribute string InviteEmailAddress; */ NS_IMETHODIMP oeICalEventImpl::GetInviteEmailAddress(char * *aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetInviteEmailAddres()\n" ); #endif if( m_inviteemail ) { *aRetVal= (char*) nsMemory::Clone( m_inviteemail, strlen(m_inviteemail)+1); if( *aRetVal == nsnull ) return NS_ERROR_OUT_OF_MEMORY; } else *aRetVal= EmptyReturn(); return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetInviteEmailAddress(const char * aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetInviteEmailAddres()\n" ); #endif if( m_inviteemail ) nsMemory::Free( m_inviteemail ); if( aNewVal ) m_inviteemail= (char*) nsMemory::Clone( aNewVal, strlen(aNewVal)+1); else m_inviteemail = nsnull; return NS_OK; } /* attribute boolean RecurInterval; */ NS_IMETHODIMP oeICalEventImpl::GetRecurInterval(PRUint32 *aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetRecurInterval()\n" ); #endif *aRetVal = m_recurinterval; return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetRecurInterval(PRUint32 aNewVal ) { #ifdef ICAL_DEBUG_ALL printf( "SetRecurInterval()\n" ); #endif m_recurinterval = aNewVal; return NS_OK; } /* attribute string RecurUnits; */ NS_IMETHODIMP oeICalEventImpl::GetRecurUnits(char **aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetRecurUnits()\n" ); #endif if( m_recurunits ) { *aRetVal= (char*) nsMemory::Clone( m_recurunits, strlen(m_recurunits)+1); if( *aRetVal == nsnull ) return NS_ERROR_OUT_OF_MEMORY; } else *aRetVal= EmptyReturn(); return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetRecurUnits(const char * aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetRecurUnits()\n" ); #endif if( m_recurunits ) nsMemory::Free( m_recurunits ); if( aNewVal ) m_recurunits= (char*) nsMemory::Clone( aNewVal, strlen(aNewVal)+1); else m_recurunits = nsnull; return NS_OK; } /* attribute boolean Recur; */ NS_IMETHODIMP oeICalEventImpl::GetRecur(PRBool *aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetRecur()\n" ); #endif *aRetVal = m_recur; return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetRecur(PRBool aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetRecur()\n" ); #endif m_recur = aNewVal; return NS_OK; } /* attribute boolean RecurForever; */ NS_IMETHODIMP oeICalEventImpl::GetRecurForever(PRBool *aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetRecurForever() = " ); #endif *aRetVal = m_recurforever; #ifdef ICAL_DEBUG_ALL printf( "%d\n", *aRetVal ); #endif return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetRecurForever(PRBool aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetRecurForever()\n" ); #endif m_recurforever = aNewVal; return NS_OK; } NS_IMETHODIMP oeICalEventImpl::GetLastAlarmAck(PRTime *aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetLastAlarmAck()\n" ); #endif *aRetVal = ConvertToPrtime( m_lastalarmack ); return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetLastAlarmAck(PRTime aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetLastAlarmAck()\n" ); #endif m_lastalarmack = ConvertFromPrtime( aNewVal ); return NS_OK; } NS_IMETHODIMP oeICalEventImpl::GetNextRecurrence( PRTime begin, PRTime *retval, PRBool *isvalid ) { #ifdef ICAL_DEBUG_ALL printf( "GetNextRecurrence()\n" ); #endif //for non recurring events *isvalid = false; if( !m_recur ) { PRTime start; m_start->GetTime( &start ); PRInt64 startinsec,begininsec,msecpersec; LL_I2L( msecpersec, PR_MSEC_PER_SEC ); LL_DIV( startinsec, start, msecpersec ); LL_DIV( begininsec, begin, msecpersec ); if( LL_CMP( startinsec, > , begininsec ) ) { *retval = start; *isvalid = true; } return NS_OK; } //for recurring events icalcomponent *vcalendar = AsIcalComponent(); if ( !vcalendar ) { #ifdef ICAL_DEBUG printf( "oeICalEventImpl::GetNextRecurrence() failed!\n" ); #endif return NS_OK; } icalcomponent *vevent = icalcomponent_get_first_component( vcalendar, ICAL_VEVENT_COMPONENT ); icalproperty *prop = icalcomponent_get_first_property( vevent, ICAL_RRULE_PROPERTY ); if ( prop != 0) { struct icalrecurrencetype recur = icalproperty_get_rrule(prop); // printf("#### %s\n",icalrecurrencetype_as_string(&recur)); icalrecur_iterator* ritr = icalrecur_iterator_new(recur,m_start->m_datetime); struct icaltimetype next; for(next = icalrecur_iterator_next(ritr); !icaltime_is_null_time(next); next = icalrecur_iterator_next(ritr)){ next.is_date = false; next = icaltime_normalize( next ); // printf( "recur: %d-%d-%d %d:%d:%d\n" , next.year, next.month, next.day, next.hour, next.minute, next.second ); //quick fix for the recurrence getting out of the end of the month into the next month //like 31st of each month but when you get February if( recur.freq == ICAL_MONTHLY_RECURRENCE && !m_recurweeknumber && next.day != m_start->m_datetime.day) { //#ifdef ICAL_DEBUG // printf( "Wrong day in month\n" ); //#endif // continue; next.day = 0; icaltime_normalize( next ); } PRTime nextinms = ConvertToPrtime( next ); if( LL_CMP(nextinms, > ,begin) && !IsExcepted( nextinms ) ) { // printf( "Result: %d-%d-%d %d:%d\n" , next.year, next.month, next.day, next.hour, next.minute ); *retval = nextinms; *isvalid = true; break; } } icalrecur_iterator_free(ritr); } icalcomponent_free( vcalendar ); return NS_OK; } icaltimetype oeICalEventImpl::GetNextRecurrence( icaltimetype begin ) { icaltimetype result = icaltime_null_time(); PRTime begininms = ConvertToPrtime( begin ); PRTime resultinms; PRBool isvalid; GetNextRecurrence( begininms ,&resultinms, &isvalid ); if( !isvalid ) return result; result = ConvertFromPrtime( resultinms ); return result; } icaltimetype oeICalEventImpl::GetNextAlarmTime( icaltimetype begin ) { #ifdef ICAL_DEBUG_ALL printf( "oeICalEventImpl::GetNextAlarmTime()\n" ); #endif icaltimetype result = icaltime_null_time(); if( !m_hasalarm ) return result; icaltimetype starting = begin; if( !icaltime_is_null_time( m_lastalarmack ) && icaltime_compare( begin, m_lastalarmack ) < 0 ) starting = m_lastalarmack; icaltimetype checkloop = starting; do { checkloop = GetNextRecurrence( checkloop ); result = checkloop; if( icaltime_is_null_time( checkloop ) ) { break; } result = CalculateAlarmTime( result ); } while ( icaltime_compare( starting, result ) >= 0 ); for( unsigned int i=0; i 0 ) { result = snoozetime; } } } return result; } icaltimetype oeICalEventImpl::CalculateAlarmTime( icaltimetype date ) { icaltimetype result = date; if( strcasecmp( m_alarmunits, "days" ) == 0 ) icaltime_adjust( &result, -(signed long)m_alarmlength, 0, 0, 0 ); else if( strcasecmp( m_alarmunits, "hours" ) == 0 ) icaltime_adjust( &result, 0, -(signed long)m_alarmlength, 0, 0 ); else icaltime_adjust( &result, 0, 0, -(signed long)m_alarmlength, 0 ); return result; } NS_IMETHODIMP oeICalEventImpl::GetStart(oeIDateTime * *start) { *start = m_start; NS_ADDREF(*start); return NS_OK; } NS_IMETHODIMP oeICalEventImpl::GetEnd(oeIDateTime * *end) { *end = m_end; NS_ADDREF(*end); return NS_OK; } NS_IMETHODIMP oeICalEventImpl::GetRecurEnd(oeIDateTime * *recurend) { *recurend = m_recurend; NS_ADDREF(*recurend); return NS_OK; } NS_IMETHODIMP oeICalEventImpl::GetRecurWeekdays(PRInt16 *aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetRecurWeekdays()\n" ); #endif *aRetVal = m_recurweekdays; return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetRecurWeekdays(PRInt16 aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetRecurWeekdays()\n" ); #endif m_recurweekdays = aNewVal; return NS_OK; } NS_IMETHODIMP oeICalEventImpl::GetRecurWeekNumber(PRInt16 *aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetRecurWeekNumber()\n" ); #endif *aRetVal = m_recurweeknumber; return NS_OK; } NS_IMETHODIMP oeICalEventImpl::SetRecurWeekNumber(PRInt16 aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "SetRecurWeekNumber()\n" ); #endif m_recurweeknumber = aNewVal; return NS_OK; } NS_IMETHODIMP oeICalEventImpl::GetIcalString(char **aRetVal) { #ifdef ICAL_DEBUG_ALL printf( "GetIcalString() = " ); #endif *aRetVal = nsnull; icalcomponent *vcalendar = AsIcalComponent(); if ( !vcalendar ) { #ifdef ICAL_DEBUG printf( "oeICalEventImpl::GetIcalString() failed!\n" ); #endif return NS_OK; } char *str = icalcomponent_as_ical_string( vcalendar ); if( str ) { *aRetVal= (char*) nsMemory::Clone( str, strlen(str)+1); if( *aRetVal == nsnull ) return NS_ERROR_OUT_OF_MEMORY; } else *aRetVal= EmptyReturn(); icalcomponent_free( vcalendar ); #ifdef ICAL_DEBUG_ALL printf( "\"%s\"\n", *aRetVal ); #endif return NS_OK; } NS_IMETHODIMP oeICalEventImpl::ParseIcalString(const char *aNewVal) { #ifdef ICAL_DEBUG_ALL printf( "ParseIcalString( %s )\n", aNewVal ); #endif icalcomponent *vevent = icalparser_parse_string( aNewVal ); ParseIcalComponent( vevent ); icalcomponent_free( vevent ); return NS_OK; } NS_IMETHODIMP oeICalEventImpl::AddException( PRTime exdate ) { #ifdef ICAL_DEBUG_ALL printf( "oeICalEventImpl::AddException()\n" ); #endif icaltimetype tmpexdate = ConvertFromPrtime( exdate ); tmpexdate.hour = 0; tmpexdate.minute = 0; tmpexdate.second = 0; exdate = ConvertToPrtime( tmpexdate ); m_exceptiondates.push_back( exdate ); return NS_OK; } NS_IMETHODIMP oeICalEventImpl::GetExceptions(nsISimpleEnumerator **datelist ) { #ifdef ICAL_DEBUG_ALL printf( "oeICalEventImpl::GetExceptions()\n" ); #endif nsCOMPtr dateEnum = new oeDateEnumerator(); if (!dateEnum) return NS_ERROR_OUT_OF_MEMORY; for( unsigned int i=0; iAddDate( m_exceptiondates[i] ); } // bump ref count return dateEnum->QueryInterface(NS_GET_IID(nsISimpleEnumerator), (void **)datelist); } bool oeICalEventImpl::IsExcepted( PRTime date ) { #ifdef ICAL_DEBUG_ALL printf( "oeICalEventImpl::IsExcepted() = " ); #endif icaltimetype tmpexdate = ConvertFromPrtime( date ); tmpexdate.hour = 0; tmpexdate.minute = 0; tmpexdate.second = 0; date = ConvertToPrtime( tmpexdate ); bool result = false; for( unsigned int i=0; im_datetime = icalproperty_get_dtstart( prop ); } //enddate prop = icalcomponent_get_first_property( vevent, ICAL_DTEND_PROPERTY ); if ( prop != 0) { icaltimetype end; end = icalproperty_get_dtstart( prop ); m_end->m_datetime = end; } else { m_end->m_datetime = m_start->m_datetime; } //recurenddate & recurforever & recur & recurweekday & recurweeknumber m_recur = false; m_recurforever = true; prop = icalcomponent_get_first_property( vevent, ICAL_RRULE_PROPERTY ); if ( prop != 0) { m_recur = true; struct icalrecurrencetype recur; recur = icalproperty_get_rrule(prop); m_recurend->m_datetime = recur.until; m_recurend->m_datetime.is_date = false; m_recurend->m_datetime.is_utc = false; if( !icaltime_is_null_time( recur.until ) ) m_recurforever = false; if( recur.freq == ICAL_WEEKLY_RECURRENCE ) { int k=0; while( recur.by_day[k] != ICAL_RECURRENCE_ARRAY_MAX ) { m_recurweekdays += 1 << (recur.by_day[k]-1); k++; } } else if( recur.freq == ICAL_MONTHLY_RECURRENCE ) { if( recur.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX ) m_recurweeknumber = icalrecurrencetype_day_position(recur.by_day[0]); if( m_recurweeknumber < 0 ) m_recurweeknumber = 5; } } //recurunits for( prop = icalcomponent_get_first_property( vevent, ICAL_X_PROPERTY ); prop != 0 ; prop = icalcomponent_get_next_property( vevent, ICAL_X_PROPERTY ) ) { icalparameter *tmppar = icalproperty_get_first_parameter( prop, ICAL_MEMBER_PARAMETER ); if ( tmppar != 0 ) { tmpstr = icalparameter_get_member( tmppar ); if( strcmp( tmpstr, "RecurUnits" ) == 0 ) break; } } if ( prop != 0) { tmpstr = (char *)icalproperty_get_value_as_string( prop ); SetRecurUnits( tmpstr ); } else SetRecurUnits( "weeks" ); //recur exceptions for( prop = icalcomponent_get_first_property( vevent, ICAL_RECURRENCEID_PROPERTY ); prop != 0 ; prop = icalcomponent_get_next_property( vevent, ICAL_RECURRENCEID_PROPERTY ) ) { icaltimetype exdate = icalproperty_get_recurrenceid( prop ); PRTime exdateinms = ConvertToPrtime( exdate ); m_exceptiondates.push_back( exdateinms ); } //snoozetimes icalcomponent *tmpcomp = icalcomponent_get_first_component( vevent, ICAL_X_COMPONENT ); if ( tmpcomp != 0) { for( prop = icalcomponent_get_first_property( tmpcomp, ICAL_DTSTAMP_PROPERTY ); prop != 0 ; prop = icalcomponent_get_next_property( tmpcomp, ICAL_DTSTAMP_PROPERTY ) ) { icaltimetype snoozetime = icalproperty_get_dtstamp( prop ); if( !icaltime_is_null_time( m_lastalarmack ) && icaltime_compare( m_lastalarmack, snoozetime ) >= 0 ) continue; PRTime snoozetimeinms = icaltime_as_timet( snoozetime ); snoozetimeinms *= 1000; m_snoozetimes.push_back( snoozetimeinms ); } } return true; } #define ICALEVENT_VERSION "2.0" #define ICALEVENT_PRODID "PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.0//EN" // ggf icalcomponent* oeICalEventImpl::AsIcalComponent() { #ifdef ICAL_DEBUG_ALL printf( "AsIcalComponent()\n" ); #endif icalcomponent *newcalendar; newcalendar = icalcomponent_new_vcalendar(); if ( !newcalendar ) { #ifdef ICAL_DEBUG printf( "oeICalEventImpl::AsIcalComponent() failed: Cannot create VCALENDAR!\n" ); #endif return nsnull; } //version icalproperty *prop = icalproperty_new_version( ICALEVENT_VERSION ); icalcomponent_add_property( newcalendar, prop ); //prodid - ggf prop = icalproperty_new_prodid( ICALEVENT_PRODID ); icalcomponent_add_property( newcalendar, prop ); icalcomponent *vevent = icalcomponent_new_vevent(); //id prop = icalproperty_new_uid( m_id ); icalcomponent_add_property( vevent, prop ); //title if( m_title && strlen( m_title ) != 0 ){ prop = icalproperty_new_summary( m_title ); icalcomponent_add_property( vevent, prop ); } //description if( m_description && strlen( m_description ) != 0 ){ prop = icalproperty_new_description( m_description ); icalcomponent_add_property( vevent, prop ); } //location if( m_location && strlen( m_location ) != 0 ){ prop = icalproperty_new_location( m_location ); icalcomponent_add_property( vevent, prop ); } //category if( m_category && strlen( m_category ) != 0 ){ prop = icalproperty_new_categories( m_category ); icalcomponent_add_property( vevent, prop ); } //isprivate if( m_isprivate ) prop = icalproperty_new_class( ICAL_CLASS_PRIVATE ); else prop = icalproperty_new_class( ICAL_CLASS_PUBLIC ); icalcomponent_add_property( vevent, prop ); icalparameter *tmppar; //syncId if( m_syncid && strlen( m_syncid ) != 0 ){ icalparameter *tmppar = icalparameter_new_member( "SyncId" ); prop = icalproperty_new_x( m_syncid ); icalproperty_add_parameter( prop, tmppar ); icalcomponent_add_property( vevent, prop ); } //allday if( m_allday ) { tmppar = icalparameter_new_member( "AllDay" ); prop = icalproperty_new_x( "TRUE" ); icalproperty_add_parameter( prop, tmppar ); icalcomponent_add_property( vevent, prop ); } //alarm if( m_hasalarm ) { struct icaltriggertype trig; icalcomponent *valarm = icalcomponent_new_valarm(); trig.time.year = trig.time.month = trig.time.day = trig.time.hour = trig.time.minute = trig.time.second = 0; trig.duration.is_neg = true; trig.duration.days = trig.duration.weeks = trig.duration.hours = trig.duration.minutes = trig.duration.seconds = 0; if( m_alarmunits ) { if( strcasecmp( m_alarmunits, "days" ) == 0 ) trig.duration.days = m_alarmlength; else if( strcasecmp( m_alarmunits, "hours" ) == 0 ) trig.duration.hours = m_alarmlength; else trig.duration.minutes = m_alarmlength; } else trig.duration.minutes = m_alarmlength; if( m_alarmlength == 0 ) trig.duration.seconds = 1; prop = icalproperty_new_trigger( trig ); icalcomponent_add_property( valarm, prop ); icalcomponent_add_component( vevent, valarm ); } //alarmunits if( m_alarmunits && strlen( m_alarmunits ) != 0 ){ icalparameter *tmppar = icalparameter_new_member( "AlarmUnits" ); prop = icalproperty_new_x( m_alarmunits ); icalproperty_add_parameter( prop, tmppar ); icalcomponent_add_property( vevent, prop ); } char tmpstr[20]; //alarmlength if( m_alarmlength ) { sprintf( tmpstr, "%lu", m_alarmlength ); tmppar = icalparameter_new_member( "AlarmLength" ); prop = icalproperty_new_x( tmpstr ); icalproperty_add_parameter( prop, tmppar ); icalcomponent_add_property( vevent, prop ); } //alarmemail if( m_alarmemail && strlen( m_alarmemail ) != 0 ){ icalparameter *tmppar = icalparameter_new_member( "AlarmEmailAddress" ); prop = icalproperty_new_x( m_alarmemail ); icalproperty_add_parameter( prop, tmppar ); icalcomponent_add_property( vevent, prop ); } //lastalarmack if( !icaltime_is_null_time( m_lastalarmack ) ) { prop = icalproperty_new_dtstamp( m_lastalarmack ); icalcomponent_add_property( vevent, prop ); } //inviteemail if( m_inviteemail && strlen( m_inviteemail ) != 0 ){ icalparameter *tmppar = icalparameter_new_member( "InviteEmailAddress" ); prop = icalproperty_new_x( m_inviteemail ); icalproperty_add_parameter( prop, tmppar ); icalcomponent_add_property( vevent, prop ); } //Create enddate if does not exist if( icaltime_is_null_time( m_end->m_datetime ) ) { //Set to the same as start date 23:59 m_end->m_datetime = m_start->m_datetime; m_end->SetHour( 23 ); m_end->SetMinute( 59 ); } //recurunits if( m_recurunits && strlen( m_recurunits ) != 0 ){ icalparameter *tmppar = icalparameter_new_member( "RecurUnits" ); prop = icalproperty_new_x( m_recurunits ); icalproperty_add_parameter( prop, tmppar ); icalcomponent_add_property( vevent, prop ); } //recurinterval sprintf( tmpstr, "%lu", m_recurinterval ); tmppar = icalparameter_new_member( "RecurInterval" ); prop = icalproperty_new_x( tmpstr ); icalproperty_add_parameter( prop, tmppar ); icalcomponent_add_property( vevent, prop ); //recurrence if( m_recur ) { int recurtype = RECUR_NONE; int interval = m_recurinterval; if( interval == 0 ) interval = 1; if( m_recurunits ) { if( strcasecmp( m_recurunits , "days" ) == 0 ) { recurtype = RECUR_DAILY; } else if( strcasecmp( m_recurunits , "weeks" ) == 0 ) { recurtype = RECUR_WEEKLY; // recurtype = RECUR_DAILY; // interval = 7 * m_recurinterval; } else if( strcasecmp( m_recurunits , "months" ) == 0 ) { recurtype = RECUR_MONTHLY_MDAY; } else if( strcasecmp( m_recurunits, "months_day" ) == 0 ) { recurtype = RECUR_MONTHLY_WDAY; } else if( strcasecmp( m_recurunits , "years" ) == 0 ) { recurtype = RECUR_YEARLY; } } struct icalrecurrencetype recur; icalrecurrencetype_clear( &recur ); // for( int i=0; im_datetime.year; recur.until.month = m_recurend->m_datetime.month; recur.until.day = m_recurend->m_datetime.day; recur.until.hour = 23; recur.until.minute = 59; recur.until.second = 59; } switch ( recurtype ) { case RECUR_NONE: break; case RECUR_DAILY: recur.freq = ICAL_DAILY_RECURRENCE; prop = icalproperty_new_rrule( recur ); icalcomponent_add_property( vevent, prop ); break; case RECUR_WEEKLY:{ recur.freq = ICAL_WEEKLY_RECURRENCE; //if the recur rule is weekly make sure a weekdaymask exists if( m_recurweekdays == 0 ) { m_recurweekdays = 1 << (icaltime_day_of_week( m_start->m_datetime )-1); } short weekdaymask = m_recurweekdays; int k=0; // bool weekdaymatchesstartdate=false; for( int i=0; i<7; i++ ) { if( weekdaymask & 1 ) { recur.by_day[k++]=i+1; // if( !weekdaymatchesstartdate ) { // m_start->AdjustToWeekday( i+1 ); // m_end->AdjustToWeekday( i+1 ); // weekdaymatchesstartdate=true; // } } weekdaymask >>= 1; } prop = icalproperty_new_rrule( recur ); icalcomponent_add_property( vevent, prop ); break; } case RECUR_MONTHLY_MDAY: recur.freq = ICAL_MONTHLY_RECURRENCE; if( m_recurweeknumber ) { // printf( "DAY: %d\n" , icaltime_day_of_week( m_start->m_datetime ) ); // printf( "WEEKNUMBER: %d\n" , m_recurweeknumber ); if( m_recurweeknumber != 5 ) recur.by_day[0] = icaltime_day_of_week( m_start->m_datetime ) + m_recurweeknumber*8; else recur.by_day[0] = - icaltime_day_of_week( m_start->m_datetime ) - 8 ; } prop = icalproperty_new_rrule( recur ); icalcomponent_add_property( vevent, prop ); break; case RECUR_MONTHLY_WDAY: recur.freq = ICAL_MONTHLY_RECURRENCE; prop = icalproperty_new_rrule( recur ); icalcomponent_add_property( vevent, prop ); break; case RECUR_YEARLY: recur.by_month[0] = m_start->m_datetime.month; recur.freq = ICAL_YEARLY_RECURRENCE; prop = icalproperty_new_rrule( recur ); icalcomponent_add_property( vevent, prop ); break; } //exceptions for( unsigned int i=0; iSetHour( 0 ); m_start->SetMinute( 0 ); } prop = icalproperty_new_dtstart( m_start->m_datetime ); icalcomponent_add_property( vevent, prop ); //enddate if( m_allday ) { m_end->SetHour( 23 ); m_end->SetMinute( 59 ); } prop = icalproperty_new_dtend( m_end->m_datetime ); icalcomponent_add_property( vevent, prop ); //snoozetimes icalcomponent *tmpcomp=NULL; for( unsigned int i=0; i