libkcal

scheduler.cpp
1/*
2 This file is part of libkcal.
3
4 Copyright (c) 2001,2004 Cornelius Schumacher <schumacher@kde.org>
5 Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21*/
22
23#include <tdelocale.h>
24#include <kdebug.h>
25#include <tdemessagebox.h>
26#include <tdestandarddirs.h>
27
28#include "calhelper.h"
29#include "event.h"
30#include "todo.h"
31#include "freebusy.h"
32#include "icalformat.h"
33#include "calendar.h"
34#include "calendarresources.h"
35#include "freebusycache.h"
36#include "assignmentvisitor.h"
37
38#include "scheduler.h"
39
40using namespace KCal;
41
42ScheduleMessage::ScheduleMessage(IncidenceBase *incidence,int method,ScheduleMessage::Status status)
43{
44 mIncidence = incidence;
45 mMethod = method;
46 mStatus = status;
47}
48
50{
51 switch (status) {
52 case PublishUpdate:
53 return i18n("Updated Publish");
54 case PublishNew:
55 return i18n("Publish");
56 case Obsolete:
57 return i18n("Obsolete");
58 case RequestNew:
59 return i18n("New Request");
60 case RequestUpdate:
61 return i18n("Updated Request");
62 default:
63 return i18n("Unknown Status: %1").arg(TQString::number(status));
64 }
65}
66
67struct Scheduler::Private
68{
69 Private() : mFreeBusyCache( 0 ) {}
70
71 FreeBusyCache *mFreeBusyCache;
72};
73
75{
76 mCalendar = calendar;
77 mFormat = new ICalFormat();
78 mFormat->setTimeZone( calendar->timeZoneId(), !calendar->isLocalTime() );
79
80 d = new Private;
81}
82
83Scheduler::~Scheduler()
84{
85 delete d;
86
87 delete mFormat;
88}
89
90void Scheduler::setFreeBusyCache( FreeBusyCache *c )
91{
92 d->mFreeBusyCache = c;
93}
94
95FreeBusyCache *Scheduler::freeBusyCache() const
96{
97 return d->mFreeBusyCache;
98}
99
101 Method method,
103 const TQString &attendee )
104{
105 kdDebug(5800) << "Scheduler::acceptTransaction, method="
106 << methodName( method ) << endl;
107
108 switch (method) {
109 case Publish:
110 return acceptPublish(incidence, status, method);
111 case Request:
112 return acceptRequest( incidence, status, attendee );
113 case Add:
114 return acceptAdd(incidence, status);
115 case Cancel:
116 return acceptCancel(incidence, status, attendee );
117 case Declinecounter:
118 return acceptDeclineCounter(incidence, status);
119 case Reply:
120 return acceptReply(incidence, status, method);
121 case Refresh:
122 return acceptRefresh(incidence, status);
123 case Counter:
124 return acceptCounter(incidence, status);
125 default:
126 break;
127 }
128 deleteTransaction(incidence);
129 return false;
130}
131
133{
134 switch (method) {
135 case Publish:
136 return TQString::fromLatin1("Publish");
137 case Request:
138 return TQString::fromLatin1("Request");
139 case Refresh:
140 return TQString::fromLatin1("Refresh");
141 case Cancel:
142 return TQString::fromLatin1("Cancel");
143 case Add:
144 return TQString::fromLatin1("Add");
145 case Reply:
146 return TQString::fromLatin1("Reply");
147 case Counter:
148 return TQString::fromLatin1("Counter");
149 case Declinecounter:
150 return TQString::fromLatin1("Decline Counter");
151 default:
152 return TQString::fromLatin1("Unknown");
153 }
154}
155
157{
158 switch (method) {
159 case Publish:
160 return i18n("Publish");
161 case Request:
162 return i18n("Request");
163 case Refresh:
164 return i18n("Refresh");
165 case Cancel:
166 return i18n("Cancel");
167 case Add:
168 return i18n("Add");
169 case Reply:
170 return i18n("Reply");
171 case Counter:
172 return i18n("counter proposal","Counter");
173 case Declinecounter:
174 return i18n("decline counter proposal","Decline Counter");
175 default:
176 return i18n("Unknown");
177 }
178}
179
180bool Scheduler::deleteTransaction(IncidenceBase *)
181{
182 return true;
183}
184
185bool Scheduler::acceptPublish( IncidenceBase *newIncBase,
186 ScheduleMessage::Status status, Method method )
187{
188 if( newIncBase->type() == "FreeBusy" ) {
189 return acceptFreeBusy( newIncBase, method );
190 }
191
192 bool res = false;
193 kdDebug(5800) << "Scheduler::acceptPublish, status="
194 << ScheduleMessage::statusName( status ) << endl;
195 Incidence *newInc = static_cast<Incidence *>( newIncBase );
196 Incidence *calInc = mCalendar->incidence( newIncBase->uid() );
197 switch ( status ) {
198 case ScheduleMessage::Unknown:
199 case ScheduleMessage::PublishNew:
200 case ScheduleMessage::PublishUpdate:
201 if ( calInc && newInc ) {
202 if ( (newInc->revision() > calInc->revision()) ||
203 (newInc->revision() == calInc->revision() &&
204 newInc->lastModified() > calInc->lastModified() ) ) {
205 AssignmentVisitor visitor;
206 const TQString oldUid = calInc->uid();
207 if ( !visitor.assign( calInc, newInc ) ) {
208 kdError(5800) << "assigning different incidence types" << endl;
209 } else {
210 calInc->setUid( oldUid );
211 calInc->setSchedulingID( newInc->uid() );
212 res = true;
213 }
214 }
215 }
216 break;
217 case ScheduleMessage::Obsolete:
218 res = true;
219 break;
220 default:
221 break;
222 }
223 deleteTransaction( newIncBase );
224 return res;
225}
226
227bool Scheduler::acceptRequest( IncidenceBase *incidence,
229 const TQString &attendee )
230{
231 Incidence *inc = static_cast<Incidence *>(incidence);
232 if ( !inc )
233 return false;
234 if (inc->type()=="FreeBusy") {
235 // reply to this request is handled in korganizer's incomingdialog
236 return true;
237 }
238
239 const Incidence::List existingIncidences = mCalendar->incidencesFromSchedulingID( inc->uid() );
240 kdDebug(5800) << "Scheduler::acceptRequest status=" << ScheduleMessage::statusName( status ) << ": found " << existingIncidences.count() << " incidences with schedulingID " << inc->schedulingID() << endl;
241 Incidence::List::ConstIterator incit = existingIncidences.begin();
242 for ( ; incit != existingIncidences.end() ; ++incit ) {
243 Incidence* const i = *incit;
244 kdDebug(5800) << "Considering this found event ("
245 << ( i->isReadOnly() ? "readonly" : "readwrite" )
246 << ") :" << mFormat->toString( i ) << endl;
247 // If it's readonly, we can't possible update it.
248 if ( i->isReadOnly() )
249 continue;
250 if ( i->revision() <= inc->revision() ) {
251 // The new incidence might be an update for the found one
252 bool isUpdate = true;
253 // Code for new invitations:
254 // If you think we could check the value of "status" to be RequestNew: we can't.
255 // It comes from a similar check inside libical, where the event is compared to
256 // other events in the calendar. But if we have another version of the event around
257 // (e.g. shared folder for a group), the status could be RequestNew, Obsolete or Updated.
258 kdDebug(5800) << "looking in " << i->uid() << "'s attendees" << endl;
259 // This is supposed to be a new request, not an update - however we want to update
260 // the existing one to handle the "clicking more than once on the invitation" case.
261 // So check the attendee status of the attendee.
262 const KCal::Attendee::List attendees = i->attendees();
263 KCal::Attendee::List::ConstIterator ait;
264 for ( ait = attendees.begin(); ait != attendees.end(); ++ait ) {
265 if( (*ait)->email() == attendee && (*ait)->status() == Attendee::NeedsAction ) {
266 // This incidence wasn't created by me - it's probably in a shared folder
267 // and meant for someone else, ignore it.
268 kdDebug(5800) << "ignoring " << i->uid() << " since I'm still NeedsAction there" << endl;
269 isUpdate = false;
270 break;
271 }
272 }
273 if ( isUpdate ) {
274 if ( i->revision() == inc->revision() &&
275 i->lastModified() > inc->lastModified() ) {
276 // This isn't an update - the found incidence was modified more recently
277 kdDebug(5800) << "This isn't an update - the found incidence was modified more recently" << endl;
278 deleteTransaction(incidence);
279 return false;
280 }
281 kdDebug(5800) << "replacing existing incidence " << i->uid() << endl;
282 bool res = true;
283 AssignmentVisitor visitor;
284 const TQString oldUid = i->uid();
285 if ( !visitor.assign( i, inc ) ) {
286 kdError(5800) << "assigning different incidence types" << endl;
287 res = false;
288 } else {
289 i->setUid( oldUid );
290 i->setSchedulingID( inc->uid() );
291 }
292 deleteTransaction( incidence );
293 return res;
294 }
295 } else {
296 // This isn't an update - the found incidence has a bigger revision number
297 kdDebug(5800) << "This isn't an update - the found incidence has a bigger revision number" << endl;
298 deleteTransaction(incidence);
299 return false;
300 }
301 }
302
303 // Move the uid to be the schedulingID and make a unique UID
304 inc->setSchedulingID( inc->uid() );
306 // notify the user in case this is an update and we didn't find the to-be-updated incidence
307 if ( existingIncidences.count() == 0 && inc->revision() > 0 ) {
308 KMessageBox::information(
309 0,
310 i18n( "<qt>"
311 "You accepted an invitation update, but an earlier version of the "
312 "item could not be found in your calendar.<p>"
313 "This may have occurred because:<ul>"
314 "<li>the organizer did not include you in the original invitation</li>"
315 "<li>you did not accept the original invitation yet</li>"
316 "<li>you deleted the original invitation from your calendar</li>"
317 "<li>you no longer have access to the calendar containing the invitation</li>"
318 "</ul>"
319 "This is not a problem, but we thought you should know.</qt>" ),
320 i18n( "Cannot find invitation to be updated" ), "AcceptCantFindIncidence" );
321 }
322 kdDebug(5800) << "Storing new incidence with scheduling uid=" << inc->schedulingID()
323 << " and uid=" << inc->uid() << endl;
324
325 CalendarResources *stdcal = dynamic_cast<CalendarResources *>( mCalendar );
326 if( stdcal && !stdcal->hasCalendarResources() ) {
327 KMessageBox::sorry(
328 0,
329 i18n( "No calendars found, unable to save the invitation." ) );
330 return false;
331 }
332
333 // FIXME: This is a nasty hack, since we need to set a parent for the
334 // resource selection dialog. However, we don't have any UI methods
335 // in the calendar, only in the CalendarResources::DestinationPolicy
336 // So we need to type-cast it and extract it from the CalendarResources
337 TQWidget *tmpparent = 0;
338 if ( stdcal ) {
339 tmpparent = stdcal->dialogParentWidget();
340 stdcal->setDialogParentWidget( 0 );
341 }
342
343TryAgain:
344 bool success = false;
345 if ( stdcal ) {
346 success = stdcal->addIncidence( inc );
347 } else {
348 success = mCalendar->addIncidence( inc );
349 }
350
351 if ( !success ) {
352 ErrorFormat *e = stdcal ? stdcal->exception() : 0;
353
354 if ( e && e->errorCode() == KCal::ErrorFormat::UserCancel &&
355 KMessageBox::warningYesNo(
356 0,
357 i18n( "You canceled the save operation. Therefore, the appointment will not be "
358 "stored in your calendar even though you accepted the invitation. "
359 "Are you certain you want to discard this invitation? " ),
360 i18n( "Discard this invitation?" ),
361 i18n( "Discard" ), i18n( "Go Back to Folder Selection" ) ) == KMessageBox::Yes ) {
362 KMessageBox::information(
363 0,
364 i18n( "The invitation \"%1\" was not saved to your calendar "
365 "but you are still listed as an attendee for that appointment.\n"
366 "If you mistakenly accepted the invitation or do not plan to attend, please notify "
367 "the organizer %2 and ask them to remove you from the attendee list.").
368 arg( inc->summary(), inc->organizer().fullName() ) );
369 deleteTransaction( incidence );
370 return true;
371 } else {
372 goto TryAgain;
373 }
374
375 // We can have a failure if the user pressed [cancel] in the resource
376 // selectdialog, so check the exception.
377 if ( !e ||
378 ( e && ( e->errorCode() != KCal::ErrorFormat::UserCancel &&
380 TQString errMessage = i18n( "Unable to save %1 \"%2\"." ).
381 arg( i18n( inc->type() ) ).
382 arg( inc->summary() );
383 KMessageBox::sorry( 0, errMessage );
384 }
385 return false;
386 }
387
388 deleteTransaction( incidence );
389 return true;
390}
391
392bool Scheduler::acceptAdd(IncidenceBase *incidence,ScheduleMessage::Status /* status */)
393{
394 deleteTransaction(incidence);
395 return false;
396}
397
398bool Scheduler::acceptCancel( IncidenceBase *incidence,
400 const TQString &attendee )
401{
402 Incidence *inc = static_cast<Incidence *>( incidence );
403 if ( !inc ) {
404 return false;
405 }
406
407 if ( inc->type() == "FreeBusy" ) {
408 // reply to this request is handled in korganizer's incomingdialog
409 return true;
410 }
411
412 const Incidence::List existingIncidences = mCalendar->incidencesFromSchedulingID( inc->uid() );
413 kdDebug(5800) << "Scheduler::acceptCancel="
414 << ScheduleMessage::statusName( status )
415 << ": found " << existingIncidences.count()
416 << " incidences with schedulingID " << inc->schedulingID()
417 << endl;
418
419 // Remove existing incidences that aren't stored in my calendar as we
420 // will never attempt to remove those -- even if we have write-access.
421 Incidence::List myExistingIncidences;
422 Incidence::List::ConstIterator incit = existingIncidences.begin();
423 for ( ; incit != existingIncidences.end() ; ++incit ) {
424 Incidence *i = *incit;
425 if ( CalHelper::isMyCalendarIncidence( mCalendar, i ) ) {
426 myExistingIncidences.append( i );
427 }
428 }
429
430 bool ret = false;
431 incit = myExistingIncidences.begin();
432 for ( ; incit != myExistingIncidences.end() ; ++incit ) {
433 Incidence *i = *incit;
434 kdDebug(5800) << "Considering this found event ("
435 << ( i->isReadOnly() ? "readonly" : "readwrite" )
436 << ") :" << mFormat->toString( i ) << endl;
437
438 // If it's readonly, we can't possible remove it.
439 if ( i->isReadOnly() ) {
440 continue;
441 }
442
443 // Code for new invitations:
444 // We cannot check the value of "status" to be RequestNew because
445 // "status" comes from a similar check inside libical, where the event
446 // is compared to other events in the calendar. But if we have another
447 // version of the event around (e.g. shared folder for a group), the
448 // status could be RequestNew, Obsolete or Updated.
449 kdDebug(5800) << "looking in " << i->uid() << "'s attendees" << endl;
450
451 // This is supposed to be a new request, not an update - however we want
452 // to update the existing one to handle the "clicking more than once
453 // on the invitation" case. So check the attendee status of the attendee.
454 bool isMine = true;
455 const KCal::Attendee::List attendees = i->attendees();
456 KCal::Attendee::List::ConstIterator ait;
457 for ( ait = attendees.begin(); ait != attendees.end(); ++ait ) {
458 if ( (*ait)->email() == attendee &&
459 (*ait)->status() == Attendee::NeedsAction ) {
460 // This incidence wasn't created by me - it's probably in a shared
461 // folder and meant for someone else, ignore it.
462 kdDebug(5800) << "ignoring " << i->uid()
463 << " since I'm still NeedsAction there" << endl;
464 isMine = false;
465 break;
466 }
467 }
468
469 if ( isMine ) {
470 kdDebug(5800) << "removing existing incidence " << i->uid() << endl;
471 if ( i->type() == "Event" ) {
472 Event *event = mCalendar->event( i->uid() );
473 ret = ( event && mCalendar->deleteEvent( event ) );
474 } else if ( i->type() == "Todo" ) {
475 Todo *todo = mCalendar->todo( i->uid() );
476 ret = ( todo && mCalendar->deleteTodo( todo ) );
477 }
478 deleteTransaction( incidence );
479 return ret;
480 }
481 }
482
483 // in case we didn't find the to-be-removed incidence
484 if ( myExistingIncidences.count() > 0 && inc->revision() > 0 ) {
485 KMessageBox::information(
486 0,
487 i18n( "The event or task could not be removed from your calendar. "
488 "Maybe it has already been deleted or is not owned by you. "
489 "Or it might belong to a read-only or disabled calendar." ) );
490 }
491 deleteTransaction( incidence );
492 return ret;
493}
494
495bool Scheduler::acceptCancel(IncidenceBase *incidence,ScheduleMessage::Status /* status */)
496{
497 const IncidenceBase *toDelete = mCalendar->incidenceFromSchedulingID( incidence->uid() );
498
499 bool ret = true;
500 if ( toDelete ) {
501 if ( toDelete->type() == "Event" ) {
502 Event *event = mCalendar->event( toDelete->uid() );
503 ret = ( event && mCalendar->deleteEvent( event ) );
504 } else if ( toDelete->type() == "Todo" ) {
505 Todo *todo = mCalendar->todo( toDelete->uid() );
506 ret = ( todo && mCalendar->deleteTodo( todo ) );
507 }
508 } else {
509 // only complain if we failed to determine the toDelete incidence
510 // on non-initial request.
511 Incidence *inc = static_cast<Incidence *>( incidence );
512 if ( inc->revision() > 0 ) {
513 ret = false;
514 }
515 }
516
517 if ( !ret ) {
518 KMessageBox::information(
519 0,
520 i18n( "The event or task to be canceled could not be removed from your calendar. "
521 "Maybe it has already been deleted or is not owned by you. "
522 "Or it might belong to a read-only or disabled calendar." ) );
523 }
524 deleteTransaction(incidence);
525 return ret;
526}
527
528bool Scheduler::acceptDeclineCounter(IncidenceBase *incidence,ScheduleMessage::Status /* status */)
529{
530 deleteTransaction(incidence);
531 return false;
532}
533
534//bool Scheduler::acceptFreeBusy(Incidence *incidence,ScheduleMessage::Status status)
535//{
536// deleteTransaction(incidence);
537// return false;
538//}
539
540bool Scheduler::acceptReply(IncidenceBase *incidence,ScheduleMessage::Status /* status */, Method method)
541{
542 if(incidence->type()=="FreeBusy") {
543 return acceptFreeBusy(incidence, method);
544 }
545 bool ret = false;
546 Event *ev = mCalendar->event(incidence->uid());
547 Todo *to = mCalendar->todo(incidence->uid());
548
549 // try harder to find the correct incidence
550 if ( !ev && !to ) {
551 const Incidence::List list = mCalendar->incidences();
552 for ( Incidence::List::ConstIterator it = list.begin(), end = list.end(); it != end; ++it ) {
553 if ( (*it)->schedulingID() == incidence->uid() ) {
554 ev = dynamic_cast<Event*>( *it );
555 to = dynamic_cast<Todo*>( *it );
556 break;
557 }
558 }
559 }
560
561 if (ev || to) {
562 //get matching attendee in calendar
563 kdDebug(5800) << "Scheduler::acceptTransaction match found!" << endl;
564 Attendee::List attendeesIn = incidence->attendees();
565 Attendee::List attendeesEv;
566 Attendee::List attendeesNew;
567 if (ev) attendeesEv = ev->attendees();
568 if (to) attendeesEv = to->attendees();
569 Attendee::List::ConstIterator inIt;
570 Attendee::List::ConstIterator evIt;
571 for ( inIt = attendeesIn.begin(); inIt != attendeesIn.end(); ++inIt ) {
572 Attendee *attIn = *inIt;
573 bool found = false;
574 for ( evIt = attendeesEv.begin(); evIt != attendeesEv.end(); ++evIt ) {
575 Attendee *attEv = *evIt;
576 if (attIn->email().lower()==attEv->email().lower()) {
577 //update attendee-info
578 kdDebug(5800) << "Scheduler::acceptTransaction update attendee" << endl;
579 attEv->setStatus(attIn->status());
580 attEv->setDelegate(attIn->delegate());
581 attEv->setDelegator(attIn->delegator());
582 ret = true;
583 found = true;
584 }
585 }
586 if ( !found && attIn->status() != Attendee::Declined )
587 attendeesNew.append( attIn );
588 }
589
590 bool attendeeAdded = false;
591 for ( Attendee::List::ConstIterator it = attendeesNew.constBegin(); it != attendeesNew.constEnd(); ++it ) {
592 Attendee* attNew = *it;
593 TQString msg = i18n("%1 wants to attend %2 but was not invited.").arg( attNew->fullName() )
594 .arg( ev ? ev->summary() : to->summary() );
595 if ( !attNew->delegator().isEmpty() )
596 msg = i18n("%1 wants to attend %2 on behalf of %3.").arg( attNew->fullName() )
597 .arg( ev ? ev->summary() : to->summary() )
598 .arg( attNew->delegator() );
599 if ( KMessageBox::questionYesNo( 0, msg, i18n("Uninvited attendee"),
600 KGuiItem(i18n("Accept Attendance")), KGuiItem(i18n("Reject Attendance")) )
601 != KMessageBox::Yes )
602 {
603 KCal::Incidence *cancel = dynamic_cast<Incidence*>( incidence );
604 if ( cancel )
605 cancel->addComment( i18n( "The organizer rejected your attendance at this meeting." ) );
606 performTransaction( cancel ? cancel : incidence, Scheduler::Cancel, attNew->fullName() );
607 delete cancel;
608 continue;
609 }
610
611 Attendee *a = new Attendee( attNew->name(), attNew->email(), attNew->RSVP(),
612 attNew->status(), attNew->role(), attNew->uid() );
613 a->setDelegate( attNew->delegate() );
614 a->setDelegator( attNew->delegator() );
615 if ( ev )
616 ev->addAttendee( a );
617 else if ( to )
618 to->addAttendee( a );
619 ret = true;
620 attendeeAdded = true;
621 }
622
623 // send update about new participants
624 if ( attendeeAdded ) {
625 bool sendMail = false;
626 if ( ev || to ) {
627 if ( KMessageBox::questionYesNo( 0, i18n( "An attendee was added to the incidence. "
628 "Do you want to email the attendees an update message?" ),
629 i18n( "Attendee Added" ), i18n( "Send Messages" ),
630 i18n( "Do Not Send" ) ) == KMessageBox::Yes ) {
631 sendMail = true;
632 }
633 }
634
635 if ( ev ) {
636 ev->setRevision( ev->revision() + 1 );
637 if ( sendMail )
638 performTransaction( ev, Scheduler::Request );
639 }
640 if ( to ) {
641 to->setRevision( to->revision() + 1 );
642 if ( sendMail )
643 performTransaction( to, Scheduler::Request );
644 }
645 }
646
647 if ( ret ) {
648 // We set at least one of the attendees, so the incidence changed
649 // Note: This should not result in a sequence number bump
650 if ( ev )
651 ev->updated();
652 else if ( to )
653 to->updated();
654 }
655 if ( to ) {
656 // for VTODO a REPLY can be used to update the completion status of
657 // a task. see RFC2446 3.4.3
658 Todo *update = dynamic_cast<Todo*> ( incidence );
659 Q_ASSERT( update );
660 if ( update && ( to->percentComplete() != update->percentComplete() ) ) {
661 to->setPercentComplete( update->percentComplete() );
662 to->updated();
663 }
664 }
665 } else
666 kdError(5800) << "No incidence for scheduling\n";
667 if (ret) deleteTransaction(incidence);
668 return ret;
669}
670
671bool Scheduler::acceptRefresh(IncidenceBase *incidence,ScheduleMessage::Status /* status */)
672{
673 // handled in korganizer's IncomingDialog
674 deleteTransaction(incidence);
675 return false;
676}
677
678bool Scheduler::acceptCounter(IncidenceBase *incidence,ScheduleMessage::Status /* status */)
679{
680 deleteTransaction(incidence);
681 return false;
682}
683
684bool Scheduler::acceptFreeBusy(IncidenceBase *incidence, Method method)
685{
686 if ( !d->mFreeBusyCache ) {
687 kdError() << "KCal::Scheduler: no FreeBusyCache." << endl;
688 return false;
689 }
690
691 FreeBusy *freebusy = static_cast<FreeBusy *>(incidence);
692
693 kdDebug(5800) << "acceptFreeBusy:: freeBusyDirName: " << freeBusyDir() << endl;
694
695 Person from;
696 if(method == Scheduler::Publish) {
697 from = freebusy->organizer();
698 }
699 if((method == Scheduler::Reply) && (freebusy->attendeeCount() == 1)) {
700 Attendee *attendee = freebusy->attendees().first();
701 from = attendee->email();
702 }
703
704 if ( !d->mFreeBusyCache->saveFreeBusy( freebusy, from ) ) return false;
705
706 deleteTransaction(incidence);
707 return true;
708}
Provides the main "calendar" object class.
Provides a Calendar composed of several Calendar Resources.
This file is part of the API for handling calendar data and provides static convenience functions for...
Helper for type correct assignment of incidences via pointers.
bool assign(IncidenceBase *target, const IncidenceBase *source)
Assigns the incidence referenced by source to the incidence referenced by target, first ensuring that...
This class represents information related to an attendee of an event.
Definition: attendee.h:37
void setDelegator(const TQString &delegator)
Sets the delegator.
Definition: attendee.h:140
void setDelegate(const TQString &delegate)
Sets the delegate.
Definition: attendee.h:131
TQString uid() const
Return unique id of the attendee.
Definition: attendee.cpp:137
TQString delegate() const
Returns the delegate.
Definition: attendee.h:135
Role role() const
Return role of Attendee.
Definition: attendee.cpp:122
TQString delegator() const
Returns the delegator.
Definition: attendee.h:144
void setStatus(PartStat s)
Set status.
Definition: attendee.cpp:56
bool RSVP() const
Return, if Attendee is asked to reply.
Definition: attendee.h:126
PartStat status() const
Return status.
Definition: attendee.cpp:61
static TQString createUniqueId()
Create a unique id string.
Definition: calformat.cpp:67
This class provides a Calendar which is composed of other Calendars known as "Resources".
void setDialogParentWidget(TQWidget *parent)
Set the widget parent for new dialogs.
bool addIncidence(Incidence *incidence)
Insert an Incidence into the Calendar.
TQWidget * dialogParentWidget()
Returns the current parent for new dialogs.
This is the main "calendar" object class.
Definition: calendar.h:171
virtual bool addIncidence(Incidence *incidence)
Insert an Incidence into the Calendar.
Definition: calendar.cpp:466
bool isLocalTime() const
Determine if Calendar Incidences are to be written without a time zone.
Definition: calendar.cpp:125
virtual Incidence::List incidences()
Return a filtered list of all Incidences for this Calendar.
Definition: calendar.cpp:178
Incidence * incidenceFromSchedulingID(const TQString &sid)
Returns the Incidence associated with the given scheduling identifier.
Definition: calendar.cpp:599
ErrorFormat * exception() const
Returns an exception, if there is any, containing information about the last error that occurred.
Definition: calendar.cpp:80
virtual Todo * todo(const TQString &uid)=0
Returns the Todo associated with the given unique identifier.
virtual bool deleteEvent(Event *event)=0
Remove an Event from the Calendar.
TQString timeZoneId() const
Get the Time Zone ID for the Calendar.
Definition: calendar.cpp:112
Incidence::List incidencesFromSchedulingID(const TQString &UID)
Searches all events and todos for (an incidence with this scheduling ID.
Definition: calendar.cpp:588
virtual bool deleteTodo(Todo *todo)=0
Remove a Todo from the Calendar.
Incidence * incidence(const TQString &uid)
Returns the Incidence associated with the given unique identifier.
Definition: calendar.cpp:576
virtual Event * event(const TQString &uid)=0
Returns the Event associated with the given unique identifier.
Calendar format related error class.
Definition: exceptions.h:65
@ NoWritableFound
No writable resource is available.
Definition: exceptions.h:80
@ UserCancel
User canceled the operation.
Definition: exceptions.h:81
ErrorCodeFormat errorCode()
Return format error code.
Definition: exceptions.cpp:101
This class provides an Event in the sense of RFC2445.
Definition: event.h:33
This class provides information about free/busy time of a calendar user.
Definition: freebusy.h:41
This class implements the iCalendar format.
Definition: icalformat.h:44
void setTimeZone(const TQString &id, bool utc)
Set id of used time zone and whether this time zone is UTC or not.
Definition: icalformat.cpp:611
TQString toString(Calendar *)
Return calendar information as string.
Definition: icalformat.cpp:225
This class provides the base class common to all calendar components.
Definition: incidencebase.h:46
void updated()
Call this to notify the observers after the IncidenceBas object has changed.
int attendeeCount() const
Return number of attendees.
TQString uid() const
Return the unique id for the event.
const Attendee::List & attendees() const
Return list of attendees.
void addComment(const TQString &comment)
Add a comment to this incidence.
void setUid(const TQString &)
Set the unique id for the event.
TQDateTime lastModified() const
Return the time the incidence was last modified.
bool isReadOnly() const
Return if the object is read-only.
void addAttendee(Attendee *attendee, bool doUpdate=true)
Add Attendee to this incidence.
This class provides the base class common to all calendar components.
Definition: incidence.h:48
void setSchedulingID(const TQString &sid)
Set the event's/todo's scheduling ID.
Definition: incidence.cpp:880
int revision() const
Return the number of revisions this event has seen.
Definition: incidence.cpp:259
TQString schedulingID() const
Return the event's/todo's scheduling ID.
Definition: incidence.cpp:885
TQString summary() const
Return short summary.
Definition: incidence.cpp:293
void setRevision(int rev)
Set the number of revisions this event has seen.
Definition: incidence.cpp:251
This class represents a person.
Definition: person.h:35
int method()
Return iTIP method associated with this message.
Definition: scheduler.h:67
Status status()
Return status of this message.
Definition: scheduler.h:71
Status
Message status.
Definition: scheduler.h:50
static TQString statusName(Status status)
Return a human-readable name for an iTIP message status.
Definition: scheduler.cpp:49
virtual TQString freeBusyDir()=0
Returns the directory where the free-busy information is stored.
FreeBusyCache * freeBusyCache() const
Return free/busy cache.
Definition: scheduler.cpp:95
bool acceptTransaction(IncidenceBase *, Method method, ScheduleMessage::Status status, const TQString &attendee=TQString())
Accept transaction.
Definition: scheduler.cpp:100
static TQString translatedMethodName(Method)
Return a translated human-readable name for a iTIP method.
Definition: scheduler.cpp:156
Scheduler(Calendar *calendar)
Create scheduler for calendar specified as argument.
Definition: scheduler.cpp:74
Method
iTIP methods.
Definition: scheduler.h:103
virtual bool performTransaction(IncidenceBase *incidence, Method method)=0
Perform iTIP transaction on incidence.
static TQString methodName(Method)
Return a machine-readable name for a iTIP method.
Definition: scheduler.cpp:132
void setFreeBusyCache(FreeBusyCache *)
Set free/busy cache used to store free/busy information.
Definition: scheduler.cpp:90
This class provides a Todo in the sense of RFC2445.
Definition: todo.h:32
int percentComplete() const
Returns how many percent of the task are completed.
Definition: todo.cpp:263
void setPercentComplete(int)
Set how many percent of the task are completed.
Definition: todo.cpp:268
bool isMyCalendarIncidence(Calendar *calendar, Incidence *incidence)
Determine if the specified incidence is likely owned by the the user, independent of the Resource typ...
Definition: calhelper.cpp:55
Namespace KCal is for global classes, objects and/or functions in libkcal.
Definition: alarm.h:38