CallId Scheduler::acceptReply( const IncidenceBase::Ptr &incidence,
                               ScheduleMessage::Status status,
                               iTIPMethod method )
{
  Q_UNUSED( status );
  if ( incidence->type() == IncidenceBase::TypeFreeBusy ) {
    return acceptFreeBusy( incidence, method );
  }

  const CallId callId = ++d->mLatestCallId;
  ResultCode resultCode = ResultCodeIncidenceOrAttendeeNotFound;
  QString errorMessage;

  Event::Ptr ev = d->mCalendar->event( incidence->uid() );
  Todo::Ptr to = d->mCalendar->todo( incidence->uid() );

  // try harder to find the correct incidence
  if ( !ev && !to ) {
    const Incidence::List list = d->mCalendar->incidences();
    for ( Incidence::List::ConstIterator it=list.constBegin(), end=list.constEnd();
          it != end; ++it ) {
      if ( (*it)->schedulingID() == incidence->uid() ) {
        ev =  ( *it ).dynamicCast<Event>();
        to = ( *it ).dynamicCast<Todo>();
        break;
      }
    }
  }

  if ( ev || to ) {
    //get matching attendee in calendar
    kDebug() << "match found!";
    Attendee::List attendeesIn = incidence->attendees();
    Attendee::List attendeesEv;
    Attendee::List attendeesNew;
    if ( ev ) {
      attendeesEv = ev->attendees();
    }
    if ( to ) {
      attendeesEv = to->attendees();
    }
    Attendee::List::ConstIterator inIt;
    Attendee::List::ConstIterator evIt;
    for ( inIt = attendeesIn.constBegin(); inIt != attendeesIn.constEnd(); ++inIt ) {
      Attendee::Ptr attIn = *inIt;
      bool found = false;
      for ( evIt = attendeesEv.constBegin(); evIt != attendeesEv.constEnd(); ++evIt ) {
        Attendee::Ptr attEv = *evIt;
        if ( attIn->email().toLower() == attEv->email().toLower() ) {
          //update attendee-info
          kDebug() << "update attendee";
          attEv->setStatus( attIn->status() );
          attEv->setDelegate( attIn->delegate() );
          attEv->setDelegator( attIn->delegator() );
          resultCode = ResultCodeSuccess;
          found = true;
        }
      }
      if ( !found && attIn->status() != Attendee::Declined ) {
        attendeesNew.append( attIn );
      }
    }

    bool attendeeAdded = false;
    for ( Attendee::List::ConstIterator it = attendeesNew.constBegin();
          it != attendeesNew.constEnd(); ++it ) {
      Attendee::Ptr attNew = *it;
      QString msg =
        i18nc( "@info", "%1 wants to attend %2 but was not invited.",
               attNew->fullName(),
               ( ev ? ev->summary() : to->summary() ) );
      if ( !attNew->delegator().isEmpty() ) {
        msg = i18nc( "@info", "%1 wants to attend %2 on behalf of %3.",
                     attNew->fullName(),
                     ( ev ? ev->summary() : to->summary() ), attNew->delegator() );
      }
      if ( KMessageBox::questionYesNo(
             0, msg, i18nc( "@title", "Uninvited attendee" ),
             KGuiItem( i18nc( "@option", "Accept Attendance" ) ),
             KGuiItem( i18nc( "@option", "Reject Attendance" ) ) ) != KMessageBox::Yes ) {
        Incidence::Ptr cancel = incidence.dynamicCast<Incidence>();
        if ( cancel ) {
          cancel->addComment(
            i18nc( "@info",
                   "The organizer rejected your attendance at this meeting." ) );
        }
        performTransaction( incidence, iTIPCancel, attNew->fullName() );
        // ### can't delete cancel here because it is aliased to incidence which
        // is accessed in the next loop iteration (CID 4232)
        // delete cancel;
        continue;
      }

      Attendee::Ptr a( new Attendee( attNew->name(), attNew->email(), attNew->RSVP(),
                                     attNew->status(), attNew->role(), attNew->uid() ) );

      a->setDelegate( attNew->delegate() );
      a->setDelegator( attNew->delegator() );
      if ( ev ) {
        ev->addAttendee( a );
      } else if ( to ) {
        to->addAttendee( a );
      }
      resultCode = ResultCodeSuccess;
      attendeeAdded = true;
    }

    // send update about new participants
    if ( attendeeAdded ) {
      bool sendMail = false;
      if ( ev || to ) {
        if ( KMessageBox::questionYesNo(
               0,
               i18nc( "@info",
                      "An attendee was added to the incidence. "
                      "Do you want to email the attendees an update message?" ),
               i18nc( "@title", "Attendee Added" ),
               KGuiItem( i18nc( "@option", "Send Messages" ) ),
               KGuiItem( i18nc( "@option", "Do Not Send" ) ) ) == KMessageBox::Yes ) {
          sendMail = true;
        }
      }

      if ( ev ) {
        ev->setRevision( ev->revision() + 1 );
        if ( sendMail ) {
          performTransaction( ev, iTIPRequest );
        }
      }
      if ( to ) {
        to->setRevision( to->revision() + 1 );
        if ( sendMail ) {
          performTransaction( to, iTIPRequest );
        }
      }
    }

    if ( resultCode == ResultCodeSuccess ) {
      // We set at least one of the attendees, so the incidence changed
      // Note: This should not result in a sequence number bump
      if ( ev ) {
        ev->updated();
      } else if ( to ) {
        to->updated();
      }
    }
    if ( to ) {
      // for VTODO a REPLY can be used to update the completion status of
      // a to-do. see RFC2446 3.4.3
      Todo::Ptr update = incidence.dynamicCast<Todo>();
      Q_ASSERT( update );
      if ( update && ( to->percentComplete() != update->percentComplete() ) ) {
        to->setPercentComplete( update->percentComplete() );
        to->updated();
      }
    }
  } else {
    kError() << "No incidence for scheduling.";
  }

  if ( resultCode == ResultCodeSuccess ) {
    deleteTransaction( incidence->uid() );
  }

  emitOperationFinished( callId, resultCode, errorMessage );

  return callId;
}
예제 #2
0
bool Scheduler::acceptReply(IncidenceBase *incidence,ScheduleMessage::Status /* status */, Method method)
{
    if(incidence->type()=="FreeBusy") {
        return acceptFreeBusy(incidence, method);
    }
    bool ret = false;
    Event *ev = mCalendar->event(incidence->uid());
    Todo *to = mCalendar->todo(incidence->uid());

    // try harder to find the correct incidence
    if ( !ev && !to ) {
        const Incidence::List list = mCalendar->incidences();
        for ( Incidence::List::ConstIterator it = list.begin(), end = list.end(); it != end; ++it ) {
            if ( (*it)->schedulingID() == incidence->uid() ) {
                ev = dynamic_cast<Event*>( *it );
                to = dynamic_cast<Todo*>( *it );
                break;
            }
        }
    }

    if (ev || to) {
        //get matching attendee in calendar
        kdDebug(5800) << "Scheduler::acceptTransaction match found!" << endl;
        Attendee::List attendeesIn = incidence->attendees();
        Attendee::List attendeesEv;
        Attendee::List attendeesNew;
        if (ev) attendeesEv = ev->attendees();
        if (to) attendeesEv = to->attendees();
        Attendee::List::ConstIterator inIt;
        Attendee::List::ConstIterator evIt;
        for ( inIt = attendeesIn.begin(); inIt != attendeesIn.end(); ++inIt ) {
            Attendee *attIn = *inIt;
            bool found = false;
            for ( evIt = attendeesEv.begin(); evIt != attendeesEv.end(); ++evIt ) {
                Attendee *attEv = *evIt;
                if (attIn->email().lower()==attEv->email().lower()) {
                    //update attendee-info
                    kdDebug(5800) << "Scheduler::acceptTransaction update attendee" << endl;
                    attEv->setStatus(attIn->status());
                    attEv->setDelegate(attIn->delegate());
                    attEv->setDelegator(attIn->delegator());
                    ret = true;
                    found = true;
                }
            }
            if ( !found && attIn->status() != Attendee::Declined )
                attendeesNew.append( attIn );
        }

        bool attendeeAdded = false;
        for ( Attendee::List::ConstIterator it = attendeesNew.constBegin(); it != attendeesNew.constEnd(); ++it ) {
            Attendee* attNew = *it;
            QString msg = i18n("%1 wants to attend %2 but was not invited.").arg( attNew->fullName() )
                          .arg( ev ? ev->summary() : to->summary() );
            if ( !attNew->delegator().isEmpty() )
                msg = i18n("%1 wants to attend %2 on behalf of %3.").arg( attNew->fullName() )
                      .arg( ev ? ev->summary() : to->summary() )
                      .arg( attNew->delegator() );
            if ( KMessageBox::questionYesNo( 0, msg, i18n("Uninvited attendee"),
                                             KGuiItem(i18n("Accept Attendance")), KGuiItem(i18n("Reject Attendance")) )
                    != KMessageBox::Yes )
            {
                KCal::Incidence *cancel = dynamic_cast<Incidence*>( incidence );
                if ( cancel )
                    cancel->addComment( i18n( "The organizer rejected your attendance at this meeting." ) );
                performTransaction( cancel ? cancel : incidence, Scheduler::Cancel, attNew->fullName() );
                delete cancel;
                continue;
            }

            Attendee *a = new Attendee( attNew->name(), attNew->email(), attNew->RSVP(),
                                        attNew->status(), attNew->role(), attNew->uid() );
            a->setDelegate( attNew->delegate() );
            a->setDelegator( attNew->delegator() );
            if ( ev )
                ev->addAttendee( a );
            else if ( to )
                to->addAttendee( a );
            ret = true;
            attendeeAdded = true;
        }

        // send update about new participants
        if ( attendeeAdded ) {
            if ( ev ) {
                ev->setRevision( ev->revision() + 1 );
                performTransaction( ev, Scheduler::Request );
            }
            if ( to ) {
                to->setRevision( ev->revision() + 1 );
                performTransaction( to, Scheduler::Request );
            }
        }

        if ( ret ) {
            // We set at least one of the attendees, so the incidence changed
            // Note: This should not result in a sequence number bump
            if ( ev )
                ev->updated();
            else if ( to )
                to->updated();
        }
        if ( to ) {
            // for VTODO a REPLY can be used to update the completion status of
            // a task. see RFC2446 3.4.3
            Todo *update = dynamic_cast<Todo*> ( incidence );
            Q_ASSERT( update );
            if ( update && ( to->percentComplete() != update->percentComplete() ) ) {
                to->setPercentComplete( update->percentComplete() );
                to->updated();
            }
        }
    } else
        kdError(5800) << "No incidence for scheduling\n";
    if (ret) deleteTransaction(incidence);
    return ret;
}