diff --git a/kcal/calendarresources.cpp b/kcal/calendarresources.cpp index c7956aff6..1e5253293 100644 --- a/kcal/calendarresources.cpp +++ b/kcal/calendarresources.cpp @@ -1,956 +1,954 @@ /* This file is part of the kcal library. Copyright (c) 2003 Cornelius Schumacher Copyright (C) 2003-2004 Reinhold Kainhofer This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** @file This file is part of the API for handling calendar data and defines the CalendarResources class. @brief This class provides a Calendar which is composed of other Calendars known as "Resources". @author Cornelius Schumacher \ @author Reinhold Kainhofer \ */ #include "calendarresources.moc" #include "incidence.h" #include "journal.h" #include "resourcecalendar.h" #include "kresources/manager.h" #include "kresources/selectdialog.h" #include "kabc/lock.h" #include #include #include #include #include #include #include using namespace KCal; /** Private classes that helps to provide binary compatibility between releases. @internal */ //@cond PRIVATE class KCal::CalendarResources::Private { public: Private( const QString &family ) : mManager( new CalendarResourceManager( family ) ), mStandardPolicy( new StandardDestinationPolicy( mManager ) ), mDestinationPolicy( mStandardPolicy ), mAskPolicy( new AskDestinationPolicy( mManager ) ), mException( 0 ), mPendingDeleteFromResourceMap( false ) {} ~Private() { delete mManager; delete mStandardPolicy; delete mAskPolicy; } bool mOpen; //flag that indicates if the resources are "open" KRES::Manager* mManager; QMap mResourceMap; StandardDestinationPolicy *mStandardPolicy; DestinationPolicy *mDestinationPolicy; AskDestinationPolicy *mAskPolicy; QMap mTickets; QMap mChangeCounts; ErrorFormat *mException; bool mPendingDeleteFromResourceMap; template< class IncidenceList > void appendIncidences( IncidenceList &result, const IncidenceList &extra, ResourceCalendar * ); }; class KCal::CalendarResources::DestinationPolicy::Private { public: Private( CalendarResourceManager *manager, QWidget *parent ) : mManager( manager ), mParent( parent ) {} CalendarResourceManager *mManager; QWidget *mParent; }; class KCal::CalendarResources::StandardDestinationPolicy::Private { public: Private() {} }; class KCal::CalendarResources::AskDestinationPolicy::Private { public: Private() {} }; class KCal::CalendarResources::Ticket::Private { public: Private( ResourceCalendar *resource ) : mResource( resource ) {} ResourceCalendar *mResource; }; //@endcond CalendarResources::DestinationPolicy::DestinationPolicy( CalendarResourceManager *manager, QWidget *parent ) : d( new KCal::CalendarResources::DestinationPolicy::Private( manager, parent ) ) { } CalendarResources::DestinationPolicy::~DestinationPolicy() { delete d; } QWidget *CalendarResources::DestinationPolicy::parent() { return d->mParent; } void CalendarResources::DestinationPolicy::setParent( QWidget *parent ) { d->mParent = parent; } CalendarResourceManager *CalendarResources::DestinationPolicy::resourceManager() { return d->mManager; } bool CalendarResources::DestinationPolicy::hasCalendarResources() { CalendarResourceManager::ActiveIterator it; for ( it = resourceManager()->activeBegin(); it != resourceManager()->activeEnd(); ++it ) { if ( !(*it)->readOnly() ) { if ( resourceManager()->standardResource() == *it ) { return true; } else { return true; } } } return false; } - CalendarResources::StandardDestinationPolicy::StandardDestinationPolicy( CalendarResourceManager *manager, QWidget *parent ) : DestinationPolicy( manager, parent ), d( new KCal::CalendarResources::StandardDestinationPolicy::Private ) { } CalendarResources::StandardDestinationPolicy::~StandardDestinationPolicy() { delete d; } ResourceCalendar *CalendarResources::StandardDestinationPolicy::destination( Incidence *incidence ) { Q_UNUSED( incidence ); return resourceManager()->standardResource(); } CalendarResources::AskDestinationPolicy::AskDestinationPolicy( CalendarResourceManager *manager, QWidget *parent ) : DestinationPolicy( manager, parent ), d( new KCal::CalendarResources::AskDestinationPolicy::Private ) { } CalendarResources::AskDestinationPolicy::~AskDestinationPolicy() { delete d; } - ResourceCalendar *CalendarResources::AskDestinationPolicy::destination( Incidence *incidence ) { Q_UNUSED( incidence ); QList list; CalendarResourceManager::ActiveIterator it; for ( it = resourceManager()->activeBegin(); it != resourceManager()->activeEnd(); ++it ) { if ( !(*it)->readOnly() ) { //Insert the first the Standard resource to get be the default selected. if ( resourceManager()->standardResource() == *it ) { list.insert( 0, *it ); } else { list.append( *it ); } } } KRES::Resource *r; r = KRES::SelectDialog::getResource( list, parent() ); return static_cast( r ); } CalendarResources::CalendarResources( const KDateTime::Spec &timeSpec, const QString &family ) : Calendar( timeSpec ), d( new KCal::CalendarResources::Private( family ) ) { d->mManager->addObserver( this ); } CalendarResources::CalendarResources( const QString &timeZoneId, const QString &family ) : Calendar( timeZoneId ), d( new KCal::CalendarResources::Private( family ) ) { d->mManager->addObserver( this ); } CalendarResources::~CalendarResources() { close(); clearException(); delete d; } void CalendarResources::clearException() { delete d->mException; d->mException = 0; } ErrorFormat *CalendarResources::exception() { return d->mException; } void CalendarResources::readConfig( KConfig *config ) { d->mManager->readConfig( config ); CalendarResourceManager::Iterator it; for ( it = d->mManager->begin(); it != d->mManager->end(); ++it ) { connectResource( *it ); } } void CalendarResources::load() { if ( !d->mManager->standardResource() ) { kDebug() << "Warning! No standard resource yet."; } // set the timezone for all resources. Otherwise we'll have those terrible tz // troubles ;-(( CalendarResourceManager::Iterator i1; for ( i1 = d->mManager->begin(); i1 != d->mManager->end(); ++i1 ) { (*i1)->setTimeSpec( timeSpec() ); } QList failed; // Open all active resources CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { if ( !(*it)->load() ) { failed.append( *it ); } Incidence::List incidences = (*it)->rawIncidences(); Incidence::List::Iterator incit; for ( incit = incidences.begin(); incit != incidences.end(); ++incit ) { (*incit)->registerObserver( this ); notifyIncidenceAdded( *incit ); } } QList::ConstIterator it2; for ( it2 = failed.constBegin(); it2 != failed.constEnd(); ++it2 ) { (*it2)->setActive( false ); emit signalResourceModified( *it2 ); } d->mOpen = true; emit calendarLoaded(); } bool CalendarResources::reload() { save(); close(); load(); return true; } CalendarResourceManager *CalendarResources::resourceManager() const { return d->mManager; } void CalendarResources::setStandardDestinationPolicy() { d->mDestinationPolicy = d->mStandardPolicy; } void CalendarResources::setAskDestinationPolicy() { d->mDestinationPolicy = d->mAskPolicy; } QWidget *CalendarResources::dialogParentWidget() { return d->mDestinationPolicy->parent(); } void CalendarResources::setDialogParentWidget( QWidget *parent ) { d->mDestinationPolicy->setParent( parent ); } void CalendarResources::close() { if ( d->mOpen ) { CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { (*it)->close(); } setModified( false ); d->mOpen = false; } } bool CalendarResources::save() { bool status = true; if ( d->mOpen && isModified() ) { status = false; CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { status = (*it)->save() || status; } setModified( false ); } return status; } bool CalendarResources::isSaving() { CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { if ( (*it)->isSaving() ) { return true; } } return false; } bool CalendarResources::addIncidence( Incidence *incidence, ResourceCalendar *resource ) { // FIXME: Use proper locking via begin/endChange! bool validRes = false; CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { if ( (*it) == resource ) { validRes = true; } } ResourceCalendar *oldResource = 0; if ( d->mResourceMap.contains( incidence ) ) { oldResource = d->mResourceMap[incidence]; } d->mResourceMap[incidence] = resource; if ( validRes && beginChange( incidence ) && resource->addIncidence( incidence ) ) { // d->mResourceMap[incidence] = resource; incidence->registerObserver( this ); notifyIncidenceAdded( incidence ); setModified( true ); endChange( incidence ); return true; } else { if ( oldResource ) { d->mResourceMap[incidence] = oldResource; } else { d->mResourceMap.remove( incidence ); } } return false; } bool CalendarResources::hasCalendarResources() { return d->mDestinationPolicy->hasCalendarResources(); } bool CalendarResources::addIncidence( Incidence *incidence ) { clearException(); ResourceCalendar *resource = d->mDestinationPolicy->destination( incidence ); if ( resource ) { d->mResourceMap[ incidence ] = resource; if ( beginChange( incidence ) && resource->addIncidence( incidence ) ) { incidence->registerObserver( this ); notifyIncidenceAdded( incidence ); d->mResourceMap[ incidence ] = resource; setModified( true ); endChange( incidence ); return true; } else { d->mResourceMap.remove( incidence ); } } else { d->mException = new ErrorFormat( ErrorFormat::UserCancel ); } return false; } bool CalendarResources::addEvent( Event *event ) { return addIncidence( event ); } bool CalendarResources::addEvent( Event *Event, ResourceCalendar *resource ) { return addIncidence( Event, resource ); } bool CalendarResources::deleteEvent( Event *event ) { bool status; if ( d->mResourceMap.find( event ) != d->mResourceMap.end() ) { status = d->mResourceMap[event]->deleteEvent( event ); if ( status ) { d->mPendingDeleteFromResourceMap = true; } } else { status = false; CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { status = (*it)->deleteEvent( event ) || status; } } if ( status ) { notifyIncidenceDeleted( event ); } setModified( status ); return status; } void CalendarResources::deleteAllEvents() { CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { (*it)->deleteAllEvents(); } } Event *CalendarResources::event( const QString &uid ) { CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { Event *event = (*it)->event( uid ); if ( event ) { d->mResourceMap[event] = *it; return event; } } // Not found return 0; } bool CalendarResources::addTodo( Todo *todo ) { return addIncidence( todo ); } bool CalendarResources::addTodo( Todo *todo, ResourceCalendar *resource ) { return addIncidence( todo, resource ); } bool CalendarResources::deleteTodo( Todo *todo ) { bool status; if ( d->mResourceMap.find( todo ) != d->mResourceMap.end() ) { status = d->mResourceMap[todo]->deleteTodo( todo ); if ( status ) { d->mPendingDeleteFromResourceMap = true; } } else { CalendarResourceManager::ActiveIterator it; status = false; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { status = (*it)->deleteTodo( todo ) || status; } } setModified( status ); return status; } void CalendarResources::deleteAllTodos() { CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { (*it)->deleteAllTodos(); } } Todo::List CalendarResources::rawTodos( TodoSortField sortField, SortDirection sortDirection ) { Todo::List result; CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { d->appendIncidences( result, (*it)->rawTodos( TodoSortUnsorted ), *it ); } return sortTodos( &result, sortField, sortDirection ); } Todo *CalendarResources::todo( const QString &uid ) { CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { Todo *todo = (*it)->todo( uid ); if ( todo ) { d->mResourceMap[todo] = *it; return todo; } } // Not found return 0; } Todo::List CalendarResources::rawTodosForDate( const QDate &date ) { Todo::List result; CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { d->appendIncidences( result, (*it)->rawTodosForDate( date ), *it ); } return result; } Alarm::List CalendarResources::alarmsTo( const KDateTime &to ) { Alarm::List result; CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { result += (*it)->alarmsTo( to ); } return result; } Alarm::List CalendarResources::alarms( const KDateTime &from, const KDateTime &to ) { Alarm::List result; CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { result += (*it)->alarms( from, to ); } return result; } /****************************** PROTECTED METHODS ****************************/ Event::List CalendarResources::rawEventsForDate( const QDate &date, const KDateTime::Spec &timeSpec, EventSortField sortField, SortDirection sortDirection ) { Event::List result; CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { d->appendIncidences( result, (*it)->rawEventsForDate( date, timeSpec ), *it ); } return sortEvents( &result, sortField, sortDirection ); } Event::List CalendarResources::rawEvents( const QDate &start, const QDate &end, const KDateTime::Spec &timeSpec, bool inclusive ) { Event::List result; CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { d->appendIncidences( result, (*it)->rawEvents( start, end, timeSpec, inclusive ), *it ); } return result; } Event::List CalendarResources::rawEventsForDate( const KDateTime &kdt ) { // @TODO: Remove the code duplication by the resourcemap iteration block. Event::List result; CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { d->appendIncidences( result, (*it)->rawEventsForDate( kdt ), *it ); } return result; } Event::List CalendarResources::rawEvents( EventSortField sortField, SortDirection sortDirection ) { Event::List result; CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { d->appendIncidences( result, (*it)->rawEvents( EventSortUnsorted ), *it ); } return sortEvents( &result, sortField, sortDirection ); } bool CalendarResources::addJournal( Journal *journal ) { return addIncidence( journal ); } bool CalendarResources::deleteJournal( Journal *journal ) { bool status; if ( d->mResourceMap.find( journal ) != d->mResourceMap.end() ) { status = d->mResourceMap[journal]->deleteJournal( journal ); if ( status ) { d->mPendingDeleteFromResourceMap = true; } } else { CalendarResourceManager::ActiveIterator it; status = false; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { status = (*it)->deleteJournal( journal ) || status; } } setModified( status ); return status; } void CalendarResources::deleteAllJournals() { CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { (*it)->deleteAllJournals(); } } bool CalendarResources::addJournal( Journal *journal, ResourceCalendar *resource ) { return addIncidence( journal, resource ); } Journal *CalendarResources::journal( const QString &uid ) { CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { Journal *journal = (*it)->journal( uid ); if ( journal ) { d->mResourceMap[journal] = *it; return journal; } } // Not found return 0; } Journal::List CalendarResources::rawJournals( JournalSortField sortField, SortDirection sortDirection ) { Journal::List result; CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { d->appendIncidences( result, (*it)->rawJournals( JournalSortUnsorted ), *it ); } return sortJournals( &result, sortField, sortDirection ); } Journal::List CalendarResources::rawJournalsForDate( const QDate &date ) { Journal::List result; CalendarResourceManager::ActiveIterator it; for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { d->appendIncidences( result, (*it)->rawJournalsForDate( date ), *it ); } return result; } //@cond PRIVATE template< class IncidenceList > void CalendarResources::Private::appendIncidences( IncidenceList &result, const IncidenceList &extra, ResourceCalendar *resource ) { result += extra; for ( typename IncidenceList::ConstIterator it = extra.begin(); it != extra.end(); ++it ) { mResourceMap[ *it ] = resource; } } //@endcond void CalendarResources::connectResource( ResourceCalendar *resource ) { connect( resource, SIGNAL( resourceChanged( ResourceCalendar * ) ), SIGNAL( calendarChanged() ) ); connect( resource, SIGNAL( resourceSaved( ResourceCalendar * ) ), SIGNAL( calendarSaved() ) ); connect( resource, SIGNAL( resourceLoadError( ResourceCalendar *, const QString & ) ), SLOT( slotLoadError( ResourceCalendar *, const QString & ) ) ); connect( resource, SIGNAL( resourceSaveError( ResourceCalendar *, const QString & ) ), SLOT( slotSaveError( ResourceCalendar *, const QString & ) ) ); } ResourceCalendar *CalendarResources::resource( Incidence *incidence ) { if ( d->mResourceMap.find( incidence ) != d->mResourceMap.end() ) { return d->mResourceMap[ incidence ]; } return 0; } void CalendarResources::resourceAdded( ResourceCalendar *resource ) { if ( !resource->isActive() ) { return; } if ( resource->open() ) { resource->load(); } connectResource( resource ); emit signalResourceAdded( resource ); } void CalendarResources::resourceModified( ResourceCalendar *resource ) { emit signalResourceModified( resource ); } void CalendarResources::resourceDeleted( ResourceCalendar *resource ) { emit signalResourceDeleted( resource ); } void CalendarResources::doSetTimeSpec( const KDateTime::Spec &timeSpec ) { // set the timezone for all resources. Otherwise we'll have those terrible // tz troubles ;-(( CalendarResourceManager::Iterator i1; for ( i1 = d->mManager->begin(); i1 != d->mManager->end(); ++i1 ) { (*i1)->setTimeSpec( timeSpec ); } } CalendarResources::Ticket::Ticket( ResourceCalendar *resource ) : d( new KCal::CalendarResources::Ticket::Private( resource ) ) { } CalendarResources::Ticket::~Ticket() { delete d; } CalendarResources::Ticket *CalendarResources::requestSaveTicket( ResourceCalendar *resource ) { KABC::Lock *lock = resource->lock(); if ( !lock ) { return 0; } if ( lock->lock() ) { return new Ticket( resource ); } else { return 0; } } ResourceCalendar *CalendarResources::Ticket::resource() const { return d->mResource; } bool CalendarResources::save( Ticket *ticket, Incidence *incidence ) { if ( !ticket || !ticket->resource() ) { return false; } // @TODO: Check if the resource was changed at all. If not, don't save. if ( ticket->resource()->save( incidence ) ) { releaseSaveTicket( ticket ); return true; } return false; } void CalendarResources::releaseSaveTicket( Ticket *ticket ) { ticket->resource()->lock()->unlock(); delete ticket; } bool CalendarResources::beginChange( Incidence *incidence ) { ResourceCalendar *r = resource( incidence ); if ( !r ) { r = d->mDestinationPolicy->destination( incidence ); if ( !r ) { kError() << "Unable to get destination resource."; return false; } d->mResourceMap[ incidence ] = r; } d->mPendingDeleteFromResourceMap = false; int count = incrementChangeCount( r ); if ( count == 1 ) { Ticket *ticket = requestSaveTicket( r ); if ( !ticket ) { kDebug() << "unable to get ticket."; decrementChangeCount( r ); return false; } else { d->mTickets[ r ] = ticket; } } return true; } bool CalendarResources::endChange( Incidence *incidence ) { ResourceCalendar *r = resource( incidence ); if ( !r ) { return false; } int count = decrementChangeCount( r ); if ( d->mPendingDeleteFromResourceMap ) { d->mResourceMap.remove( incidence ); d->mPendingDeleteFromResourceMap = false; } if ( count == 0 ) { bool ok = save( d->mTickets[ r ], incidence ); if ( ok ) { d->mTickets.remove( r ); } else { return false; } } return true; } int CalendarResources::incrementChangeCount( ResourceCalendar *r ) { if ( !d->mChangeCounts.contains( r ) ) { d->mChangeCounts.insert( r, 0 ); } int count = d->mChangeCounts[ r ]; ++count; d->mChangeCounts[ r ] = count; return count; } int CalendarResources::decrementChangeCount( ResourceCalendar *r ) { if ( !d->mChangeCounts.contains( r ) ) { kError() << "No change count for resource."; return 0; } int count = d->mChangeCounts[ r ]; --count; if ( count < 0 ) { kError() << "Can't decrement change count. It already is 0."; count = 0; } d->mChangeCounts[ r ] = count; return count; } void CalendarResources::slotLoadError( ResourceCalendar *r, const QString &err ) { Q_UNUSED( r ); emit signalErrorMessage( err ); } void CalendarResources::slotSaveError( ResourceCalendar *r, const QString &err ) { Q_UNUSED( r ); emit signalErrorMessage( err ); } diff --git a/kcal/customproperties.h b/kcal/customproperties.h index 55c4e449d..9ffec948c 100644 --- a/kcal/customproperties.h +++ b/kcal/customproperties.h @@ -1,175 +1,177 @@ /* This file is part of the kcal library. Copyright (c) 2002,2006 David Jarvie This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** @file This file is part of the API for handling calendar data and defines the CustomProperties class. @author David Jarvie \ */ #ifndef KCAL_CUSTOMPROPERTIES_H #define KCAL_CUSTOMPROPERTIES_H #include "kcal_export.h" #include #include #include namespace KCal { /** @brief A class to manage custom calendar properties. This class represents custom calendar properties. It is used as a base class for classes which represent calendar components. A custom property name written by the kcal library has the form X-KDE-APP-KEY where APP represents the application name, and KEY distinguishes individual properties for the application. In keeping with RFC2445, property names must be composed only of the characters A-Z, a-z, 0-9 and '-'. */ class KCAL_EXPORT CustomProperties { public: /** Constructs an empty custom properties instance. */ CustomProperties(); /** Copy constructor. @param other is the one to copy. */ CustomProperties( const CustomProperties &other ); /** Destructor. */ virtual ~CustomProperties(); /** Compare this with @p properties for equality. @param properties is the one to compare. @warning The comparison is not polymorphic. */ - bool operator==( const CustomProperties &properties ) const; // KDE5: make protected to prevent accidental usage + // KDE5: make protected to prevent accidental usage + bool operator==( const CustomProperties &properties ) const; /** Create or modify a custom calendar property. @param app Application name as it appears in the custom property name. @param key Property identifier specific to the application. @param value The property's value. A call with a value of QString() will be ignored. @see removeCustomProperty(). */ void setCustomProperty( const QByteArray &app, const QByteArray &key, const QString &value ); /** Delete a custom calendar property. @param app Application name as it appears in the custom property name. @param key Property identifier specific to the application. @see setCustomProperty(). */ void removeCustomProperty( const QByteArray &app, const QByteArray &key ); /** Return the value of a custom calendar property. @param app Application name as it appears in the custom property name. @param key Property identifier specific to the application. @return Property value, or QString() if (and only if) the property does not exist. */ QString customProperty( const QByteArray &app, const QByteArray &key ) const; /** Create or modify a non-KDE or non-standard custom calendar property. @param name Full property name @param value The property's value. A call with a value of QString() will be ignored. @see removeNonKDECustomProperty(). */ void setNonKDECustomProperty( const QByteArray &name, const QString &value ); /** Delete a non-KDE or non-standard custom calendar property. @param name Full property name @see setNonKDECustomProperty(). */ void removeNonKDECustomProperty( const QByteArray &name ); /** Return the value of a non-KDE or non-standard custom calendar property. @param name Full property name @return Property value, or QString() if (and only if) the property does not exist. */ QString nonKDECustomProperty( const QByteArray &name ) const; /** Initialise the alarm's custom calendar properties to the specified key/value pairs. @param properties is a QMap of property key/value pairs. @see customProperties(). */ void setCustomProperties( const QMap &properties ); /** Returns all custom calendar property key/value pairs. @see setCustomProperties(). */ QMap customProperties() const; /** Assignment operator. @warning The assignment is not polymorphic. */ - CustomProperties &operator=( const CustomProperties &other ); // KDE5: make protected to prevent accidental usage + // KDE5: make protected to prevent accidental usage + CustomProperties &operator=( const CustomProperties &other ); protected: /** Called when a custom property has been changed. The default implementation does nothing: override in derived classes to perform change processing. */ virtual void customPropertyUpdated() {} private: //@cond PRIVATE class Private; Private *const d; //@endcond }; } #endif diff --git a/kcal/incidencebase.h b/kcal/incidencebase.h index 433c44f00..6324d708b 100644 --- a/kcal/incidencebase.h +++ b/kcal/incidencebase.h @@ -1,581 +1,583 @@ /* This file is part of the kcal library. Copyright (c) 2001-2003 Cornelius Schumacher Copyright (c) 2003-2004 Reinhold Kainhofer Copyright (c) 2005 Rafal Rzepecki This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** @file This file is part of the API for handling calendar data and defines the IncidenceBase class. @author Cornelius Schumacher \ @author Reinhold Kainhofer \ @author Rafal Rzepecki \ @glossary @anchor incidence @b incidence: General term for a calendar component. Examples are events, to-dos, and journals. @glossary @anchor event @b event: An @ref incidence that has a start and end time, typically representing some occurrence of social or personal importance. May be recurring. Examples are appointments, meetings, or holidays. @glossary @anchor to-do @b to-do: An @ref incidence that has an optional start time and an optional due time typically representing some undertaking to be performed. May be recurring. Examples are "fix the bug" or "pay the bills". @glossary @anchor todo @b todo: See @ref to-do. @glossary @anchor journal @b journal: An @ref incidence with a start date that represents a diary or daily record of one's activities. May @b not be recurring. */ #ifndef KCAL_INCIDENCEBASE_H #define KCAL_INCIDENCEBASE_H #include "attendee.h" #include "customproperties.h" #include "duration.h" #include "sortablelist.h" #include #include #include class KUrl; namespace KCal { /** List of dates */ typedef SortableList DateList; /** List of times */ typedef SortableList DateTimeList; class Event; class Todo; class Journal; class FreeBusy; /** @brief An abstract class that provides a common base for all calendar incidence classes. define: organizer (person) define: uid (same as the attendee uid?) Several properties are not allowed for VFREEBUSY objects (see rfc:2445), so they are not in IncidenceBase. The hierarchy is: IncidenceBase + FreeBusy + Incidence + Event + Todo + Journal So IncidenceBase contains all properties that are common to all classes, and Incidence contains all additional properties that are common to Events, Todos and Journals, but are not allowed for FreeBusy entries. */ class KCAL_EXPORT IncidenceBase : public CustomProperties { public: /** This class provides the interface for a visitor of calendar components. It serves as base class for concrete visitors, which implement certain actions on calendar components. It allows to add functions, which operate on the concrete types of calendar components, without changing the calendar component classes. */ class KCAL_EXPORT Visitor //krazy:exclude=dpointer { public: /** Destruct Incidence::Visitor */ virtual ~Visitor() {} /** Reimplement this function in your concrete subclass of IncidenceBase::Visitor to perform actions on an Event object. @param event is a pointer to a valid Event object. */ virtual bool visit( Event *event ); /** Reimplement this function in your concrete subclass of IncidenceBase::Visitor to perform actions on a Todo object. @param todo is a pointer to a valid Todo object. */ virtual bool visit( Todo *todo ); /** Reimplement this function in your concrete subclass of IncidenceBase::Visitor to perform actions on an Journal object. @param journal is a pointer to a valid Journal object. */ virtual bool visit( Journal *journal ); /** Reimplement this function in your concrete subclass of IncidenceBase::Visitor to perform actions on a FreeBusy object. @param freebusy is a pointer to a valid FreeBusy object. */ virtual bool visit( FreeBusy *freebusy ); protected: /** Constructor is protected to prevent direct creation of visitor base class. */ Visitor() {} }; /** The IncidenceObserver class. */ class IncidenceObserver { public: /** Destroys the IncidenceObserver. */ virtual ~IncidenceObserver() {} /** The IncidenceObserver interface. @param incidenceBase is a pointer to an IncidenceBase object. */ virtual void incidenceUpdated( IncidenceBase *incidenceBase ) = 0; }; /** Constructs an empty IncidenceBase. */ IncidenceBase(); /** Constructs an IncidenceBase as a copy of another IncidenceBase object. @param ib is the IncidenceBase to copy. */ IncidenceBase( const IncidenceBase &ib ); /** Destroys the IncidenceBase. */ virtual ~IncidenceBase(); /** Assignment operator. @warning Not polymorphic. Use AssignmentVisitor for correct assignment of an instance of type IncidenceBase to another instance of type IncidenceBase. @param other is the IncidenceBase to assign. @see AssignmentVisitor */ - IncidenceBase &operator=( const IncidenceBase &other ); // KDE5: make protected to prevent accidental usage + // KDE5: make protected to prevent accidental usage + IncidenceBase &operator=( const IncidenceBase &other ); /** Compares this with IncidenceBase @p ib for equality. @warning Not polymorphic. Use ComparisonVisitor for correct comparison of two instances of type IncidenceBase. @param ib is the IncidenceBase to compare. @see ComparisonVisitor */ - bool operator==( const IncidenceBase &ib ) const; // KDE5: make protected to prevent accidental usage + // KDE5: make protected to prevent accidental usage + bool operator==( const IncidenceBase &ib ) const; /** Accept IncidenceVisitor. A class taking part in the visitor mechanism has to provide this implementation:
         bool accept(Visitor &v) { return v.visit(this); }
       
