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; }
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(); }
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); } }
/* 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 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 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; }