[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    branches/kdepim/enterprise4
From:       Allen Winter <winter () kde ! org>
Date:       2009-07-23 17:57:10
Message-ID: 1248371830.108058.6931.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 1001591 by winterz:

Merged revisions 1001496 via svnmerge from 
https://svn.kde.org/home/kde/branches/kdepim/enterprise/kdepim

........
  r1001496 | vkrause | 2009-07-23 09:05:16 -0400 (Thu, 23 Jul 2009) | 66 lines
  
  Merge the following stuff from the ancient proko2 branch. Should fix
  various issues with invitations if you have access to a calendar of
  aanother person that is also invited.
  
  Kolab issue 3724
  
  ------------------------------------------------------------------------
  r519272 | tilladam | 2006-03-16 19:35:12 +0100 (Thu, 16 Mar 2006) | 2 lines
  
  Change the buttons to "Store" and "Throw away" as requested.
  
  ------------------------------------------------------------------------
  r513844 | tilladam | 2006-02-26 18:59:04 +0100 (Sun, 26 Feb 2006) | 2 lines
  
  Make sure the transaction is cleaned up also in the error case.
  
  ------------------------------------------------------------------------
  r513842 | tilladam | 2006-02-26 18:53:37 +0100 (Sun, 26 Feb 2006) | 4 lines
  
  In case an update or cancel message is processed for an incidence that
  cannot be found, inform the user, instead of blindly adding a new
  version of the incidence. (proko2 issue 1128)
  
  ------------------------------------------------------------------------
  r365868 | dfaure | 2004-11-24 18:19:08 +0100 (Wed, 24 Nov 2004) | 2 lines
  
  Can't update readonly events.
  
  ------------------------------------------------------------------------
  r365849 | dfaure | 2004-11-24 17:12:01 +0100 (Wed, 24 Nov 2004) | 4 lines
  
  Looking at the status is too unreliable since we have several versions of the event
  and libical gets confused - the whole point of this code is to do the equivalent
  with some more logic.
  
  ------------------------------------------------------------------------
  r365838 | dfaure | 2004-11-24 16:17:15 +0100 (Wed, 24 Nov 2004) | 2 lines
  
  Reworked logic to actually fix issue526
  
  ------------------------------------------------------------------------
  r365807 | dfaure | 2004-11-24 14:26:14 +0100 (Wed, 24 Nov 2004) | 2 lines
  
  More debug output (to get more info out of michel)
  
  ------------------------------------------------------------------------
  r365223 | dfaure | 2004-11-22 21:24:57 +0100 (Mon, 22 Nov 2004) | 3 lines
  
  Tentative fix for https://intevation.de/roundup/kolab/issue526 as discussed with Till.
  The server died so full testing isn't possible tonight though.
  
  ------------------------------------------------------------------------
  r365196 | tilladam | 2004-11-22 20:22:17 +0100 (Mon, 22 Nov 2004) | 4 lines
  
  Add an additional const QString &attendee parameter to acceptTransaction
  and acceptRequests so that we can compare which of the attendees in the
  event is the one we are supposed to act upon.
  
  ------------------------------------------------------------------------
  r364294 | tilladam | 2004-11-19 18:03:43 +0100 (Fri, 19 Nov 2004) | 4 lines
  
  Add unknown attendees which did not appear in the original event as
  voluntary/optional attendees. This happens when people reply that were
  invited as part of a server side distribution list. Patch by Bo.
........


 M  +1 -1      kdepim/korganizer/kogroupware.cpp  
 M  +97 -26    kdepimlibs/kcal/scheduler.cpp  
 M  +9 -3      kdepimlibs/kcal/scheduler.h  


--- branches/kdepim/enterprise4/kdepim/korganizer/kogroupware.cpp #1001590:1001591
@@ -206,7 +206,7 @@
       }
     }
     if ( KOPrefs::instance()->outlookCompatCounterProposals() || !action.startsWith( "counter" ) )
-      scheduler.acceptTransaction( incidence, method, status );
+      scheduler.acceptTransaction( incidence, method, status, receiver );
   } else if ( action.startsWith( "cancel" ) ) {
     // Delete the old incidence, if one is present
     scheduler.acceptTransaction( incidence, KCal::iTIPCancel, status );
--- branches/kdepim/enterprise4/kdepimlibs/kcal/scheduler.cpp #1001590:1001591
@@ -135,8 +135,10 @@
   return d->mFreeBusyCache;
 }
 
