void ResourceCached::cleanUpTodoCache(const Todo::List &todoList) { CalendarLocal calendar(QString::fromLatin1("UTC")); if(KStandardDirs::exists(cacheFile())) calendar.load(cacheFile()); else return; Todo::List list = calendar.todos(); Todo::List::ConstIterator cacheIt, it; for(cacheIt = list.begin(); cacheIt != list.end(); ++cacheIt) { bool found = false; for(it = todoList.begin(); it != todoList.end(); ++it) { if((*it)->uid() == (*cacheIt)->uid()) found = true; } if(!found) { mIdMapper.removeRemoteId(mIdMapper.remoteId((*cacheIt)->uid())); Todo *todo = mCalendar.todo((*cacheIt)->uid()); if(todo) mCalendar.deleteTodo(todo); } } calendar.close(); }
Incidence *ICalFormat::fromString(const QString &text) { CalendarLocal cal(mTimeZoneId); fromString(&cal, text); Incidence *ical = 0; Event::List elist = cal.events(); if(elist.count() > 0) { ical = elist.first(); } else { Todo::List tlist = cal.todos(); if(tlist.count() > 0) { ical = tlist.first(); } else { Journal::List jlist = cal.journals(); if(jlist.count() > 0) { ical = jlist.first(); } } } return ical ? ical->clone() : 0; }
Todo::List KOTodoView::selectedTodos() { Todo::List selected; KOTodoViewItem *item = (KOTodoViewItem *)(mTodoListView->selectedItem()); // if (!item) item = mActiveItem; if (item) selected.append(item->todo()); return selected; }
QString ICalFormat::toString(Calendar *cal) { setTimeZone(cal->timeZoneId(), !cal->isLocalTime()); icalcomponent *calendar = mImpl->createCalendarComponent(cal); icalcomponent *component; // todos Todo::List todoList = cal->rawTodos(); Todo::List::ConstIterator it; for(it = todoList.begin(); it != todoList.end(); ++it) { // kdDebug(5800) << "ICalFormat::toString() write todo " // << (*it)->uid() << endl; component = mImpl->writeTodo(*it); icalcomponent_add_component(calendar, component); } // events Event::List events = cal->rawEvents(); Event::List::ConstIterator it2; for(it2 = events.begin(); it2 != events.end(); ++it2) { // kdDebug(5800) << "ICalFormat::toString() write event " // << (*it2)->uid() << endl; component = mImpl->writeEvent(*it2); icalcomponent_add_component(calendar, component); } // journals Journal::List journals = cal->journals(); Journal::List::ConstIterator it3; for(it3 = journals.begin(); it3 != journals.end(); ++it3) { kdDebug(5800) << "ICalFormat::toString() write journal " << (*it3)->uid() << endl; component = mImpl->writeJournal(*it3); icalcomponent_add_component(calendar, component); } QString text = QString::fromUtf8(icalcomponent_as_ical_string(calendar)); icalcomponent_free(calendar); icalmemory_free_ring(); if(!text) { setException(new ErrorFormat(ErrorFormat::SaveError, i18n("libical error"))); return QString::null; } return text; }
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; } }
void KOTodoEditor::loadTemplate(/*const*/ CalendarLocal &cal) { Todo::List todos = cal.todos(); if(todos.count() == 0) { KMessageBox::error(this, i18n("Template does not contain a valid to-do.")); } else { readTodo(todos.first(), 0); } }
Todo::Ptr DndFactory::createDropTodo( const QMimeData *mimeData ) { //kDebug(); Todo::Ptr todo; MemoryCalendar::Ptr calendar( createDropCalendar( mimeData ) ); if ( calendar ) { Todo::List todos = calendar->todos(); if ( !todos.isEmpty() ) { todo = Todo::Ptr( new Todo( *todos.first() ) ); } } return todo; }
Todo *DndFactory::createDropTodo( const QMimeData *md ) { kDebug(); Todo *todo = 0; Calendar *cal = createDropCalendar( md ); if ( cal ) { Todo::List todos = cal->todos(); if ( !todos.isEmpty() ) { todo = new Todo( *todos.first() ); } delete cal; } return todo; }
void KOTodoView::updateView() { // kdDebug(5850) << "KOTodoView::updateView()" << endl; int oldPos = mTodoListView->contentsY(); mItemsToDelete.clear(); mTodoListView->clear(); Todo::List todoList = calendar()->todos(); /* kdDebug(5850) << "KOTodoView::updateView(): Todo List:" << endl; Event *t; for(t = todoList.first(); t; t = todoList.next()) { kdDebug(5850) << " " << t->getSummary() << endl; if (t->getRelatedTo()) { kdDebug(5850) << " (related to " << t->getRelatedTo()->getSummary() << ")" << endl; } QPtrList<Event> l = t->getRelations(); Event *c; for(c=l.first();c;c=l.next()) { kdDebug(5850) << " - relation: " << c->getSummary() << endl; } } */ // Put for each Event a KOTodoViewItem in the list view. Don't rely on a // specific order of events. That means that we have to generate parent items // recursively for proper hierarchical display of Todos. mTodoMap.clear(); Todo::List::ConstIterator it; for( it = todoList.begin(); it != todoList.end(); ++it ) { if ( !mTodoMap.contains( *it ) ) { insertTodoItem( *it ); } } // Restore opened/closed state mTodoListView->blockSignals( true ); if( mDocPrefs ) restoreItemState( mTodoListView->firstChild() ); mTodoListView->blockSignals( false ); mTodoListView->setContentsPos( 0, oldPos ); processSelectionChange(); }
/* I chose to use libkcal instead of reading the calendar manually. It's easier to maintain this way. */ STRIGI_ENDANALYZER_RETVAL IcsEndAnalyzer::analyze( Strigi::AnalysisResult& idx, Strigi::InputStream* in ) { CalendarLocal cal( QString::fromLatin1( "UTC" ) ); const char* data; //FIXME: large calendars will exhaust memory; incremental loading would be // nice qint32 nread = in->read( data, in->size(), in->size() ); if ( nread <= 0 ) { //kDebug() <<"Reading data from input stream failed"; return Strigi::Error; } ICalFormat ical; if ( !ical.fromRawString( &cal, QByteArray::fromRawData(data, nread) ) ) { VCalFormat vcal; if ( !vcal.fromRawString( &cal, data ) ) { //kDebug() <<"Could not load calendar"; return Strigi::Error; } } idx.addValue( m_factory->field( ProductId ), cal.productId().toUtf8().data() ); idx.addValue( m_factory->field( Events ), (quint32)cal.events().count() ); idx.addValue( m_factory->field( Journals ), (quint32)cal.journals().count() ); Todo::List todos = cal.todos(); // count completed and overdue int completed = 0; int overdue = 0; foreach ( const Todo* todo, todos ) { if ( todo->isCompleted() ) { ++completed; } else if ( todo->hasDueDate() && todo->dtDue().date() < QDate::currentDate() ) { ++overdue; } } idx.addValue( m_factory->field( Todos ), (quint32)todos.count() ); idx.addValue( m_factory->field( TodosCompleted ), (quint32)completed ); idx.addValue( m_factory->field( TodosOverdue ), (quint32)overdue ); cal.close(); return Strigi::Ok; }
void MemoryCalendarTest::testRelationsCrash() { // Before, there was a crash that occurred only when reloading a calendar in which // the incidences had special relations. // This test tests that scenario, and will crash if it fails. MemoryCalendar::Ptr cal( new MemoryCalendar( KDateTime::UTC ) ); FileStorage store1( cal, ICALTESTDATADIR "test_relations.ics" ); QVERIFY(store1.load()); const Todo::List oldTodos = cal->todos(); kDebug() << "Loaded " << oldTodos.count() << " todos into oldTodos."; FileStorage store2( cal, ICALTESTDATADIR "test_relations.ics" ); QVERIFY(store2.load()); const Todo::List newTodos = cal->todos(); kDebug() << "Loaded " << newTodos.count() << " into newTodos."; // We can saftely access the old deleted todos here, since they are not really deleted // and are still kept in a map of deleted items somewhere. // // Here we make sure that non of the old items have connections to the new items, and // the other way around. // This doesn't makes sense so i commented it. when you load a calendar the second time // it reuses what it can, so oldTodo == newTodo /* foreach ( Todo::Ptr oldTodo, oldTodos ) { foreach ( Todo::Ptr newTodo, newTodos ) { QVERIFY( oldTodo != newTodo ); // Make sure that none of the new todos point to an old, deleted todo QVERIFY( newTodo->relatedTo() != oldTodo ); QVERIFY( !newTodo->relations().contains( oldTodo ) ); // Make sure that none of the old todos point to a new todo QVERIFY( oldTodo->relatedTo() != newTodo ); QVERIFY( !oldTodo->relations().contains( newTodo ) ); } } */ cal->close(); }
Incidence::List Calendar::mergeIncidenceList(const Event::List &events, const Todo::List &todos, const Journal::List &journals) { Incidence::List incidences; Event::List::ConstIterator it1; for(it1 = events.begin(); it1 != events.end(); ++it1) incidences.append(*it1); Todo::List::ConstIterator it2; for(it2 = todos.begin(); it2 != todos.end(); ++it2) incidences.append(*it2); Journal::List::ConstIterator it3; for(it3 = journals.begin(); it3 != journals.end(); ++it3) incidences.append(*it3); return incidences; }
int main( int argc, char **argv ) { KAboutData aboutData( "testcalendar", 0, ki18n( "Test Calendar" ), "0.1" ); KCmdLineArgs::init( argc, argv, &aboutData ); KCmdLineOptions options; options.add( "verbose", ki18n( "Verbose output" ) ); KCmdLineArgs::addCmdLineOptions( options ); KComponentData componentData( &aboutData ); //QCoreApplication app( KCmdLineArgs::qtArgc(), KCmdLineArgs::qtArgv() ); KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); Q_UNUSED( args ); MemoryCalendar::Ptr cal( new MemoryCalendar( KDateTime::UTC ) ); FileStorage store( cal, "cal" ); store.load(); Todo::List todoList; // Build dictionary to look up Task object from Todo uid. Each task is a // QListViewItem, and is initially added with the view as the parent. todoList = cal->rawTodos(); kDebug() << ( *todoList.begin() )->uid(); QString result = ( *todoList.begin() )->customProperty( QByteArray( "karm" ), QByteArray( "totalTaskTime" ) ); kDebug() << result; if ( result != QString( "a,b" ) ) { kDebug() << "The string a,b was expected, but given was" << result; return 1; } else { kDebug() << "Test passed"; } }
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; }
void KOWhatsNextView::updateView() { KIconLoader kil("kdepim"); QString *ipath = new QString(); kil.loadIcon("kdepim",KIcon::NoGroup,32,KIcon::DefaultState,ipath); mText = "<table width=\"100%\">\n"; mText += "<tr bgcolor=\"#3679AD\"><td><h1>"; mText += "<img src=\""; mText += *ipath; mText += "\">"; mText += "<font color=\"white\"> "; mText += i18n("What's Next?") + "</font></h1>"; mText += "</td></tr>\n<tr><td>"; mText += "<h2>"; if ( mStartDate.daysTo( mEndDate ) < 1 ) { mText += KGlobal::locale()->formatDate( mStartDate ); } else { mText += i18n("Date from - to", "%1 - %2") .arg( KGlobal::locale()->formatDate( mStartDate ) ) .arg( KGlobal::locale()->formatDate( mEndDate ) ); } mText+="</h2>\n"; Event::List events; for ( QDate date = mStartDate; date <= mEndDate; date = date.addDays( 1 ) ) events += calendar()->events(date, EventSortStartDate, SortDirectionAscending); if (events.count() > 0) { mText += "<p></p>"; kil.loadIcon("appointment",KIcon::NoGroup,22,KIcon::DefaultState,ipath); mText += "<h2><img src=\""; mText += *ipath; mText += "\">"; mText += i18n("Events:") + "</h2>\n"; mText += "<table>\n"; Event::List::ConstIterator it; for( it = events.begin(); it != events.end(); ++it ) { Event *ev = *it; if ( !ev->doesRecur() ){ appendEvent(ev); } else { // FIXME: This should actually be cleaned up. Libkcal should // provide a method to return a list of all recurrences in a // given time span. Recurrence *recur = ev->recurrence(); int duration = ev->dtStart().secsTo( ev->dtEnd() ); QDateTime start = recur->getPreviousDateTime( QDateTime( mStartDate, QTime() ) ); QDateTime end = start.addSecs( duration ); if ( end.date() >= mStartDate ) { appendEvent( ev, start, end ); } start = recur->getNextDateTime( start ); while ( start.isValid() && start.date() <= mEndDate ) { appendEvent( ev, start ); start = recur->getNextDateTime( start ); } } } mText += "</table>\n"; } mTodos.clear(); Todo::List todos = calendar()->todos( TodoSortDueDate, SortDirectionAscending ); if ( todos.count() > 0 ) { kil.loadIcon("todo",KIcon::NoGroup,22,KIcon::DefaultState,ipath); mText += "<h2><img src=\""; mText += *ipath; mText += "\">"; mText += i18n("To-do:") + "</h2>\n"; mText += "<ul>\n"; Todo::List::ConstIterator it; for( it = todos.begin(); it != todos.end(); ++it ) { Todo *todo = *it; if ( !todo->isCompleted() && todo->hasDueDate() && todo->dtDue().date() <= mEndDate ) appendTodo(todo); } bool gotone = false; int priority = 1; while (!gotone && priority<=9 ) { for( it = todos.begin(); it != todos.end(); ++it ) { Todo *todo = *it; if (!todo->isCompleted() && (todo->priority() == priority) ) { appendTodo(todo); gotone = true; } } priority++; kdDebug(5850) << "adding the todos..." << endl; } mText += "</ul>\n"; } QStringList myEmails( KOPrefs::instance()->allEmails() ); int replies = 0; events = calendar()->events( QDate::currentDate(), QDate(2975,12,6) ); Event::List::ConstIterator it2; for( it2 = events.begin(); it2 != events.end(); ++it2 ) { Event *ev = *it2; Attendee *me = ev->attendeeByMails( myEmails ); if (me!=0) { if (me->status()==Attendee::NeedsAction && me->RSVP()) { if (replies == 0) { mText += "<p></p>"; kil.loadIcon("reply",KIcon::NoGroup,22,KIcon::DefaultState,ipath); mText += "<h2><img src=\""; mText += *ipath; mText += "\">"; mText += i18n("Events and to-dos that need a reply:") + "</h2>\n"; mText += "<table>\n"; } replies++; appendEvent( ev ); } } } todos = calendar()->todos(); Todo::List::ConstIterator it3; for( it3 = todos.begin(); it3 != todos.end(); ++it3 ) { Todo *to = *it3; Attendee *me = to->attendeeByMails( myEmails ); if (me!=0) { if (me->status()==Attendee::NeedsAction && me->RSVP()) { if (replies == 0) { mText += "<p></p>"; kil.loadIcon("reply",KIcon::NoGroup,22,KIcon::DefaultState,ipath); mText += "<h2><img src=\""; mText += *ipath; mText += "\">"; mText += i18n("Events and to-dos that need a reply:") + "</h2>\n"; mText += "<table>\n"; } replies++; appendEvent(to); } } kdDebug () << "check for todo-replies..." << endl; } if (replies > 0 ) mText += "</table>\n"; mText += "</td></tr>\n</table>\n"; kdDebug(5850) << "KOWhatsNextView::updateView: text: " << mText << endl; delete ipath; mView->setText(mText); }
void SearchDialog::search(const QRegExp &re) { QDate startDt = mStartDate->date(); QDate endDt = mEndDate->date(); Event::List events; if(mEventsCheck->isChecked()) { events = mCalendar->events(startDt, endDt, mInclusiveCheck->isChecked()); } Todo::List todos; if(mTodosCheck->isChecked()) { if(mIncludeUndatedTodos->isChecked()) { Todo::List alltodos = mCalendar->todos(); Todo::List::iterator it; Todo *todo; for(it = alltodos.begin(); it != alltodos.end(); ++it) { todo = *it; if((!todo->hasStartDate() && !todo->hasDueDate()) || // undated (todo->hasStartDate() && (todo->dtStart() >= startDt) && (todo->dtStart() <= endDt)) || // start dt in range (todo->hasDueDate() && (todo->dtDue().date() >= startDt) && (todo->dtDue() <= endDt)) || // due dt in range (todo->hasCompletedDate() && (todo->completed().date() >= startDt) && (todo->completed() <= endDt))) // completed dt in range { todos.append(todo); } } } else { QDate dt = startDt; while(dt <= endDt) { todos += mCalendar->todos(dt); dt = dt.addDays(1); } } } Journal::List journals; if(mJournalsCheck->isChecked()) { QDate dt = startDt; while(dt <= endDt) { journals += mCalendar->journals(dt); dt = dt.addDays(1); } } Incidence::List allIncidences = Calendar::mergeIncidenceList(events, todos, journals); mMatchedEvents.clear(); Incidence::List::ConstIterator it; for(it = allIncidences.begin(); it != allIncidences.end(); ++it) { Incidence *ev = *it; if(mSummaryCheck->isChecked()) { #if QT_VERSION >= 300 if(re.search(ev->summary()) != -1) { #else if(re.match(ev->summary()) != -1) { #endif mMatchedEvents.append(ev); continue; } } if(mDescriptionCheck->isChecked()) { #if QT_VERSION >= 300 if(re.search(ev->description()) != -1) { #else if(re.match(ev->description()) != -1) { #endif mMatchedEvents.append(ev); continue; } } if(mCategoryCheck->isChecked()) { #if QT_VERSION >= 300 if(re.search(ev->categoriesStr()) != -1) { #else if(re.match(ev->categoriesStr()) != -1) { #endif mMatchedEvents.append(ev); continue; } } } }
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"; }
Todo::List Calendar::sortTodos(Todo::List *todoList, TodoSortField sortField, SortDirection sortDirection) { Todo::List todoListSorted; Todo::List tempList, t; Todo::List alphaList; Todo::List::Iterator sortIt; Todo::List::Iterator eit; // Notice we alphabetically presort Summaries first. // We do this so comparison "ties" stay in a nice order. // Note that Todos may not have Start DateTimes nor due DateTimes. switch(sortField) { case TodoSortUnsorted: todoListSorted = *todoList; break; case TodoSortStartDate: alphaList = sortTodos(todoList, TodoSortSummary, sortDirection); for(eit = alphaList.begin(); eit != alphaList.end(); ++eit) { if((*eit)->hasStartDate()) { sortIt = todoListSorted.begin(); if(sortDirection == SortDirectionAscending) { while(sortIt != todoListSorted.end() && (*eit)->dtStart() >= (*sortIt)->dtStart()) { ++sortIt; } } else { while(sortIt != todoListSorted.end() && (*eit)->dtStart() < (*sortIt)->dtStart()) { ++sortIt; } } todoListSorted.insert(sortIt, *eit); } else { // Keep a list of the Todos without Start DateTimes tempList.append(*eit); } } if(sortDirection == SortDirectionAscending) { // Append the list of Todos without Start DateTimes todoListSorted += tempList; } else { // Prepend the list of Todos without Start DateTimes tempList += todoListSorted; todoListSorted = tempList; } break; case TodoSortDueDate: alphaList = sortTodos(todoList, TodoSortSummary, sortDirection); for(eit = alphaList.begin(); eit != alphaList.end(); ++eit) { if((*eit)->hasDueDate()) { sortIt = todoListSorted.begin(); if(sortDirection == SortDirectionAscending) { while(sortIt != todoListSorted.end() && (*eit)->dtDue() >= (*sortIt)->dtDue()) { ++sortIt; } } else { while(sortIt != todoListSorted.end() && (*eit)->dtDue() < (*sortIt)->dtDue()) { ++sortIt; } } todoListSorted.insert(sortIt, *eit); } else { // Keep a list of the Todos without Due DateTimes tempList.append(*eit); } } if(sortDirection == SortDirectionAscending) { // Append the list of Todos without Due DateTimes todoListSorted += tempList; } else { // Prepend the list of Todos without Due DateTimes tempList += todoListSorted; todoListSorted = tempList; } break; case TodoSortPriority: alphaList = sortTodos(todoList, TodoSortSummary, sortDirection); for(eit = alphaList.begin(); eit != alphaList.end(); ++eit) { sortIt = todoListSorted.begin(); if(sortDirection == SortDirectionAscending) { while(sortIt != todoListSorted.end() && (*eit)->priority() >= (*sortIt)->priority()) { ++sortIt; } } else { while(sortIt != todoListSorted.end() && (*eit)->priority() < (*sortIt)->priority()) { ++sortIt; } } todoListSorted.insert(sortIt, *eit); } break; case TodoSortPercentComplete: alphaList = sortTodos(todoList, TodoSortSummary, sortDirection); for(eit = alphaList.begin(); eit != alphaList.end(); ++eit) { sortIt = todoListSorted.begin(); if(sortDirection == SortDirectionAscending) { while(sortIt != todoListSorted.end() && (*eit)->percentComplete() >= (*sortIt)->percentComplete()) { ++sortIt; } } else { while(sortIt != todoListSorted.end() && (*eit)->percentComplete() < (*sortIt)->percentComplete()) { ++sortIt; } } todoListSorted.insert(sortIt, *eit); } break; case TodoSortSummary: for(eit = todoList->begin(); eit != todoList->end(); ++eit) { sortIt = todoListSorted.begin(); if(sortDirection == SortDirectionAscending) { while(sortIt != todoListSorted.end() && (*eit)->summary() >= (*sortIt)->summary()) { ++sortIt; } } else { while(sortIt != todoListSorted.end() && (*eit)->summary() < (*sortIt)->summary()) { ++sortIt; } } todoListSorted.insert(sortIt, *eit); } break; } return todoListSorted; }