23 #include "scheduler.h"
25 #ifndef KDEPIM_NO_KRESOURCES
33 #include "assignmentvisitor.h"
35 #include <klocalizedstring.h>
37 #include <kmessagebox.h>
38 #include <kstandarddirs.h>
43 class KCal::ScheduleMessage::Private
60 d->mIncidence = incidence;
89 return i18nc(
"@item this is a new scheduling message",
90 "New Scheduling Message" );
92 return i18nc(
"@item this is an update to an existing scheduling message",
93 "Updated Scheduling Message" );
95 return i18nc(
"@item obsolete status",
"Obsolete" );
97 return i18nc(
"@item this is a request for a new scheduling message",
98 "New Scheduling Message Request" );
100 return i18nc(
"@item this is a request for an update to an existing scheduling message",
101 "Updated Scheduling Message Request" );
103 return i18nc(
"@item unknown status",
"Unknown Status: %1",
int( status ) );
113 struct KCal::Scheduler::Private
116 : mFreeBusyCache( 0 )
125 mCalendar = calendar;
130 Scheduler::~Scheduler()
138 d->mFreeBusyCache = c;
143 return d->mFreeBusyCache;
156 const QString &email )
158 kDebug() <<
"method=" <<
methodName( method );
162 return acceptPublish( incidence, status, method );
166 return acceptAdd( incidence, status );
168 return acceptCancel( incidence, status, email );
169 case iTIPDeclineCounter:
170 return acceptDeclineCounter( incidence, status );
172 return acceptReply( incidence, status, method );
174 return acceptRefresh( incidence, status );
176 return acceptCounter( incidence, status );
180 deleteTransaction( incidence );
188 return QLatin1String(
"Publish" );
190 return QLatin1String(
"Request" );
192 return QLatin1String(
"Refresh" );
194 return QLatin1String(
"Cancel" );
196 return QLatin1String(
"Add" );
198 return QLatin1String(
"Reply" );
200 return QLatin1String(
"Counter" );
201 case iTIPDeclineCounter:
202 return QLatin1String(
"Decline Counter" );
204 return QLatin1String(
"Unknown" );
212 return i18nc(
"@item event, to-do, journal or freebusy posting",
"Publish" );
214 return i18nc(
"@item event, to-do or freebusy scheduling requests",
"Request" );
216 return i18nc(
"@item event, to-do or freebusy reply to request",
"Reply" );
219 "@item event, to-do or journal additional property request",
"Add" );
221 return i18nc(
"@item event, to-do or journal cancellation notice",
"Cancel" );
223 return i18nc(
"@item event or to-do description update request",
"Refresh" );
225 return i18nc(
"@item event or to-do submit counter proposal",
"Counter" );
226 case iTIPDeclineCounter:
227 return i18nc(
"@item event or to-do decline a counter proposal",
"Decline Counter" );
229 return i18nc(
"@item no method",
"Unknown" );
242 if( newIncBase->
type() ==
"FreeBusy" ) {
243 return acceptFreeBusy( newIncBase, method );
256 if ( calInc && newInc ) {
261 const QString oldUid = calInc->
uid();
262 if ( !visitor.
assign( calInc, newInc ) ) {
263 kError() <<
"assigning different incidence types";
278 deleteTransaction( newIncBase );
290 const QString &email )
296 if ( inc->
type() ==
"FreeBusy" ) {
303 <<
": found " << existingIncidences.count()
304 <<
" incidences with schedulingID " << inc->
schedulingID();
305 Incidence::List::ConstIterator incit = existingIncidences.begin();
306 for ( ; incit != existingIncidences.end() ; ++incit ) {
308 kDebug() <<
"Considering this found event ("
309 << ( i->
isReadOnly() ?
"readonly" :
"readwrite" )
317 bool isUpdate =
true;
323 kDebug() <<
"looking in " << i->
uid() <<
"'s attendees";
328 KCal::Attendee::List::ConstIterator ait;
329 for ( ait = attendees.begin(); ait != attendees.end(); ++ait ) {
333 kDebug() <<
"ignoring " << i->
uid() <<
" since I'm still NeedsAction there";
342 kDebug() <<
"This isn't an update - the found incidence was modified more recently";
343 deleteTransaction( i );
346 kDebug() <<
"replacing existing incidence " << i->
uid();
349 const QString oldUid = i->
uid();
350 if ( !visitor.
assign( i, inc ) ) {
351 kError() <<
"assigning different incidence types";
357 deleteTransaction( incidence );
362 kDebug() <<
"This isn't an update - the found incidence has a bigger revision number";
363 deleteTransaction( incidence );
373 if ( existingIncidences.count() > 0 || inc->
revision() == 0 ||
374 KMessageBox::questionYesNo(
377 "The event, to-do or journal to be updated could not be found. "
378 "Maybe it has already been deleted, or the calendar that "
379 "contains it is disabled. Press 'Store' to create a new "
380 "one or 'Throw away' to discard this update." ),
381 i18nc(
"@title",
"Discard this update?" ),
382 KGuiItem( i18nc(
"@option",
"Store" ) ),
383 KGuiItem( i18nc(
"@option",
"Throw away" ) ),
384 "AcceptCantFindIncidence" ) == KMessageBox::Yes ) {
385 kDebug() <<
"Storing new incidence with scheduling uid=" << inc->
schedulingID()
386 <<
" and uid=" << inc->
uid();
388 #ifndef KDEPIM_NO_KRESOURCES
393 i18nc(
"@info",
"No calendars found, unable to save the invitation." ) );
407 bool success =
false;
408 #ifndef KDEPIM_NO_KRESOURCES
416 #ifndef KDEPIM_NO_KRESOURCES
423 KMessageBox::warningYesNo(
426 "You canceled the save operation. Therefore, the appointment will not be "
427 "stored in your calendar even though you accepted the invitation. "
428 "Are you certain you want to discard this invitation? " ),
429 i18nc(
"@title",
"Discard this invitation?" ),
430 KGuiItem( i18nc(
"@option",
"Discard" ) ),
431 KGuiItem( i18nc(
"@option",
"Go Back to Folder Selection" ) ) ) == KMessageBox::Yes ) {
432 KMessageBox::information(
435 "The invitation \"%1\" was not saved to your calendar "
436 "but you are still listed as an attendee for that appointment.\n"
437 "If you mistakenly accepted the invitation or do not plan to attend, please "
438 "notify the organizer %2 and ask them to remove you from the attendee list.",
440 deleteTransaction( incidence );
451 QString errMessage = i18nc(
"@info",
"Unable to save %1 \"%2\".",
453 KMessageBox::sorry( 0, errMessage );
458 deleteTransaction( incidence );
464 deleteTransaction( incidence );
470 const QString &attendee )
477 if ( inc->
type() ==
"FreeBusy" ) {
483 kDebug() <<
"Scheduler::acceptCancel="
485 <<
": found " << existingIncidences.count()
486 <<
" incidences with schedulingID " << inc->
schedulingID();
489 Incidence::List::ConstIterator incit = existingIncidences.begin();
490 for ( ; incit != existingIncidences.end() ; ++incit ) {
492 kDebug() <<
"Considering this found event ("
493 << ( i->
isReadOnly() ?
"readonly" :
"readwrite" )
507 kDebug() <<
"looking in " << i->
uid() <<
"'s attendees";
514 KCal::Attendee::List::ConstIterator ait;
515 for ( ait = attendees.begin(); ait != attendees.end(); ++ait ) {
516 if ( (*ait)->email() == attendee &&
520 kDebug() <<
"ignoring " << i->
uid()
521 <<
" since I'm still NeedsAction there";
528 kDebug() <<
"removing existing incidence " << i->
uid();
529 if ( i->
type() ==
"Event" ) {
531 ret = (
event && mCalendar->
deleteEvent( event ) );
532 }
else if ( i->
type() ==
"Todo" ) {
534 ret = ( todo && mCalendar->
deleteTodo( todo ) );
536 deleteTransaction( incidence );
542 if ( existingIncidences.count() > 0 && inc->
revision() > 0 ) {
543 KMessageBox::information(
546 "The event or task could not be removed from your calendar. "
547 "Maybe it has already been deleted or is not owned by you. "
548 "Or it might belong to a read-only or disabled calendar." ) );
550 deleteTransaction( incidence );
563 if ( toDelete->
type() ==
"Event" ) {
565 ret = (
event && mCalendar->
deleteEvent( event ) );
566 }
else if ( toDelete->
type() ==
"Todo" ) {
568 ret = ( todo && mCalendar->
deleteTodo( todo ) );
580 KMessageBox::information(
583 "The event or task to be canceled could not be removed from your calendar. "
584 "Maybe it has already been deleted or is not owned by you. "
585 "Or it might belong to a read-only or disabled calendar." ) );
587 deleteTransaction( incidence );
591 bool Scheduler::acceptDeclineCounter(
IncidenceBase *incidence,
595 deleteTransaction( incidence );
604 if ( incidence->
type() ==
"FreeBusy" ) {
605 return acceptFreeBusy( incidence, method );
614 for ( Incidence::List::ConstIterator it=list.constBegin(), end=list.constEnd();
616 if ( (*it)->schedulingID() == incidence->
uid() ) {
617 ev =
dynamic_cast<Event*
>( *it );
618 to =
dynamic_cast<Todo*
>( *it );
626 kDebug() <<
"match found!";
636 Attendee::List::ConstIterator inIt;
637 Attendee::List::ConstIterator evIt;
638 for ( inIt = attendeesIn.constBegin(); inIt != attendeesIn.constEnd(); ++inIt ) {
641 for ( evIt = attendeesEv.constBegin(); evIt != attendeesEv.constEnd(); ++evIt ) {
643 if ( attIn->
email().toLower() == attEv->
email().toLower() ) {
645 kDebug() <<
"update attendee";
654 attendeesNew.append( attIn );
658 bool attendeeAdded =
false;
659 for ( Attendee::List::ConstIterator it = attendeesNew.constBegin();
660 it != attendeesNew.constEnd(); ++it ) {
663 i18nc(
"@info",
"%1 wants to attend %2 but was not invited.",
667 msg = i18nc(
"@info",
"%1 wants to attend %2 on behalf of %3.",
671 if ( KMessageBox::questionYesNo(
672 0, msg, i18nc(
"@title",
"Uninvited attendee" ),
673 KGuiItem( i18nc(
"@option",
"Accept Attendance" ) ),
674 KGuiItem( i18nc(
"@option",
"Reject Attendance" ) ) ) != KMessageBox::Yes ) {
679 "The organizer rejected your attendance at this meeting." ) );
698 attendeeAdded =
true;
702 if ( attendeeAdded ) {
703 bool sendMail =
false;
705 if ( KMessageBox::questionYesNo(
708 "An attendee was added to the incidence. "
709 "Do you want to email the attendees an update message?" ),
710 i18nc(
"@title",
"Attendee Added" ),
711 KGuiItem( i18nc(
"@option",
"Send Messages" ) ),
712 KGuiItem( i18nc(
"@option",
"Do Not Send" ) ) ) == KMessageBox::Yes ) {
743 Todo *update =
dynamic_cast<Todo*
> ( incidence );
751 kError() <<
"No incidence for scheduling.";
755 deleteTransaction( incidence );
764 deleteTransaction( incidence );
771 deleteTransaction( incidence );
775 bool Scheduler::acceptFreeBusy(
IncidenceBase *incidence, iTIPMethod method )
777 if ( !d->mFreeBusyCache ) {
778 kError() <<
"KCal::Scheduler: no FreeBusyCache.";
787 if( method == iTIPPublish ) {
790 if ( ( method == iTIPReply ) && ( freebusy->
attendeeCount() == 1 ) ) {
796 if ( !d->mFreeBusyCache->saveFreeBusy( freebusy, from ) ) {
800 deleteTransaction( incidence );
Incidence * incidenceFromSchedulingID(const QString &sid)
Returns the Incidence associated with the given scheduling identifier.
QString email() const
Returns the email address for this person.
QString schedulingID() const
Returns the incidence scheduling ID.
bool isReadOnly() const
Returns true the object is read-only; false otherwise.
Helper for type correct assignment of incidences via pointers.
virtual bool deleteTodo(Todo *todo)=0
Removes a Todo from the calendar.
const Attendee::List & attendees() const
Returns a list of incidence attendees.
Provides a To-do in the sense of RFC2445.
Represents the main calendar class.
An abstract class that provides a common base for all calendar incidence classes. ...
bool KCAL_DEPRECATED acceptRequest(IncidenceBase *, ScheduleMessage::Status status)
void setDialogParentWidget(QWidget *parent)
Set the widget parent for new dialogs.
void updated()
Call this to notify the observers after the IncidenceBase object has changed.
Represents information related to an attendee of an Calendar Incidence, typically a meeting or task (...
This class provides a Calendar which is composed of other Calendars known as "Resources".
ErrorFormat * exception()
Returns an exception, if there is any, containing information about the last error that occurred...
Incidence * incidence(const QString &uid)
Returns the Incidence associated with the given unique identifier.
void setFreeBusyCache(FreeBusyCache *)
Sets the free/busy cache used to store free/busy information.
This class provides an Event in the sense of RFC2445.
A Scheduling message class.
virtual QString freeBusyDir()=0
Returns the directory where the free-busy information is stored.
void setDelegate(const QString &delegate)
Sets the delegate.
QString uid() const
Returns the unique id (uid) for the incidence.
Status status()
Returns the status of this message.
KDateTime::Spec timeSpec() const
Get the time specification (time zone etc.) used for creating or modifying incidences in the Calendar...
PartStat status() const
Returns the PartStat of the attendee.
An abstract base class to allow different implementations of storing free busy information, e.g.
~ScheduleMessage()
Destructor.
virtual bool performTransaction(IncidenceBase *incidence, iTIPMethod method)=0
Performs iTIP transaction on incidence.
Event, to-do or journal declined.
static QString translatedMethodName(iTIPMethod method)
Returns a translated human-readable name for a iTIP method.
void setEmail(const QString &email)
Sets the email address for this person to email.
KDateTime lastModified() const
Returns the time the incidence was last modified.
bool addIncidence(Incidence *incidence)
Inserts an Incidence into the calendar.
bool assign(IncidenceBase *target, const IncidenceBase *source)
Assigns the incidence referenced by source to the incidence referenced by target, first ensuring that...
This file is part of the API for handling calendar data and defines the CalendarResources class...
virtual QByteArray type() const =0
Prints the type of Incidence as a string.
Represents a person, by name ane email address.
This file is part of the API for handling calendar data and defines the Todo class.
virtual Event * event(const QString &uid)=0
Returns the Event associated with the given unique identifier.
FreeBusyCache * freeBusyCache() const
Returns the free/busy cache.
This file is part of the API for handling calendar data and defines the Calendar class.
QString name() const
Returns the person name string.
Person organizer() const
Returns the Person associated with this incidence.
Provides the abstract base class common to non-FreeBusy (Events, To-dos, Journals) calendar component...
This class provides a template for lists of pointers.
This file is part of the API for handling calendar data and defines the FreeBusyCache abstract base c...
This file is part of the API for handling calendar data and defines the FreeBusy class.
void setUid(const QString &uid)
Returns the type of Incidence as a translated string.
virtual bool deleteEvent(Event *event)=0
Removes an Event from the calendar.
IncidenceBase * event()
Returns the event associated with this message.
QString uid() const
Returns the UID of the attendee.
void setName(const QString &name)
Sets the name of the person to name.
bool hasCalendarResources()
Return true if we have resources configure.
Event, to-do or journal needs action (default)
QString delegate() const
Returns the delegate.
bool RSVP() const
Returns the attendee RSVP flag.
QString delegator() const
Returns the delegator.
This class provides an encapsulation of iTIP transactions (RFC 2446).
int attendeeCount() const
Returns the number of incidence attendees.
Role role() const
Returns the Role of the attendee.
virtual bool addIncidence(Incidence *incidence)
Inserts an Incidence into the calendar.
This file is part of the API for handling calendar data and defines the Event class.
QString fullName() const
Returns the full name of this person.
static QString methodName(iTIPMethod method)
Returns a machine-readable name for a iTIP method.
void setDelegator(const QString &delegator)
Sets the delegator.
void addComment(const QString &comment)
Adds a comment to thieincidence.
void addAttendee(Attendee *attendee, bool doUpdate=true)
Add Attendee to this incidence.
virtual Todo * todo(const QString &uid)=0
Returns the Todo associated with the given unique identifier.
Request new message posting.
Scheduler(Calendar *calendar)
Creates a scheduler for calendar specified as argument.
void setRevision(int rev)
Sets the number of revisions this incidence has seen.
static QString statusName(Status status)
Returns a human-readable name for an iTIP message status.
void setPercentComplete(int percent)
Sets what percentage of the to-do is completed.
int percentComplete() const
Returns what percentage of the to-do is completed.
iTIPMethod method()
Returns the iTIP method associated with this message.
void setSchedulingID(const QString &sid)
Set the incidence scheduling ID.
int revision() const
Returns the number of revisions this incidence has seen.
Incidence::List incidencesFromSchedulingID(const QString &sid)
Searches all events and todos for an incidence with this scheduling identifiere.
virtual Incidence::List incidences()
Returns a filtered list of all Incidences for this Calendar.
void setStatus(PartStat status)
Sets the PartStat of the attendee to status.
Provides information about the free/busy time of a calendar.
bool KCAL_DEPRECATED acceptTransaction(IncidenceBase *incidence, iTIPMethod method, ScheduleMessage::Status status)
QString summary() const
Returns the incidence summary.
ScheduleMessage(IncidenceBase *incidence, iTIPMethod method, Status status)
Creates a scheduling message with method as defined in iTIPMethod and a status.
QString error()
Returns the error message if there is any.