void EventArchiver::run(Calendar *calendar, const QDate &limitDate, QWidget *widget, bool withGUI, bool errorIfNone) { // We need to use rawEvents, otherwise events hidden by filters will not be archived. Incidence::List incidences; Event::List events; Todo::List todos; Journal::List journals; if(KOPrefs::instance()->mArchiveEvents) { events = calendar->rawEvents( QDate(1769, 12, 1), // #29555, also advertised by the "limitDate not included" in the class docu limitDate.addDays(-1), true); } if(KOPrefs::instance()->mArchiveTodos) { Todo::List t = calendar->rawTodos(); Todo::List::ConstIterator it; for(it = t.begin(); it != t.end(); ++it) { if((*it) && ((*it)->isCompleted()) && ((*it)->completed().date() < limitDate)) { todos.append(*it); } } } incidences = Calendar::mergeIncidenceList(events, todos, journals); kdDebug(5850) << "EventArchiver: archiving incidences before " << limitDate << " -> " << incidences.count() << " incidences found." << endl; if(incidences.isEmpty()) { if(withGUI && errorIfNone) KMessageBox::information(widget, i18n("There are no items before %1") .arg(KGlobal::locale()->formatDate(limitDate)), "ArchiverNoIncidences"); return; } switch(KOPrefs::instance()->mArchiveAction) { case KOPrefs::actionDelete: deleteIncidences(calendar, limitDate, widget, incidences, withGUI); break; case KOPrefs::actionArchive: archiveIncidences(calendar, limitDate, widget, incidences, withGUI); break; } }
Incidence::Ptr DndFactory::pasteIncidence( const KDateTime &newDateTime, const QFlags<PasteFlag> &pasteOptions ) { QClipboard *clipboard = QApplication::clipboard(); MemoryCalendar::Ptr calendar( createDropCalendar( clipboard->mimeData() ) ); if ( !calendar ) { kDebug() << "Can't parse clipboard"; return Incidence::Ptr(); } Incidence::List incidenceList = calendar->incidences(); Incidence::Ptr incidence = incidenceList.isEmpty() ? Incidence::Ptr() : incidenceList.first(); return d->pasteIncidence( incidence, newDateTime, pasteOptions ); }
Incidence *DndFactory::pasteIncidence( const QDate &newDate, const QTime *newTime ) { QClipboard *cb = QApplication::clipboard(); Calendar *cal = createDropCalendar( cb->mimeData() ); if ( !cal ) { kDebug() << "Can't parse clipboard"; return 0; } Incidence::List incList = cal->incidences(); Incidence *inc = incList.isEmpty() ? 0 : incList.first(); Incidence *newInc = d->pasteIncidence( inc, newDate, newTime ); newInc->setRelatedTo( 0 ); return newInc; }
void KCalResourceSlox::uploadIncidences() { QDomDocument doc; QDomElement ms = WebdavHandler::addDavElement( doc, doc, "multistatus" ); QDomElement pu = WebdavHandler::addDavElement( doc, ms, "propertyupdate" ); QDomElement set = WebdavHandler::addElement( doc, pu, "D:set" ); QDomElement prop = WebdavHandler::addElement( doc, set, "D:prop" ); mUploadIsDelete = false; Incidence::List added = addedIncidences(); Incidence::List changed = changedIncidences(); Incidence::List deleted = deletedIncidences(); if ( !added.isEmpty() ) { mUploadedIncidence = added.first(); } else if ( !changed.isEmpty() ) { mUploadedIncidence = changed.first(); } else if ( !deleted.isEmpty() ) { mUploadedIncidence = deleted.first(); mUploadIsDelete = true; } else { mUploadedIncidence = 0; kDebug() << "FINISHED"; emit resourceSaved( this ); return; } // Don't try to upload recurring incidences as long as the resource doesn't // correctly write them in order to avoid corrupting data on the server. // FIXME: Remove when recurrences are correctly written. if ( mUploadedIncidence->recurs() && type() == "slox" ) { clearChange( mUploadedIncidence ); uploadIncidences(); return; } KUrl url = mPrefs->url(); QString sloxId = mUploadedIncidence->customProperty( "SLOX", "ID" ); if ( !sloxId.isEmpty() ) { WebdavHandler::addSloxElement( this, doc, prop, fieldName( ObjectId ), sloxId ); } else { if ( mUploadIsDelete ) { kError() << "Incidence to delete doesn't have a SLOX id"; clearChange( mUploadedIncidence ); uploadIncidences(); return; } } WebdavHandler::addSloxElement( this, doc, prop, fieldName( ClientId ), mUploadedIncidence->uid() ); if ( type() == "ox" ) { const QString lastModified = mUploadedIncidence->customProperty( "SLOX", "LastModified" ); WebdavHandler::addSloxElement( this, doc, prop, fieldName( LastModified ), lastModified ); } if ( mUploadIsDelete ) { if ( mUploadedIncidence->type() == "Event" ) { url.setPath( "/servlet/webdav.calendar/" + sloxId ); } else if ( mUploadedIncidence->type() == "Todo" ) { url.setPath( "/servlet/webdav.tasks/" + sloxId ); } else { kWarning() << "Unsupported incidence type:" << mUploadedIncidence->type(); return; } if ( type() == "ox" ) { WebdavHandler::addSloxElement( this, doc, prop, "method", "DELETE" ); if ( mUploadedIncidence->type() == "Event" ) WebdavHandler::addSloxElement( this, doc, prop, fieldName( FolderId ), mPrefs->calendarFolderId() ); else if ( mUploadedIncidence->type() == "Todo" ) WebdavHandler::addSloxElement( this, doc, prop, fieldName( FolderId ), mPrefs->taskFolderId() ); } else { QDomElement remove = WebdavHandler::addElement( doc, pu, "D:remove" ); QDomElement prop = WebdavHandler::addElement( doc, remove, "D:prop" ); WebdavHandler::addSloxElement( this, doc, prop, "sloxid", sloxId ); } } else { createIncidenceAttributes( doc, prop, mUploadedIncidence ); // FIXME: Use a visitor if ( mUploadedIncidence->type() == "Event" ) { url.setPath( "/servlet/webdav.calendar/file.xml" ); createEventAttributes( doc, prop, static_cast<Event *>( mUploadedIncidence ) ); // TODO: OX supports recurrences also for tasks createRecurrenceAttributes( doc, prop, mUploadedIncidence ); } else if ( mUploadedIncidence->type() == "Todo" ) { url.setPath( "/servlet/webdav.tasks/file.xml" ); createTodoAttributes( doc, prop, static_cast<Todo *>( mUploadedIncidence ) ); } else { kWarning() << "Unsupported incidence type:" << mUploadedIncidence->type(); return; } } url.setUser( mPrefs->user() ); url.setPass( mPrefs->password() ); kDebug() << url; kDebug() << "UPLOAD:" << doc.toString( 2 ); mUploadJob = KIO::davPropPatch( url, doc, KIO::HideProgressInfo ); connect( mUploadJob, SIGNAL( result( KJob * ) ), SLOT( slotUploadResult( KJob * ) ) ); connect( mUploadJob, SIGNAL( percent( KJob *, unsigned long ) ), SLOT( slotUploadProgress( KJob *, unsigned long ) ) ); mUploadProgress = KPIM::ProgressManager::instance()->createProgressItem( KPIM::ProgressManager::getUniqueID(), i18n("Uploading incidence") ); connect( mUploadProgress, SIGNAL( progressItemCanceled( KPIM::ProgressItem * ) ), SLOT( cancelUpload() ) ); }
CallId Scheduler::acceptRequest( const IncidenceBase::Ptr &incidence, ScheduleMessage::Status status, const QString &email ) { Incidence::Ptr inc = incidence.staticCast<Incidence>() ; if ( !inc ) { kWarning() << "Accept what?"; return -1; } const CallId callId = ++d->mLatestCallId; ResultCode resultCode = ResultCodeSuccess; QString errorMessage; if ( inc->type() == IncidenceBase::TypeFreeBusy ) { emitOperationFinished( callId, ResultCodeSuccess, QString() ); // reply to this request is handled in korganizer's incomingdialog return callId; } const Incidence::List existingIncidences = d->mCalendar->incidencesFromSchedulingID( inc->uid() ); kDebug() << "status=" << Stringify::scheduleMessageStatus( status ) //krazy:exclude=kdebug << ": found " << existingIncidences.count() << " incidences with schedulingID " << inc->schedulingID() << "; uid was = " << inc->uid(); if ( existingIncidences.isEmpty() ) { // Perfectly normal if the incidence doesn't exist. This is probably // a new invitation. kDebug() << "incidence not found; calendar = " << d->mCalendar.data() << "; incidence count = " << d->mCalendar->incidences().count(); } Incidence::List::ConstIterator incit = existingIncidences.begin(); for ( ; incit != existingIncidences.end() ; ++incit ) { Incidence::Ptr existingIncidence = *incit; kDebug() << "Considering this found event (" << ( existingIncidence->isReadOnly() ? "readonly" : "readwrite" ) << ") :" << d->mFormat->toString( existingIncidence ); // If it's readonly, we can't possible update it. if ( existingIncidence->isReadOnly() ) { continue; } if ( existingIncidence->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 " << existingIncidence->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 Attendee::List attendees = existingIncidence->attendees(); 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 " << existingIncidence->uid() << " since I'm still NeedsAction there"; isUpdate = false; break; } } if ( isUpdate ) { if ( existingIncidence->revision() == inc->revision() && existingIncidence->lastModified() > inc->lastModified() ) { // This isn't an update - the found incidence was modified more recently deleteTransaction( existingIncidence->uid() ); errorMessage = QLatin1String( "This isn't an update - " "the found incidence was modified more recently" ); kDebug() << errorMessage; emitOperationFinished( callId, ResultCodeNotUpdate, errorMessage ); return callId; } kDebug() << "replacing existing incidence " << existingIncidence->uid(); bool emitResult = true; const QString oldUid = existingIncidence->uid(); if ( existingIncidence->type() != inc->type() ) { errorMessage = QLatin1String( "Cannot assign two different incidence types" ); resultCode = ResultCodeDifferentIncidenceTypes; } else { IncidenceBase *existingIncidenceBase = existingIncidence.data(); IncidenceBase *incBase = inc.data(); *existingIncidenceBase = *incBase; existingIncidence->setSchedulingID( inc->uid(), oldUid ); Akonadi::Item item = d->mCalendar->itemForIncidenceUid( oldUid ); item.setPayload<Incidence::Ptr>( existingIncidence ); if ( item.isValid() ) { const int changeId = d->mChanger->modifyIncidence( item ); if ( changeId >= 0 ) { d->mCallIdByChangeId.insert( changeId, callId ); emitResult = false; // will be emitted in the job result's slot. } else { resultCode = ResultCodeErrorUpdatingIncidence; errorMessage = QLatin1String( "Error while trying to update the incidence" ); } } else { resultCode = ResultCodeIncidenceNotFound; errorMessage = QLatin1String( "Couldn't find incidence in calendar" ); } } if ( emitResult ) { deleteTransaction( incidence->uid() ); emitOperationFinished( callId, resultCode, errorMessage ); } return callId; } } else { // This isn't an update - the found incidence has a bigger revision number deleteTransaction( incidence->uid() ); errorMessage = QLatin1String( "This isn't an update - " "the found incidence has a bigger revision number" ); kDebug() << errorMessage; emitOperationFinished( callId, ResultCodeNotUpdate, errorMessage ); return callId; } } // Move the uid to be the schedulingID and make a unique UID inc->setSchedulingID( inc->uid(), CalFormat::createUniqueId() ); // notify the user in case this is an update and we didn't find the to-be-updated incidence if ( existingIncidences.count() == 0 && inc->revision() > 0 ) { KMessageBox::information( 0, i18nc( "@info", "<para>You accepted an invitation update, but an earlier version of the " "item could not be found in your calendar.</para>" "<para>This may have occurred because:<list>" "<item>the organizer did not include you in the original invitation</item>" "<item>you did not accept the original invitation yet</item>" "<item>you deleted the original invitation from your calendar</item>" "<item>you no longer have access to the calendar containing the invitation</item>" "</list></para>" "<para>This is not a problem, but we thought you should know.</para>" ), i18nc( "@title", "Cannot find invitation to be updated" ), "AcceptCantFindIncidence" ); } kDebug() << "Storing new incidence with scheduling uid=" << inc->schedulingID() << " and uid=" << inc->uid(); const int changeId = d->mChanger->createIncidence( inc ); if ( changeId > 0 ) { d->mCallIdByChangeId[changeId] = callId; } else { emitOperationFinished( callId, ResultCodeErrorCreatingIncidence, QLatin1String( "Error creating incidence" ) ); } return callId; }