Added ability to relate alarm to end/due of event/task

Next step to fix bug 155882: Tasks (ToDo) need an Alarm (just like Events)
This commit is contained in:
mostafah%oeone.com 2003-08-22 13:27:20 +00:00
Родитель b6d7dc92b6
Коммит 1e24cf7c99
12 изменённых файлов: 160 добавлений и 61 удалений

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

@ -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
//////////////////////////////////////////////////

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

@ -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"

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

@ -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<nsISupportsArray> m_attachments;
nsCOMPtr<nsISupportsArray> m_contacts;
oeIICal *m_calendar;

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

@ -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;
}

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

@ -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 );

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

@ -71,7 +71,6 @@ public:
private:
int m_percent;
oeDateTimeImpl *m_completed;
oeDateTimeImpl *m_due;
oeICalEventImpl *mEvent;
};

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

@ -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)]

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

@ -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" );

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

@ -24,6 +24,7 @@
- Colin Phillips <colinp@oeone.com>
- Chris Charabaruk <ccharabaruk@meldstar.com>
- ArentJan Banck <ajbanck@planet.nl>
- Mostafa Hosseini <mostafah@oeone.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
@ -98,6 +99,7 @@
<script type="application/x-javascript" src="chrome://calendar/content/eventDialog.js"/>
<script type="application/x-javascript" src="chrome://calendar/content/selectAddressesDialog.js"/>
<script type="application/x-javascript" src="chrome://calendar/content/attachFile.js"/>
<!-- needed to get the default categories -->
<script type="application/x-javascript" src="chrome://calendar/content/pref/rootCalendarPref.js"/>
@ -236,7 +238,12 @@
<menuitem label="&alarm.units.days;" labelplural="&alarm.units.days;" labelsingular="&alarm.units.days.singular;" value="days"/>
</menupopup>
</menulist>
<label id="alarm-length-text" for="alarm-length-field" value="&newevent.beforealarm.label;"/>
<menulist id="alarm-trigger-relation" crop="none">
<menupopup>
<menuitem label="&newevent.beforealarm.label;" value="ICAL_RELATED_START"/>
<menuitem label="&newevent.beforealarmends.label;" value="ICAL_RELATED_END"/>
</menupopup>
</menulist>
</hbox>
<hbox id="alarm-box-email" align="center">

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

@ -203,6 +203,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", "" );
@ -379,6 +380,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" ) )
{
@ -824,7 +826,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";
@ -836,14 +838,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" );

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

@ -247,7 +247,12 @@
<menuitem label="&alarm.units.days;" labelplural="&alarm.units.days;" labelsingular="&alarm.units.days.singular;" value="days"/>
</menupopup>
</menulist>
<label id="alarm-length-text" for="alarm-length-field" value="&newtodo.beforealarm.label;"/>
<menulist id="alarm-trigger-relation" crop="none">
<menupopup>
<menuitem label="&newtodo.beforealarm.label;" value="ICAL_RELATED_START"/>
<menuitem label="&newtodo.beforealarmends.label;" value="ICAL_RELATED_END"/>
</menupopup>
</menulist>
</hbox>
<hbox id="alarm-box-email" align="center">

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

@ -84,6 +84,7 @@
<!ENTITY newevent.invite.label "Invite" >
<!ENTITY newevent.email.label "Email Alarm To" >
<!ENTITY newevent.beforealarm.label "before the event starts" >
<!ENTITY newevent.beforealarmends.label "before the event ends" >
<!ENTITY newevent.repeat.label "Repeat every" >
<!ENTITY newevent.until.label "Until" >
<!ENTITY newevent.forever.label "Forever" >
@ -141,6 +142,7 @@
<!ENTITY newtodo.cancelled.label "Cancelled">
<!ENTITY newtodo.status.label "Status">
<!ENTITY newtodo.beforealarm.label "before the task starts" >
<!ENTITY newtodo.beforealarmends.label "before the task is due" >
<!ENTITY newtodo.newtodo.tab.label "Task" >
<!ENTITY newtodo.status.longlabel "Task Status">
<!ENTITY newtodo.duetime.warning "Your start time is after your due time.">