-bool Scheduler::acceptTransaction( IncidenceBase *incidence, iTIPMethod method,
-                                   ScheduleMessage::Status status )
+bool Scheduler::acceptTransaction( IncidenceBase *incidence,
+                                   iTIPMethod method,
+                                   ScheduleMessage::Status status,
+                                   const QString &email )
 {
   kDebug() << "method=" << methodName( method );
 
@@ -144,7 +146,7 @@
   case iTIPPublish:
     return acceptPublish( incidence, status, method );
   case iTIPRequest:
-    return acceptRequest( incidence, status );
+    return acceptRequest( incidence, status, email );
   case iTIPAdd:
     return acceptAdd( incidence, status );
   case iTIPCancel:
@@ -260,36 +262,98 @@
   return res;
 }
 
-bool Scheduler::acceptRequest( IncidenceBase *newIncBase, ScheduleMessage::Status /* status */)
+bool Scheduler::acceptRequest( IncidenceBase *incidence,
+                               ScheduleMessage::Status status,
+                               const QString &email )
 {
-  if ( newIncBase->type() == "FreeBusy" ) {
+  Incidence *inc = static_cast<Incidence *>( incidence );
+  if ( !inc ) {
+    return false;
+  }
+   if ( inc->type() == "FreeBusy" ) {
     // reply to this request is handled in korganizer's incomingdialog
     return true;
   }
-  Incidence *newInc = dynamic_cast<Incidence *>( newIncBase );
-  if ( newInc ) {
-    bool res = true;
-    Incidence *exInc = mCalendar->incidenceFromSchedulingID( newIncBase->uid() );
-    if ( exInc ) {
-      res = false;
-      if ( ( newInc->revision() > exInc->revision() ) ||
-           ( newInc->revision() == exInc->revision() &&
-             newInc->lastModified()>exInc->lastModified() ) ) {
-        mCalendar->deleteIncidence( exInc );
-        res = true;
+
+  const Incidence::List existingIncidences = mCalendar->incidencesFromSchedulingID( inc->uid() );
+  kDebug() << "status=" << ScheduleMessage::statusName( status )
+           << ": found " << existingIncidences.count()
+           << " incidences with schedulingID " << inc->schedulingID();
+  Incidence::List::ConstIterator incit = existingIncidences.begin();
+  for ( ; incit != existingIncidences.end() ; ++incit ) {
+    Incidence *i = *incit;
+    kDebug() << "Considering this found event ("
+             << ( i->isReadOnly() ? "readonly" : "readwrite" )
+             << ") :" << mFormat->toString( i );
+    // If it's readonly, we can't possible update it.
+    if ( i->isReadOnly() ) {
+      continue;
+    }
+    if ( i->revision() <= inc->revision() ) {
+      // The new incidence might be an update for the found one
+      bool isUpdate = true;
+      // Code for new invitations:
+      // If you think we could check the value of "status" to be RequestNew:  we can't.
+      // It comes from a similar check inside libical, where the event is compared to
+      // other events in the calendar. But if we have another version of the event around
+      // (e.g. shared folder for a group), the status could be RequestNew, Obsolete or Updated.
+      kDebug() << "looking in " << i->uid() << "'s attendees";
+      // This is supposed to be a new request, not an update - however we want to update
+      // the existing one to handle the "clicking more than once on the invitation" case.
+      // So check the attendee status of the attendee.
+      const KCal::Attendee::List attendees = i->attendees();
+      KCal::Attendee::List::ConstIterator ait;
+      for ( ait = attendees.begin(); ait != attendees.end(); ++ait ) {
+        if( (*ait)->email() == email && (*ait)->status() == Attendee::NeedsAction ) {
+          // This incidence wasn't created by me - it's probably in a shared folder
+          // and meant for someone else, ignore it.
+          kDebug() << "ignoring " << i->uid() << " since I'm still NeedsAction there";
+          isUpdate = false;
+          break;
+        }
       }
+      if ( isUpdate ) {
+        if ( i->revision() == inc->revision() &&
+             i->lastModified() > inc->lastModified() ) {
+          // This isn't an update - the found incidence was modified more recently
+          kDebug() << "This isn't an update - the found incidence was modified more recently";
+          deleteTransaction( i );
+          return false;
+        }
+        kDebug() << "replacing existing incidence " << i->uid();
+        mCalendar->deleteIncidence( i );
+        break; // replacing one is enough
+      }
+    } else {
+      // This isn't an update - the found incidence has a bigger revision number
+      kDebug() << "This isn't an update - the found incidence has a bigger revision number";
+      deleteTransaction(incidence);
+      return false;
     }
-    if ( res ) {
-      // Move the uid to be the schedulingID and make a unique UID
-      newInc->setSchedulingID( newInc->uid() );
-      newInc->setUid( CalFormat::createUniqueId() );
+  }
 
-      mCalendar->addIncidence( newInc );
-    }
-    deleteTransaction( newIncBase );
-    return res;
+  // Move the uid to be the schedulingID and make a unique UID
+  inc->setSchedulingID( inc->uid() );
+  inc->setUid( CalFormat::createUniqueId() );
+  // in case this is an update and we didn't find the to-be-updated incidence,
+  // ask whether we should create a new one, or drop the update
+  if ( existingIncidences.count() > 0 || inc->revision() == 0 ||
+       KMessageBox::warningYesNo(
+         0,
+         i18nc( "@info",
+                "The event, to-do or journal to be updated could not be found. "
+                "Maybe it has already been deleted, or the calendar that "
+                "contains it is disabled. Press continue to create a new "
+                "one or 'throw away' to discard this update." ),
+         i18nc( "@title", "Discard this update?" ),
+         KGuiItem( i18nc( "@option", "Store" ) ),
+         KGuiItem( i18nc( "@option", "Throw away" ) ) ) == KMessageBox::Yes ) {
+    kDebug() << "Storing new incidence with scheduling uid=" << inc->schedulingID()
+             << " and uid=" << inc->uid();
+    mCalendar->addIncidence( inc );
   }
-  return false;
+  deleteTransaction(incidence);
+  return true;
 }
 
 bool Scheduler::acceptAdd( IncidenceBase *incidence, ScheduleMessage::Status /* status */)
@@ -302,7 +366,14 @@
 {
   bool ret = false;
   const IncidenceBase *toDelete = mCalendar->incidenceFromSchedulingID( incidence->uid() );
-  if ( toDelete ) {
+  if ( !toDelete ) {
+      KMessageBox::error(
+        0,
+        i18nc( "@info",
+               "The event, to-do or journal to be canceled could not be found. "
+               "Maybe it has already been deleted, or the calendar that "
+               "contains it is disabled." ) );
+  } else {
     Event *event = mCalendar->event( toDelete->uid() );
     if ( event ) {
       mCalendar->deleteEvent( event );
--- branches/kdepim/enterprise4/kdepimlibs/kcal/scheduler.h #1001590:1001591
@@ -165,11 +165,16 @@
       processing a iTIP message with the current calendar and specifies the
       action to be taken for this incidence.
 
+      @param incidence the incidence for the transaction.
       @param method iTIP transaction method to check.
       @param status scheduling status.
+      @param email the email address of the person for whom this
+      transaction is to be performed.
     */
-    bool acceptTransaction( IncidenceBase *, iTIPMethod method,
-                            ScheduleMessage::Status status );
+    bool acceptTransaction( IncidenceBase *incidence,
+                            iTIPMethod method,
+                            ScheduleMessage::Status status,
+                            const QString &email = QString() );
 
     /**
       Returns a machine-readable name for a iTIP method.
@@ -200,7 +205,8 @@
 
   protected:
     bool acceptPublish( IncidenceBase *, ScheduleMessage::Status status, iTIPMethod method );
-    bool acceptRequest( IncidenceBase *, ScheduleMessage::Status status );
+    bool acceptRequest( IncidenceBase *, ScheduleMessage::Status status,
+                        const QString &email );
     bool acceptAdd( IncidenceBase *, ScheduleMessage::Status status );
     bool acceptCancel( IncidenceBase *, ScheduleMessage::Status status );
     bool acceptDeclineCounter( IncidenceBase *, ScheduleMessage::Status status );
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic