[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kdepimlibs/calendaring] akonadi/calendar: Introduce the invitation handling code into IncidenceChan
From: Sergio Martins <iamsergio () gmail ! com>
Date: 2012-07-31 21:34:39
Message-ID: 20120731213439.F24A8A6094 () git ! kde ! org
[Download RAW message or body]
Git commit 800765f0f7553aa733d36980b18c6f4b63c3ad4f by Sergio Martins.
Committed on 31/07/2012 at 23:32.
Pushed by smartins into branch 'calendaring'.
Introduce the invitation handling code into IncidenceChanger.
M +173 -0 akonadi/calendar/incidencechanger.cpp
M +3 -0 akonadi/calendar/incidencechanger.h
M +9 -0 akonadi/calendar/incidencechanger_p.h
M +10 -0 akonadi/calendar/invitationhandler_p.cpp
M +3 -0 akonadi/calendar/invitationhandler_p.h
http://commits.kde.org/kdepimlibs/800765f0f7553aa733d36980b18c6f4b63c3ad4f
diff --git a/akonadi/calendar/incidencechanger.cpp \
b/akonadi/calendar/incidencechanger.cpp index 87a6444..1da6ab0 100644
--- a/akonadi/calendar/incidencechanger.cpp
+++ b/akonadi/calendar/incidencechanger.cpp
@@ -19,6 +19,7 @@
*/
#include "incidencechanger.h"
#include "incidencechanger_p.h"
+#include "mailscheduler_p.h"
#include <Akonadi/ItemCreateJob>
#include <Akonadi/ItemModifyJob>
@@ -35,6 +36,26 @@
using namespace Akonadi;
using namespace KCalCore;
+InvitationHandler::Action actionFromStatus( InvitationHandler::SendResult result )
+{
+ //enum SendResult {
+ // Canceled, /**< Sending was canceled by the user, meaning there are
+ // local changes of which other attendees are not aware. \
*/ + // FailKeepUpdate, /**< Sending failed, the changes to the incidence must \
be kept. */ + // FailAbortUpdate, /**< Sending failed, the changes to the \
incidence must be undone. */ + // NoSendingNeeded, /**< In some cases it is not \
needed to send an invitation + // (e.g. when we are the \
only attendee) */ + // Success
+ switch ( result ) {
+ case InvitationHandler::ResultCanceled:
+ return InvitationHandler::ActionDontSendMessage;
+ case InvitationHandler::ResultSuccess:
+ return InvitationHandler::ActionSendMessage;
+ default:
+ return InvitationHandler::ActionAsk;
+ }
+}
+
namespace Akonadi {
static Akonadi::Collection selectCollection( QWidget *parent,
int &dialogCode,
@@ -142,6 +163,7 @@ IncidenceChanger::Private::Private( bool enableHistory, \
IncidenceChanger *qq ) : mUseHistory = enableHistory;
mDestinationPolicy = DestinationPolicyDefault;
mRespectsCollectionRights = false;
+ mGroupwareCommunication = false;
mLatestAtomicOperationId = 0;
mBatchOperationInProgress = false;
@@ -415,6 +437,147 @@ bool IncidenceChanger::Private::deleteAlreadyCalled( \
Akonadi::Item::Id id ) cons return mDeletedItemIds.contains( id );
}
+bool IncidenceChanger::Private::handleInvitationsBeforeChange( const Change::Ptr \
&change ) +{
+ bool result = true;
+ if ( mGroupwareCommunication ) {
+ InvitationHandler handler( FetchJobCalendar::Ptr(), change->parentWidget ); // \
TODO make async + if ( mInvitationStatusByAtomicOperation.contains( \
change->atomicOperationId ) ) { + handler.setDefaultAction( actionFromStatus( \
mInvitationStatusByAtomicOperation.value( change->atomicOperationId ) ) ); + }
+
+ switch( change->type ) {
+ case IncidenceChanger::ChangeTypeCreate:
+ // nothing needs to be done
+ break;
+ case IncidenceChanger::ChangeTypeDelete:
+ {
+ InvitationHandler::SendResult status;
+
+ Incidence::Ptr incidence = \
change->originalItem.payload<KCalCore::Incidence::Ptr>(); + status = \
handler.sendIncidenceDeletedMessage( KCalCore::iTIPCancel, incidence ); + if ( \
change->atomicOperationId ) { + mInvitationStatusByAtomicOperation.insert( \
change->atomicOperationId, status ); + }
+ result = status != InvitationHandler::ResultFailAbortUpdate;
+ }
+ break;
+ case IncidenceChanger::ChangeTypeModify:
+ {
+ Incidence::Ptr oldIncidence = \
change->originalItem.payload<KCalCore::Incidence::Ptr>(); + Incidence::Ptr \
newIncidence = change->originalItem.payload<KCalCore::Incidence::Ptr>(); +
+ const bool modify = handler.handleIncidenceAboutToBeModified( newIncidence \
); + if ( !modify ) {
+ if ( newIncidence->type() == oldIncidence->type() ) {
+ IncidenceBase *i1 = newIncidence.data();
+ IncidenceBase *i2 = oldIncidence.data();
+ *i1 = *i2;
+ }
+ result = false;
+ }
+ }
+ break;
+ default:
+ Q_ASSERT( false );
+ result = false;
+ }
+ }
+ return result;
+}
+
+bool IncidenceChanger::Private::handleInvitationsAfterChange( const Change::Ptr \
&change ) +{
+ if ( mGroupwareCommunication ) {
+ InvitationHandler handler( FetchJobCalendar::Ptr(), change->parentWidget ); // \
TODO make async + switch( change->type ) {
+ case IncidenceChanger::ChangeTypeCreate:
+ {
+ Incidence::Ptr incidence = \
change->newItem.payload<KCalCore::Incidence::Ptr>(); + const \
InvitationHandler::SendResult status = + \
handler.sendIncidenceCreatedMessage( KCalCore::iTIPRequest, incidence ); +
+ if ( status == InvitationHandler::ResultFailAbortUpdate ) {
+ kError() << "Sending invitations failed, but did not delete the \
incidence"; + }
+
+ const uint atomicOperationId = change->atomicOperationId;
+ if ( atomicOperationId != 0 ) {
+ mInvitationStatusByAtomicOperation.insert( atomicOperationId, status );
+ }
+ }
+ break;
+ case IncidenceChanger::ChangeTypeDelete:
+ {
+ Incidence::Ptr incidence = \
change->originalItem.payload<KCalCore::Incidence::Ptr>(); + Q_ASSERT( \
incidence ); + if ( !handler.thatIsMe( incidence->organizer()->email() ) ) {
+ const QStringList myEmails = handler.allEmails();
+ bool notifyOrganizer = false;
+ for ( QStringList::ConstIterator it = myEmails.begin(); it != \
myEmails.end(); ++it ) { + const QString email = *it;
+ KCalCore::Attendee::Ptr me( incidence->attendeeByMail( email ) );
+ if ( me ) {
+ if ( me->status() == KCalCore::Attendee::Accepted ||
+ me->status() == KCalCore::Attendee::Delegated ) {
+ notifyOrganizer = true;
+ }
+ KCalCore::Attendee::Ptr newMe( new KCalCore::Attendee( *me ) );
+ newMe->setStatus( KCalCore::Attendee::Declined );
+ incidence->clearAttendees();
+ incidence->addAttendee( newMe );
+ break;
+ }
+ }
+
+ if ( notifyOrganizer ) {
+ FetchJobCalendar::Ptr invalidPtr;
+ MailScheduler scheduler( invalidPtr ); // TODO make async
+ scheduler.performTransaction( incidence, KCalCore::iTIPReply );
+ }
+ }
+ }
+ break;
+ case IncidenceChanger::ChangeTypeModify:
+ {
+ Incidence::Ptr oldIncidence = \
change->originalItem.payload<KCalCore::Incidence::Ptr>(); + Incidence::Ptr \
newIncidence = change->newItem.payload<KCalCore::Incidence::Ptr>(); + if ( \
mInvitationStatusByAtomicOperation.contains( change->atomicOperationId ) ) { + \
handler.setDefaultAction( actionFromStatus( mInvitationStatusByAtomicOperation.value( \
change->atomicOperationId ) ) ); + }
+ const bool attendeeStatusChanged = myAttendeeStatusChanged( newIncidence,
+ oldIncidence,
+ \
handler.allEmails() ); + InvitationHandler::SendResult status = \
handler.sendIncidenceModifiedMessage( KCalCore::iTIPRequest, + \
newIncidence, + \
attendeeStatusChanged ); +
+ if ( change->atomicOperationId != 0 ) {
+ mInvitationStatusByAtomicOperation.insert( change->atomicOperationId, \
status ); + }
+ }
+ break;
+ default:
+ Q_ASSERT( false );
+ return false;
+ }
+ }
+ return true;
+}
+
+/** static */
+bool IncidenceChanger::Private::myAttendeeStatusChanged( const Incidence::Ptr \
&newInc, + const \
Incidence::Ptr &oldInc, + \
const QStringList &myEmails ) +{
+ Q_ASSERT( newInc );
+ Q_ASSERT( oldInc );
+ const Attendee::Ptr oldMe = oldInc->attendeeByMails( myEmails );
+ const Attendee::Ptr newMe = newInc->attendeeByMails( myEmails );
+
+ return oldMe && newMe && oldMe->status() != newMe->status();
+}
+
IncidenceChanger::IncidenceChanger( QObject *parent ) : QObject( parent )
, d( new Private( \
/**history=*/true, this ) ) {
@@ -905,6 +1068,16 @@ History* IncidenceChanger::history() const
return d->mHistory;
}
+void IncidenceChanger::setGroupwareCommuniation( bool enabled )
+{
+ d->mGroupwareCommunication = enabled;
+}
+
+bool IncidenceChanger::groupwareCommunication() const
+{
+ return d->mGroupwareCommunication;
+}
+
QString IncidenceChanger::Private::showErrorDialog( IncidenceChanger::ResultCode \
resultCode, QWidget *parent )
{
diff --git a/akonadi/calendar/incidencechanger.h \
b/akonadi/calendar/incidencechanger.h index 05f8722..0f3568f 100644
--- a/akonadi/calendar/incidencechanger.h
+++ b/akonadi/calendar/incidencechanger.h
@@ -311,6 +311,9 @@ class AKONADI_CALENDAR_EXPORT IncidenceChanger : public QObject
*/
History* history() const;
+ void setGroupwareCommuniation( bool enabled );
+ bool groupwareCommunication() const;
+
Q_SIGNALS:
/**
* Emitted when IncidenceChanger creates an Incidence in akonadi.
diff --git a/akonadi/calendar/incidencechanger_p.h \
b/akonadi/calendar/incidencechanger_p.h index 9e59468..04dbdcc 100644
--- a/akonadi/calendar/incidencechanger_p.h
+++ b/akonadi/calendar/incidencechanger_p.h
@@ -25,6 +25,7 @@
#define AKONADI_INCIDENCECHANGER_P_H
#include "incidencechanger.h"
+#include "invitationhandler_p.h"
#include "history.h"
#include <Akonadi/Item>
@@ -273,6 +274,12 @@ class IncidenceChanger::Private : public QObject
void cleanupTransaction();
bool allowAtomicOperation( int atomicOperationId, const Change::Ptr &change ) \
const;
+ bool handleInvitationsBeforeChange( const Change::Ptr &change );
+ bool handleInvitationsAfterChange( const Change::Ptr &change );
+ static bool myAttendeeStatusChanged( const KCalCore::Incidence::Ptr \
&newIncidence, + const \
KCalCore::Incidence::Ptr &oldIncidence, + \
const QStringList &myEmails ); +
public Q_SLOTS:
void handleCreateJobResult( KJob* );
void handleModifyJobResult( KJob* );
@@ -314,8 +321,10 @@ class IncidenceChanger::Private : public QObject
QHash<uint,AtomicOperation*> mAtomicOperations;
bool mRespectsCollectionRights;
+ bool mGroupwareCommunication;
QHash<Akonadi::TransactionSequence*, uint> mAtomicOperationByTransaction;
+ QHash<uint,InvitationHandler::SendResult> mInvitationStatusByAtomicOperation;
uint mLatestAtomicOperationId;
bool mBatchOperationInProgress;
diff --git a/akonadi/calendar/invitationhandler_p.cpp \
b/akonadi/calendar/invitationhandler_p.cpp index b76cd6c..fd7853f 100644
--- a/akonadi/calendar/invitationhandler_p.cpp
+++ b/akonadi/calendar/invitationhandler_p.cpp
@@ -634,4 +634,14 @@ void InvitationHandler::onSchedulerFinished( \
MailScheduler::Result result, const success ? QString() : i18n( "Error: %1", \
errorMsg ) ); }
+QStringList InvitationHandler::allEmails() const
+{
+ return d->allEmails();
+}
+
+bool InvitationHandler::thatIsMe( const QString &email ) const
+{
+ return d->thatIsMe( email );
+}
+
#include "invitationhandler_p.moc"
diff --git a/akonadi/calendar/invitationhandler_p.h \
b/akonadi/calendar/invitationhandler_p.h index b18edf4..a6ce657 100644
--- a/akonadi/calendar/invitationhandler_p.h
+++ b/akonadi/calendar/invitationhandler_p.h
@@ -166,6 +166,9 @@ class InvitationHandler : public QObject
// Frees calendar if it doesn't have jobs running
void calendarJobFinished( bool success, const QString &errorString );
+ QStringList allEmails() const;
+ bool thatIsMe( const QString &email ) const;
+
Q_SIGNALS:
/**
This signal is emitted when an invitation for a counter proposal is sent.
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic