diff --git a/calendar/libxpical/oeICalContainerImpl.cpp b/calendar/libxpical/oeICalContainerImpl.cpp index 9a87bf149c5..ad3d26d5f15 100644 --- a/calendar/libxpical/oeICalContainerImpl.cpp +++ b/calendar/libxpical/oeICalContainerImpl.cpp @@ -1485,6 +1485,15 @@ void oeICalContainerFilter::UpdateAllFilters( PRInt32 icaltype ) NS_IMETHODIMP oeICalContainerFilter::ReportError( PRInt16 severity, PRUint32 errorid, const char *errorstring ) { return NS_ERROR_NOT_IMPLEMENTED; } + +NS_IMETHODIMP oeICalContainerFilter::SetParameter( const char *name, const char *value ) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP oeICalContainerFilter::GetParameter( const char *name, char **value ) { + return NS_ERROR_NOT_IMPLEMENTED; +} + /////////////////////////////////////////////////// // FilterDateTime ////////////////////////////////////////////////// diff --git a/calendar/libxpical/oeICalEventImpl.cpp b/calendar/libxpical/oeICalEventImpl.cpp index 67569aabb12..f6afd6d4e8d 100644 --- a/calendar/libxpical/oeICalEventImpl.cpp +++ b/calendar/libxpical/oeICalEventImpl.cpp @@ -66,6 +66,7 @@ #define DEFAULT_ALARM_UNITS "minutes" #define DEFAULT_ALARM_LENGTH 15 #define DEFAULT_RECUR_UNITS "weeks" +#define DEFAULT_ALARMTRIGGER_RELATION ICAL_RELATED_START extern oeIICalContainer *gContainer; @@ -274,6 +275,7 @@ oeICalEventImpl::oeICalEventImpl() m_allday = false; m_hasalarm = false; m_alarmlength = DEFAULT_ALARM_LENGTH; + m_alarmtriggerrelation = DEFAULT_ALARMTRIGGER_RELATION; m_alarmemail = nsnull; m_inviteemail = nsnull; m_recurinterval = 1; @@ -1088,7 +1090,7 @@ icaltimetype oeICalEventImpl::GetNextRecurrence( icaltimetype begin, bool *isbeg } if( icaltime_is_null_time( nextpropagation ) ) { - struct icaldurationtype eventlength = icaltime_subtract( m_end->m_datetime, m_start->m_datetime ); + struct icaldurationtype eventlength = GetLength(); struct icaltimetype end = icaltime_add( next, eventlength ); if( icaltime_compare( end , begin ) <= 0 ) @@ -1193,6 +1195,10 @@ icaltimetype oeICalEventImpl::CalculateAlarmTime( icaltimetype date ) { else icaltime_adjust( &result, 0, 0, -(signed long)m_alarmlength, 0 ); + //Add the length to the final result if alarm trigger is relative to end of event + if( m_alarmtriggerrelation == ICAL_RELATED_END ) + result = icaltime_add( result, GetLength() ); + return result; } @@ -1208,6 +1214,14 @@ icaltimetype oeICalEventImpl::CalculateEventTime( icaltimetype alarmtime ) { return result; } +icaldurationtype oeICalEventImpl::GetLength() { + + if( !icaldurationtype_is_null_duration( m_duration ) ) + return m_duration; + + return icaltime_subtract( m_end->m_datetime, m_start->m_datetime );; +} + NS_IMETHODIMP oeICalEventImpl::GetStart(oeIDateTime * *start) { *start = m_start; @@ -1660,7 +1674,7 @@ void oeICalEventImpl::ChopAndAddEventToEnum( struct icaltimetype startdate, nsIS eventDisplay->SetDisplayEndDate( enddateinms ); } else { if( isbeginning ) { - struct icaldurationtype eventlength = icaltime_subtract( m_end->m_datetime, m_start->m_datetime ); + struct icaldurationtype eventlength = GetLength(); struct icaltimetype eventenddate = icaltime_add( startdate, eventlength ); if( icaltime_compare( endofday, eventenddate ) < 0 ) { @@ -1707,6 +1721,8 @@ bool oeICalEventImpl::ParseIcalComponent( icalcomponent *comp ) return false; } + m_type = icalcomponent_isa( vevent ); + const char *tmpstr; //id icalproperty *prop = icalcomponent_get_first_property( vevent, ICAL_UID_PROPERTY ); @@ -1850,8 +1866,17 @@ bool oeICalEventImpl::ParseIcalComponent( icalcomponent *comp ) //alarm icalcomponent *valarm = icalcomponent_get_first_component( vevent, ICAL_VALARM_COMPONENT ); - if ( valarm != 0) + if ( valarm != 0) { m_hasalarm= true; + prop = icalcomponent_get_first_property( valarm, ICAL_TRIGGER_PROPERTY ); + if( prop ) { + icalparameter *tmppar = icalproperty_get_first_parameter( prop, ICAL_RELATED_PARAMETER ); + if( tmppar ) { + m_alarmtriggerrelation = icalparameter_get_related( tmppar ); + } else + m_alarmtriggerrelation = ICAL_RELATED_START; + } + } else m_hasalarm= false; @@ -2033,10 +2058,41 @@ bool oeICalEventImpl::ParseIcalComponent( icalcomponent *comp ) m_end->SetTzID( tzid ); } } - } else if( !icaltime_is_null_time( m_start->m_datetime ) ) { - m_end->m_datetime = m_start->m_datetime; } else { - m_end->m_datetime = icaltime_null_time(); + prop = icalcomponent_get_first_property( vevent, ICAL_DUE_PROPERTY ); + if ( prop != 0) { + m_end->m_datetime = icalproperty_get_due( prop ); + bool datevalue=m_end->m_datetime.is_date; + m_end->m_datetime.is_date = false; //Because currently we depend on m_datetime being a complete datetime value. + const char *tzid=nsnull; + if( m_end->m_datetime.is_utc && !datevalue ) + tzid="/Mozilla.org/BasicTimezones/GMT"; + m_end->m_datetime.is_utc = false; + if( datevalue ) { + m_end->SetHour( 0 ); + m_end->SetMinute( 0 ); + } + icalparameter *tmppar = icalproperty_get_first_parameter( prop, ICAL_TZID_PARAMETER ); + if( tmppar ) + tzid = icalparameter_get_tzid( tmppar ); + if( tzid ) { + if( !datevalue ) { + PRTime timeinms; + m_end->GetTime( &timeinms ); + m_end->SetTimeInTimezone( timeinms, tzid ); + } else { + m_end->SetTzID( tzid ); + } + } + } else { + if( m_type == ICAL_VEVENT_COMPONENT && !icaltime_is_null_time( m_start->m_datetime ) ) { + m_end->m_datetime = m_start->m_datetime; + m_end->SetHour( 23 ); + m_end->SetMinute( 59 ); + } else { + m_end->m_datetime = icaltime_null_time(); + } + } } } else { if( !icaltime_is_null_time( m_start->m_datetime ) ) { @@ -2316,6 +2372,12 @@ icalcomponent* oeICalEventImpl::AsIcalComponent() trig.duration.seconds = 1; prop = icalproperty_new_trigger( trig ); + + if( m_alarmtriggerrelation != DEFAULT_ALARMTRIGGER_RELATION ) { + icalparameter *tmppar = icalparameter_new_related( m_alarmtriggerrelation ); + icalproperty_add_parameter( prop, tmppar ); + } + icalcomponent_add_property( valarm, prop ); icalcomponent_add_component( vevent, valarm ); } @@ -2661,6 +2723,42 @@ NS_IMETHODIMP oeICalEventImpl::ReportError( PRInt16 severity, PRUint32 errorid, return NS_OK; } +NS_IMETHODIMP oeICalEventImpl::SetParameter( const char *name, const char *value ) { + if( strcmp( name, "ICAL_RELATED_PARAMETER" ) == 0 ) { + if( strcmp( value, "ICAL_RELATED_START" ) == 0 ) + m_alarmtriggerrelation = ICAL_RELATED_START; + else if( strcmp( value, "ICAL_RELATED_END" ) == 0 ) + m_alarmtriggerrelation = ICAL_RELATED_END; + else + return NS_ERROR_ILLEGAL_VALUE; + + return NS_OK; + } + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP oeICalEventImpl::GetParameter( const char *name, char **value ) { + *value = nsnull; + if( strcmp( name, "ICAL_RELATED_PARAMETER" ) == 0 ) { + char *tmpstr=nsnull; + switch ( m_alarmtriggerrelation ) { + case ICAL_RELATED_START: + tmpstr = "ICAL_RELATED_START"; + break; + case ICAL_RELATED_END: + tmpstr = "ICAL_RELATED_END"; + break; + } + if( tmpstr ) { + *value = (char*) nsMemory::Clone( tmpstr, strlen( tmpstr )+1); + return NS_OK; + } + else + return NS_ERROR_UNEXPECTED; + } + return NS_ERROR_NOT_AVAILABLE; +} + /********************************************************************************************/ #include "nsIServiceManager.h" diff --git a/calendar/libxpical/oeICalEventImpl.h b/calendar/libxpical/oeICalEventImpl.h index d38efe78216..3a0561377fd 100644 --- a/calendar/libxpical/oeICalEventImpl.h +++ b/calendar/libxpical/oeICalEventImpl.h @@ -136,6 +136,7 @@ private: bool m_allday; bool m_hasalarm; unsigned long m_alarmlength; + icalparameter_related m_alarmtriggerrelation; char *m_alarmunits; char *m_alarmemail; char *m_inviteemail; @@ -157,6 +158,7 @@ private: nsVoidArray m_snoozetimes; icaltimetype CalculateAlarmTime( icaltimetype date ); bool IsExcepted( PRTime date ); + icaldurationtype GetLength(); nsCOMPtr m_attachments; nsCOMPtr m_contacts; oeIICal *m_calendar; diff --git a/calendar/libxpical/oeICalImpl.cpp b/calendar/libxpical/oeICalImpl.cpp index c0fa343e7a4..fab8895bb36 100644 --- a/calendar/libxpical/oeICalImpl.cpp +++ b/calendar/libxpical/oeICalImpl.cpp @@ -2744,3 +2744,11 @@ NS_IMETHODIMP oeICalFilter::ReportError( PRInt16 severity, PRUint32 errorid, con return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP oeICalFilter::SetParameter( const char *name, const char *value ) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP oeICalFilter::GetParameter( const char *name, char **value ) { + return NS_ERROR_NOT_IMPLEMENTED; +} + diff --git a/calendar/libxpical/oeICalTodoImpl.cpp b/calendar/libxpical/oeICalTodoImpl.cpp index b8757de3f52..f3e7bd61583 100644 --- a/calendar/libxpical/oeICalTodoImpl.cpp +++ b/calendar/libxpical/oeICalTodoImpl.cpp @@ -87,9 +87,6 @@ oeICalTodoImpl::oeICalTodoImpl() /* member initializers and constructor code */ nsresult rv; - if( NS_FAILED( rv = NS_NewDateTime((oeIDateTime**) &m_due ))) { - m_due = nsnull; - } if( NS_FAILED( rv = NS_NewDateTime((oeIDateTime**) &m_completed ))) { m_completed = nsnull; } @@ -102,8 +99,6 @@ oeICalTodoImpl::~oeICalTodoImpl() printf( "oeICalTodoImpl::~oeICalTodoImpl()\n"); #endif /* destructor code */ - if( m_due ) - m_due->Release(); if( m_completed ) m_completed->Release(); mEvent->Release(); @@ -121,9 +116,7 @@ bool oeICalTodoImpl::matchId( const char *id ) { /* readonly attribute oeIDateTime due; */ NS_IMETHODIMP oeICalTodoImpl::GetDue(oeIDateTime * *due) { - *due = m_due; - NS_ADDREF(*due); - return NS_OK; + return mEvent->GetEnd( due ); } /* areadonly attribute oeIDateTime completed; */ @@ -274,16 +267,6 @@ bool oeICalTodoImpl::ParseIcalComponent( icalcomponent *comp ) m_completed->m_datetime = icaltime_null_time(); } - //due - prop = icalcomponent_get_first_property( vtodo, ICAL_DUE_PROPERTY ); - if (prop != 0) { - icaltimetype due; - due = icalproperty_get_due( prop ); - m_due->m_datetime = due; - } else { - m_due->m_datetime = icaltime_null_time(); - } - return true; } @@ -331,8 +314,13 @@ icalcomponent* oeICalTodoImpl::AsIcalComponent() icalparameter *newpar = icalparameter_new_member( icalparameter_get_member( oldpar ) ); icalproperty_add_parameter( newprop, newpar ); } else if( propkind == ICAL_DTEND_PROPERTY ) { - //do nothing - continue; + //Change DTEND to DUE + newprop = icalproperty_new_due( icalproperty_get_dtend( prop ) ); + icalparameter *oldpar = icalproperty_get_first_parameter( prop, ICAL_TZID_PARAMETER ); + if( oldpar ) { + icalparameter *newpar = icalparameter_new_tzid( icalparameter_get_tzid( oldpar ) ); + icalproperty_add_parameter( newprop, newpar ); + } } else { newprop = icalproperty_new_clone( prop ); } @@ -351,30 +339,6 @@ icalcomponent* oeICalTodoImpl::AsIcalComponent() icalcomponent_add_property( vtodo, prop ); } - /* This isn't really needed - //Create due if does not exist - if( icaltime_is_null_time( m_due->m_datetime ) ) { - prop = icalcomponent_get_first_property( vtodo, ICAL_DTSTART_PROPERTY ); - if( prop ) { - m_due->m_datetime = icalproperty_get_dtstart( prop ); - //Set to the same as start date 23:59 - m_due->SetHour( 23 ); m_due->SetMinute( 59 ); - } - } - - PRBool m_allday; - GetAllDay ( &m_allday ); - if( m_allday ) { - m_due->SetHour( 23 ); - m_due->SetMinute( 59 ); - }*/ - - //due - if( m_due && !icaltime_is_null_time( m_due->m_datetime ) ) { - prop = icalproperty_new_due( m_due->m_datetime ); - icalcomponent_add_property( vtodo, prop ); - } - //completed if( m_completed && !icaltime_is_null_time( m_completed->m_datetime ) ) { prop = icalproperty_new_completed( m_completed->m_datetime ); diff --git a/calendar/libxpical/oeICalTodoImpl.h b/calendar/libxpical/oeICalTodoImpl.h index ffb4fdbd1c3..7658b0cec06 100644 --- a/calendar/libxpical/oeICalTodoImpl.h +++ b/calendar/libxpical/oeICalTodoImpl.h @@ -71,7 +71,6 @@ public: private: int m_percent; oeDateTimeImpl *m_completed; - oeDateTimeImpl *m_due; oeICalEventImpl *mEvent; }; diff --git a/calendar/libxpical/oeIICal.idl b/calendar/libxpical/oeIICal.idl index 5f8441ca268..767093df9b5 100644 --- a/calendar/libxpical/oeIICal.idl +++ b/calendar/libxpical/oeIICal.idl @@ -157,6 +157,8 @@ interface oeIICalEvent : nsISupports void removeContacts(); void reportError( in short severity, in unsigned long errorid, in string errorstring ); + void setParameter( in string name, in string value ); + string getParameter( in string name ); }; [scriptable, uuid(f95df40e-0d5f-49ec-9ba8-4b88d3eb53e0)] diff --git a/calendar/resources/content/eventDialog.js b/calendar/resources/content/eventDialog.js index e1bddf3fe3b..71463cc2e1e 100644 --- a/calendar/resources/content/eventDialog.js +++ b/calendar/resources/content/eventDialog.js @@ -182,7 +182,7 @@ function loadCalendarEventDialog() setFieldValue( "description-field", gEvent.description ); setFieldValue( "location-field", gEvent.location ); setFieldValue( "uri-field", gEvent.url ); - + switch( gEvent.status ) { case gEvent.ICAL_STATUS_TENTATIVE: @@ -211,6 +211,7 @@ function loadCalendarEventDialog() setFieldValue( "alarm-checkbox", gEvent.alarm, "checked" ); setFieldValue( "alarm-length-field", gEvent.alarmLength ); setFieldValue( "alarm-length-units", gEvent.alarmUnits ); + setFieldValue( "alarm-trigger-relation", gEvent.getParameter( "ICAL_RELATED_PARAMETER" ) ); if( gEvent.alarmEmailAddress == "" && "new" == args.mode ) gEvent.alarmEmailAddress = opener.getCharPref( opener.gCalendarWindow.calendarPreferences.calendarPref, "alarms.emailaddress", "" ); @@ -374,6 +375,7 @@ function onOKCommand() gEvent.alarm = getFieldValue( "alarm-checkbox", "checked" ); gEvent.alarmLength = getFieldValue( "alarm-length-field" ); gEvent.alarmUnits = getFieldValue( "alarm-length-units", "value" ); + gEvent.setParameter( "ICAL_RELATED_PARAMETER", getFieldValue( "alarm-trigger-relation", "value" ) ); if ( getFieldValue( "alarm-email-checkbox", "checked" ) ) { @@ -678,7 +680,6 @@ function onDatePick( datepicker ) function prepareTimePicker( timeFieldName ) { // get the popup and the field we are editing - var timePickerPopup = document.getElementById( "oe-time-picker-popup" ); var timeField = document.getElementById( timeFieldName ); @@ -810,7 +811,7 @@ function updateAlarmItemEnabled() var alarmField = "alarm-length-field"; var alarmMenu = "alarm-length-units"; - var alarmLabel = "alarm-length-text"; + var alarmTrigger = "alarm-trigger-relation"; var alarmEmailCheckbox = "alarm-email-checkbox"; var alarmEmailField = "alarm-email-field"; @@ -822,14 +823,14 @@ function updateAlarmItemEnabled() setFieldValue( alarmCheckBox, true, "checked" ); setFieldValue( alarmField, false, "disabled" ); setFieldValue( alarmMenu, false, "disabled" ); - setFieldValue( alarmLabel, false, "disabled" ); + setFieldValue( alarmTrigger, false, "disabled" ); setFieldValue( alarmEmailCheckbox, false, "disabled" ); } else { setFieldValue( alarmField, true, "disabled" ); setFieldValue( alarmMenu, true, "disabled" ); - setFieldValue( alarmLabel, true, "disabled" ); + setFieldValue( alarmTrigger, true, "disabled" ); setFieldValue( alarmEmailField, true, "disabled" ); setFieldValue( alarmEmailCheckbox, true, "disabled" ); setFieldValue( alarmEmailCheckbox, false, "checked" ); diff --git a/calendar/resources/content/eventDialog.xul b/calendar/resources/content/eventDialog.xul index 5707c53de15..5923c6d4353 100644 --- a/calendar/resources/content/eventDialog.xul +++ b/calendar/resources/content/eventDialog.xul @@ -24,6 +24,7 @@ - Colin Phillips - Chris Charabaruk - ArentJan Banck + - 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 @@ -98,6 +99,7 @@