@param v is a reference to a Visitor object. */ virtual bool accept( Visitor &v ) { Q_UNUSED( v ); return false; } /** Prints the type of Incidence as a string. */ virtual QByteArray type() const = 0; /** Sets the unique id for the incidence to @p uid. @param uid is the string containing the incidence @ref uid. @see uid() */ void setUid( const QString &uid ); /** Returns the unique id (@ref uid) for the incidence. @see setUid() */ QString uid() const; /** Returns the uri for the incidence, of form urn:x-ical:\ */ KUrl uri() const; /** Sets the time the incidence was last modified to @p lm. It is stored as a UTC date/time. @param lm is the KDateTime when the incidence was last modified. @see lastModified() */ void setLastModified( const KDateTime &lm ); /** Returns the time the incidence was last modified. @see setLastModified() */ KDateTime lastModified() const; /** Sets the organizer for the incidence. @param organizer is a Person to use as the incidence @ref organizer. @see organizer(), setOrganizer(const QString &) */ void setOrganizer( const Person &organizer ); /** Sets the incidence organizer to any string @p organizer. @param organizer is a string to use as the incidence @ref organizer. @see organizer(), setOrganizer(const Person &) */ void setOrganizer( const QString &organizer ); /** Returns the Person associated with this incidence. @see setOrganizer(const QString &), setOrganizer(const Person &) */ Person organizer() const; /** Sets readonly status. @param readOnly if set, the incidence is read-only; else the incidence can be modified. @see isReadOnly(). */ virtual void setReadOnly( bool readOnly ); /** Returns true the object is read-only; false otherwise. @see setReadOnly() */ bool isReadOnly() const { return mReadOnly; } /** Sets the incidence's starting date/time with a KDateTime. The incidence's all-day status is set according to whether @p dtStart is a date/time (not all-day) or date-only (all-day). @param dtStart is the incidence start date/time. @see dtStart(). */ virtual void setDtStart( const KDateTime &dtStart ); /** Returns an incidence's starting date/time as a KDateTime. @see setDtStart(). */ virtual KDateTime dtStart() const; /** Returns an incidence's starting time as a string formatted according to the user's locale settings. @param shortfmt If set to true, use short date format, if set to false use long format. @param spec If set, return the time in the given spec, else use the incidence's current spec. @deprecated use IncidenceFormatter::timeToString() */ virtual KDE_DEPRECATED QString dtStartTimeStr( bool shortfmt = true, const KDateTime::Spec &spec = KDateTime::Spec() ) const; /** Returns an incidence's starting date as a string formatted according to the user's locale settings. @param shortfmt If set to true, use short date format, if set to false use long format. @param spec If set, return the date in the given spec, else use the incidence's current spec. @deprecated use IncidenceFormatter::dateToString() */ virtual KDE_DEPRECATED QString dtStartDateStr( bool shortfmt = true, const KDateTime::Spec &spec = KDateTime::Spec() ) const; /** Returns an incidence's starting date and time as a string formatted according to the user's locale settings. @param shortfmt If set to true, use short date format, if set to false use long format. @param spec If set, return the date and time in the given spec, else use the incidence's current spec. @deprecated use IncidenceFormatter::dateTimeToString() */ virtual KDE_DEPRECATED QString dtStartStr( bool shortfmt = true, const KDateTime::Spec &spec = KDateTime::Spec() ) const; /** Sets the incidence duration. @param duration the incidence duration @see duration() */ virtual void setDuration( const Duration &duration ); /** Returns the length of the incidence duration. @see setDuration() */ Duration duration() const; /** Sets if the incidence has a duration. @param hasDuration true if the incidence has a duration; false otherwise. @see hasDuration() */ void setHasDuration( bool hasDuration ); /** Returns true if the incidence has a duration; false otherwise. @see setHasDuration() */ bool hasDuration() const; /** Returns true or false depending on whether the incidence is all-day. i.e. has a date but no time attached to it. @see setAllDay() */ bool allDay() const; /** Sets whether the incidence is all-day, i.e. has a date but no time attached to it. @param allDay sets whether the incidence is all-day. @see allDay() */ void setAllDay( bool allDay ); /** Shift the times of the incidence so that they appear at the same clock time as before but in a new time zone. The shift is done from a viewing time zone rather than from the actual incidence time zone. For example, shifting an incidence whose start time is 09:00 America/New York, using an old viewing time zone (@p oldSpec) of Europe/London, to a new time zone (@p newSpec) of Europe/Paris, will result in the time being shifted from 14:00 (which is the London time of the incidence start) to 14:00 Paris time. @param oldSpec the time specification which provides the clock times @param newSpec the new time specification */ virtual void shiftTimes( const KDateTime::Spec &oldSpec, const KDateTime::Spec &newSpec ); /** Adds a comment to thieincidence. Does not add a linefeed character; simply appends the text as specified. @param comment is the QString containing the comment to add. @see removeComment(). */ void addComment( const QString &comment ); /** Removes a comment from the incidence. Removes the first comment whose string is an exact match for the specified string in @p comment. @param comment is the QString containing the comment to remove. @return true if match found, false otherwise. @see addComment(). */ bool removeComment( const QString &comment ); /** Deletes all incidence comments. */ void clearComments(); /** Returns all incidence comments as a list of strings. */ QStringList comments() const; /** Add Attendee to this incidence. IncidenceBase takes ownership of the Attendee object. @param attendee a pointer to the attendee to add @param doUpdate If true the Observers are notified, if false they are not. */ void addAttendee( Attendee *attendee, bool doUpdate = true ); /** Removes all attendees from the incidence. */ void clearAttendees(); /** Returns a list of incidence attendees. */ const Attendee::List &attendees() const; /** Returns the number of incidence attendees. */ int attendeeCount() const; /** Returns the attendee with the specified email address. @param email is a QString containing an email address of the form "FirstName LastName ". @see attendeeByMails(), attendeesByUid(). */ Attendee *attendeeByMail( const QString &email ) const; /** Returns the first incidence attendee with one of the specified email addresses. @param emails is a list of QStrings containing email addresses of the form "FirstName LastName ". @param email is a QString containing a single email address to search in addition to the list specified in @p emails. @see attendeeByMail(), attendeesByUid(). */ Attendee *attendeeByMails( const QStringList &emails, const QString &email = QString() ) const; /** Returns the incidence attendee with the specified attendee @acronym UID. @param uid is a QString containing an attendee @acronym UID. @see attendeeByMail(), attendeeByMails(). */ Attendee *attendeeByUid( const QString &uid ) const; /** Register observer. The observer is notified when the observed object changes. @param observer is a pointer to an IncidenceObserver object that will be watching this incidence. @see unRegisterObserver() */ void registerObserver( IncidenceObserver *observer ); /** Unregister observer. It isn't notified anymore about changes. @param observer is a pointer to an IncidenceObserver object that will be watching this incidence. @see registerObserver(). */ void unRegisterObserver( IncidenceObserver *observer ); /** Call this to notify the observers after the IncidenceBase object has changed. */ void updated(); /** Call this when a group of updates is going to be made. This suppresses change notifications until endUpdates() is called, at which point updated() will automatically be called. */ void startUpdates(); /** Call this when a group of updates is complete, to notify observers that the instance has changed. This should be called in conjunction with startUpdates(). */ void endUpdates(); protected: /** @copydoc CustomProperties::customPropertyUpdated() */ virtual void customPropertyUpdated(); /** Identifies a read-only incidence. */ bool mReadOnly; private: //@cond PRIVATE class Private; Private *const d; //@endcond }; } #endif