//@cond PRIVATE void FreeBusy::Private::init( const Event::List &eventList, const KDateTime &start, const KDateTime &end ) { int extraDays, i, x, duration; duration = start.daysTo( end ); QDate day; KDateTime tmpStart; KDateTime tmpEnd; // Loops through every event in the calendar Event::List::ConstIterator it; for ( it = eventList.constBegin(); it != eventList.constEnd(); ++it ) { Event::Ptr event = *it; // If this event is transparent it shouldn't be in the freebusy list. if ( event->transparency() == Event::Transparent ) { continue; } // The code below can not handle all-day events. Fixing this resulted // in a lot of duplicated code. Instead, make a copy of the event and // set the period to the full day(s). This trick works for recurring, // multiday, and single day all-day events. Event::Ptr allDayEvent; if ( event->allDay() ) { // addDay event. Do the hack kDebug() << "All-day event"; allDayEvent = Event::Ptr( new Event( *event ) ); // Set the start and end times to be on midnight KDateTime st = allDayEvent->dtStart(); st.setTime( QTime( 0, 0 ) ); KDateTime nd = allDayEvent->dtEnd(); nd.setTime( QTime( 23, 59, 59, 999 ) ); allDayEvent->setAllDay( false ); allDayEvent->setDtStart( st ); allDayEvent->setDtEnd( nd ); kDebug() << "Use:" << st.toString() << "to" << nd.toString(); // Finally, use this event for the setting below event = allDayEvent; } // This whole for loop is for recurring events, it loops through // each of the days of the freebusy request for ( i = 0; i <= duration; ++i ) { day = start.addDays( i ).date(); tmpStart.setDate( day ); tmpEnd.setDate( day ); if ( event->recurs() ) { if ( event->isMultiDay() ) { // FIXME: This doesn't work for sub-daily recurrences or recurrences with // a different time than the original event. extraDays = event->dtStart().daysTo( event->dtEnd() ); for ( x = 0; x <= extraDays; ++x ) { if ( event->recursOn( day.addDays( -x ), start.timeSpec() ) ) { tmpStart.setDate( day.addDays( -x ) ); tmpStart.setTime( event->dtStart().time() ); tmpEnd = event->duration().end( tmpStart ); addLocalPeriod( q, tmpStart, tmpEnd ); break; } } } else { if ( event->recursOn( day, start.timeSpec() ) ) { tmpStart.setTime( event->dtStart().time() ); tmpEnd.setTime( event->dtEnd().time() ); addLocalPeriod ( q, tmpStart, tmpEnd ); } } } } // Non-recurring events addLocalPeriod( q, event->dtStart(), event->dtEnd() ); } q->sortList(); }
Incidence::Ptr pasteIncidence( const Incidence::Ptr &incidence, KDateTime newDateTime, const QFlags<PasteFlag> &pasteOptions ) { Incidence::Ptr inc( incidence ); if ( inc ) { inc = Incidence::Ptr( inc->clone() ); inc->recreate(); } if ( inc && newDateTime.isValid() ) { if ( inc->type() == Incidence::TypeEvent ) { Event::Ptr event = inc.staticCast<Event>(); if ( pasteOptions & FlagPasteAtOriginalTime ) { // Set date and preserve time and timezone stuff const QDate date = newDateTime.date(); newDateTime = event->dtStart(); newDateTime.setDate( date ); } // in seconds const int durationInSeconds = event->dtStart().secsTo( event->dtEnd() ); const int durationInDays = event->dtStart().daysTo( event->dtEnd() ); event->setDtStart( newDateTime ); if ( newDateTime.isDateOnly() ) { event->setDtEnd( newDateTime.addDays( durationInDays ) ); } else { event->setDtEnd( newDateTime.addSecs( durationInSeconds ) ); } } else if ( inc->type() == Incidence::TypeTodo ) { Todo::Ptr aTodo = inc.staticCast<Todo>(); const bool pasteAtDtStart = ( pasteOptions & FlagTodosPasteAtDtStart ); if ( pasteOptions & FlagPasteAtOriginalTime ) { // Set date and preserve time and timezone stuff const QDate date = newDateTime.date(); newDateTime = pasteAtDtStart ? aTodo->dtStart() : aTodo->dtDue(); newDateTime.setDate( date ); } if ( pasteAtDtStart ) { aTodo->setDtStart( newDateTime ); } else { aTodo->setDtDue( newDateTime ); } } else if ( inc->type() == Incidence::TypeJournal ) { if ( pasteOptions & FlagPasteAtOriginalTime ) { // Set date and preserve time and timezone stuff const QDate date = newDateTime.date(); newDateTime = inc->dtStart(); newDateTime.setDate( date ); } inc->setDtStart( newDateTime ); } else { kDebug() << "Trying to paste unknown incidence of type" << int( inc->type() ); } } return inc; }
void ICalFormatTest::testCharsets() { ICalFormat format; const QDate currentDate = QDate::currentDate(); Event::Ptr event = Event::Ptr( new Event() ); event->setUid( "12345" ); event->setDtStart( KDateTime( currentDate ) ); event->setDtEnd( KDateTime( currentDate.addDays( 1 ) ) ); // ΓΌ const QChar latin1_umlaut[] = { 0xFC, '\0' }; event->setSummary( QString( latin1_umlaut ) ); // Test if toString( Incidence ) didn't mess charsets const QString serialized = format.toString( event.staticCast<Incidence>() ); const QChar utf_umlaut[] = { 0xC3, 0XBC, '\0' }; QVERIFY( serialized.toUtf8().contains( QString( utf_umlaut ).toLatin1().constData() ) ); QVERIFY( !serialized.toUtf8().contains( QString( latin1_umlaut ).toLatin1().constData() ) ); QVERIFY( serialized.toLatin1().contains( QString( latin1_umlaut ).toLatin1().constData() ) ); QVERIFY( !serialized.toLatin1().contains( QString( utf_umlaut ).toLatin1().constData() ) ); // test fromString( QString ) const QString serializedCalendar = "BEGIN:VCALENDAR\nPRODID:-//K Desktop Environment//NONSGML libkcal 3.2//EN\nVERSION:2.0\n" + serialized + "\nEND:VCALENDAR"; Incidence::Ptr event2 = format.fromString( serializedCalendar ); QVERIFY( event->summary() == event2->summary() ); QVERIFY( event2->summary().toUtf8() == QByteArray( QString( utf_umlaut ).toLatin1().constData() ) ); // test save() MemoryCalendar::Ptr calendar( new MemoryCalendar( "UTC" ) ); calendar->addIncidence( event ); QVERIFY( format.save( calendar, "hommer.ics" ) ); // Make sure hommer.ics is in UTF-8 QFile file( "hommer.ics" ); QVERIFY( file.open( QIODevice::ReadOnly | QIODevice::Text ) ); const QByteArray bytesFromFile = file.readAll(); QVERIFY( bytesFromFile.contains( QString( utf_umlaut ).toLatin1().constData() ) ); QVERIFY( !bytesFromFile.contains( QString( latin1_umlaut ).toLatin1().constData() ) ); file.close(); // Test load: MemoryCalendar::Ptr calendar2( new MemoryCalendar( "UTC" ) ); QVERIFY( format.load( calendar2, "hommer.ics" ) ); QVERIFY( calendar2->incidences().count() == 1 ); // kDebug() << format.toString( event.staticCast<Incidence>() ); // kDebug() << format.toString( calendar2->incidences().first() ); Event::Ptr loadedEvent = calendar2->incidences().first().staticCast<Event>(); QVERIFY( loadedEvent->summary().toUtf8() == QByteArray( QString( utf_umlaut ).toLatin1().constData() ) ); QVERIFY( *loadedEvent == *event ); // Test fromRawString() MemoryCalendar::Ptr calendar3( new MemoryCalendar( "UTC" ) ); format.fromRawString( calendar3, bytesFromFile ); QVERIFY( calendar3->incidences().count() == 1 ); QVERIFY( *calendar3->incidences().first() == *event ); unlink( "hommer.ics" ); }