gecko-dev/calendar/libxpical/oeICalImpl.cpp
mvl%exedo.nl edab1c498d use utf8 strings instead of ascii for path names
bug 164600, r=mostafah
2004-11-08 18:23:03 +00:00

2833 lines
84 KiB
C++

/* ***** 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 <mostafah@oeone.com>
* Cristian Tapus <cristian_tapus@yahoo.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 ***** */
/* This file implements an XPCOM object which represents a calendar object. It is a container
of events and prepares responses for queries made upon the calendar in whole. The task of reading from
and writing to the calendar data storage is currently performed by this object */
#ifndef WIN32
#include <unistd.h>
#endif
#define __cplusplus__ 1
#include "oeICalImpl.h"
#include "oeICalEventImpl.h"
#include "nsMemory.h"
#include "stdlib.h"
#include "nsCOMPtr.h"
#include "nsISimpleEnumerator.h"
#include "nsString.h"
#include "nsIURL.h"
#include "nsNetCID.h"
#include "nsEscape.h"
#include "nsISupportsArray.h"
#include "nsXPCOM.h"
#include "nsComponentManagerUtils.h"
#include "nsIWindowMediator.h"
#include "nsIServiceManager.h"
#include "nsIDOMWindowInternal.h"
#include "nsIDOMDocument.h"
#include "nsIDOMElement.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
extern "C" {
#include "icalss.h"
}
icaltimetype ConvertFromPrtime( PRTime indate );
PRTime ConvertToPrtime ( icaltimetype indate );
void AlarmTimerCallback(nsITimer *aTimer, void *aClosure);
void GenerateUUID(char *output);
icalcomponent* icalcomponent_fetch( icalcomponent* parent,const char* uid )
{
icalcomponent *inner;
icalproperty *prop;
const char *this_uid;
for(inner = icalcomponent_get_first_component( parent , ICAL_ANY_COMPONENT );
inner != 0;
inner = icalcomponent_get_next_component( parent , ICAL_ANY_COMPONENT ) ){
prop = icalcomponent_get_first_property(inner,ICAL_UID_PROPERTY);
if ( prop ) {
this_uid = icalproperty_get_uid( prop );
if(this_uid==0){
icalerror_warn("icalcomponent_fetch found a component with no UID");
continue;
}
if (strcmp(uid,this_uid)==0){
return inner;
}
} else {
icalerror_warn("icalcomponent_fetch found a component with no UID");
}
}
return nsnull;
}
/*
* This function adds the first component of the child component to the
* first component of the parent icalfileset (which is a icalfileset_impl)
*
* This is used in the following member functions: AddEvent, ModifyEvent,
* AddTodo, ModifyTodo
*
*/
icalerrorenum icalfileset_add_first_to_first_component(icalfileset *parent,
icalcomponent* child)
{
#ifdef ICAL_DEBUG
printf("icalfileset_add_first_to_first_component()::\n");
#endif
struct icalfileset_impl* impl = (struct icalfileset_impl*)parent;
icalerror_check_arg_re((parent!=0),"parent", ICAL_BADARG_ERROR);
icalerror_check_arg_re((child!=0),"child",ICAL_BADARG_ERROR);
// get the first component of the child which is either a vevent or a vtodo
icalcomponent* vfirst = icalcomponent_get_first_component(child, ICAL_VEVENT_COMPONENT);
if (vfirst==0) {
vfirst = icalcomponent_get_first_component(child, ICAL_VTODO_COMPONENT);
}
if (vfirst==0) return ICAL_INTERNAL_ERROR;
// extract the first (presumably) vcalendar component of the parent stream
struct icalfileset_impl* firstc = (struct icalfileset_impl*)icalfileset_get_first_component(impl);
icalcomponent_kind kind_firstc;
if (firstc!=0)
kind_firstc = icalcomponent_isa (firstc);
else
// the check below will fail due to firstc==0
kind_firstc = ICAL_VCALENDAR_COMPONENT;
if ( (firstc==0) || (kind_firstc != ICAL_VCALENDAR_COMPONENT) ) {
// if parent stream is empty or first component is not a VCALENDAR
// then create a new vcalendar component
firstc = (struct icalfileset_impl*)icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
if (firstc==0) {
#ifdef ICAL_DEBUG
printf("icalfileset_add_first_to_first_component():: firstc is still NULL\n");
#endif
return ICAL_INTERNAL_ERROR;
}
// add component to parent stream
icalfileset_add_component(parent, firstc);
} else {
// I need to remove the version and the prodid
//version
icalproperty *prop = icalcomponent_get_first_property(firstc, ICAL_VERSION_PROPERTY );
icalcomponent_remove_property( firstc, prop );
//prodid
prop = icalcomponent_get_first_property( firstc, ICAL_PRODID_PROPERTY );
icalcomponent_remove_property( firstc, prop );
}
//version
icalproperty *prop = icalproperty_new_version( ICALEVENT_VERSION );
icalcomponent_add_property( firstc, prop );
//prodid
prop = icalproperty_new_prodid( ICALEVENT_PRODID );
icalcomponent_add_property( firstc, prop );
// get the timezone component if any
icalcomponent* timezone = icalcomponent_get_first_component(child, ICAL_VTIMEZONE_COMPONENT);
// we know that we have at most one timezone component inside the child component
if (timezone!=0) icalcomponent_add_component(firstc, timezone);
// add first component of child into the first component of stream
icalcomponent_add_component(firstc, vfirst);
icalfileset_mark(parent);
return ICAL_NO_ERROR;
}
oeEventEnumerator::oeEventEnumerator( )
:
mCurrentIndex( 0 )
{
NS_NewISupportsArray(getter_AddRefs(mEventVector));
}
oeEventEnumerator::~oeEventEnumerator()
{
}
NS_IMPL_ISUPPORTS1(oeEventEnumerator, nsISimpleEnumerator)
NS_IMETHODIMP
oeEventEnumerator::HasMoreElements(PRBool *result)
{
PRUint32 count = 0;
mEventVector->Count(&count);
if( mCurrentIndex >= count )
{
*result = PR_FALSE;
}
else
{
*result = PR_TRUE;
}
return NS_OK;
}
NS_IMETHODIMP
oeEventEnumerator::GetNext(nsISupports **_retval)
{
PRUint32 count = 0;
mEventVector->Count(&count);
if( mCurrentIndex >= count )
{
*_retval = nsnull;
}
else
{
nsCOMPtr<nsISupports> event;
mEventVector->QueryElementAt( mCurrentIndex, NS_GET_IID(nsISupports), getter_AddRefs(event));
*_retval = event;
NS_ADDREF( *_retval );
++mCurrentIndex;
}
return NS_OK;
}
NS_IMETHODIMP
oeEventEnumerator::AddEvent( nsISupports* event)
{
PRUint32 count = 0;
mEventVector->Count( &count );
mEventVector->InsertElementAt( event, count );
return NS_OK;
}
/* date enumerator */
oeDateEnumerator::oeDateEnumerator( )
:
mCurrentIndex( 0 )
{
}
oeDateEnumerator::~oeDateEnumerator()
{
for( int i=0; i<mDateVector.Count(); i++ ) {
PRTime *timeptr = (PRTime*)(mDateVector[i]);
delete timeptr;
}
mDateVector.Clear();
}
NS_IMPL_ISUPPORTS1(oeDateEnumerator, nsISimpleEnumerator)
NS_IMETHODIMP
oeDateEnumerator::HasMoreElements(PRBool *result)
{
if( mCurrentIndex >= mDateVector.Count() )
{
*result = PR_FALSE;
}
else
{
*result = PR_TRUE;
}
return NS_OK;
}
NS_IMETHODIMP
oeDateEnumerator::GetNext(nsISupports **_retval)
{
if( mCurrentIndex >= mDateVector.Count() )
{
*_retval = nsnull;
}
else
{
nsresult rv;
nsCOMPtr<nsISupportsPRTime> nsPRTime = do_CreateInstance( NS_SUPPORTS_PRTIME_CONTRACTID , &rv);
if( NS_FAILED( rv ) ) {
*_retval = nsnull;
return rv;
}
nsISupportsPRTime* date;
rv = nsPRTime->QueryInterface(NS_GET_IID(nsISupportsPRTime), (void **)&date);
if( NS_FAILED( rv ) ) {
*_retval = nsnull;
return rv;
}
date->SetData( *(PRTime *)(mDateVector[ mCurrentIndex ]) );
*_retval = date;
++mCurrentIndex;
}
return NS_OK;
}
NS_IMETHODIMP
oeDateEnumerator::AddDate(PRTime date)
{
PRTime *newdate = new PRTime;
if (!newdate)
return NS_ERROR_OUT_OF_MEMORY;
*newdate = date;
mDateVector.AppendElement( newdate );
return NS_OK;
}
//////////////////////////////////////////////////
// ICal Factory
//////////////////////////////////////////////////
nsresult
NS_NewICal( oeIICal** inst )
{
NS_PRECONDITION(inst != nsnull, "null ptr");
if (! inst)
return NS_ERROR_NULL_POINTER;
*inst = new oeICalImpl();
if (! *inst)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*inst);
return NS_OK;
}
oeICalImpl::oeICalImpl()
{
#ifdef ICAL_DEBUG
printf( "oeICalImpl::oeICalImpl()\n" );
#endif
m_batchMode = false;
m_suppressAlarms = false;
m_alarmtimer = nsnull;
m_filter = new oeICalFilter();
NS_ADDREF( m_filter );
NS_NewISupportsArray(getter_AddRefs(m_observerlist));
NS_NewISupportsArray(getter_AddRefs(m_todoobserverlist));
}
oeICalImpl::~oeICalImpl()
{
#ifdef ICAL_DEBUG
printf( "oeICalImpl::~oeICalImpl()\n" );
#endif
CancelAlarmTimer();
NS_RELEASE( m_filter );
}
/**
* NS_IMPL_ISUPPORTS1 expands to a simple implementation of the nsISupports
* interface. This includes a proper implementation of AddRef, Release,
* and QueryInterface. If this class supported more interfaces than just
* nsISupports,
* you could use NS_IMPL_ADDREF() and NS_IMPL_RELEASE() to take care of the
* simple stuff, but you would have to create QueryInterface on your own.
* nsSampleFactory.cpp is an example of this approach.
* Notice that the second parameter to the macro is the static IID accessor
* method, and NOT the #defined IID.
*/
NS_IMPL_ISUPPORTS1(oeICalImpl, oeIICal)
nsVoidArray *oeICalImpl::GetEventList()
{
return &m_eventlist;
}
/**
*
* Test
*
* DESCRIPTION: An exported XPCOM function used by the tester program to make sure
* all main internal functions are working properly
* PARAMETERS:
* None
*
* RETURN
* None
*/
NS_IMETHODIMP
oeICalImpl::Test(void)
{
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test()\n" );
#endif
icalset *stream;
icalcomponent *icalcalendar,*icalevent;
struct icaltimetype start, end;
char uidstr[10]="900000000";
char icalrawcalendarstr[] = "BEGIN:VCALENDAR\n\
BEGIN:VEVENT\n\
END:VEVENT\n\
END:VCALENDAR\n\
";
stream = icalfileset_new(m_serveraddr.get());
if ( !stream ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: Cannot open stream: %s!\n", m_serveraddr.get() );
#endif
return NS_ERROR_FAILURE;
}
icalcalendar = icalparser_parse_string(icalrawcalendarstr);
if ( !icalcalendar ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: Cannot create VCALENDAR!\n" );
#endif
return NS_ERROR_FAILURE;
}
icalevent = icalcomponent_get_first_component(icalcalendar,ICAL_VEVENT_COMPONENT);
if ( !icalevent ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: VEVENT not found!\n" );
#endif
return NS_ERROR_FAILURE;
}
icalproperty *uid = icalproperty_new_uid( uidstr );
icalcomponent_add_property( icalevent, uid );
icalproperty *title = icalproperty_new_summary( "Lunch time" );
icalcomponent_add_property( icalevent, title );
icalproperty *description = icalproperty_new_description( "Will be out for one hour" );
icalcomponent_add_property( icalevent, description );
icalproperty *location = icalproperty_new_location( "Restaurant" );
icalcomponent_add_property( icalevent, location );
icalproperty *category = icalproperty_new_categories( "Personal" );
icalcomponent_add_property( icalevent, category );
icalproperty *classp = icalproperty_new_class( ICAL_CLASS_PRIVATE );
icalcomponent_add_property( icalevent, classp );
start.year = 2001; start.month = 8; start.day = 15;
start.hour = 12; start.minute = 24; start.second = 0;
start.is_utc = false; start.is_date = false;
end.year = 2001; end.month = 8; end.day = 15;
end.hour = 13; end.minute = 24; end.second = 0;
end.is_utc = false; end.is_date = false;
icalproperty *dtstart = icalproperty_new_dtstart( start );
icalproperty *dtend = icalproperty_new_dtend( end );
icalcomponent_add_property( icalevent, dtstart );
icalcomponent_add_property( icalevent, dtend );
//
icalproperty *xprop = icalproperty_new_x( "TRUE" );
icalparameter *xpar = icalparameter_new_member( "AllDay" ); //NOTE: new_member is used because new_x didn't work
// Better to be changed to new_x when problem is solved
icalproperty_add_parameter( xprop, xpar );
icalcomponent_add_property( icalevent, xprop );
//
xprop = icalproperty_new_x( "FALSE" );
xpar = icalparameter_new_member( "Alarm" );
icalproperty_add_parameter( xprop, xpar );
icalcomponent_add_property( icalevent, xprop );
//
xprop = icalproperty_new_x( "FALSE" );
xpar = icalparameter_new_member( "AlarmWentOff" );
icalproperty_add_parameter( xprop, xpar );
icalcomponent_add_property( icalevent, xprop );
//
xprop = icalproperty_new_x( "5" );
xpar = icalparameter_new_member( "AlarmLength" );
icalproperty_add_parameter( xprop, xpar );
icalcomponent_add_property( icalevent, xprop );
//
xprop = icalproperty_new_x( "mostafah@oeone.com" );
xpar = icalparameter_new_member( "AlarmEmailAddres" );
icalproperty_add_parameter( xprop, xpar );
icalcomponent_add_property( icalevent, xprop );
//
xprop = icalproperty_new_x( "mostafah@oeone.com" );
xpar = icalparameter_new_member( "InviteEmailAddres" );
icalproperty_add_parameter( xprop, xpar );
icalcomponent_add_property( icalevent, xprop );
//
xprop = icalproperty_new_x( "5" );
xpar = icalparameter_new_member( "SnoozeTime" );
icalproperty_add_parameter( xprop, xpar );
icalcomponent_add_property( icalevent, xprop );
//
xprop = icalproperty_new_x( "0" );
xpar = icalparameter_new_member( "RecurType" );
icalproperty_add_parameter( xprop, xpar );
icalcomponent_add_property( icalevent, xprop );
//
xprop = icalproperty_new_x( "0" );
xpar = icalparameter_new_member( "RecurInterval" );
icalproperty_add_parameter( xprop, xpar );
icalcomponent_add_property( icalevent, xprop );
//
xprop = icalproperty_new_x( "days" );
xpar = icalparameter_new_member( "RepeatUnits" );
icalproperty_add_parameter( xprop, xpar );
icalcomponent_add_property( icalevent, xprop );
//
xprop = icalproperty_new_x( "FALSE" );
xpar = icalparameter_new_member( "RepeatForever" );
icalproperty_add_parameter( xprop, xpar );
icalcomponent_add_property( icalevent, xprop );
//
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.seconds = 0;
trig.duration.minutes = 1;
xprop = icalproperty_new_trigger( trig );
icalcomponent_add_property( valarm, xprop );
icalcomponent_add_component( icalevent, valarm );
icalfileset_add_component(stream,icalcalendar);
if( icalfileset_commit(stream) != ICAL_NO_ERROR ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() : WARNING icalfileset_commit() unsuccessful\n" );
#endif
}
#ifdef ICAL_DEBUG
printf("Appended Event\n");
#endif
icalcomponent *fetchedcal = icalfileset_fetch( stream, uidstr );
if ( !fetchedcal ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: Cannot fetch event!\n" );
#endif
return NS_ERROR_FAILURE;
}
icalcomponent *fetchedevent = icalcomponent_get_first_component( fetchedcal,ICAL_VEVENT_COMPONENT);
if ( !fetchedevent ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: VEVENT not found!\n" );
#endif
return NS_ERROR_FAILURE;
}
#ifdef ICAL_DEBUG
printf("Fetched Event\n");
#endif
icalproperty *tmpprop;
//
tmpprop = icalcomponent_get_first_property( fetchedevent, ICAL_UID_PROPERTY );
if ( !tmpprop ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: UID not found!\n" );
#endif
return NS_ERROR_FAILURE;
}
#ifdef ICAL_DEBUG
printf("id: %s\n", icalproperty_get_uid( tmpprop ) );
#endif
//
tmpprop = icalcomponent_get_first_property( fetchedevent, ICAL_SUMMARY_PROPERTY );
if ( !tmpprop ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: SUMMARY not found!\n" );
#endif
return NS_ERROR_FAILURE;
}
#ifdef ICAL_DEBUG
printf("Title: %s\n", icalproperty_get_summary( tmpprop ) );
#endif
//
tmpprop = icalcomponent_get_first_property( fetchedevent, ICAL_CATEGORIES_PROPERTY );
if ( !tmpprop ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: CATEGORIES not found!\n" );
#endif
return NS_ERROR_FAILURE;
}
#ifdef ICAL_DEBUG
printf("Category: %s\n", icalproperty_get_categories( tmpprop ) );
#endif
//
tmpprop = icalcomponent_get_first_property( fetchedevent, ICAL_DESCRIPTION_PROPERTY );
if ( !tmpprop ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: DESCRIPTION not found!\n" );
#endif
return NS_ERROR_FAILURE;
}
#ifdef ICAL_DEBUG
printf("Description: %s\n", icalproperty_get_description( tmpprop ) );
#endif
//
tmpprop = icalcomponent_get_first_property( fetchedevent, ICAL_LOCATION_PROPERTY );
if ( !tmpprop ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: LOCATION not found!\n" );
#endif
return NS_ERROR_FAILURE;
}
#ifdef ICAL_DEBUG
printf("Location: %s\n", icalproperty_get_location( tmpprop ) );
#endif
//
tmpprop = icalcomponent_get_first_property( fetchedevent, ICAL_CLASS_PROPERTY );
if ( !tmpprop ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: CLASS not found!\n" );
#endif
return NS_ERROR_FAILURE;
}
#ifdef ICAL_DEBUG
printf("Class: %s\n", (icalproperty_get_class( tmpprop ) == ICAL_CLASS_PUBLIC) ? "PUBLIC" : "PRIVATE" );
#endif
//
tmpprop = icalcomponent_get_first_property( fetchedevent, ICAL_DTSTART_PROPERTY );
if ( !tmpprop ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: DTSTART not found!\n" );
#endif
return NS_ERROR_FAILURE;
}
start = icalproperty_get_dtstart( tmpprop );
#ifdef ICAL_DEBUG
printf("Start: %d-%d-%d %d:%d\n", start.year, start.month, start.day, start.hour, start.minute );
#endif
//
tmpprop = icalcomponent_get_first_property( fetchedevent, ICAL_DTEND_PROPERTY );
if ( !tmpprop ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: DTEND not found!\n" );
#endif
return NS_ERROR_FAILURE;
}
end = icalproperty_get_dtstart( tmpprop );
#ifdef ICAL_DEBUG
printf("End: %d-%d-%d %d:%d\n", end.year, end.month, end.day, end.hour, end.minute );
#endif
//
for( tmpprop = icalcomponent_get_first_property( fetchedevent, ICAL_X_PROPERTY );
tmpprop != 0 ;
tmpprop = icalcomponent_get_next_property( fetchedevent, ICAL_X_PROPERTY ) ) {
#ifdef ICAL_DEBUG
icalparameter *tmppar = icalproperty_get_first_parameter( tmpprop, ICAL_MEMBER_PARAMETER );
printf("%s: %s\n", icalparameter_get_member( tmppar ), icalproperty_get_value_as_string( tmpprop ) );
#endif
}
icalcomponent *newcomp = icalcomponent_new_clone( fetchedcal );
if ( !newcomp ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: Cannot clone event!\n" );
#endif
return NS_ERROR_FAILURE;
}
icalcomponent *newevent = icalcomponent_get_first_component( newcomp, ICAL_VEVENT_COMPONENT );
if ( !newevent ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: VEVENT not found!\n" );
#endif
return NS_ERROR_FAILURE;
}
tmpprop = icalcomponent_get_first_property( newevent, ICAL_SUMMARY_PROPERTY );
if ( !tmpprop ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: SUMMARY not found!\n" );
#endif
return NS_ERROR_FAILURE;
}
icalproperty_set_summary( tmpprop, "LUNCH AND LEARN TIME" );
// icalfileset_modify( stream, fetchedcal, newcomp );
icalfileset_remove_component( stream, fetchedcal );
icalfileset_add_component( stream, newcomp );
icalcomponent_free( fetchedcal );
//
#ifdef ICAL_DEBUG
printf("Event updated\n");
printf( "New Title: %s\n", icalproperty_get_summary( tmpprop ) );
#endif
fetchedcal = icalfileset_fetch( stream, uidstr );
if ( !fetchedcal ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() failed: Cannot fetch event!\n" );
#endif
return NS_ERROR_FAILURE;
}
icalfileset_remove_component( stream, fetchedcal );
#ifdef ICAL_DEBUG
printf("Removed Event\n");
#endif
if( icalfileset_commit(stream) != ICAL_NO_ERROR ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::Test() : WARNING icalfileset_commit() unsuccessful\n" );
#endif
}
icalfileset_free(stream);
return NS_OK;
}
NS_IMETHODIMP
oeICalImpl::SetServer( const nsACString &aServer ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::SetServer(%s)\n", PromiseFlatCString(aServer).get() );
#endif
if( StringBeginsWith(aServer, NS_LITERAL_CSTRING("file:///") ) ) {
nsCOMPtr<nsIURL> url( do_CreateInstance(NS_STANDARDURL_CONTRACTID) );
nsCString filePath;
url->SetSpec( aServer );
url->GetFilePath( filePath );
m_serveraddr = filePath;
NS_UnescapeURL( m_serveraddr );
} else
m_serveraddr = aServer;
icalset *stream;
//UGLY HACK TO ADD DEPENDANCY TO stat() in libc. ( -lc didn't work )
int dummy=0;
if( dummy )
stat(NULL,NULL);
stream = icalfileset_new(m_serveraddr.get());
if ( !stream ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::SetServer() failed: Cannot open stream: %s!\n", m_serveraddr.get() );
#endif
return NS_OK;
}
nsresult rv;
icalcomponent *vcalendar;
icalcomponent *vevent,*vtodo;
oeICalEventImpl *icalevent;
oeICalTodoImpl *icaltodo;
for( vcalendar = icalfileset_get_first_component( stream );
vcalendar != 0;
vcalendar = icalfileset_get_next_component( stream ) ) {
for( vevent = icalcomponent_get_first_component( vcalendar, ICAL_VEVENT_COMPONENT );
vevent != 0;
vevent = icalcomponent_get_next_component( vcalendar, ICAL_VEVENT_COMPONENT ) ) {
if( NS_FAILED( rv = NS_NewICalEvent((oeIICalEvent**) &icalevent ))) {
return rv;
}
if( icalevent->ParseIcalComponent( vevent ) ) {
m_eventlist.AppendElement( icalevent );
icalevent->SetParent( this );
} else {
icalevent->Release();
}
}
for( vtodo = icalcomponent_get_first_component( vcalendar, ICAL_VTODO_COMPONENT );
vtodo != 0;
vtodo = icalcomponent_get_next_component( vcalendar, ICAL_VTODO_COMPONENT ) ) {
if( NS_FAILED( rv = NS_NewICalTodo((oeIICalTodo**) &icaltodo ))) {
return rv;
}
if( icaltodo->ParseIcalComponent( vtodo ) ) {
m_todolist.Add( icaltodo );
icaltodo->SetParent( this );
} else {
icaltodo->Release();
}
}
}
icalfileset_free(stream);
unsigned int i;
PRUint32 observercount;
m_observerlist->Count(&observercount);
for( i=0; i<observercount; i++ ) {
nsCOMPtr<oeIICalObserver>observer;
m_observerlist->QueryElementAt( i, NS_GET_IID(oeIICalObserver), getter_AddRefs(observer));
nsresult rv;
rv = observer->OnLoad();
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::SetServer() : WARNING Call to observer's onLoad() unsuccessful: %x\n", rv );
}
#endif
}
m_todoobserverlist->Count(&observercount);
for( i=0; i<observercount; i++ ) {
nsCOMPtr<oeIICalTodoObserver>observer;
m_todoobserverlist->QueryElementAt( i, NS_GET_IID(oeIICalTodoObserver), getter_AddRefs(observer));
nsresult rv;
rv = observer->OnLoad();
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::SetServer() : WARNING Call to observer's onLoad() unsuccessful: %x\n", rv );
}
#endif
}
SetupAlarmManager();
return NS_OK;
}
NS_IMETHODIMP
oeICalImpl::GetServer( nsACString &aServer ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::GetServer()\n" );
#endif
aServer = m_serveraddr;
return NS_OK;
}
/* attribute boolean batchMode; */
NS_IMETHODIMP oeICalImpl::GetBatchMode(PRBool *aBatchMode)
{
*aBatchMode = m_batchMode;
return NS_OK;
}
NS_IMETHODIMP oeICalImpl::SetBatchMode(PRBool aBatchMode)
{
bool newBatchMode = aBatchMode;
if( m_batchMode != newBatchMode )
{
m_batchMode = aBatchMode;
// if batch mode changed to off, call set up alarm mamnager
if( !m_batchMode )
{
SetupAlarmManager();
}
// tell observers about the change
//The container will take care of this for now
/*
unsigned int i;
for( i=0; i<m_observerlist.size(); i++ )
{
if( m_batchMode ) {
nsresult rv;
rv = m_observerlist[i]->OnStartBatch();
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::SetBatchMode() : WARNING Call to observer's onStartBatch() unsuccessful: %x\n", rv );
}
#endif
}
else {
nsresult rv;
rv = m_observerlist[i]->OnEndBatch();
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::SetBatchMode() : WARNING Call to observer's onEndBatch() unsuccessful: %x\n", rv );
}
#endif
}
}
for( i=0; i<m_todoobserverlist.size(); i++ )
{
if( m_batchMode ) {
nsresult rv;
rv = m_todoobserverlist[i]->OnStartBatch();
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::SetBatchMode() : WARNING Call to observer's onStartBatch() unsuccessful: %x\n", rv );
}
#endif
}
else {
nsresult rv;
rv = m_todoobserverlist[i]->OnEndBatch();
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::SetBatchMode() : WARNING Call to observer's onEndBatch() unsuccessful: %x\n", rv );
}
#endif
}
}*/
}
return NS_OK;
}
/* attribute boolean suppressAlarms; */
NS_IMETHODIMP oeICalImpl::GetSuppressAlarms(PRBool *aRetVal)
{
*aRetVal = m_suppressAlarms;
return NS_OK;
}
NS_IMETHODIMP oeICalImpl::SetSuppressAlarms(PRBool aNewVal)
{
if( m_suppressAlarms ) {
if( !aNewVal ) {
m_suppressAlarms = PR_FALSE;
SetupAlarmManager();
}
} else {
if( aNewVal ) {
m_suppressAlarms = PR_TRUE;
CancelAlarmTimer();
}
}
return NS_OK;
}
/**
*
* AddEvent
*
* DESCRIPTION: Adds an event
*
* PARAMETERS:
* icalcalendar - The XPCOM component representing an event
* retid - Place to store the returned id
*
* RETURN
* None
*/
NS_IMETHODIMP oeICalImpl::AddEvent(oeIICalEvent *icalevent,char **retid)
{
#ifdef ICAL_DEBUG
printf( "oeICalImpl::AddEvent()\n" );
#endif
icalset *stream;
icalcomponent *vcalendar;
stream = icalfileset_new(m_serveraddr.get());
if ( !stream ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::AddEvent() failed: Cannot open stream: %s!\n", serveraddr );
#endif
return NS_OK;
}
((oeICalEventImpl *)icalevent)->GetId( retid );
if( *retid == nsnull ) {
char uidstr[40];
GenerateUUID( uidstr );
((oeICalEventImpl *)icalevent)->SetId( uidstr );
((oeICalEventImpl *)icalevent)->GetId( retid );
}
vcalendar = ((oeICalEventImpl *)icalevent)->AsIcalComponent();
icalfileset_add_first_to_first_component( stream, vcalendar );
if( icalfileset_commit(stream) != ICAL_NO_ERROR ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::AddEvent() : WARNING icalfileset_commit() unsuccessful\n" );
#endif
}
icalfileset_free( stream );
icalevent->AddRef();
m_eventlist.AppendElement( icalevent );
((oeICalEventImpl *)icalevent)->SetParent( this );
PRUint32 observercount;
m_observerlist->Count(&observercount);
for( unsigned int i=0; i<observercount; i++ ) {
nsCOMPtr<oeIICalObserver>observer;
m_observerlist->QueryElementAt( i, NS_GET_IID(oeIICalObserver), getter_AddRefs(observer));
nsresult rv;
rv = observer->OnAddItem( icalevent );
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::AddEvent() : WARNING Call to observer's onAddItem() unsuccessful: %x\n", rv );
}
#endif
}
SetupAlarmManager();
return NS_OK;
}
/**
*
* ModifyEvent
*
* DESCRIPTION: Updates an event
*
* PARAMETERS:
* icalcalendar - The XPCOM component representing an event
* retid - Place to store the returned id
*
* RETURN
* None
*/
NS_IMETHODIMP oeICalImpl::ModifyEvent(oeIICalEvent *icalevent, char **retid)
{
#ifdef ICAL_DEBUG
printf( "oeICalImpl::ModifyEvent()\n" );
#endif
icalset *stream;
icalcomponent *vcalendar;
nsresult rv;
//This might be a TODO object. If so then call the appropriate function.
nsCOMPtr<oeIICalTodo> icaltodo;
rv = icalevent->QueryInterface(NS_GET_IID(oeIICalTodo), (void **)&icaltodo);
if( NS_SUCCEEDED( rv ) ) {
return ModifyTodo( icaltodo, retid );
}
stream = icalfileset_new(m_serveraddr.get());
if ( !stream ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::ModifyEvent() failed: Cannot open stream: %s!\n", serveraddr );
#endif
return NS_OK;
}
icalevent->GetId( retid );
if( *retid == nsnull ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::ModifyEvent() - Invalid Id.\n" );
#endif
icalfileset_free(stream);
return NS_OK;
}
icalcomponent *fetchedvcal = icalfileset_fetch( stream, *retid );
oeICalEventImpl *oldevent=nsnull;
if( fetchedvcal ) {
icalcomponent *fetchedvevent = icalcomponent_fetch( fetchedvcal, *retid );
if( fetchedvevent ) {
icalcomponent_remove_component( fetchedvcal, fetchedvevent );
if ( !icalcomponent_get_first_real_component( fetchedvcal ) ) {
icalfileset_remove_component( stream, fetchedvcal );
icalcomponent_free( fetchedvcal );
}
if( NS_FAILED( rv = NS_NewICalEvent((oeIICalEvent**) &oldevent ))) {
nsMemory::Free( *retid );
*retid = nsnull;
icalfileset_free(stream);
return rv;
}
oldevent->ParseIcalComponent( fetchedvevent );
icalcomponent_free( fetchedvevent );
} else {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::ModifyEvent() - WARNING Event not found.\n" );
#endif
nsMemory::Free( *retid );
*retid = nsnull;
icalfileset_free(stream);
return NS_OK;
}
} else {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::ModifyEvent() - WARNING Event not found.\n" );
#endif
nsMemory::Free( *retid );
*retid = nsnull;
icalfileset_free(stream);
return NS_OK;
}
//Update Last-Modified
icalevent->UpdateLastModified();
vcalendar = ((oeICalEventImpl *)icalevent)->AsIcalComponent();
icalfileset_add_first_to_first_component( stream, vcalendar );
if( icalfileset_commit(stream) != ICAL_NO_ERROR ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::ModifyEvent() : WARNING icalfileset_commit() unsuccessful\n" );
#endif
}
icalfileset_free(stream);
PRUint32 observercount;
m_observerlist->Count(&observercount);
for( unsigned int i=0; i<observercount; i++ ) {
nsCOMPtr<oeIICalObserver>observer;
m_observerlist->QueryElementAt( i, NS_GET_IID(oeIICalObserver), getter_AddRefs(observer));
rv = observer->OnModifyItem( icalevent, oldevent );
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::ModifyEvent() : WARNING Call to observer's onModifyItem() unsuccessful: %x\n", rv );
}
#endif
}
oldevent->Release();
SetupAlarmManager();
return NS_OK;
}
/**
*
* FetchEvent
*
* DESCRIPTION: Fetches an event
*
* PARAMETERS:
* ev - Place to store the XPCOM representation of the fetched event
* id - Id of the event to fetch
*
* RETURN
* None
*/
NS_IMETHODIMP oeICalImpl::FetchEvent( const char *id, oeIICalEvent **ev)
{
#ifdef ICAL_DEBUG_ALL
printf( "oeICalImpl::FetchEvent()\n" );
#endif
if( id == nsnull ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::FetchEvent() - Invalid Id.\n" );
#endif
*ev = nsnull;
return NS_OK;
}
*ev = nsnull; //initialize to null
oeIICalEvent *event;
for (PRInt32 i = 0 ; i < m_eventlist.Count(); ++i) {
event = NS_STATIC_CAST(oeIICalEvent*, m_eventlist[i]);
// XXX Evil cast
if (event && ((oeICalEventImpl *)event)->matchId(id)) {
*ev = event;
NS_ADDREF(*ev);
break;
}
}
return NS_OK;
}
/**
*
* DeleteEvent
*
* DESCRIPTION: Deletes an event
*
* PARAMETERS:
* id - Id of the event to delete
*
* RETURN
* None
*/
NS_IMETHODIMP
oeICalImpl::DeleteEvent( const char *id )
{
#ifdef ICAL_DEBUG
printf( "oeICalImpl::DeleteEvent( %s )\n", id );
#endif
icalset *stream;
stream = icalfileset_new(m_serveraddr.get());
if ( !stream ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::DeleteEvent() failed: Cannot open stream: %s!\n", serveraddr );
#endif
return NS_OK;
}
if( id == nsnull ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::DeleteEvent() - Invalid Id.\n" );
#endif
icalfileset_free(stream);
return NS_OK;
}
icalcomponent *fetchedvcal = icalfileset_fetch( stream, id );
if( !fetchedvcal ) {
icalfileset_free(stream);
#ifdef ICAL_DEBUG
printf( "oeICalImpl::DeleteEvent() - WARNING Event not found.\n" );
#endif
return NS_OK;
}
icalcomponent *fetchedvevent = icalcomponent_fetch( fetchedvcal, id );
if( !fetchedvevent ) {
icalfileset_free(stream);
#ifdef ICAL_DEBUG
printf( "oeICalImpl::DeleteEvent() - WARNING Event not found.\n" );
#endif
return NS_OK;
}
icalcomponent_remove_component( fetchedvcal, fetchedvevent );
icalcomponent_free( fetchedvevent );
if ( !icalcomponent_get_first_real_component( fetchedvcal ) ) {
icalfileset_remove_component( stream, fetchedvcal );
icalcomponent_free( fetchedvcal );
}
icalfileset_mark( stream ); //Make sure stream is marked as dirty
if( icalfileset_commit(stream) != ICAL_NO_ERROR ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::DeleteEvent() : WARNING icalfileset_commit() unsuccessful\n" );
#endif
}
icalfileset_free(stream);
oeIICalEvent *icalevent;
FetchEvent( id , &icalevent );
m_eventlist.RemoveElement(icalevent);
PRUint32 observercount;
m_observerlist->Count(&observercount);
for( unsigned int i=0; i<observercount; i++ ) {
nsCOMPtr<oeIICalObserver>observer;
m_observerlist->QueryElementAt( i, NS_GET_IID(oeIICalObserver), getter_AddRefs(observer));
nsresult rv;
rv = observer->OnDeleteItem( icalevent );
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::DeleteEvent() : WARNING Call to observer's onDeleteItem() unsuccessful: %x\n", rv );
}
#endif
}
icalevent->Release();
SetupAlarmManager();
return NS_OK;
}
/**
* recurCompareFunc
*
* helper for GetAllEvents, compares two events by either the next recurrance,
* or the previous if no next
*/
int
recurCompareFunc(const void* aElement1, const void* aElement2, void* aData)
{
oeICalEventImpl* event1 = (oeICalEventImpl *)aElement1;
oeICalEventImpl* event2 = (oeICalEventImpl *)aElement2;
icaltimetype* now = (icaltimetype *)aData;
icaltimetype time1 = event1->GetNextRecurrence(*now, nsnull);
if (icaltime_is_null_time(time1)) {
time1 = event1->GetPreviousOccurrence(*now);
}
icaltimetype time2 = event2->GetNextRecurrence(*now, nsnull);
if (icaltime_is_null_time(time2)) {
time2 = event2->GetPreviousOccurrence(*now);
}
return icaltime_compare(time1, time2);
}
/**
*
* GetAllEvents
*
* DESCRIPTION: Returns a list of all the events in this calendar in an enumerator.
* The events are sorted based on the order of their next occurence if they recur in
* the future or their last occurence in the past otherwise.
* Here's a presentation of the sort criteria using the time axis:
* -----(Last occurence of Event1)---(Last occurence of Event2)----(Now)----(Next occurence of Event3)---->
* (Note that Event1 and Event2 will not recur in the future.)
*/
NS_IMETHODIMP
oeICalImpl::GetAllEvents(nsISimpleEnumerator **resultList )
{
#ifdef ICAL_DEBUG
printf( "oeICalImpl::GetAllEvents()\n" );
#endif
//Create a new enumerator to be returned
oeEventEnumerator *eventEnum = new oeEventEnumerator();
if (!eventEnum)
return NS_ERROR_OUT_OF_MEMORY;
nsVoidArray eventlist;
eventlist = m_eventlist;
//Calculate the present time in milliseconds
PRTime nowinms = PR_Now();
PRInt64 usecpermsec;
LL_I2L( usecpermsec, PR_USEC_PER_MSEC );
LL_DIV( nowinms, nowinms, usecpermsec );
struct icaltimetype now = ConvertFromPrtime( nowinms );
struct icaltimetype checkdate = now;
//use Now-1 so we ensure we consider Now in the calculation
icaltime_adjust( &now, 0, 0, 0, -1 );
// Sort the eventlist
eventlist.Sort(recurCompareFunc, &now);
PRUint32 num2;
num2 = eventlist.Count();
for (PRUint32 j = 0; j < num2; ++j) {
eventEnum->AddEvent((oeICalEventImpl *)(eventlist[j]));
}
*resultList = eventEnum;
// bump ref count
NS_ADDREF(*resultList);
return NS_OK;
}
NS_IMETHODIMP
oeICalImpl::GetEventsForMonth( PRTime datems, nsISimpleEnumerator **eventlist ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::GetEventsForMonth()\n" );
#endif
struct icaltimetype checkdate = ConvertFromPrtime( datems );
checkdate.day = 1;
checkdate.hour = 0;
checkdate.minute = 0;
checkdate.second = 0;
icaltime_adjust( &checkdate, 0, 0 , 0, -1 );
#ifdef ICAL_DEBUG_ALL
printf( "CHECKDATE: %s\n" , icaltime_as_ctime( checkdate ) );
#endif
PRTime checkdateinms = ConvertToPrtime( checkdate );
struct icaltimetype checkenddate = ConvertFromPrtime( datems );
checkenddate.month++;
checkenddate.day = 1;
checkenddate.hour = 0;
checkenddate.minute = 0;
checkenddate.second = 0;
checkenddate = icaltime_normalize( checkenddate );
#ifdef ICAL_DEBUG_ALL
printf( "CHECKENDDATE: %s\n" , icaltime_as_ctime( checkenddate ) );
#endif
PRTime checkenddateinms = ConvertToPrtime( checkenddate );
return GetEventsForRange(checkdateinms ,checkenddateinms, eventlist );
}
NS_IMETHODIMP
oeICalImpl::GetEventsForWeek( PRTime datems, nsISimpleEnumerator **eventlist ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::GetEventsForWeek()\n" );
#endif
struct icaltimetype checkdate = ConvertFromPrtime( datems );
checkdate.hour = 0;
checkdate.minute = 0;
checkdate.second = 0;
icaltime_adjust( &checkdate, 0, 0 , 0, -1 );
PRTime checkdateinms = ConvertToPrtime( checkdate );
struct icaltimetype checkenddate = ConvertFromPrtime( datems );
checkenddate.hour = 0;
checkenddate.minute = 0;
checkenddate.second = 0;
icaltime_adjust( &checkenddate, 7, 0 , 0, 0 );
PRTime checkenddateinms = ConvertToPrtime( checkenddate );
return GetEventsForRange(checkdateinms ,checkenddateinms, eventlist );
}
NS_IMETHODIMP
oeICalImpl::GetEventsForDay( PRTime datems, nsISimpleEnumerator **eventlist ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::GetEventsForDay()\n" );
#endif
struct icaltimetype checkdate = ConvertFromPrtime( datems );
checkdate.hour = 0;
checkdate.minute = 0;
checkdate.second = 0;
icaltime_adjust( &checkdate, 0, 0, 0, -1 );
PRTime checkdateinms = ConvertToPrtime( checkdate );
struct icaltimetype checkenddate = ConvertFromPrtime( datems );
checkenddate.hour = 0;
checkenddate.minute = 0;
checkenddate.second = 0;
icaltime_adjust( &checkenddate, 1, 0, 0, 0 );
PRTime checkenddateinms = ConvertToPrtime( checkenddate );
return GetEventsForRange(checkdateinms ,checkenddateinms, eventlist );
}
class eventOccurence {
public:
PRTime start;
nsCOMPtr<oeIICalEvent> event;
bool isbeginning;
bool isallday;
};
int
occurCompareFunc(const void* aElement1, const void* aElement2, void* aData)
{
eventOccurence* occur1 = (eventOccurence *)aElement1;
eventOccurence* occur2 = (eventOccurence *)aElement2;
return (occur1->start - occur2->start);
}
NS_IMETHODIMP
oeICalImpl::GetEventsForRange(PRTime aBeginDate, PRTime aEndDate, nsISimpleEnumerator **aResult)
{
#ifdef ICAL_DEBUG_ALL
printf( "oeICalImpl::GetEventsForRange()\n" );
#endif
oeEventEnumerator *eventEnum = new oeEventEnumerator();
if (!eventEnum)
return NS_ERROR_OUT_OF_MEMORY;
*aResult = eventEnum;
NS_ADDREF(*aResult);
struct icaltimetype checkdate = ConvertFromPrtime(aBeginDate);
icaltime_adjust(&checkdate, 0, 0, 0, -1);
struct icaltimetype checkenddate = ConvertFromPrtime(aEndDate);
nsVoidArray occurList;
oeIICalEvent *tmpevent;
PRInt32 i;
for (i = 0 ; i < m_eventlist.Count(); ++i) {
tmpevent = NS_STATIC_CAST(oeIICalEvent*, m_eventlist[i]);
struct icaltimetype check = checkdate;
bool isbeginning;
check = ((oeICalEventImpl *)tmpevent)->GetNextRecurrence(check, &isbeginning);
while (!icaltime_is_null_time(check) && (icaltime_compare(check, checkenddate) < 0)) {
eventOccurence *occur = new eventOccurence();
if (!occur) {
// I whish i knew a better way to do this cleanup stuff..
for (PRInt32 j = 0 ; j < occurList.Count(); ++j) {
eventOccurence *occur = NS_STATIC_CAST(eventOccurence*, occurList[j]);
delete occur;
}
return NS_ERROR_OUT_OF_MEMORY;
}
occur->start = ConvertToPrtime(check);
occur->event = tmpevent;
occur->isbeginning = isbeginning;
occur->isallday = check.is_date;
occurList.AppendElement(occur);
check = ((oeICalEventImpl *)tmpevent)->GetNextRecurrence(check, &isbeginning);
}
}
occurList.Sort(occurCompareFunc, nsnull);
for (i = 0 ; i < occurList.Count(); ++i) {
eventOccurence *occur = NS_STATIC_CAST(eventOccurence*, occurList[i]);
tmpevent = NS_STATIC_CAST(oeIICalEvent*, occur->event);
((oeICalEventImpl *)tmpevent)->
ChopAndAddEventToEnum(ConvertFromPrtime(occur->start), aResult,
occur->isallday, occur->isbeginning );
delete occur;
}
return NS_OK;
}
NS_IMETHODIMP
oeICalImpl::GetFirstEventsForRange(PRTime aBeginDate, PRTime aEndDate, nsISimpleEnumerator **aResult)
{
#ifdef ICAL_DEBUG
printf( "oeICalImpl::GetFirstEventsForRange()\n" );
#endif
oeEventEnumerator *eventEnum = new oeEventEnumerator();
if (!eventEnum)
return NS_ERROR_OUT_OF_MEMORY;
*aResult = eventEnum;
NS_ADDREF(*aResult);
nsCOMPtr<nsISupportsArray> eventArray;
NS_NewISupportsArray(getter_AddRefs(eventArray));
if (eventArray == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
oeIICalEvent *event;
PRInt32 i;
for (i = 0 ; i < m_eventlist.Count(); ++i) {
event = NS_STATIC_CAST(oeIICalEvent*, m_eventlist[i]);
eventArray->AppendElement(event);
}
struct icaltimetype checkdate = ConvertFromPrtime(aBeginDate);
icaltime_adjust(&checkdate, 0, 0, 0, -1);
struct icaltimetype checkenddate = ConvertFromPrtime(aEndDate);
nsVoidArray occurList;
oeIICalEvent *tmpevent;
for (i = 0 ; i < m_eventlist.Count(); ++i) {
tmpevent = NS_STATIC_CAST(oeIICalEvent*, m_eventlist[i]);
struct icaltimetype check = checkdate;
bool isbeginning;
check = ((oeICalEventImpl *)tmpevent)->GetNextRecurrence(check, &isbeginning);
if (!icaltime_is_null_time(check) && (icaltime_compare(check, checkenddate) < 0)) {
eventOccurence *occur = new eventOccurence();
if (!occur) {
// I whish i knew a better way to do this cleanup stuff..
for (PRInt32 j = 0 ; i < occurList.Count(); ++j) {
eventOccurence *occur = NS_STATIC_CAST(eventOccurence*, occurList[j]);
delete occur;
}
return NS_ERROR_OUT_OF_MEMORY;
}
occur->start = ConvertToPrtime(check);
occur->event = tmpevent;
occur->isbeginning = isbeginning;
occur->isallday = check.is_date;
occurList.AppendElement(occur);
check = ((oeICalEventImpl *)tmpevent)->GetNextRecurrence(check, &isbeginning);
}
}
occurList.Sort(occurCompareFunc, nsnull);
for (i = 0 ; i < occurList.Count(); ++i) {
eventOccurence *occur = NS_STATIC_CAST(eventOccurence*, occurList[i]);
tmpevent = NS_STATIC_CAST(oeIICalEvent*, occur->event);
((oeICalEventImpl *)tmpevent)->
ChopAndAddEventToEnum(ConvertFromPrtime(occur->start), aResult,
occur->isallday, occur->isbeginning );
delete occur;
}
return NS_OK;
}
icaltimetype oeICalImpl::GetNextEvent( icaltimetype starting ) {
#ifdef ICAL_DEBUG_ALL
printf( "oeICalImpl::GetNextEvent()\n" );
#endif
icaltimetype soonest = icaltime_null_time();
oeIICalEvent *tmpevent;
for (PRInt32 i = 0 ; i < m_eventlist.Count(); ++i) {
tmpevent = NS_STATIC_CAST(oeIICalEvent*, m_eventlist[i]);
icaltimetype next = ((oeICalEventImpl *)tmpevent)->GetNextRecurrence( starting, nsnull );
next.is_date = false;
if( !icaltime_is_null_time( next ) && ( icaltime_is_null_time( soonest ) || (icaltime_compare( soonest, next ) > 0) ) ) {
soonest = next;
}
}
return soonest;
}
NS_IMETHODIMP
oeICalImpl::GetNextNEvents( PRTime datems, PRInt32 maxcount, nsISimpleEnumerator **eventlist ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::GetNextNEvents( %d )\n", maxcount );
#endif
oeEventEnumerator *eventEnum = new oeEventEnumerator();
if (!eventEnum)
return NS_ERROR_OUT_OF_MEMORY;
*eventlist = eventEnum;
NS_ADDREF(*eventlist);
struct icaltimetype checkdate = ConvertFromPrtime( datems );
icaltime_adjust( &checkdate, 0, 0, 0, -1 );
int count = 0;
icaltimetype nextcheckdate;
do {
nextcheckdate = GetNextEvent( checkdate );
if( !icaltime_is_null_time( nextcheckdate )) {
oeIICalEvent *tmpevent;
for (PRInt32 i = 0 ; (count < maxcount) && (i < m_eventlist.Count()); ++i) {
bool isbeginning,isallday;
tmpevent = NS_STATIC_CAST(oeIICalEvent*, m_eventlist[i]);
icaltimetype next = ((oeICalEventImpl *)tmpevent)->GetNextRecurrence( checkdate, &isbeginning );
isallday = next.is_date;
next.is_date = false;
if( !icaltime_is_null_time( next ) && (icaltime_compare( nextcheckdate, next ) == 0) ) {
((oeICalEventImpl *)tmpevent)->ChopAndAddEventToEnum( nextcheckdate, eventlist, isallday, isbeginning );
count++;
}
}
checkdate = nextcheckdate;
}
} while ( !icaltime_is_null_time( nextcheckdate ) && (count < maxcount) );
return NS_OK;
}
#ifdef ICAL_DEBUG_ALL
int gObservercount=0;
#endif
NS_IMETHODIMP
oeICalImpl::AddObserver(oeIICalObserver *observer)
{
#ifdef ICAL_DEBUG_ALL
gObservercount++;
printf( "oeICalImpl::AddObserver(): %d\n", gObservercount );
#endif
if( observer ) {
observer->AddRef();
PRUint32 observercount;
m_observerlist->Count( &observercount );
m_observerlist->InsertElementAt( observer, observercount );
// observer->OnLoad();
}
return NS_OK;
}
NS_IMETHODIMP
oeICalImpl::RemoveObserver(oeIICalObserver *observer)
{
#ifdef ICAL_DEBUG_ALL
gObservercount--;
printf( "oeICalImpl::RemoveObserver(): %d\n", gObservercount );
#endif
if( observer ) {
PRUint32 observercount;
m_observerlist->Count( &observercount );
for( unsigned int i=0; i<observercount; i++ ) {
nsCOMPtr<oeIICalObserver>tmpobserver;
m_observerlist->QueryElementAt( i, NS_GET_IID(oeIICalObserver), getter_AddRefs(tmpobserver));
if( observer == tmpobserver ) {
m_observerlist->RemoveElementAt( i );
observer->Release();
break;
}
}
}
return NS_OK;
}
NS_IMETHODIMP
oeICalImpl::AddTodoObserver(oeIICalTodoObserver *observer)
{
#ifdef ICAL_DEBUG_ALL
printf( "oeICalImpl::AddTodoObserver()\n" );
#endif
if( observer ) {
observer->AddRef();
PRUint32 observercount;
m_todoobserverlist->Count( &observercount );
m_todoobserverlist->InsertElementAt( observer, observercount );
// observer->OnLoad();
}
return NS_OK;
}
NS_IMETHODIMP
oeICalImpl::RemoveTodoObserver(oeIICalTodoObserver *observer)
{
#ifdef ICAL_DEBUG_ALL
printf( "oeICalImpl::RemoveTodoObserver()\n" );
#endif
if( observer ) {
PRUint32 observercount;
m_todoobserverlist->Count( &observercount );
for( unsigned int i=0; i<observercount; i++ ) {
nsCOMPtr<oeIICalTodoObserver>tmpobserver;
m_todoobserverlist->QueryElementAt( i, NS_GET_IID(oeIICalTodoObserver), getter_AddRefs(tmpobserver));
if( observer == tmpobserver ) {
m_todoobserverlist->RemoveElementAt( i );
observer->Release();
break;
}
}
}
return NS_OK;
}
void AlarmTimerCallback(nsITimer *aTimer, void *aClosure)
{
#ifdef ICAL_DEBUG
printf( "AlarmTimerCallback\n" );
#endif
oeICalImpl *icallib = (oeICalImpl *)aClosure;
icallib->SetupAlarmManager();
}
NS_IMETHODIMP UpdateCalendarIcon( PRBool hasAlarm )
{
nsresult rv;
nsCOMPtr<nsIWindowMediator> windowMediator =
do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv,rv);
static PRBool lastTimeHadAlarm = false;
if( lastTimeHadAlarm == hasAlarm )
return NS_OK;
lastTimeHadAlarm = hasAlarm;
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
// why use DOM window enumerator instead of XUL window...????
if (NS_SUCCEEDED(windowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator))))
{
PRBool more;
windowEnumerator->HasMoreElements(&more);
while(more)
{
nsCOMPtr<nsISupports> nextWindow = nsnull;
windowEnumerator->GetNext(getter_AddRefs(nextWindow));
nsCOMPtr<nsIDOMWindowInternal> domWindow(do_QueryInterface(nextWindow));
if( domWindow ) {
nsCOMPtr<nsIDOMDocument> domDocument;
domWindow->GetDocument(getter_AddRefs(domDocument));
if(domDocument)
{
nsCOMPtr<nsIDOMElement> domElement;
domDocument->GetElementById(NS_LITERAL_STRING("mini-cal"), getter_AddRefs(domElement));
if (domElement) {
if ( hasAlarm ) {
domElement->SetAttribute(NS_LITERAL_STRING("BiffState"), NS_LITERAL_STRING("Alarm"));
}
else {
domElement->RemoveAttribute(NS_LITERAL_STRING("BiffState"));
}
}
}
}
windowEnumerator->HasMoreElements(&more);
}
}
return NS_OK;
}
void oeICalImpl::SetupAlarmManager() {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::SetupAlarmManager()\n" );
#endif
if( m_suppressAlarms )
return;
if( m_batchMode )
{
#ifdef ICAL_DEBUG
printf( "oeICalImpl::SetupAlarmManager() - defering alarms while in batch mode\n" );
#endif
return;
}
static icaltimetype lastcheck = icaltime_null_time();
UpdateCalendarIcon( false );
PRTime todayinms = PR_Now();
PRInt64 usecpermsec;
LL_I2L( usecpermsec, PR_USEC_PER_MSEC );
LL_DIV( todayinms, todayinms, usecpermsec );
icaltimetype now = ConvertFromPrtime( todayinms );
icaltimetype nextalarm = icaltime_null_time();
int processmissed = -1; // -1 means the value has not been read from the preferences. 0 or 1 are valid values.
oeICalEventImpl *event;
for (PRInt32 i = 0 ; i < m_eventlist.Count(); ++i) {
event = NS_STATIC_CAST(oeICalEventImpl*, m_eventlist[i]);
icaltimetype begin=icaltime_null_time();
begin.year = 1970; begin.month=1; begin.day=1;
icaltimetype alarmtime = begin;
do {
alarmtime = event->GetNextAlarmTime( alarmtime );
if( icaltime_is_null_time( alarmtime ) )
break;
if( icaltime_compare( alarmtime, now ) <= 0 ) {
#ifdef ICAL_DEBUG
printf( "ALARM WENT OFF: %s\n", icaltime_as_ical_string( alarmtime ) );
#endif
nsresult rv;
if( processmissed == -1 ) {
nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
if ( NS_SUCCEEDED(rv) && prefBranch ) {
rv = prefBranch->GetBoolPref("calendar.alarms.showmissed", &processmissed);
} else {
processmissed = true; //if anything goes wrong just consider the default setting
}
}
if( !processmissed ) {
time_t timediff = icaltime_as_timet( now ) - icaltime_as_timet( alarmtime );
if( timediff > 30 ) //if alarmtime is older than 30 seconds it won't be processed.
continue;
}
UpdateCalendarIcon( true );
oeIICalEventDisplay* eventDisplay;
rv = NS_NewICalEventDisplay( event, &eventDisplay );
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::SetupAlarmManager() : WARNING Cannot create oeIICalEventDisplay instance: %x\n", rv );
}
#endif
icaltimetype eventtime = event->CalculateEventTime( alarmtime );
eventDisplay->SetDisplayDate( ConvertToPrtime( eventtime ) );
PRUint32 observercount;
m_observerlist->Count( &observercount );
for( unsigned int i=0; i<observercount; i++ ) {
nsCOMPtr<oeIICalObserver>observer;
m_observerlist->QueryElementAt( i, NS_GET_IID(oeIICalObserver), getter_AddRefs(observer));
rv = observer->OnAlarm( eventDisplay );
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::SetupAlarmManager() : WARNING Call to observer's onAlarm() unsuccessful: %x\n", rv );
}
#endif
}
NS_RELEASE( eventDisplay );
}
else {
if( icaltime_is_null_time( nextalarm ) )
nextalarm = alarmtime;
else if( icaltime_compare( nextalarm, alarmtime ) > 0 )
nextalarm = alarmtime;
break;
}
} while ( 1 );
}
TodoList *tmptodolistptr = &m_todolist;
while( tmptodolistptr ) {
oeIICalTodo *todo = tmptodolistptr->todo;
if( todo ) {
oeICalEventImpl *event = ((oeICalTodoImpl *)todo)->GetBaseEvent();
icaltimetype begin=icaltime_null_time();
begin.year = 1970; begin.month=1; begin.day=1;
icaltimetype alarmtime = begin;
do {
alarmtime = event->GetNextAlarmTime( alarmtime );
if( icaltime_is_null_time( alarmtime ) )
break;
if( icaltime_compare( alarmtime, now ) <= 0 ) {
#ifdef ICAL_DEBUG
printf( "ALARM WENT OFF: %s\n", icaltime_as_ical_string( alarmtime ) );
#endif
nsresult rv;
if( processmissed == -1 ) {
nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
if ( NS_SUCCEEDED(rv) && prefBranch ) {
rv = prefBranch->GetBoolPref("calendar.alarms.showmissed", &processmissed);
} else {
processmissed = true; //if anything goes wrong just consider the default setting
}
}
if( !processmissed ) {
time_t timediff = icaltime_as_timet( now ) - icaltime_as_timet( alarmtime );
if( timediff > 30 ) //if alarmtime is older than 30 seconds it won't be processed.
continue;
}
UpdateCalendarIcon( true );
oeIICalEventDisplay* eventDisplay;
rv = NS_NewICalEventDisplay( todo, &eventDisplay );
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::SetupAlarmManager() : WARNING Cannot create oeIICalEventDisplay instance: %x\n", rv );
}
#endif
icaltimetype eventtime = event->CalculateEventTime( alarmtime );
eventDisplay->SetDisplayDate( ConvertToPrtime( eventtime ) );
PRUint32 observercount;
//Here we should be using the todo observer list but nothing implements
//alarm handling for todos yet so we'll just use the one for events
m_observerlist->Count( &observercount );
for( unsigned int i=0; i<observercount; i++ ) {
nsCOMPtr<oeIICalObserver>observer;
m_observerlist->QueryElementAt( i, NS_GET_IID(oeIICalObserver), getter_AddRefs(observer));
rv = observer->OnAlarm( eventDisplay );
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::SetupAlarmManager() : WARNING Call to observer's onAlarm() unsuccessful: %x\n", rv );
}
#endif
}
NS_RELEASE( eventDisplay );
}
else {
if( icaltime_is_null_time( nextalarm ) )
nextalarm = alarmtime;
else if( icaltime_compare( nextalarm, alarmtime ) > 0 )
nextalarm = alarmtime;
break;
}
} while ( 1 );
}
tmptodolistptr = tmptodolistptr->next;
}
lastcheck = now;
CancelAlarmTimer(); //cancel the current alarm timer if any
if( !icaltime_is_null_time( nextalarm ) ) {
#ifdef ICAL_DEBUG
printf( "NEXT ALARM IS: %s\n", icaltime_as_ical_string( nextalarm ) );
#endif
time_t timediff = icaltime_as_timet( nextalarm ) - icaltime_as_timet( now );
nsresult rv;
nsCOMPtr<nsITimer> alarmtimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
alarmtimer->QueryInterface(NS_GET_IID(nsITimer), (void **)&m_alarmtimer);
if( NS_FAILED( rv ) )
m_alarmtimer = nsnull;
else
#ifdef NS_INIT_REFCNT //A temporary way of keeping backward compatibility with Mozilla 1.0 source compile
m_alarmtimer->Init( AlarmTimerCallback, this, timediff*1000, PR_TRUE, NS_TYPE_ONE_SHOT );
#else
m_alarmtimer->InitWithFuncCallback( AlarmTimerCallback, this, timediff*1000, nsITimer::TYPE_ONE_SHOT );
#endif
}
}
void oeICalImpl::CancelAlarmTimer() {
if( m_alarmtimer ) {
PRUint32 delay = 0;
#ifdef NS_INIT_REFCNT //A temporary way of keeping backward compatibility with Mozilla 1.0 source compile
delay = m_alarmtimer->GetDelay();
#else
m_alarmtimer->GetDelay( &delay );
#endif
if ( delay != 0 )
m_alarmtimer->Cancel();
m_alarmtimer->Release();
m_alarmtimer = nsnull;
}
}
/**
*
* AddTodo
*
* DESCRIPTION: Adds a TODO component
*
* PARAMETERS:
* icaltodo - The XPCOM component representing a TODO
* retid - Place to store the returned id
*
*/
NS_IMETHODIMP oeICalImpl::AddTodo(oeIICalTodo *icaltodo,char **retid)
{
#ifdef ICAL_DEBUG
printf( "oeICalImpl::AddTodo()\n" );
#endif
icalset *stream;
icalcomponent *vcalendar;
stream = icalfileset_new(m_serveraddr.get());
if ( !stream ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::AddTodo() failed: Cannot open stream: %s!\n", serveraddr );
#endif
return NS_OK;
}
((oeICalTodoImpl *)icaltodo)->GetId( retid );
if( *retid == nsnull ) {
char uidstr[40];
GenerateUUID( uidstr );
((oeICalTodoImpl *)icaltodo)->SetId( uidstr );
((oeICalTodoImpl *)icaltodo)->GetId( retid );
}
vcalendar = ((oeICalTodoImpl *)icaltodo)->AsIcalComponent();
icalfileset_add_first_to_first_component( stream, vcalendar );
if( icalfileset_commit(stream) != ICAL_NO_ERROR ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::AddTodo() : WARNING icalfileset_commit() unsuccessful\n" );
#endif
}
icalfileset_free( stream );
icaltodo->AddRef();
m_todolist.Add( icaltodo );
((oeICalTodoImpl *)icaltodo)->SetParent( this );
PRUint32 observercount;
m_todoobserverlist->Count( &observercount );
for( unsigned int i=0; i<observercount; i++ ) {
nsCOMPtr<oeIICalTodoObserver>observer;
m_todoobserverlist->QueryElementAt( i, NS_GET_IID(oeIICalTodoObserver), getter_AddRefs(observer));
nsresult rv;
rv = observer->OnAddItem( icaltodo );
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::AddTodo() : WARNING Call to observer's onAddItem() unsuccessful: %x\n", rv );
}
#endif
}
SetupAlarmManager();
return NS_OK;
}
NS_IMETHODIMP
oeICalImpl::DeleteTodo( const char *id )
{
#ifdef ICAL_DEBUG
printf( "oeICalImpl::DeleteTodo( %s )\n", id );
#endif
icalset *stream;
stream = icalfileset_new(m_serveraddr.get());
if ( !stream ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::DeleteTodo() failed: Cannot open stream: %s!\n", serveraddr );
#endif
return NS_OK;
}
if( id == nsnull ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::DeleteTodo() - Invalid Id.\n" );
#endif
icalfileset_free(stream);
return NS_OK;
}
icalcomponent *fetchedvcal = icalfileset_fetch( stream, id );
if( !fetchedvcal ) {
icalfileset_free(stream);
#ifdef ICAL_DEBUG
printf( "oeICalImpl::DeleteTodo() - WARNING Event not found.\n" );
#endif
return NS_OK;
}
icalcomponent *fetchedvevent = icalcomponent_fetch( fetchedvcal, id );
if( !fetchedvevent ) {
icalfileset_free(stream);
#ifdef ICAL_DEBUG
printf( "oeICalImpl::DeleteTodo() - WARNING Event not found.\n" );
#endif
return NS_OK;
}
icalcomponent_remove_component( fetchedvcal, fetchedvevent );
icalcomponent_free( fetchedvevent );
if ( !icalcomponent_get_first_real_component( fetchedvcal ) ) {
icalfileset_remove_component( stream, fetchedvcal );
icalcomponent_free( fetchedvcal );
}
icalfileset_mark( stream ); //Make sure stream is marked as dirty
if( icalfileset_commit(stream) != ICAL_NO_ERROR ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::DeleteTodo() : WARNING icalfileset_commit() unsuccessful\n" );
#endif
}
icalfileset_free(stream);
oeIICalTodo *icalevent;
FetchTodo( id , &icalevent );
m_todolist.Remove( id );
PRUint32 observercount;
m_todoobserverlist->Count( &observercount );
for( unsigned int i=0; i<observercount; i++ ) {
nsCOMPtr<oeIICalTodoObserver>observer;
m_todoobserverlist->QueryElementAt( i, NS_GET_IID(oeIICalTodoObserver), getter_AddRefs(observer));
nsresult rv;
rv = observer->OnDeleteItem( icalevent );
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::DeleteTodo() : WARNING Call to observer's onDeleteItem() unsuccessful: %x\n", rv );
}
#endif
}
icalevent->Release();
SetupAlarmManager();
return NS_OK;
}
NS_IMETHODIMP oeICalImpl::FetchTodo( const char *id, oeIICalTodo **ev)
{
#ifdef ICAL_DEBUG_ALL
printf( "oeICalImpl::FetchTodo()\n" );
#endif
if( id == nsnull ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::FetchTodo() - Invalid Id.\n" );
#endif
*ev = nsnull;
return NS_OK;
}
oeIICalTodo* event = m_todolist.GetTodoById( id );
if( event != nsnull ) {
event->AddRef();
}
*ev = event;
return NS_OK;
}
NS_IMETHODIMP oeICalImpl::ModifyTodo(oeIICalTodo *icalevent, char **retid)
{
#ifdef ICAL_DEBUG
printf( "oeICalImpl::ModifyTodo()\n" );
#endif
icalset *stream;
icalcomponent *vcalendar;
stream = icalfileset_new(m_serveraddr.get());
if ( !stream ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::ModifyTodo() failed: Cannot open stream: %s!\n", serveraddr );
#endif
return NS_OK;
}
icalevent->GetId( retid );
if( *retid == nsnull ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::ModifyTodo() - Invalid Id.\n" );
#endif
icalfileset_free(stream);
return NS_OK;
}
icalcomponent *fetchedvcal = icalfileset_fetch( stream, *retid );
oeICalTodoImpl *oldevent=nsnull;
if( fetchedvcal ) {
icalcomponent *fetchedvevent = icalcomponent_fetch( fetchedvcal, *retid );
if( fetchedvevent ) {
icalcomponent_remove_component( fetchedvcal, fetchedvevent );
if ( !icalcomponent_get_first_real_component( fetchedvcal ) ) {
icalfileset_remove_component( stream, fetchedvcal );
icalcomponent_free( fetchedvcal );
}
nsresult rv;
if( NS_FAILED( rv = NS_NewICalTodo((oeIICalTodo**) &oldevent ))) {
nsMemory::Free( *retid );
*retid = nsnull;
icalfileset_free(stream);
return rv;
}
oldevent->ParseIcalComponent( fetchedvevent );
icalcomponent_free( fetchedvevent );
} else {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::ModifyTodo() - WARNING Event not found.\n" );
#endif
nsMemory::Free( *retid );
*retid = nsnull;
icalfileset_free(stream);
return NS_OK;
}
} else {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::ModifyTodo() - WARNING Event not found.\n" );
#endif
nsMemory::Free( *retid );
*retid = nsnull;
icalfileset_free(stream);
return NS_OK;
}
//Update Last-Modified
icalevent->UpdateLastModified();
vcalendar = ((oeICalTodoImpl *)icalevent)->AsIcalComponent();
icalfileset_add_first_to_first_component( stream, vcalendar );
if( icalfileset_commit(stream) != ICAL_NO_ERROR ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::ModifyTodo() : WARNING icalfileset_commit() unsuccessful\n" );
#endif
}
icalfileset_free(stream);
PRUint32 observercount;
m_todoobserverlist->Count( &observercount );
for( unsigned int i=0; i<observercount; i++ ) {
nsCOMPtr<oeIICalTodoObserver>observer;
m_todoobserverlist->QueryElementAt( i, NS_GET_IID(oeIICalTodoObserver), getter_AddRefs(observer));
nsresult rv;
rv = observer->OnModifyItem( icalevent, oldevent );
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::ModifyTodo() : WARNING Call to observer's onModifyItem() unsuccessful: %x\n", rv );
}
#endif
}
oldevent->Release();
SetupAlarmManager();
return NS_OK;
}
NS_IMETHODIMP
oeICalImpl::GetAllTodos(nsISimpleEnumerator **resultList )
{
#ifdef ICAL_DEBUG
printf( "oeICalImpl::GetAllTodos()\n" );
#endif
oeEventEnumerator *todoEnum = new oeEventEnumerator();
if (!todoEnum)
return NS_ERROR_OUT_OF_MEMORY;
*resultList = todoEnum;
NS_ADDREF(*resultList);
TodoList *tmplistptr = &m_todolist;
while( tmplistptr ) {
if( tmplistptr->todo ) {
if( SatisfiesFilter( tmplistptr->todo ) )
todoEnum->AddEvent( tmplistptr->todo );
}
tmplistptr = tmplistptr->next;
}
// bump ref count
// return todoEnum->QueryInterface(NS_GET_IID(nsISimpleEnumerator), (void **)resultList);
return NS_OK;
}
NS_IMETHODIMP oeICalImpl::ReportError( PRInt16 severity, PRUint32 errorid, const char *errorstring ) {
if( severity >= oeIICalError::CAL_PROBLEM ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::ReportError(%d,%x) : %s\n", severity, errorid, errorstring );
#endif
} else {
#ifdef ICAL_DEBUG_ALL
printf( "oeICalImpl::ReportError(%d,%x) : %s\n", severity, errorid, errorstring );
#endif
}
unsigned int i;
PRUint32 observercount;
m_observerlist->Count(&observercount);
for( i=0; i<observercount; i++ ) {
nsCOMPtr<oeIICalObserver>observer;
m_observerlist->QueryElementAt( i, NS_GET_IID(oeIICalObserver), getter_AddRefs(observer));
nsresult rv;
rv = observer->OnError( severity, errorid, errorstring );
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::ReportError() : WARNING Call to observer's onError() unsuccessful: %x\n", rv );
}
#endif
}
m_todoobserverlist->Count(&observercount);
for( i=0; i<observercount; i++ ) {
nsCOMPtr<oeIICalTodoObserver>observer;
m_todoobserverlist->QueryElementAt( i, NS_GET_IID(oeIICalTodoObserver), getter_AddRefs(observer));
nsresult rv;
rv = observer->OnError( severity, errorid, errorstring );
#ifdef ICAL_DEBUG
if( NS_FAILED( rv ) ) {
printf( "oeICalImpl::ReportError() : WARNING Call to observer's onError() unsuccessful: %x\n", rv );
}
#endif
}
return NS_OK;
}
/*************************************************************************************************************/
/*************************************************************************************************************/
/*************************************************************************************************************/
/* Filter stuff here */
/*************************************************************************************************************/
/*************************************************************************************************************/
bool oeICalImpl::SatisfiesFilter( oeIICalTodo *comp )
{
bool result=false;
if( m_filter && m_filter->m_completed ) {
if( icaltime_is_null_time( m_filter->m_completed->m_datetime ) )
return true;
}
oeDateTimeImpl *completed;
nsresult rv;
rv = comp->GetCompleted( (oeIDateTime **)&completed );
if( NS_FAILED( rv ) ) {
#ifdef ICAL_DEBUG
printf( "oeICalImpl::SatisfiesFilter() : WARNING GetCompleted() unsuccessful\n" );
#endif
return false;
}
if( icaltime_is_null_time( completed->m_datetime ) )
result = true;
if( icaltime_compare( completed->m_datetime , m_filter->m_completed->m_datetime ) > 0 )
result = true;
NS_RELEASE( completed );
return result;
}
NS_IMETHODIMP oeICalImpl::GetFilter( oeIICalTodo **retval )
{
*retval = m_filter;
NS_ADDREF(*retval);
return NS_OK;
}
NS_IMETHODIMP oeICalImpl::ResetFilter()
{
if( m_filter && m_filter->m_completed )
m_filter->m_completed->m_datetime = icaltime_null_time();
return NS_OK;
}
NS_IMPL_ISUPPORTS1(oeICalFilter, oeIICalTodo)
oeICalFilter::oeICalFilter()
{
nsresult rv;
if( NS_FAILED( rv = NS_NewDateTime((oeIDateTime**) &m_completed ))) {
m_completed = nsnull;
}
}
oeICalFilter::~oeICalFilter()
{
if( m_completed )
m_completed->Release();
}
NS_IMETHODIMP oeICalFilter::GetType(Componenttype *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetId(char **aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetId(const char *aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetTitle(nsACString& aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetTitle(const nsACString& aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetDescription(nsACString& aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetDescription(const nsACString& aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetLocation(nsACString& aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetLocation(const nsACString& aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetCategories(nsACString& aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetCategories(const nsACString& aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetUrl(nsACString& aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetUrl(const nsACString& aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetPrivateEvent(PRBool *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetPrivateEvent(PRBool aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetMethod(eventMethodProperty *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetMethod(eventMethodProperty aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetStatus(eventStatusProperty *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetStatus(eventStatusProperty aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetPriority(PRInt16 *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetPriority(PRInt16 aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetSyncId(char * *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetSyncId(const char * aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetAllDay(PRBool *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetAllDay(PRBool aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetAlarm(PRBool *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetAlarm(PRBool aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetAlarmUnits(char * *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetAlarmUnits(const char * aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetAlarmLength(PRUint32 *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetAlarmLength(PRUint32 aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetAlarmEmailAddress(char * *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetAlarmEmailAddress(const char * aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetInviteEmailAddress(char * *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetInviteEmailAddress(const char * aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetRecurInterval(PRUint32 *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetRecurInterval(PRUint32 aNewVal )
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetRecurCount(PRUint32 *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetRecurCount(PRUint32 aNewVal )
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetRecurUnits(char **aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetRecurUnits(const char * aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetRecur(PRBool *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetRecur(PRBool aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetRecurForever(PRBool *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetRecurForever(PRBool aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetLastModified(PRTime *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::UpdateLastModified()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetLastAlarmAck(PRTime *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetLastAlarmAck(PRTime aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetNextRecurrence( PRTime begin, PRTime *retval, PRBool *isvalid ) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetPreviousOccurrence( PRTime beforethis, PRTime *retval, PRBool *isvalid ) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetStart(oeIDateTime * *start)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetEnd(oeIDateTime * *end)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetStamp(oeIDateTime * *stamp)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetRecurEnd(oeIDateTime * *recurend)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetRecurWeekdays(PRInt16 *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetRecurWeekdays(PRInt16 aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetRecurWeekNumber(PRInt16 *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetRecurWeekNumber(PRInt16 aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetIcalString(nsACString& aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::ParseIcalString(const nsACString& aNewVal, PRBool *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::AddException( PRTime exdate )
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::RemoveAllExceptions()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetExceptions(nsISimpleEnumerator **datelist )
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetSnoozeTime( PRTime snoozetime )
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::Clone( oeIICalEvent **ev )
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetDue(oeIDateTime * *due)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetCompleted(oeIDateTime * *completed)
{
*completed = m_completed;
NS_ADDREF(*completed);
return NS_OK;
}
NS_IMETHODIMP oeICalFilter::GetPercent(PRInt16 *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetPercent(PRInt16 aNewVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::AddAttachment(nsIMsgAttachment *attachment)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::RemoveAttachment(nsIMsgAttachment *attachment)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::RemoveAttachments()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetAttachmentsArray(nsISupportsArray * *aAttachmentsArray)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::AddContact(nsIAbCard *contact)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::RemoveContact(nsIAbCard *contact)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::RemoveContacts()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetContactsArray(nsISupportsArray * *aContactsArray)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetParent( oeIICal *parent)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetParent( oeIICal **parent)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetTodoIcalString(nsACString& aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::ParseTodoIcalString(const nsACString& aNewVal, PRBool *aRetVal)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::SetDuration(PRBool is_negative, PRUint16 weeks, PRUint16 days, PRUint16 hours, PRUint16 minutes, PRUint16 seconds)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::GetDuration(PRBool *is_negative, PRUint16 *weeks, PRUint16 *days, PRUint16 *hours, PRUint16 *minutes, PRUint16 *seconds)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP oeICalFilter::ReportError( PRInt16 severity, PRUint32 errorid, const char *errorstring ) {
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;
}