static bool compareUids(const QStringList &_uids, const Incidence::List &incidences) { QStringList uids = _uids; foreach(const KCalCore::Incidence::Ptr &incidence, incidences) { if (uids.contains(incidence->uid())) uids.removeAll(incidence->uid()); } if (uids.isEmpty() && _uids.count() == incidences.count()) { return true; } else { qDebug() << uids.count() << incidences.count(); return false; } }
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; } }
CallId Scheduler::acceptCancel( const IncidenceBase::Ptr &incidence, ScheduleMessage::Status status, const QString &attendee ) { Incidence::Ptr inc = incidence.staticCast<Incidence>(); if ( !inc ) { return -1; } const CallId callId = ++d->mLatestCallId; ResultCode resultCode = ResultCodeSuccess; QString errorMessage; if ( inc->type() == IncidenceBase::TypeFreeBusy ) { // reply to this request is handled in korganizer's incomingdialog emitOperationFinished( callId, resultCode, errorMessage ); return callId; } const Incidence::List existingIncidences = d->mCalendar->incidencesFromSchedulingID( inc->uid() ); kDebug() << "Scheduler::acceptCancel=" << Stringify::scheduleMessageStatus( status ) //krazy2:exclude=kdebug << ": found " << existingIncidences.count() << " incidences with schedulingID " << inc->schedulingID(); Incidence::List::ConstIterator incit = existingIncidences.begin(); for ( ; incit != existingIncidences.end() ; ++incit ) { Incidence::Ptr i = *incit; kDebug() << "Considering this found event (" << ( i->isReadOnly() ? "readonly" : "readwrite" ) << ") :" << d->mFormat->toString( i ); // If it's readonly, we can't possible remove it. if ( i->isReadOnly() ) { continue; } // Code for new invitations: // We cannot check the value of "status" to be RequestNew because // "status" 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. bool isMine = true; const Attendee::List attendees = i->attendees(); Attendee::List::ConstIterator ait; for ( ait = attendees.begin(); ait != attendees.end(); ++ait ) { if ( (*ait)->email() == attendee && (*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"; isMine = false; break; } } if ( isMine ) { //TODO_SERGIO: use ItemDeleteJob and make this async. kDebug() << "removing existing incidence " << i->uid(); Akonadi::Item item = d->mCalendar->itemForIncidenceUid( i->uid() ); bool emitResult = true; if ( item.isValid() ) { const int changeId = d->mChanger->deleteIncidence( item ); if ( changeId >= 0 ) { d->mCallIdByChangeId.insert( changeId, callId ); d->mDeletedIncidenceByChangeId.insert( changeId, i ); emitResult = false; // will be emitted in the job result's slot. } else { resultCode = ResultCodeErrorDeletingIncidence; errorMessage = QLatin1String( "Error while trying to delete the incidence" ); } } else { resultCode = ResultCodeIncidenceNotFound; errorMessage = QLatin1String( "Couldn't find incidence in calendar" ); } if ( emitResult ) { deleteTransaction( incidence->uid() ); errorMessage = QLatin1String( "Error deleting incidence" ); emitOperationFinished( callId, resultCode, errorMessage ); } return callId; } } // in case we didn't find the to-be-removed incidence if ( existingIncidences.count() > 0 && inc->revision() > 0 ) { KMessageBox::error( 0, i18nc( "@info", "The event or task could not be removed from your calendar. " "Maybe it has already been deleted or is not owned by you. " "Or it might belong to a read-only or disabled calendar." ) ); resultCode = ResultCodeIncidenceNotFound; errorMessage = QLatin1String( "Incidence not found" ); } deleteTransaction( incidence->uid() ); emitOperationFinished( callId, resultCode, errorMessage ); return callId; }
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; }
void HtmlExport::createTodo (QTextStream *ts,Todo *todo) { kdDebug(5850) << "HtmlExport::createTodo()" << endl; bool completed = todo->isCompleted(); Incidence::List relations = todo->relations(); *ts << "<tr>\n"; *ts << " <td class=\"sum"; if (completed) *ts << "done"; *ts << "\">\n"; *ts << " <a name=\"" << todo->uid() << "\"></a>\n"; *ts << " <b>" << cleanChars(todo->summary()) << "</b>\n"; if (!todo->description().isEmpty()) { *ts << " <p>" << breakString(cleanChars(todo->description())) << "</p>\n"; } if (relations.count()) { *ts << " <div align=\"right\"><a href=\"#sub" << todo->uid() << "\">" << i18n("Sub-Tasks") << "</a></div>\n"; } *ts << " </td>\n"; *ts << " <td"; if (completed) *ts << " class=\"done\""; *ts << ">\n"; *ts << " " << todo->priority() << "\n"; *ts << " </td>\n"; *ts << " <td"; if (completed) *ts << " class=\"done\""; *ts << ">\n"; *ts << " " << i18n("%1 %").arg(todo->percentComplete()) << "\n"; *ts << " </td>\n"; if ( mSettings->taskDueDate() ) { *ts << " <td"; if (completed) *ts << " class=\"done\""; *ts << ">\n"; if (todo->hasDueDate()) { *ts << " " << todo->dtDueDateStr() << "\n"; } else { *ts << " \n"; } *ts << " </td>\n"; } if ( mSettings->taskLocation() ) { *ts << " <td"; if (completed) *ts << " class=\"done\""; *ts << ">\n"; formatLocation(ts,todo); *ts << " </td>\n"; } if ( mSettings->taskCategories() ) { *ts << " <td"; if (completed) *ts << " class=\"done\""; *ts << ">\n"; formatCategories(ts,todo); *ts << " </td>\n"; } if ( mSettings->taskAttendees() ) { *ts << " <td"; if (completed) *ts << " class=\"done\""; *ts << ">\n"; formatAttendees(ts,todo); *ts << " </td>\n"; } *ts << "</tr>\n"; }
void HtmlExport::createTodoList ( QTextStream *ts ) { Todo::List rawTodoList = mCalendar->todos(); Todo::List::Iterator it = rawTodoList.begin(); while ( it != rawTodoList.end() ) { Todo *ev = *it; Todo *subev = ev; if ( ev->relatedTo() ) { if ( ev->relatedTo()->type()=="Todo" ) { if ( rawTodoList.find( static_cast<Todo *>( ev->relatedTo() ) ) == rawTodoList.end() ) { rawTodoList.append( static_cast<Todo *>( ev->relatedTo() ) ); } } } it = rawTodoList.find( subev ); ++it; } // FIXME: Sort list by priorities. This is brute force and should be // replaced by a real sorting algorithm. Todo::List todoList; for ( int i = 1; i <= 9; ++i ) { for( it = rawTodoList.begin(); it != rawTodoList.end(); ++it ) { if ( (*it)->priority() == i && checkSecrecy( *it ) ) { todoList.append( *it ); } } } for( it = rawTodoList.begin(); it != rawTodoList.end(); ++it ) { if ( (*it)->priority() == 0 && checkSecrecy( *it ) ) { todoList.append( *it ); } } int columns = 3; *ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">\n"; *ts << " <tr>\n"; *ts << " <th class=\"sum\">" << i18n("Task") << "</th>\n"; *ts << " <th>" << i18n("Priority") << "</th>\n"; *ts << " <th>" << i18n("Completed") << "</th>\n"; if ( mSettings->taskDueDate() ) { *ts << " <th>" << i18n("Due Date") << "</th>\n"; ++columns; } if ( mSettings->taskLocation() ) { *ts << " <th>" << i18n("Location") << "</th>\n"; ++columns; } if ( mSettings->taskCategories() ) { *ts << " <th>" << i18n("Categories") << "</th>\n"; ++columns; } if ( mSettings->taskAttendees() ) { *ts << " <th>" << i18n("Attendees") << "</th>\n"; ++columns; } *ts << " </tr>\n"; // Create top-level list. for( it = todoList.begin(); it != todoList.end(); ++it ) { if ( !(*it)->relatedTo() ) createTodo( ts, *it ); } // Create sub-level lists for( it = todoList.begin(); it != todoList.end(); ++it ) { Incidence::List relations = (*it)->relations(); if (relations.count()) { // Generate sub-task list of event ev *ts << " <tr>\n"; *ts << " <td class=\"subhead\" colspan="; *ts << "\"" << QString::number(columns) << "\""; *ts << "><a name=\"sub" << (*it)->uid() << "\"></a>" << i18n("Sub-Tasks of: ") << "<a href=\"#" << (*it)->uid() << "\"><b>" << cleanChars( (*it)->summary()) << "</b></a></td>\n"; *ts << " </tr>\n"; Todo::List sortedList; // FIXME: Sort list by priorities. This is brute force and should be // replaced by a real sorting algorithm. for ( int i = 1; i <= 9; ++i ) { Incidence::List::ConstIterator it2; for( it2 = relations.begin(); it2 != relations.end(); ++it2 ) { Todo *ev3 = dynamic_cast<Todo *>( *it2 ); if ( ev3 && ev3->priority() == i ) sortedList.append( ev3 ); } } Incidence::List::ConstIterator it2; for( it2 = relations.begin(); it2 != relations.end(); ++it2 ) { Todo *ev3 = dynamic_cast<Todo *>( *it2 ); if ( ev3 && ev3->priority() == 0 ) sortedList.append( ev3 ); } Todo::List::ConstIterator it3; for( it3 = sortedList.begin(); it3 != sortedList.end(); ++it3 ) { createTodo( ts, *it3 ); } } } *ts << "</table>\n"; }
void HtmlExport::createTodo(QTextStream *ts, const Todo::Ptr &todo) { qCDebug(KCALUTILS_LOG); const bool completed = todo->isCompleted(); Incidence::List relations = d->mCalendar->relations(todo->uid()); *ts << "<tr>" << endl; *ts << " <td class=\"sum"; if (completed) { *ts << "done"; } *ts << "\">" << endl; *ts << " <a name=\"" << todo->uid() << "\"></a>" << endl; *ts << " <b>" << cleanChars(todo->summary()) << "</b>" << endl; if (!todo->description().isEmpty()) { *ts << " <p>" << breakString(cleanChars(todo->description())) << "</p>" << endl; } if (relations.count()) { *ts << " <div align=\"right\"><a href=\"#sub" << todo->uid() << "\">" << i18nc("@title:column sub-to-dos of the parent to-do", "Sub-To-dos") << "</a></div>" << endl; } *ts << " </td>" << endl; *ts << " <td"; if (completed) { *ts << " class=\"done\""; } *ts << ">" << endl; *ts << " " << todo->priority() << endl; *ts << " </td>" << endl; *ts << " <td"; if (completed) { *ts << " class=\"done\""; } *ts << ">" << endl; *ts << " " << i18nc("@info to-do percent complete", "%1 %", todo->percentComplete()) << endl; *ts << " </td>" << endl; if (d->mSettings->taskDueDate()) { *ts << " <td"; if (completed) { *ts << " class=\"done\""; } *ts << ">" << endl; if (todo->hasDueDate()) { *ts << " " << Stringify::formatDate(todo->dtDue(true)) << endl; } else { *ts << " " << endl; } *ts << " </td>" << endl; } if (d->mSettings->taskLocation()) { *ts << " <td"; if (completed) { *ts << " class=\"done\""; } *ts << ">" << endl; formatLocation(ts, todo); *ts << " </td>" << endl; } if (d->mSettings->taskCategories()) { *ts << " <td"; if (completed) { *ts << " class=\"done\""; } *ts << ">" << endl; formatCategories(ts, todo); *ts << " </td>" << endl; } if (d->mSettings->taskAttendees()) { *ts << " <td"; if (completed) { *ts << " class=\"done\""; } *ts << ">" << endl; formatAttendees(ts, todo); *ts << " </td>" << endl; } *ts << "</tr>" << endl; }
void HtmlExport::createTodoList(QTextStream *ts) { Todo::List rawTodoList = d->mCalendar->todos(); int index = 0; while (index < rawTodoList.count()) { Todo::Ptr ev = rawTodoList[ index ]; Todo::Ptr subev = ev; const QString uid = ev->relatedTo(); if (!uid.isEmpty()) { Incidence::Ptr inc = d->mCalendar->incidence(uid); if (inc && inc->type() == Incidence::TypeTodo) { Todo::Ptr todo = inc.staticCast<Todo>(); if (!rawTodoList.contains(todo)) { rawTodoList.append(todo); } } } index = rawTodoList.indexOf(subev); ++index; } // FIXME: Sort list by priorities. This is brute force and should be // replaced by a real sorting algorithm. Todo::List todoList; Todo::List::ConstIterator it; for (int i = 1; i <= 9; ++i) { for (it = rawTodoList.constBegin(); it != rawTodoList.constEnd(); ++it) { if ((*it)->priority() == i && checkSecrecy(*it)) { todoList.append(*it); } } } for (it = rawTodoList.constBegin(); it != rawTodoList.constEnd(); ++it) { if ((*it)->priority() == 0 && checkSecrecy(*it)) { todoList.append(*it); } } int columns = 3; *ts << "<table border=\"0\" cellpadding=\"3\" cellspacing=\"3\">" << endl; *ts << " <tr>" << endl; *ts << " <th class=\"sum\">" << i18nc("@title:column", "To-do") << "</th>" << endl; *ts << " <th>" << i18nc("@title:column to-do priority", "Priority") << "</th>" << endl; *ts << " <th>" << i18nc("@title:column to-do percent completed", "Completed") << "</th>" << endl; if (d->mSettings->taskDueDate()) { *ts << " <th>" << i18nc("@title:column to-do due date", "Due Date") << "</th>" << endl; ++columns; } if (d->mSettings->taskLocation()) { *ts << " <th>" << i18nc("@title:column to-do location", "Location") << "</th>" << endl; ++columns; } if (d->mSettings->taskCategories()) { *ts << " <th>" << i18nc("@title:column to-do categories", "Categories") << "</th>" << endl; ++columns; } if (d->mSettings->taskAttendees()) { *ts << " <th>" << i18nc("@title:column to-do attendees", "Attendees") << "</th>" << endl; ++columns; } *ts << " </tr>" << endl; // Create top-level list. for (it = todoList.constBegin(); it != todoList.constEnd(); ++it) { if ((*it)->relatedTo().isEmpty()) { createTodo(ts, *it); } } // Create sub-level lists for (it = todoList.constBegin(); it != todoList.constEnd(); ++it) { Incidence::List relations = d->mCalendar->relations((*it)->uid()); if (relations.count()) { // Generate sub-to-do list *ts << " <tr>" << endl; *ts << " <td class=\"subhead\" colspan="; *ts << "\"" << QString::number(columns) << "\""; *ts << "><a name=\"sub" << (*it)->uid() << "\"></a>" << i18nc("@title:column sub-to-dos of the parent to-do", "Sub-To-dos of: ") << "<a href=\"#" << (*it)->uid() << "\"><b>" << cleanChars((*it)->summary()) << "</b></a></td>" << endl; *ts << " </tr>" << endl; Todo::List sortedList; // FIXME: Sort list by priorities. This is brute force and should be // replaced by a real sorting algorithm. for (int i = 1; i <= 9; ++i) { Incidence::List::ConstIterator it2; for (it2 = relations.constBegin(); it2 != relations.constEnd(); ++it2) { Todo::Ptr ev3 = (*it2).staticCast<Todo>(); if (ev3 && ev3->priority() == i) { sortedList.append(ev3); } } } Incidence::List::ConstIterator it2; for (it2 = relations.constBegin(); it2 != relations.constEnd(); ++it2) { Todo::Ptr ev3 = (*it2).staticCast<Todo>(); if (ev3 && ev3->priority() == 0) { sortedList.append(ev3); } } Todo::List::ConstIterator it3; for (it3 = sortedList.constBegin(); it3 != sortedList.constEnd(); ++it3) { createTodo(ts, *it3); } } } *ts << "</table>" << endl; }