Branch 'c++/master' - 55 commits - c++/CMakeLists.txt c++/compiled c++/.gitignore c++/lib c++/tests schemas/base.xsd schemas/contact.xsd schemas/event.xsd schemas/ical schemas/incidence.xsd schemas/kolabformat-xcard.xsd schemas/kolabformat.xsd schemas/note.xsd schemas/task.xsd schemas/xCard.xsd testfiles/xcalCalendar.xml testfiles/xcalEvent.xml
Christian Mollekopf
mollekopf at kolabsys.com
Tue Dec 27 13:28:29 CET 2011
c++/.gitignore | 2
c++/CMakeLists.txt | 70 +-
c++/compiled/README | 18
c++/compiled/XMLParserWrapper.cpp | 260 +++++++++
c++/compiled/XMLParserWrapper.h | 76 ++
c++/compiled/grammar-input-stream.cxx | 115 ++++
c++/compiled/grammar-input-stream.hxx | 53 ++
c++/compiled/xsdbin.cxx | 505 +++++++++++++++++++
c++/lib/CMakeLists.txt | 50 +
c++/lib/DEVELOPMENT | 13
c++/lib/conversions.h | 435 ++++++++++++++++
c++/lib/incidence_p.h | 46 +
c++/lib/kcalconversions.h | 665 +++++++++++++++++++++++++
c++/lib/kcalkolabformat.cpp | 31 +
c++/lib/kcalkolabformat.h | 19
c++/lib/kolabcontainers.cpp | 652 ++++++++++++++++++++++++
c++/lib/kolabcontainers.h | 253 +++++++++
c++/lib/kolabcontainers.i | 11
c++/lib/kolabconversions.h | 740 ++++++++++++++++++++++++++++
c++/lib/kolabformat.cpp | 33 +
c++/lib/kolabformat.h | 20
c++/lib/kolabformat.i | 26
c++/lib/kolabkcalconversion.cpp | 362 +------------
c++/lib/kolabkcalconversion.h | 9
c++/lib/kolabtodo.cpp | 269 ++++++++++
c++/lib/kolabtodo.h | 97 +++
c++/lib/test.php | 16
c++/lib/test.py | 10
c++/tests/CMakeLists.txt | 16
c++/tests/bindingstest.cpp | 412 ++++++---------
c++/tests/bindingstest.h | 22
c++/tests/kcalconversiontest.cpp | 163 +++++-
c++/tests/kcalconversiontest.h | 10
c++/tests/testfiles/icalEvent.xml | 93 +++
c++/tests/testfiles/testkolabevent.xml | 38 -
schemas/base.xsd | 92 ---
schemas/contact.xsd | 82 ---
schemas/event.xsd | 25
schemas/ical/iCalendar-props.xsd | 24
schemas/ical/iCalendar-valtypes.xsd | 64 ++
schemas/ical/iCalendar-wscal-extensions.xsd | 1
schemas/ical/iCalendar.xsd | 21
schemas/ical/kolabformat-xcal.xsd | 142 +++++
schemas/ical/kolabformat.xsd | 39 -
schemas/incidence.xsd | 95 ---
schemas/kolabformat-xcard.xsd | 35 +
schemas/kolabformat.xsd | 79 ++
schemas/note.xsd | 33 -
schemas/task.xsd | 29 -
schemas/xCard.xsd | 126 ++++
testfiles/xcalCalendar.xml | 142 +++++
testfiles/xcalEvent.xml | 34 +
52 files changed, 5613 insertions(+), 1060 deletions(-)
New commits:
commit 19d4fe0288d49e7e8150d9dd7719fd3427e88ef7
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Tue Dec 27 13:27:00 2011 +0100
toKCalCore conversion function
roundtrip test to check overhead of additional conversion
diff --git a/c++/lib/kolabkcalconversion.cpp b/c++/lib/kolabkcalconversion.cpp
index 544d66c..d40d819 100644
--- a/c++/lib/kolabkcalconversion.cpp
+++ b/c++/lib/kolabkcalconversion.cpp
@@ -1,6 +1,5 @@
#include "kolabkcalconversion.h"
-#include "bindings/incidence.hxx"
#include <kcalcore/recurrence.h>
#include <QtCore/QBitArray>
#include <QtCore/QVector>
@@ -8,352 +7,45 @@
namespace Kolab {
namespace KCalConversion {
-
- enum CYCLE {
- Yearly,
- Monthly,
- Weekly,
- Daily
- };
- /*
-void setInterval(const KolabXSD::Interval &interval, KCalCore::RecurrenceRule::PeriodType type)
-{
-
-}*/
-
-// KCalCore::Recurrence* recur = incidence->recurrence(); // yeah, this creates it
-//setup a KCalCore::Recurrence from a KolabXSD::Recurrence
-void toKCal(KCalCore::Recurrence* recur, const KolabXSD::Recurrence &recurrence)
-{
-
- for (KolabXSD::Recurrence::rule_const_iterator it = recurrence.rule().begin(); it != recurrence.rule().end(); it++) {
- KCalCore::RecurrenceRule r;
-
- if (it->yearly()) {
- if (it->yearly()->interval()) { //TODO yearly day
- r.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
- r.setFrequency(*(it->yearly()->interval()));
-
- /*if (it->monthly() && it->monthly()->list()) { //interval is not supported
-
- QList<int> months;
- for (KolabXSD::Recurrence::rule_const_iterator month = it->monthly()->list().begin(); month != it->monthly()->list().end(); month++) {
- months.append(*month);
- }
- r.setByMonths(months);
- Q_ASSERT(!it->weekly()); //Not supported TODO setByWeekNumbers
-
-
- if (it->daily() && it->daily()->list()) {
- QList<int> monthDays;
- for (KolabXSD::Recurrence::rule_const_iterator day = it->daily()->list().begin(); day != it->daily()->list().end(); day++) {
- monthDays.append(*day);
- }
- r.setByMonthDays(*day);
- }
-
- }*/
-
- }
-
- }
-
- /*if (it->yearly()) {
- if (it->yearly()->interval()) {
- recur->setYearly(*(it->yearly()->interval()));
- } else if (it->yearly()->list()) { //TODO
-
- }
- }*/
-
- if (it->monthly()) {
- const KolabXSD::Interval &interval = *(it->monthly());
-
- if (r.recurrenceType() == KCalCore::RecurrenceRule::rNone) {
- if (interval.interval()) {
- r.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
- r.setFrequency(*(interval.interval()));
- } else {
- r.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
- r.setFrequency(1);
- }
- }
-
- if (r.recurrenceType() == KCalCore::RecurrenceRule::rYearly) {
-
- if (interval.interval()) {
- //TODO create list from interval
- } else if (interval.list().size()) {
- QList<int> list;
- for (KolabXSD::Interval::list_const_iterator value = interval.list().begin(); value != interval.list().end(); value++) {
- list.append(*value);
- }
- r.setByMonths(list);
- }
- }
-
-
- }
- /*
- if (it->weekly()) {
- const KolabXSD::Interval &interval = *(it->weekly());
-
- if (r.recurrenceType() == KCalCore::RecurrenceRule::rNone) {
- if (interval.interval()) {
- r.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
- r.setFrequency(*(interval.interval()));
- } else {
- r.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
- r.setFrequency(1);
- }
- }
-
- if (r.recurrenceType() == KCalCore::RecurrenceRule::rYearly) {
-
- if (interval.interval()) {
- //TODO create list from interval
- } else if (interval.list()) {
- QList<int> list;
- for (KolabXSD::Recurrence::rule_const_iterator day = interval.list().begin(); day != interval.list().end(); day++) {
- list.append(*day);
- }
- r.setByMonths(list);
- }
- }
-
-
- }*/
-
- /*
- if (it->minutely() && it->minutely()->interval()) {
- recur->setMinutely(*(it->minutely()->interval()));
- }*/
- }
-
-
-
-#if 0
- // done below recur->setFrequency( mRecurrence.interval );
- if ( mRecurrence.rule == "minutely" ) {
- recur->setMinutely( mRecurrence.interval );
- } else if ( mRecurrence.rule == "hourly" ) {
- recur->setHourly( mRecurrence.interval );
- } else if ( mRecurrence.rule == "daily" ) {
- recur->setDaily( mRecurrence.interval );
- } else if ( mRecurrence.rule == "weekly" ) {
- QBitArray rDays = daysListToBitArray( mRecurrence.days );
- recur->setWeekly( mRecurrence.interval, rDays );
- } else if ( mRecurrence.rule == "monthly" ) {
- recur->setMonthly( mRecurrence.interval );
- if ( mRecurrence.type == "weekday" ) {
- recur->addMonthlyPos( mRecurrence.dayNumber.toInt(), daysListToBitArray( mRecurrence.days ) );
- } else if ( mRecurrence.type == "daynumber" ) {
- recur->addMonthlyDate( mRecurrence.dayNumber.toInt() );
- } else kWarning() <<"Unhandled monthly recurrence type" << mRecurrence.type;
- } else if ( mRecurrence.rule == "yearly" ) {
- recur->setYearly( mRecurrence.interval );
- if ( mRecurrence.type == "monthday" ) {
- recur->addYearlyDate( mRecurrence.dayNumber.toInt() );
- for ( int i = 0; i < 12; ++i )
- if ( s_monthName[ i ] == mRecurrence.month )
- recur->addYearlyMonth( i+1 );
- } else if ( mRecurrence.type == "yearday" ) {
- recur->addYearlyDay( mRecurrence.dayNumber.toInt() );
- } else if ( mRecurrence.type == "weekday" ) {
- for ( int i = 0; i < 12; ++i )
- if ( s_monthName[ i ] == mRecurrence.month )
- recur->addYearlyMonth( i+1 );
- recur->addYearlyPos( mRecurrence.dayNumber.toInt(), daysListToBitArray( mRecurrence.days ) );
- } else kWarning() <<"Unhandled yearly recurrence type" << mRecurrence.type;
- } else kWarning() <<"Unhandled recurrence rule" << mRecurrence.rule;
-
- if ( mRecurrence.rangeType == "number" ) {
- recur->setDuration( mRecurrence.range.toInt() );
- } else if ( mRecurrence.rangeType == "date" ) {
- recur->setEndDate( stringToDate( mRecurrence.range ) );
- } // "none" is default since tje set*ly methods set infinite recurrence
-
- incidence->recurrence()->setExDates( mRecurrence.exclusions );
-#endif
+KDateTime toDate(const Kolab::DateTime &dt)
+{
+ KDateTime date;
+ if (dt.isDateOnly()) {
+ date.setDateOnly(true);
+ date.setDate(QDate(dt.year(), dt.month(), dt.day()));
+ } else {
+ date.setDate(QDate(dt.year(), dt.month(), dt.day()));
+ date.setTime(QTime(dt.hour(), dt.minute(), dt.second()));
+ if (dt.isUTC()) {
+ date.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+ } else if (dt.timezone().empty()) {
+ date.setTimeSpec(KDateTime::Spec(KTimeZone(QString::fromStdString(dt.timezone()))));
+ }
+ }
+ return date;
}
-//setup a KolabXSD:Recurrence from a KCalCore recurrence
-KolabXSD::Recurrence fromKCal( KCalCore::Recurrence* recur )
+void setIncidence(KCalCore::Incidence &i, const Kolab::Event &e)
{
- KolabXSD::Recurrence recurrence;
-
- KolabXSD::Interval interval;
- interval.interval() = recur->frequency();
- switch ( recur->recurrenceType() ) {
- case KCalCore::Recurrence::rMinutely: {
- KolabXSD::Rule rule;
- rule.minutely(interval);
- recurrence.rule().push_back(rule);
- break;
+ if (!e.uid().empty()) {
+ i.setUid(QString::fromStdString(e.uid()));
}
- case KCalCore::Recurrence::rHourly: {
- KolabXSD::Rule rule;
- rule.hourly(interval);
- recurrence.rule().push_back(rule);
- break;
- }
- case KCalCore::Recurrence::rDaily: {
- KolabXSD::Rule rule;
- rule.daily(interval);
- recurrence.rule().push_back(rule);
- break;
- }
- case KCalCore::Recurrence::rWeekly: { // every X weeks
- KolabXSD::Rule rule;
- rule.weekly(interval);
- KolabXSD::Interval days;
- {
- QBitArray arr = recur->days();
- for ( uint idx = 0 ; idx < 7 ; ++idx )
- if ( arr.testBit( idx ) )
- days.list().push_back(idx);
- }
- rule.daily(days);
- recurrence.rule().push_back(rule);
- break;
- }
- case KCalCore::Recurrence::rMonthlyPos: {
-
- foreach( const KCalCore::RecurrenceRule::WDayPos &monthPos, recur->monthPositions()) {
- KolabXSD::Rule rule;
- rule.monthly(interval);
- KolabXSD::Interval weeks;
- weeks.list().push_back(monthPos.pos());
- rule.weekly(weeks);
- KolabXSD::Interval days;
- days.list().push_back(monthPos.day());
- rule.daily(days);
- recurrence.rule().push_back(rule);
- }
- /*
- recurrence.monthly(interval);
-
- KolabXSD::Interval days;
-
- QMap <int, int> m_dayPosMap;
- foreach( const KCalCore::RecurrenceRule::WDayPos &monthPos, recur->monthPositions()) {
- m_dayPosMap.insertMulti(monthPos.day(), monthPos.pos());
- }
-
- foreach( int day, m_dayPosMap.uniqueKeys()) {
- KolabXSD::Interval weeks;
- if (m_dayPosMap.values(day).contains(0)) {
- weeks.interval(1);
- } else {
- foreach (int pos, m_dayPosMap.values(day)) {
- weeks.list.push_back(pos);
- }
- }
- recurrence.weekly(weeks);
- }
-
- if ( !monthPositions.isEmpty() ) {
- foreach( const KCalCore::RecurrenceRule::WDayPos &monthPos, monthPositions) {
- if (monthPos.pos() != 0) { //pos == 0 => every week
- KolabXSD::Interval weeks;
- foreach( const KCalCore::RecurrenceRule::WDayPos &monthPos, monthPos.) {
- weeks.list().push_back(monthPos.pos);
- }
- recurrence.weekly(weeks);
- } else {
-
- }
-
- days.list().push_back(monthPos.day());
- }
-
- }
-
- recurrence.daily(days);*/
- break;
- }
- case KCalCore::Recurrence::rMonthlyDay: {
- KolabXSD::Rule rule;
- rule.monthly(interval);
- KolabXSD::Interval weeks;
- weeks.interval(0);
- rule.weekly(weeks);
- QList<int> monthDays = recur->monthDays();
- if ( !monthDays.isEmpty() ) {
- KolabXSD::Interval days;
- foreach( int day, monthDays) {
- days.list().push_back(day);
- }
- rule.daily(days);
- }
- recurrence.rule().push_back(rule);
- break;
- }
- /*
- case KCalCore::Recurrence::rYearlyMonth: // (day n of Month Y)
- {
- KolabXSD::Recurrence recurrence;
- mRecurrence.rule = "yearly";
- mRecurrence.type = "monthday";
- QList<int> rmd = recur->yearDates();
- int day = !rmd.isEmpty() ? rmd.first() : recur->startDate().day();
- mRecurrence.dayNumber = QString::number( day );
- QList<int> months = recur->yearMonths();
- if ( !months.isEmpty() )
- mRecurrence.month = s_monthName[ months.first() - 1 ]; // #### Kolab XML limitation: only one month specified
- recurrences.append(recurrence);
- break;
+
+ if (e.start().isValid()) {
+ i.setDtStart(toDate(e.start()));
}
- case KCalCore::Recurrence::rYearlyDay: // YearlyDay (day N of the year). Not supported by Outlook
- mRecurrence.rule = "yearly";
- mRecurrence.type = "yearday";
- mRecurrence.dayNumber = QString::number( recur->yearDays().first() );
- break;
- case KCalCore::Recurrence::rYearlyPos: // (weekday X of week N of month Y)
- mRecurrence.rule = "yearly";
- mRecurrence.type = "weekday";
- QList<int> months = recur->yearMonths();
- if ( !months.isEmpty() )
- mRecurrence.month = s_monthName[ months.first() - 1 ]; // #### Kolab XML limitation: only one month specified
- QList<KCalCore::RecurrenceRule::WDayPos> monthPositions = recur->yearPositions();
- if ( !monthPositions.isEmpty() ) {
- KCalCore::RecurrenceRule::WDayPos monthPos = monthPositions.first();
- // TODO: Handle multiple days in the same week
- mRecurrence.dayNumber = QString::number( monthPos.pos() );
- mRecurrence.days.append( s_weekDayName[ monthPos.day()-1 ] );
- //mRecurrence.dayNumber = QString::number( *recur->yearNums().getFirst() );
- // Not handled: monthPos.negative (nth days before end of month)
- }
- break;*/
- }
- /* TODO for each recurrence rule
- int howMany = recur->duration();
- if ( howMany > 0 ) {
- recurrence.count(howMany);
- } else if ( howMany == 0 ) {
- const KDateTime &dt = recur->endDateTime();
- KolabXSD::Recurrence::enddate_type endDate(dt.date().year(), dt.date().month(), dt.date().day(), dt.time().hour(), dt.time().minute(), dt.time().second());
- recurrence.enddate(endDate);
- }
- */
- /*
- foreach (const QDate &date, recur->exDates()) {
- KolabXSD::Exception exception;
- //exception.date(); //TODO
-
- recurrence.exception().push_back(exception);
- }*/
-
- return recurrence;
}
-KCalCore::Recurrence getRecurrence(KolabXSD::Recurrence* recur)
+KCalCore::Event::Ptr toKCalCore(const Kolab::Event &event)
{
-
+ KCalCore::Event::Ptr e(new KCalCore::Event);
+ setIncidence(*e, event);
+ return e;
}
+
}
}
\ No newline at end of file
diff --git a/c++/lib/kolabkcalconversion.h b/c++/lib/kolabkcalconversion.h
index bd46003..36de14f 100644
--- a/c++/lib/kolabkcalconversion.h
+++ b/c++/lib/kolabkcalconversion.h
@@ -1,17 +1,16 @@
#ifndef KOLABKCALTOOLS_H
#define KOLABKCALTOOLS_H
-#include <bindings/incidence.hxx>
#include <kcalcore/recurrence.h>
+#include "kolabcontainers.h"
+#include <kcalcore/event.h>
namespace Kolab {
namespace KCalConversion {
- //setup a KCalCore::Recurrence from a KolabXSD::Recurrence
- void toKCal(KCalCore::Recurrence* recur, const KolabXSD::Recurrence &recurrence);
- //setup a KolabXSD:Recurrence from a KCalCore recurrence
- KolabXSD::Recurrence fromKCal( KCalCore::Recurrence* recur );
+ KCalCore::Event::Ptr toKCalCore(const Kolab::Event &);
+// Kolab::Event writeEvent(KCalCore::Event::Ptr);
};
};
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 463636f..76b8726 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -13,6 +13,7 @@
#include <xercesc/dom/DOMImplementation.hpp>
#include <lib/kolabformat.h>
#include <kdebug.h>
+#include <lib/kolabkcalconversion.h>
namespace QTest {
@@ -195,6 +196,22 @@ void BindingsTest::todoCompletness()
}
+void BindingsTest::BenchmarkRoundtripKolab()
+{
+ boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("../../tests/testfiles/icalEvent.xml", true);
+ std::string result = Kolab::writeKolabEvent(*event);
+ QBENCHMARK {
+ Kolab::readKolabEvent(result, false);
+ }
+}
+void BindingsTest::BenchmarkRoundtripKCAL()
+{
+ boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("../../tests/testfiles/icalEvent.xml", true);
+ std::string result = Kolab::writeKolabEvent(*event);
+ QBENCHMARK {
+ Kolab::KCalConversion::toKCalCore(*Kolab::readKolabEvent(result, false));
+ }
+}
QTEST_MAIN( BindingsTest )
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index 4e6205b..77e17a6 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -17,6 +17,9 @@ class BindingsTest : public QObject
void BenchmarkRoundtrip();
void eventCompletness();
void todoCompletness();
+
+ void BenchmarkRoundtripKolab();
+ void BenchmarkRoundtripKCAL();
};
#endif
\ No newline at end of file
commit 8c6fab2ef8532371f5f5ede58681bf7a2b78bd7a
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Tue Dec 27 13:25:57 2011 +0100
conversiontest benchmark
diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index be1d3a6..3c6e1b2 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -67,10 +67,10 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) #needed becuase the swig bindings need -fPIC
-add_library(kolabxml SHARED lib/kolabformat.cpp lib/kolabcontainers.cpp lib/kolabtodo.cpp compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+add_library(kolabxml SHARED lib/kolabformat.cpp lib/kolabcontainers.cpp lib/kolabtodo.cpp compiled/XMLParserWrapper.cpp lib/kolabkcalconversion.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
target_link_libraries(kolabxml xerces-c)
-add_library(kolabxmlkcal SHARED lib/kcalkolabformat.cpp ${SCHEMA_SOURCEFILES})
+add_library(kolabxmlkcal SHARED lib/kcalkolabformat.cpp compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
target_link_libraries(kolabxmlkcal xerces-c)
add_subdirectory(tests)
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index 822015d..754e08b 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -11,6 +11,6 @@ QT4_AUTOMOC(bindingstest.cpp)
add_executable(bindingstest bindingstest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabxml xerces-c kcalcore)
-# QT4_AUTOMOC(kcalconversiontest.cpp)
-# add_executable(kcalconversiontest kcalconversiontest.cpp ${KCALCONVERSIONTEST_MOC})
-# target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} kolabxmlkcal xerces-c kcalcore)
+QT4_AUTOMOC(kcalconversiontest.cpp)
+add_executable(kcalconversiontest kcalconversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${KCALCONVERSIONTEST_MOC})
+target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} kolabxmlkcal xerces-c kcalcore)
diff --git a/c++/tests/kcalconversiontest.cpp b/c++/tests/kcalconversiontest.cpp
index 15d90fe..c5e5e9c 100644
--- a/c++/tests/kcalconversiontest.cpp
+++ b/c++/tests/kcalconversiontest.cpp
@@ -8,6 +8,7 @@
#include <lib/kcalkolabformat.h>
+
void KCalConversionTest::testDate()
{
KDateTime dt1(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
@@ -23,6 +24,34 @@ void KCalConversionTest::testDate()
QCOMPARE(date3.zone_present(), false);
}
+void KCalConversionTest::BenchmarkRoundtripKCAL()
+{
+ std::ifstream ifs;
+// ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit);
+ ifs.open ("../../tests/testfiles/icalEvent.xml");
+ std::string result;
+
+ std::istream_iterator<std::string> DataBegin( ifs );
+ std::istream_iterator<std::string> DataEnd;
+
+ while( DataBegin != DataEnd ) {
+ result += *DataBegin;
+ result += "\n";
+ DataBegin++;
+ }
+
+
+// std::string a;
+// while (!ifs.eof()) {
+// ifs >> a;
+// result.append(a);
+// }
+ std::cout << result << std::endl;
+ QBENCHMARK {
+ Kolab::readEvent(result, false);
+ }
+}
+
void KCalConversionTest::readEvent()
{
@@ -341,4 +370,4 @@ class KCalConversionTest : public QObject
QTEST_MAIN( KCalConversionTest )
-#include "moc_kcalconversiontest.cxx"
+#include "kcalconversiontest.moc"
diff --git a/c++/tests/kcalconversiontest.h b/c++/tests/kcalconversiontest.h
index f1f5a32..6545e5c 100644
--- a/c++/tests/kcalconversiontest.h
+++ b/c++/tests/kcalconversiontest.h
@@ -9,6 +9,9 @@ class KCalConversionTest : public QObject
Q_OBJECT
private slots:
+
+ void BenchmarkRoundtripKCAL();
+
void testConversion_data();
void testConversion();
commit ba21cea52064e6acab8ec808053e0063fe7510c1
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Tue Dec 27 13:25:09 2011 +0100
missing todo properties
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 170b489..c22b5b5 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -691,11 +691,9 @@ template < > struct IncidenceTrait <Kolab::Todo>
getIncidenceProperties<KolabType::properties_type>(prop, event);
-// /* if (event.end().isValid()) {
-// prop.dtend(fromDate<KolabTypes, typename icalendar_2_0::properties1::dtend_type>(event.end()));
-// }/* else if */(event.duration().isValid()) {
-// //TODO
-// }*/
+ if (event.due().isValid()) {
+ prop.due(fromDate<KolabTypes, typename icalendar_2_0::properties1::due_type>(event.due()));
+ }
// if (event.transparency()) {
// prop.transp( icalendar_2_0::properties::transp_type(TRANSPARENT));
@@ -707,35 +705,23 @@ template < > struct IncidenceTrait <Kolab::Todo>
components.vtodo().push_back(inc);
}
- static void readIncidence(Kolab::Todo &event, const icalendar_2_0::KolabTodo& vevent)
+ static void readIncidence(Kolab::Todo &todo, const icalendar_2_0::KolabTodo& vevent)
{
const icalendar_2_0::KolabTodo::properties_type &prop = vevent.properties();
- setIncidenceProperties<Kolab::Todo, icalendar_2_0::KolabTodo::properties_type>(event, prop);
-
-// if (prop.dtend()) {
-// event.setEnd(*toDate<KolabTypes>(*prop.dtend()));
-// // event.setDtEnd(*toDate<KCalCoreTypes>(*prop.dtend()));
-// // if (event.dtEnd().timeType() != event.dtStart().timeType()) {
-// // kWarning() << "dtEnd has wrong timespec";
-// // }
-// } else if (prop.duration()) {
-// //TODO implement
-// // KCalCore::Duration duration.;
-// // event.setDuration(duration << prop.duration());
-// }
-// //TODO check for equality of timespecs
-//
-// if (prop.transp()) {
-// if (toString(*prop.transp()) == TRANSPARENT) {
-// event.setTransparency(true);
-// } else {
-// event.setTransparency(false);
-// if (toString(*prop.transp()) != OPAQUE) {
-// std::cerr << "wrong transparency value " << toString(*prop.transp()) << std::endl;
-// }
-// }
-// }
+ setIncidenceProperties<Kolab::Todo, icalendar_2_0::KolabTodo::properties_type>(todo, prop);
+
+ if (prop.related_to()) {
+ //TODO
+ }
+ if (prop.due()) {
+ todo.setDue(*toDate<KolabTypes>(*prop.due()));
+ }
+ if (prop.percent_complete()) {
+ //TODO
+ }
+
+
}
static icalendar_2_0::components2::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index 10baba3..bea6fd3 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -79,7 +79,9 @@
<xs:element name="sequence" type="SequencePropType" minOccurs="0"/>
<xs:element name="class" type="ClassPropType" minOccurs="0"/>
<xs:element name="categories" type="CategoriesPropType" minOccurs="0"/>
+ <xs:element name="related-to" type="RelatedToPropType" minOccurs="0"/>
<xs:element name="dtstart" type="DtstartPropType" minOccurs="0"/>
+ <xs:element name="due" type="DuePropType" minOccurs="0"/>
<xs:element name="rrule" type="RrulePropType" minOccurs="0"/>
<xs:element name="rdate" type="RdatePropType" minOccurs="0"/>
<xs:element name="exdate" type="ExdatePropType" minOccurs="0"/>
@@ -88,6 +90,7 @@
<xs:element name="description" type="DescriptionPropType" minOccurs="0"/>
<xs:element name="priority" type="PriorityPropType" minOccurs="0"/>
<xs:element name="status" type="StatusPropType" minOccurs="0"/>
+ <xs:element name="percent-complete" type="PercentCompletePropType" minOccurs="0"/>
<xs:element name="location" type="LocationPropType" minOccurs="0"/>
<xs:element name="organizer" type="OrganizerPropType" minOccurs="0"/>
<xs:element name="attendee" type="AttendeePropType" minOccurs="0" maxOccurs="unbounded"/>
commit e39021dcfddcf79a9ecad99098bb9da245b6292b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Tue Dec 27 11:40:26 2011 +0100
todo implementation
diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 22e1947..be1d3a6 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -67,10 +67,10 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) #needed becuase the swig bindings need -fPIC
-add_library(kolabxml SHARED lib/kolabformat.cpp lib/kolabcontainers.cpp compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+add_library(kolabxml SHARED lib/kolabformat.cpp lib/kolabcontainers.cpp lib/kolabtodo.cpp compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
target_link_libraries(kolabxml xerces-c)
-add_library(kolabxmlkcal lib/kcalkolabformat.cpp ${SCHEMA_SOURCEFILES})
+add_library(kolabxmlkcal SHARED lib/kcalkolabformat.cpp ${SCHEMA_SOURCEFILES})
target_link_libraries(kolabxmlkcal xerces-c)
add_subdirectory(tests)
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 796ec9f..6afd122 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -308,7 +308,7 @@ typename T::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
}
///Trait for Incidence object
-template <typename T>
+template <typename T, typename I>
struct IncidenceConverter;
///Trait for incidence properties specialized for Event/Todo/Journal
@@ -384,7 +384,7 @@ template <typename T>
std::string writeIncidence(const typename T::IncidenceType &incidence) {
using namespace icalendar_2_0;
- typedef IncidenceConverter< typename T::Incidence > IC;
+ typedef IncidenceConverter< typename T::Incidence, typename T::IncidenceType > IC;
typedef typename T::KolabType KolabType;
try {
diff --git a/c++/lib/incidence_p.h b/c++/lib/incidence_p.h
new file mode 100644
index 0000000..e7a3b99
--- /dev/null
+++ b/c++/lib/incidence_p.h
@@ -0,0 +1,46 @@
+#ifndef INCIDENCE_P
+#define INCIDENCE_P
+
+#include "kolabcontainers.h"
+
+namespace Kolab {
+
+ struct PrivateIncidence
+ {
+ PrivateIncidence()
+ : sequence(0),
+ classification(Public),
+ thisAndFuture(false),
+ priority(0),
+ status(UndefinedStatus){}
+
+ std::string uid;
+ DateTime created;
+ DateTime lastModified;
+ int sequence;
+ Classification classification;
+ std::vector< std::string > categories;
+ DateTime start;
+
+ DateTime recurrenceID;
+ bool thisAndFuture;
+ std::string summary;
+ std::string description;
+ std::string location;
+ int priority;
+ Status status;
+ RecurrenceRule rrule;
+ std::vector< DateTime > recurrenceDates;
+ std::vector< DateTime > exceptionDates;
+ std::string organizerEmail;
+ std::string organizerName;
+ Duration duration;
+
+ std::vector<Attendee> attendees;
+ std::vector<Attachment> attachments;
+ std::vector<CustomProperty> customProperties;
+ };
+
+}
+
+#endif
\ No newline at end of file
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
index 2c3f7a4..1b18204 100644
--- a/c++/lib/kcalconversions.h
+++ b/c++/lib/kcalconversions.h
@@ -559,7 +559,7 @@ void getIncidenceProperties(T &prop, const KCalCore::Incidence &inc)
}
-template <> struct IncidenceConverter < KCalCore::Incidence >
+template <> struct IncidenceConverter < KCalCore::Incidence, KCalCore::Incidence >
{
typedef DateTimeConverter< KDateTime> DC;
static std::string uid(const KCalCore::Incidence &inc) {
diff --git a/c++/lib/kcalkolabformat.cpp b/c++/lib/kcalkolabformat.cpp
index 82d9995..5d217d3 100644
--- a/c++/lib/kcalkolabformat.cpp
+++ b/c++/lib/kcalkolabformat.cpp
@@ -20,7 +20,7 @@ KCalCore::Todo::Ptr readTodo(const std::string& s, bool isUrl)
std::string writeEvent(KCalCore::Event::Ptr event)
{
- return writeIncidence< IncidenceTrait<KCalCore::Event> >(*event);
+// return writeIncidence< IncidenceTrait<KCalCore::Event> >(*event);
}
std::string writeTodo(KCalCore::Todo::Ptr todo)
diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index cfd94ad..0123348 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -1,4 +1,5 @@
#include "kolabcontainers.h"
+#include "incidence_p.h"
namespace Kolab {
@@ -360,43 +361,15 @@ bool RecurrenceRule::isValid() const
-struct Event::Private
+struct Event::Private: public PrivateIncidence
{
Private()
- : sequence(0),
- classification(Public),
- thisAndFuture(false),
- priority(0),
- status(UndefinedStatus),
+ : PrivateIncidence(),
isTransparent(false){}
-
- std::string uid;
- DateTime created;
- DateTime lastModified;
- int sequence;
- Classification classification;
- std::vector< std::string > categories;
- DateTime start;
+
DateTime end;
-
- DateTime recurrenceID;
- bool thisAndFuture;
- std::string summary;
- std::string description;
- int priority;
- Status status;
- std::string location;
bool isTransparent;
- RecurrenceRule rrule;
- std::vector< DateTime > recurrenceDates;
- std::vector< DateTime > exceptionDates;
- std::string organizerEmail;
- std::string organizerName;
Duration duration;
-
- std::vector<Attendee> attendees;
- std::vector<Attachment> attachments;
- std::vector<CustomProperty> customProperties;
};
Event::Event()
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index 32251b0..06b6929 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -244,6 +244,9 @@ private:
boost::scoped_ptr<Private> d;
};
+
+
+
}
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 0e34d4e..170b489 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -3,6 +3,7 @@
#include "conversions.h"
#include "kolabcontainers.h"
#include <boost/foreach.hpp>
+#include "kolabtodo.h"
namespace Kolab {
@@ -308,8 +309,8 @@ void setCalAddress(const icalendar_2_0::CalAddressPropertyType &cal, std::string
}
-template <typename KolabType, typename T>
-void setIncidenceProperties(Kolab::Event &inc, const T &prop)
+template <typename I, typename T>
+void setIncidenceProperties(I &inc, const T &prop)
{
typedef DateTimeConverter<Kolab::DateTime> DC;
@@ -469,8 +470,8 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const Recurrenc
}
-template <typename T>
-void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form Event to template
+template <typename T, typename I>
+void getIncidenceProperties(T &prop, const I &inc) //TODO switch form Event to template
{
using namespace icalendar_2_0;
@@ -585,18 +586,18 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
}
-template <> struct IncidenceConverter < Incidence >
+template <typename T> struct IncidenceConverter < Incidence, T >
{
typedef DateTimeConverter< DateTime> DC;
- static std::string uid(const Event &inc) {
+ static std::string uid(const T &inc) {
return inc.uid();
}
- static xml_schema::date_time dtstamp(const Event &inc) {
+ static xml_schema::date_time dtstamp(const T &inc) {
return DC::fromDateTime(inc.lastModified());
}
- static xml_schema::date_time created(const Event &inc) {
+ static xml_schema::date_time created(const T &inc) {
return DC::fromDateTime(inc.created());
}
@@ -665,17 +666,89 @@ template < > struct IncidenceTrait <Kolab::Event>
}
}
- static icalendar_2_0::components2::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components) //TODO to base trait
+ static icalendar_2_0::components2::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
{
return components.vevent().begin();
}
- static icalendar_2_0::components2::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components) //TODO to base trait
+ static icalendar_2_0::components2::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
{
return components.vevent().end();
}
};
+template < > struct IncidenceTrait <Kolab::Todo>
+{
+ typedef typename icalendar_2_0::KolabTodo KolabType;
+ typedef typename Kolab::Todo IncidenceType;
+ typedef typename boost::shared_ptr<Kolab::Todo> IncidencePtr;
+ typedef typename Kolab::Incidence Incidence;
+
+ static void writeIncidence(KolabType& vevent, const Kolab::Todo &event)
+ {
+ KolabType::properties_type &prop = vevent.properties();
+
+ getIncidenceProperties<KolabType::properties_type>(prop, event);
+
+// /* if (event.end().isValid()) {
+// prop.dtend(fromDate<KolabTypes, typename icalendar_2_0::properties1::dtend_type>(event.end()));
+// }/* else if */(event.duration().isValid()) {
+// //TODO
+// }*/
+
+// if (event.transparency()) {
+// prop.transp( icalendar_2_0::properties::transp_type(TRANSPARENT));
+// }
+ }
+
+ static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc) //TODO to base trait
+ {
+ components.vtodo().push_back(inc);
+ }
+
+ static void readIncidence(Kolab::Todo &event, const icalendar_2_0::KolabTodo& vevent)
+ {
+ const icalendar_2_0::KolabTodo::properties_type &prop = vevent.properties();
+
+ setIncidenceProperties<Kolab::Todo, icalendar_2_0::KolabTodo::properties_type>(event, prop);
+
+// if (prop.dtend()) {
+// event.setEnd(*toDate<KolabTypes>(*prop.dtend()));
+// // event.setDtEnd(*toDate<KCalCoreTypes>(*prop.dtend()));
+// // if (event.dtEnd().timeType() != event.dtStart().timeType()) {
+// // kWarning() << "dtEnd has wrong timespec";
+// // }
+// } else if (prop.duration()) {
+// //TODO implement
+// // KCalCore::Duration duration.;
+// // event.setDuration(duration << prop.duration());
+// }
+// //TODO check for equality of timespecs
+//
+// if (prop.transp()) {
+// if (toString(*prop.transp()) == TRANSPARENT) {
+// event.setTransparency(true);
+// } else {
+// event.setTransparency(false);
+// if (toString(*prop.transp()) != OPAQUE) {
+// std::cerr << "wrong transparency value " << toString(*prop.transp()) << std::endl;
+// }
+// }
+// }
+ }
+
+ static icalendar_2_0::components2::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
+ {
+ return components.vtodo().begin();
+ }
+
+ static icalendar_2_0::components2::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
+ {
+ return components.vtodo().end();
+ }
+
+};
+
}//Namespace
\ No newline at end of file
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index ab43acc..3ef1e2a 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -4,6 +4,7 @@
#include <bindings/kolabformat-xcal.hxx>
#include "kolabcontainers.h"
#include "kolabconversions.h"
+#include "kolabtodo.h"
namespace Kolab {
@@ -17,6 +18,16 @@ std::string writeKolabEvent(const Kolab::Event &event)
return writeIncidence< IncidenceTrait<Kolab::Event> >(event);
}
+boost::shared_ptr<Kolab::Todo> readKolabTodo(const std::string& s, bool isUrl)
+{
+ return readIncidence< IncidenceTrait<Kolab::Todo> >(s, isUrl);
+}
+
+std::string writeKolabTodo(const Kolab::Todo &event)
+{
+ return writeIncidence< IncidenceTrait<Kolab::Todo> >(event);
+}
+
}
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index cb8064c..03e245b 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -5,13 +5,16 @@
#include <string>
#include <boost/shared_ptr.hpp>
#include "kolabcontainers.h"
-
+#include "kolabtodo.h"
namespace Kolab {
boost::shared_ptr<Kolab::Event> readKolabEvent(const std::string& s, bool isUrl);
std::string writeKolabEvent(const Kolab::Event &);
+boost::shared_ptr<Kolab::Todo> readKolabTodo(const std::string& s, bool isUrl);
+std::string writeKolabTodo(const Kolab::Todo &);
+
}
#endif // KOLABFORMAT_H
diff --git a/c++/lib/kolabtodo.cpp b/c++/lib/kolabtodo.cpp
new file mode 100644
index 0000000..22ae95e
--- /dev/null
+++ b/c++/lib/kolabtodo.cpp
@@ -0,0 +1,269 @@
+#include "kolabtodo.h"
+#include "incidence_p.h"
+
+namespace Kolab {
+
+
+struct Todo::Private: public PrivateIncidence
+{
+ Private()
+ : PrivateIncidence() {}
+
+ DateTime due;
+};
+
+Todo::Todo()
+: d(new Todo::Private())
+{
+
+}
+
+Todo::Todo(const Todo &other)
+: d(new Todo::Private())
+{
+ *d = *other.d;
+}
+
+Todo::~Todo()
+{
+
+}
+
+void Todo::setUid(const std::string &uid)
+{
+ d->uid = uid;
+}
+
+std::string Todo::uid() const
+{
+ return d->uid;
+}
+
+void Todo::setCreated(const Kolab::DateTime &created)
+{
+ d->created = created;
+}
+
+DateTime Todo::created() const
+{
+ return d->created;
+}
+
+void Todo::setLastModified(const Kolab::DateTime &lastMod)
+{
+ d->lastModified = lastMod;
+}
+
+DateTime Todo::lastModified() const
+{
+ return d->lastModified;
+}
+
+void Todo::setSequence(int sequence)
+{
+ d->sequence = sequence;
+}
+
+int Todo::sequence() const
+{
+ return d->sequence;
+}
+
+void Todo::setClassification(Classification class_)
+{
+ d->classification = class_;
+}
+
+Classification Todo::classification() const
+{
+ return d->classification;
+}
+
+void Todo::setCategories(const std::vector< std::string > &categories)
+{
+ d->categories = categories;
+}
+
+void Todo::addCategory(const std::string &cat)
+{
+ d->categories.push_back(cat);
+}
+
+std::vector< std::string > Todo::categories() const
+{
+ return d->categories;
+}
+
+void Todo::setStart(const Kolab::DateTime &start)
+{
+ d->start = start;
+}
+
+DateTime Todo::start() const
+{
+ return d->start;
+}
+
+void Todo::setDue(const Kolab::DateTime &due)
+{
+ d->due = due;
+}
+
+DateTime Todo::due() const
+{
+ return d->due;
+}
+
+void Todo::setRecurrenceID(const Kolab::DateTime &rID, bool thisandfuture)
+{
+ d->recurrenceID = rID;
+ d->thisAndFuture = thisandfuture;
+}
+
+DateTime Todo::recurrenceID() const
+{
+ return d->recurrenceID;
+}
+
+bool Todo::thisAndFuture() const
+{
+ return d->thisAndFuture;
+}
+
+void Todo::setSummary(const std::string &summary)
+{
+ d->summary = summary;
+}
+
+std::string Todo::summary() const
+{
+ return d->summary;
+}
+
+void Todo::setDescription(const std::string &description)
+{
+ d->description = description;
+}
+
+std::string Todo::description() const
+{
+ return d->description;
+}
+
+void Todo::setPriority(int priority)
+{
+ d->priority = priority;
+}
+
+int Todo::priority() const
+{
+ return d->priority;
+}
+
+void Todo::setStatus(Status status)
+{
+ d->status = status;
+}
+
+Status Todo::status() const
+{
+ return d->status;
+}
+
+void Todo::setLocation(const std::string &location)
+{
+ d->location = location;
+}
+
+std::string Todo::location() const
+{
+ return d->location;
+}
+
+void Todo::setRecurrenceRule(const Kolab::RecurrenceRule &rrule)
+{
+ d->rrule = rrule;
+}
+
+RecurrenceRule Todo::recurrenceRule() const
+{
+ return d->rrule;
+}
+
+void Todo::setRecurrenceDates(const std::vector< DateTime > &dates)
+{
+ d->recurrenceDates = dates;
+}
+
+void Todo::addRecurrenceDate(const Kolab::DateTime &dt)
+{
+ d->recurrenceDates.push_back(dt);
+}
+
+std::vector< DateTime > Todo::recurrenceDates() const
+{
+ return d->recurrenceDates;
+}
+
+void Todo::setExceptionDates(const std::vector< DateTime > &dates)
+{
+ d->exceptionDates = dates;
+}
+
+void Todo::addExceptionDate(const Kolab::DateTime &dt)
+{
+ d->exceptionDates.push_back(dt);
+}
+
+std::vector< DateTime > Todo::exceptionDates() const
+{
+ return d->exceptionDates;
+}
+
+void Todo::setOrganizer(const std::string& email, const std::string& name)
+{
+ d->organizerEmail = email;
+ d->organizerName = name;
+}
+
+std::string Todo::organizerEmail() const
+{
+ return d->organizerEmail;
+}
+
+std::string Todo::organizerName() const
+{
+ return d->organizerName;
+}
+
+void Todo::setAttendees(const std::vector< Attendee > &attendees)
+{
+ d->attendees = attendees;
+}
+
+std::vector< Attendee > Todo::attendees() const
+{
+ return d->attendees;
+}
+
+void Todo::setAttachments(const std::vector< Attachment > &attach)
+{
+ d->attachments = attach;
+}
+
+std::vector< Attachment > Todo::attachments() const
+{
+ return d->attachments;
+}
+
+void Todo::setCustomProperties(const std::vector< CustomProperty > &prop)
+{
+ d->customProperties = prop;
+}
+
+std::vector< CustomProperty > Todo::customProperties() const
+{
+ return d->customProperties;
+}
+
+}
\ No newline at end of file
diff --git a/c++/lib/kolabtodo.h b/c++/lib/kolabtodo.h
new file mode 100644
index 0000000..60c677a
--- /dev/null
+++ b/c++/lib/kolabtodo.h
@@ -0,0 +1,97 @@
+
+
+#ifndef KOLAB_TODO_H
+#define KOLAB_TODO_H
+
+#include <string>
+#include <vector>
+#include <boost/scoped_ptr.hpp>
+#include "kolabcontainers.h"
+namespace Kolab {
+
+
+class Todo {
+public:
+ Todo();
+ ~Todo();
+ Todo(const Todo &);
+ void operator=(const Todo &);
+
+ void setUid(const std::string &);
+ std::string uid() const;
+
+ void setCreated(const DateTime &);
+ DateTime created() const;
+
+ void setLastModified(const DateTime &);
+ DateTime lastModified() const;
+
+ void setSequence(int);
+ int sequence() const;
+
+ void setClassification(Classification);
+ Classification classification() const;
+
+ void setCategories(const std::vector<std::string> &);
+ void addCategory(const std::string &);
+ std::vector<std::string> categories() const;
+
+ void setStart(const DateTime &);
+ DateTime start() const;
+
+ void setDue(const DateTime &);
+ DateTime due() const;
+
+ void setRecurrenceRule(const RecurrenceRule &);
+ RecurrenceRule recurrenceRule() const;
+
+ void setRecurrenceDates(const std::vector<DateTime> &);
+ void addRecurrenceDate(const DateTime &);
+ std::vector<DateTime> recurrenceDates() const;
+
+ void setExceptionDates(const std::vector<DateTime> &);
+ void addExceptionDate(const DateTime &);
+ std::vector<DateTime> exceptionDates() const;
+
+ void setRecurrenceID(const DateTime &, bool thisandfuture);
+ DateTime recurrenceID() const;
+ bool thisAndFuture() const;
+
+ void setSummary(const std::string &);
+ std::string summary() const;
+
+ void setDescription(const std::string &);
+ std::string description() const;
+
+ void setPriority(int);
+ int priority() const;
+
+ void setStatus(Status);
+ Status status() const;
+
+ void setPercentComplete(int);
+ int percentComplete() const;
+
+ void setLocation(const std::string &);
+ std::string location() const;
+
+ void setOrganizer(const std::string &email, const std::string &name);
+ std::string organizerEmail() const;
+ std::string organizerName() const;
+
+ void setAttendees(const std::vector<Attendee> &);
+ std::vector<Attendee> attendees() const;
+
+ void setAttachments(const std::vector<Attachment> &);
+ std::vector<Attachment> attachments() const;
+
+ void setCustomProperties(const std::vector<CustomProperty> &);
+ std::vector<CustomProperty> customProperties() const;
+private:
+ struct Private;
+ boost::scoped_ptr<Private> d;
+};
+
+}
+
+#endif
\ No newline at end of file
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index f45cc85..463636f 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -98,11 +98,9 @@ void BindingsTest::BenchmarkRoundtrip()
}
// void BindingsTest::eventCompletness_data()
-
-
-void BindingsTest::eventCompletness()
+template <typename T>
+void setIncidence(T &ev)
{
- Kolab::Event ev;
ev.setUid("UID");
ev.setCreated(Kolab::DateTime(2006,1,6,12,0,0)); //UTC
ev.setLastModified(Kolab::DateTime(2006,1,6,12,0,0));
@@ -110,9 +108,7 @@ void BindingsTest::eventCompletness()
ev.setClassification(Kolab::Confidential);
ev.addCategory("Category");
ev.setStart(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
- ev.setEnd(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
- //TODO duration
- ev.setTransparency(true);
+
Kolab::RecurrenceRule rule;
rule.setFrequency(Kolab::RecurrenceRule::Daily);
rule.setCount(5);
@@ -129,12 +125,11 @@ void BindingsTest::eventCompletness()
//Attendee
//attach
//x-prop
-
- std::string result = Kolab::writeKolabEvent(ev);
- std::cout << result << endl;
- boost::shared_ptr<Kolab::Event> e = Kolab::readKolabEvent(result, false);
- const Kolab::Event &re = *e;
-
+}
+
+template <typename T>
+void checkIncidence(const T &ev, const T &re)
+{
QCOMPARE(ev.uid(), re.uid());
QCOMPARE(ev.created(), re.created());
QCOMPARE(ev.lastModified(), re.lastModified());
@@ -143,8 +138,6 @@ void BindingsTest::eventCompletness()
QCOMPARE(ev.categories().size(), re.categories().size());
QCOMPARE(ev.categories().at(0), re.categories().at(0));
QCOMPARE(ev.start(), re.start());
- QCOMPARE(ev.end(), re.end());
- QCOMPARE(ev.transparency(), re.transparency());
const Kolab::RecurrenceRule &r1 = ev.recurrenceRule();
const Kolab::RecurrenceRule &r2 = re.recurrenceRule();
@@ -155,7 +148,6 @@ void BindingsTest::eventCompletness()
QCOMPARE(r1.count(), r2.count());
QCOMPARE(r1.end(), r2.end());
-// QCOMPARE(ev.recurrenceRule(), re.recurrenceRule());
QCOMPARE(ev.recurrenceDates().size(), re.recurrenceDates().size());
QCOMPARE(ev.recurrenceDates().at(0), re.recurrenceDates().at(0));
QCOMPARE(ev.exceptionDates().size(), re.exceptionDates().size());
@@ -166,6 +158,40 @@ void BindingsTest::eventCompletness()
QCOMPARE(ev.priority(), re.priority());
QCOMPARE(ev.status(), re.status());
QCOMPARE(ev.location(), re.location());
+}
+
+
+
+void BindingsTest::eventCompletness()
+{
+ Kolab::Event ev;
+ setIncidence(ev);
+ ev.setEnd(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
+ //TODO duration
+ ev.setTransparency(true);
+
+ std::string result = Kolab::writeKolabEvent(ev);
+// std::cout << result << endl;
+ boost::shared_ptr<Kolab::Event> e = Kolab::readKolabEvent(result, false);
+ const Kolab::Event &re = *e;
+ checkIncidence(ev, re);
+ QCOMPARE(ev.end(), re.end());
+ QCOMPARE(ev.transparency(), re.transparency());
+
+}
+
+void BindingsTest::todoCompletness()
+{
+ Kolab::Todo ev;
+ setIncidence(ev);
+ ev.setDue(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
+
+ std::string result = Kolab::writeKolabTodo(ev);
+// std::cout << result << endl;
+ boost::shared_ptr<Kolab::Todo> e = Kolab::readKolabTodo(result, false);
+ const Kolab::Todo &re = *e;
+ checkIncidence(ev, re);
+ QCOMPARE(ev.due(), re.due());
}
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index e9ef0ed..4e6205b 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -16,6 +16,7 @@ class BindingsTest : public QObject
void roundtripReverseEvent();
void BenchmarkRoundtrip();
void eventCompletness();
+ void todoCompletness();
};
#endif
\ No newline at end of file
commit 0dd6dfbcb04827d23ae229099783b63c6c9baa21
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Tue Dec 27 10:48:28 2011 +0100
singleton to share initialization
diff --git a/c++/compiled/XMLParserWrapper.h b/c++/compiled/XMLParserWrapper.h
index 5476871..40038f4 100644
--- a/c++/compiled/XMLParserWrapper.h
+++ b/c++/compiled/XMLParserWrapper.h
@@ -40,6 +40,11 @@ public:
XMLParserWrapper();
~XMLParserWrapper();
+ static XMLParserWrapper &inst(){
+ static XMLParserWrapper instance;
+ return instance;
+ };
+
xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseFile(const std::string &url);
xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseString(const std::string &s);
xml_schema::dom::auto_ptr<xercesc::DOMDocument> parse(std::istream &ifs, const std::string &name);
@@ -56,10 +61,6 @@ private:
xercesc::XMLGrammarPool *gp;
};
-// static XMLParserWrapper inst(){
-// static XMLParserWrapper instance;
-// return instance;
-// };
#endif
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 9234573..796ec9f 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -330,17 +330,15 @@ typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
// xml_schema::properties props;
std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
if (isUrl) {
- XMLParserWrapper wrapper;
- xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = wrapper.parseFile(s);
+ xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = XMLParserWrapper::inst().parseFile(s);
if (doc.get()) {
icalendar = icalendar_2_0::icalendar(doc);
}
// props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../../schemas/ical/kolabformat-xcal.xsd"); //Force schema
// icalendar = icalendar_2_0::icalendar(s, 0, props);
} else {
- XMLParserWrapper wrapper;
// props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "/home/chrigi/work/kolab/xmlformat/libkolabxml/schemas/ical/kolabformat-xcal.xsd"); //Force schema
- xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = wrapper.parseString(s);
+ xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = XMLParserWrapper::inst().parseString(s);
if (doc.get()) {
icalendar = icalendar_2_0::icalendar(doc);
}
commit 01b86d00fab7438cb61561b5c15fd16fb0fc78b5
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Tue Dec 27 10:35:20 2011 +0100
functions to copy exceptionDates and rDates
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 03d7c55..9234573 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -8,6 +8,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/numeric/conversion/converter_policies.hpp>
#include <boost/numeric/conversion/cast.hpp>
+#include <boost/foreach.hpp>
#include <fstream>
#include <iostream>
@@ -105,6 +106,26 @@ typename T::DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProp
return date;
}
+// template <typename T, typename I>
+// typename T::DatePtr toDate(const I &dtProperty)
+// {
+// typedef DateTimeConverter<typename T::DateType> DC;
+// typename T::DatePtr date;
+// if (dtProperty.date_time()) {
+// date = DC::toDate(*dtProperty.date_time());
+// } else if (dtProperty.date()) {
+// date = DC::toDate(*dtProperty.date());
+// }
+//
+// if (dtProperty.parameters()) {
+// const std::string &tzid = getTimezone(*dtProperty.parameters());
+// if (tzid.size()) {
+// DC::setTimezone(date, tzid);
+// }
+// }
+// return date;
+// }
+
template <typename T> typename T::DatePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
{
typedef typename T::DateType DateType;
@@ -175,6 +196,67 @@ void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const ty
}
}
+template <typename T, typename I>
+std::vector<typename T::DateType> toDateTimeList(I datelistProperty)
+{
+ typedef typename T::DateType DateType;
+ typedef DateTimeConverter<DateType> DC;
+
+ std::vector<DateType> list;
+
+ std::string tzid;
+ if (datelistProperty.parameters()) {
+ tzid = getTimezone(*datelistProperty.parameters());
+ }
+ if (!datelistProperty.date().empty()) {
+ BOOST_FOREACH(const xml_schema::date &d, datelistProperty.date()) {
+ list.push_back(*DC::toDate(d));
+ }
+ } else if (!datelistProperty.date_time().empty()) {
+ BOOST_FOREACH(const xml_schema::date_time &d, datelistProperty.date_time()) {
+ typename DC::Ptr date = DC::toDate(d);
+ if (tzid.size()) {
+ date->setTimezone(tzid);
+ }
+ list.push_back(*date);
+ }
+ }
+ return list;
+}
+
+template <typename T, typename I>
+std::auto_ptr<I> fromDateTimeList(const std::vector<typename T::DateType> &dtlist)
+{
+ typedef typename T::DateType DateType;
+ typedef typename T::DatePtr DatePtr;
+ typedef DateTimeConverter<DateType> DC;
+
+ std::auto_ptr<I> ptr(new I);
+ BOOST_FOREACH(const DateType &dt, dtlist) {
+ if (DC::isDateOnly(dt)) {
+ ptr->date().push_back(DC::fromDate(dt));
+ } else {
+ ptr->date_time().push_back(DC::fromDateTime(dt));
+ }
+ //TODO handle utc
+ //TODO check for equality of timezones?
+ }
+
+ if (!dtlist.empty() && !DC::getTimezone(dtlist.at(0)).empty()) {
+ const std::string &timezone = DC::getTimezone(dtlist.at(0));
+ if (timezone.size() != 0) {
+ std::string tz(TZ_PREFIX);
+ tz.append(timezone);
+ icalendar_2_0::TzidParamType tzidParam(tz);
+ icalendar_2_0::ArrayOfParameters parameters;
+ parameters.baseParameter().push_back(tzidParam);
+ ptr->parameters(parameters);
+ }
+ }
+
+ return ptr;
+}
+
///trait to convert recurrence properties
@@ -256,8 +338,8 @@ typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
// props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../../schemas/ical/kolabformat-xcal.xsd"); //Force schema
// icalendar = icalendar_2_0::icalendar(s, 0, props);
} else {
-// props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "/home/chrigi/work/kolab/xmlformat/libkolabxml/schemas/ical/kolabformat-xcal.xsd"); //Force schema
XMLParserWrapper wrapper;
+// props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "/home/chrigi/work/kolab/xmlformat/libkolabxml/schemas/ical/kolabformat-xcal.xsd"); //Force schema
xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = wrapper.parseString(s);
if (doc.get()) {
icalendar = icalendar_2_0::icalendar(doc);
@@ -287,7 +369,6 @@ typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
// return event;
// }
// }
-
return *incidences.begin();
} catch (const xml_schema::exception& e) {
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index c2bd4ee..0e34d4e 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -347,47 +347,14 @@ void setIncidenceProperties(Kolab::Event &inc, const T &prop)
}
if (prop.rdate()) {
- const icalendar_2_0::KolabEvent::properties_type::rdate_type &rdate = *prop.rdate();
- std::string tzid;
- if (rdate.parameters()) {
- tzid = getTimezone(*rdate.parameters());
- }
- if (!rdate.date().empty()) {
- BOOST_FOREACH(const xml_schema::date &d, rdate.date()) {
- inc.addRecurrenceDate(*DC::toDate(d));
- }
- } else if (!rdate.date_time().empty()) {
- BOOST_FOREACH(const xml_schema::date_time &d, rdate.date_time()) {
- DC::Ptr date = DC::toDate(d);
- if (tzid.size()) {
- date->setTimezone(tzid);
- }
- inc.addRecurrenceDate(*date);
- }
- } else if (!rdate.period().empty()) {
+ inc.setRecurrenceDates(toDateTimeList<KolabTypes, icalendar_2_0::KolabEvent::properties_type::rdate_type>(*prop.rdate()));
+ if (!prop.rdate()->period().empty()) {
std::cout << "the period element must not be used, ignored." << std::endl;
}
}
-
+
if (prop.exdate()) {
- const icalendar_2_0::KolabEvent::properties_type::exdate_type &exdate = *prop.exdate();
- std::string tzid;
- if (exdate.parameters()) {
- tzid = getTimezone(*exdate.parameters());
- }
- if (!exdate.date().empty()) {
- BOOST_FOREACH(const xml_schema::date &d, exdate.date()) {
- inc.exceptionDates().push_back(*DC::toDate(d));
- }
- } else if (!exdate.date_time().empty()) {
- BOOST_FOREACH(const xml_schema::date_time &d, exdate.date_time()) {
- DC::Ptr date = DC::toDate(d);
- if (tzid.size()) {
- date->setTimezone(tzid);
- }
- inc.exceptionDates().push_back(*date);
- }
- }
+ inc.setExceptionDates(toDateTimeList<KolabTypes, icalendar_2_0::KolabEvent::properties_type::exdate_type>(*prop.exdate()));
}
if (prop.recurrence_id()) {
@@ -508,6 +475,7 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
using namespace icalendar_2_0;
typedef T properties;
+ typedef DateTimeConverter< DateTime> DC;
prop.sequence(fromInt<xml_schema::integer>(inc.sequence()));
@@ -539,11 +507,11 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
}
if (!inc.recurrenceDates().empty()) {
- //TODO
+ prop.rdate(fromDateTimeList<KolabTypes, typename properties::rdate_type>(inc.recurrenceDates()));
}
if (!inc.exceptionDates().empty()) {
- //TODO
+ prop.exdate(fromDateTimeList<KolabTypes, typename properties::exdate_type>(inc.exceptionDates()));
}
if (inc.recurrenceID().isValid()) {
commit 1383fb863f5936f5c1343077d29f4da93f96aa4f
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Tue Dec 27 10:34:02 2011 +0100
With scoped_ptr the order of destruction is wrong
diff --git a/c++/compiled/XMLParserWrapper.cpp b/c++/compiled/XMLParserWrapper.cpp
index aef1b5a..2b1467d 100644
--- a/c++/compiled/XMLParserWrapper.cpp
+++ b/c++/compiled/XMLParserWrapper.cpp
@@ -27,7 +27,9 @@
#include "grammar-input-stream.hxx"
XMLParserWrapper::XMLParserWrapper()
-: ehp(eh)
+: ehp(eh),
+ parser(0),
+ gp(0)
{
// We need to initialize the Xerces-C++ runtime because we
// are doing the XML-to-DOM parsing ourselves.
@@ -39,8 +41,10 @@ XMLParserWrapper::XMLParserWrapper()
XMLParserWrapper::~XMLParserWrapper()
{
-// xercesc::XMLPlatformUtils::Terminate ();
-//FIXME if this is enabled we get a segfault, maybe because the scope_ptr are note yet destructed?
+ delete parser;
+ delete gp;
+ xercesc::XMLPlatformUtils::Terminate ();
+
}
@@ -48,7 +52,7 @@ void XMLParserWrapper::init()
{
using namespace std;
- if (parser.get()) {
+ if (parser) {
return;
}
try
@@ -60,7 +64,7 @@ void XMLParserWrapper::init()
//
MemoryManager* mm (XMLPlatformUtils::fgMemoryManager);
- gp.reset (new XMLGrammarPoolImpl (mm));
+ gp = new XMLGrammarPoolImpl (mm);
try
{
@@ -92,8 +96,8 @@ void XMLParserWrapper::init()
// Xerces-C++ 3.0.0 and later.
//
- parser.reset(impl->createLSParser (
- DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp.get ()));
+ parser = impl->createLSParser (
+ DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp);
DOMConfiguration* conf (parser->getDomConfig ());
@@ -157,9 +161,8 @@ void XMLParserWrapper::init()
// Same as above but for Xerces-C++ 2 series.
//
- parser.reset (
- impl->createDOMBuilder(
- DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp.get ()));
+ parser = impl->createDOMBuilder(
+ DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp);
parser->setFeature (XMLUni::fgDOMComments, false);
diff --git a/c++/compiled/XMLParserWrapper.h b/c++/compiled/XMLParserWrapper.h
index 8351cf9..5476871 100644
--- a/c++/compiled/XMLParserWrapper.h
+++ b/c++/compiled/XMLParserWrapper.h
@@ -49,12 +49,11 @@ private:
xsd::cxx::xml::dom::bits::error_handler_proxy<char> ehp;
#if _XERCES_VERSION >= 30000
- boost::scoped_ptr<xercesc::DOMLSParser> parser;
+ xercesc::DOMLSParser *parser;
#else
- boost::scoped_ptr<xercesc::DOMBuilder> parser;
+ xercesc::DOMBuilder *parser;
#endif
-
- boost::scoped_ptr<xercesc::XMLGrammarPool> gp;
+ xercesc::XMLGrammarPool *gp;
};
// static XMLParserWrapper inst(){
commit 7e69bd2fb4558891a7e5dd24357c9497dfaeff1e
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Tue Dec 27 10:19:17 2011 +0100
initialization
diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index 289e831..cfd94ad 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -38,7 +38,6 @@ DateTime::DateTime(int year, int month, int day, int hour, int minute, int secon
d->minute = minute;
d->second = second;
d->isUtc = isUtc;
- std::cout << "utc";
}
DateTime::DateTime(const std::string& timezone, int year, int month, int day, int hour, int minute, int second)
@@ -51,7 +50,6 @@ DateTime::DateTime(const std::string& timezone, int year, int month, int day, in
d->minute = minute;
d->second = second;
d->timezone = timezone;
- std::cout << "tz";
}
DateTime::DateTime(int year, int month, int day)
@@ -175,6 +173,12 @@ bool DateTime::isValid() const
struct RecurrenceRule::Private
{
+ Private()
+ : freq(None),
+ weekstart(Monday),
+ count(-1),
+ interval(1){};
+
Frequencey freq;
Weekday weekstart;
DateTime end;
@@ -359,7 +363,12 @@ bool RecurrenceRule::isValid() const
struct Event::Private
{
Private()
- : classification(Public){}
+ : sequence(0),
+ classification(Public),
+ thisAndFuture(false),
+ priority(0),
+ status(UndefinedStatus),
+ isTransparent(false){}
std::string uid;
DateTime created;
commit eb998ba7db804a8acba2c3dc673925b5010dad27
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Tue Dec 27 10:18:39 2011 +0100
check recurrence
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index fbd0c3c..f45cc85 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -145,6 +145,16 @@ void BindingsTest::eventCompletness()
QCOMPARE(ev.start(), re.start());
QCOMPARE(ev.end(), re.end());
QCOMPARE(ev.transparency(), re.transparency());
+
+ const Kolab::RecurrenceRule &r1 = ev.recurrenceRule();
+ const Kolab::RecurrenceRule &r2 = re.recurrenceRule();
+ QCOMPARE(r1.isValid(), r2.isValid());
+ QCOMPARE(r1.frequency(), r2.frequency());
+ QCOMPARE(r1.interval(), r2.interval());
+ QCOMPARE(r1.weekStart(), r2.weekStart());
+ QCOMPARE(r1.count(), r2.count());
+ QCOMPARE(r1.end(), r2.end());
+
// QCOMPARE(ev.recurrenceRule(), re.recurrenceRule());
QCOMPARE(ev.recurrenceDates().size(), re.recurrenceDates().size());
QCOMPARE(ev.recurrenceDates().at(0), re.recurrenceDates().at(0));
commit 9fd4fd76ac3be43174ee3fbcd7469d23f8828d79
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Mon Dec 26 19:28:15 2011 +0100
define strings centrally
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index dba9717..03d7c55 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -12,7 +12,20 @@
#include <fstream>
#include <iostream>
-#define TZ_PREFIX "/kolab.org/"
+const char* const TZ_PREFIX = "/kolab.org/";
+
+const char* const NEEDSACTION = "NEEDS-ACTION";
+const char* const COMPLETED = "OPAQUE";
+const char* const INPROCESS = "IN-PROCESS";
+const char* const CANCELLED = "CANCELLED";
+const char* const TENTATIVE = "TENTATIVE";
+const char* const CONFIRMED = "CONFIRMED";
+const char* const DRAFT = "DRAFT";
+const char* const FINAL = "FINAL";
+
+const char* const CONFIDENTIAL = "CONFIDENTIAL";
+const char* const PRIVATE = "PRIVATE";
+const char* const PUBLIC = "PUBLIC";
namespace Kolab {
@@ -162,6 +175,8 @@ void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const ty
}
}
+
+
///trait to convert recurrence properties
template <typename T>
struct RecurrenceConverter;
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 333d192..c2bd4ee 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -324,9 +324,9 @@ void setIncidenceProperties(Kolab::Event &inc, const T &prop)
if (prop.class_()) {
std::string string(toString(*prop.class_()));
Kolab::Classification sec = Public;
- if (string == "PRIVATE") {
+ if (string == PRIVATE) {
sec = Private;
- } else if (string == "CONFIDENTIAL") {
+ } else if (string == CONFIDENTIAL) {
sec = Confidential;
}
inc.setClassification(sec);
@@ -410,21 +410,21 @@ void setIncidenceProperties(Kolab::Event &inc, const T &prop)
if (prop.status()) {
const std::string &status = toString(*prop.status());
- if (status == "NEEDS-ACTION") {
+ if (status == NEEDSACTION) {
inc.setStatus(NeedsAction);
- } else if (status == "COMPLETED") {
+ } else if (status == COMPLETED) {
inc.setStatus(Completed);
- } else if (status == "IN-PROCESS") {
+ } else if (status == INPROCESS) {
inc.setStatus(InProcess);
- } else if (status == "CANCELLED") {
+ } else if (status == CANCELLED) {
inc.setStatus(Cancelled);
- } else if (status == "TENTATIVE") {
+ } else if (status == TENTATIVE) {
inc.setStatus(Tentative);
- } else if (status == "CONFIRMED") {
+ } else if (status == CONFIRMED) {
inc.setStatus(Confirmed);
- } else if (status == "DRAFT") {
+ } else if (status == DRAFT) {
inc.setStatus(Draft);
- } else if (status == "FINAL") {
+ } else if (status == FINAL) {
inc.setStatus(Final);
} else {
std::cout << "Unhandled status";
@@ -501,6 +501,7 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const Recurrenc
return rruleProp;
}
+
template <typename T>
void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form Event to template
{
@@ -512,13 +513,13 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
switch (inc.classification()) {
case Kolab::Confidential:
- prop.class_(typename properties::class_type("CONFIDENTIAL"));
+ prop.class_(typename properties::class_type(CONFIDENTIAL));
break;
case Kolab::Private:
- prop.class_(typename properties::class_type("PRIVATE"));
+ prop.class_(typename properties::class_type(PRIVATE));
break;
default:
- prop.class_(typename properties::class_type("PUBLIC"));
+ prop.class_(typename properties::class_type(PUBLIC));
break;
}
@@ -565,28 +566,28 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
if (inc.status() != UndefinedStatus) {
switch (inc.status()) {
case NeedsAction:
- prop.status(typename properties::status_type("NEEDS-ACTION"));
+ prop.status(typename properties::status_type(NEEDSACTION));
break;
case Completed:
- prop.status(typename properties::status_type("COMPLETED"));
+ prop.status(typename properties::status_type(COMPLETED));
break;
case InProcess:
- prop.status(typename properties::status_type("IN-PROCESS"));
+ prop.status(typename properties::status_type(INPROCESS));
break;
case Cancelled:
- prop.status(typename properties::status_type("CANCELLED"));
+ prop.status(typename properties::status_type(CANCELLED));
break;
case Tentative:
- prop.status(typename properties::status_type("TENTATIVE"));
+ prop.status(typename properties::status_type(TENTATIVE));
break;
case Confirmed:
- prop.status(typename properties::status_type("CONFIRMED"));
+ prop.status(typename properties::status_type(CONFIRMED));
break;
case Draft:
- prop.status(typename properties::status_type("DRAFT"));
+ prop.status(typename properties::status_type(DRAFT));
break;
case Final:
- prop.status(typename properties::status_type("FINAL"));
+ prop.status(typename properties::status_type(FINAL));
break;
default:
std::cout << "unhandled status " << inc.status() << std::endl;
commit 585c72f015793783bc5daa797acf3c78ee9bc269
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Mon Dec 26 19:22:42 2011 +0100
fixed transparency
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 1a0e41b..333d192 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -527,9 +527,7 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
}
if (inc.start().isValid()) {
- typename properties::dtstart_type dtstart;
- setDateTimeProperty<KolabTypes>(dtstart, inc.start());
- prop.dtstart(dtstart);
+ prop.dtstart(fromDate<KolabTypes, typename properties::dtstart_type>(inc.start()));
}
if (inc.recurrenceRule().isValid()) {
@@ -548,7 +546,8 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
}
if (inc.recurrenceID().isValid()) {
- //TODO
+ //TODO THISANDFUTURE
+ prop.recurrence_id(fromDate<KolabTypes, typename properties::recurrence_id_type>(inc.recurrenceID()));
}
if (!inc.summary().empty()) {
@@ -634,6 +633,9 @@ template <> struct IncidenceConverter < Incidence >
};
+const char* const TRANSPARENT = "TRANSPARENT";
+const char* const OPAQUE = "OPAQUE";
+
template < > struct IncidenceTrait <Kolab::Event>
{
typedef typename icalendar_2_0::KolabEvent KolabType;
@@ -648,12 +650,14 @@ template < > struct IncidenceTrait <Kolab::Event>
getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
if (event.end().isValid()) {
- icalendar_2_0::properties::dtend_type dtend;
- setDateTimeProperty<KolabTypes>(dtend, event.end());
- prop.dtend(dtend);
+ prop.dtend(fromDate<KolabTypes, typename icalendar_2_0::properties::dtend_type>(event.end()));
}/* else if (event.duration().isValid()) {
//TODO
}*/
+
+ if (event.transparency()) {
+ prop.transp( icalendar_2_0::properties::transp_type(TRANSPARENT));
+ }
}
static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc) //TODO to base trait
@@ -681,7 +685,14 @@ template < > struct IncidenceTrait <Kolab::Event>
//TODO check for equality of timespecs
if (prop.transp()) {
- //TODO implement
+ if (toString(*prop.transp()) == TRANSPARENT) {
+ event.setTransparency(true);
+ } else {
+ event.setTransparency(false);
+ if (toString(*prop.transp()) != OPAQUE) {
+ std::cerr << "wrong transparency value " << toString(*prop.transp()) << std::endl;
+ }
+ }
}
}
commit 3776922a7b47425f5b9a2f6cac7916c55b9ce5f5
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Mon Dec 26 19:22:26 2011 +0100
return auto_ptr instead of setProperty function
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 642bd33..dba9717 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -110,6 +110,33 @@ template <typename T> typename T::DatePtr toDate(const icalendar_2_0::UtcDatetim
return date;
}
+template <typename T, typename I>
+std::auto_ptr<I> fromDate(const typename T::DateType &dt)
+{
+ typedef typename T::DateType DateType;
+ typedef typename T::DatePtr DatePtr;
+ typedef DateTimeConverter<DateType> DC;
+
+ std::auto_ptr<I> ptr(new I);
+
+ if (DC::isDateOnly(dt)) {
+ ptr->date(DC::fromDate(dt));
+ } else {
+ ptr->date_time(DC::fromDateTime(dt));
+
+ const std::string &timezone = DC::getTimezone(dt);
+ if (timezone.size() != 0) {
+ std::string tz(TZ_PREFIX);
+ tz.append(timezone);
+ icalendar_2_0::TzidParamType tzidParam(tz);
+ icalendar_2_0::ArrayOfParameters parameters;
+ parameters.baseParameter().push_back(tzidParam);
+ ptr->parameters(parameters);
+ }
+ }
+ return ptr;
+}
+
template <typename T>
void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const typename T::DateType &dt)
commit 958ec4fb4b14b3b041fb0125f514adfe7ee7dbd2
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Mon Dec 26 17:55:52 2011 +0100
serialization code
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 59666a8..642bd33 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -12,7 +12,6 @@
#include <fstream>
#include <iostream>
-
#define TZ_PREFIX "/kolab.org/"
namespace Kolab {
@@ -226,7 +225,7 @@ typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
}
if (!icalendar.get()) {
- std::cerr << "failed to parse calendar!";
+ std::cerr << "failed to parse calendar!" << std::endl;
return IncidencePtr();
}
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index a9e1498..32251b0 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -49,6 +49,7 @@ enum Classification {
};
enum Status {
+ UndefinedStatus,
NeedsAction,
Completed,
InProcess,
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 2f822b7..1a0e41b 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -1,27 +1,6 @@
-// template <> struct DateTimeConverter<DateTime>
-// {
-// typedef typename boost::shared_ptr<DateTime> Ptr;
-// Ptr toDate(const xml_schema::date &dt)
-// {
-// Ptr date(new DateTime());
-//
-// return date;
-// }
-// Ptr toDate(const xml_schema::date_time &dt)
-// {
-// Ptr date(new DateTime());
-// return date;
-// }
-//
-// void setTimezone(Ptr date, const std::string &tzid )
-// {
-// date->setTimezone(tzid);
-// }
-// };
#include "conversions.h"
-
#include "kolabcontainers.h"
#include <boost/foreach.hpp>
@@ -54,11 +33,19 @@ std::auto_ptr<T> fromStringList(const std::vector<std::string> &list)
return ptr;
}
-void setString(icalendar_2_0::TextPropertyType &p, const std::string &s)
+std::string toString(const icalendar_2_0::TextPropertyType &s)
{
- p.text(s);
+ return s.text();
}
+// template <typename T>
+// std::auto_ptr<T> fromString(const std::string &s)
+// {
+// std::auto_ptr<T> ptr(new T());
+// p.text(s);
+// return ptr;
+// }
+
template <> struct DateTimeConverter<DateTime>
{
typedef DateTime Type;
@@ -308,8 +295,17 @@ template <> struct RecurrenceConverter < RecurrenceRule >
};
-
-
+void setCalAddress(const icalendar_2_0::CalAddressPropertyType &cal, std::string &email, std::string &name)
+{
+ if (cal.parameters()) {
+ for (icalendar_2_0::ArrayOfParameters::baseParameter_const_iterator it((*cal.parameters()).baseParameter().begin()); it != (*cal.parameters()).baseParameter().end(); it++) {
+ if (const icalendar_2_0::CnParamType * tz = dynamic_cast<const icalendar_2_0::CnParamType*> (&*it)) {
+ name = tz->text();
+ }
+ }
+ }
+ email = cal.cal_address();
+}
template <typename KolabType, typename T>
@@ -430,6 +426,8 @@ void setIncidenceProperties(Kolab::Event &inc, const T &prop)
inc.setStatus(Draft);
} else if (status == "FINAL") {
inc.setStatus(Final);
+ } else {
+ std::cout << "Unhandled status";
}
}
@@ -438,27 +436,29 @@ void setIncidenceProperties(Kolab::Event &inc, const T &prop)
}
if (prop.organizer()) {
-// icalendar_2_0::KolabEvent::properties_type::organizer();
-// inc.
-// KCalCore::Person person;
+ std::string email;
+ std::string name;
+ setCalAddress(*prop.organizer(), email, name);
+ inc.setOrganizer(email, name);
}
if (prop.attendee().size()) {
-
+ //TODO
}
if (prop.attach().size()) {
-
+ //TODO
}
if (prop.x_custom().size()) {
-
+ //TODO
}
}
template <typename T, typename I>
-xsd::cxx::tree::sequence <T> &toList(xsd::cxx::tree::sequence <T> &list, const std::vector<int> &input) {
+T fromList(const std::vector<int> &input) {
+ T list;
BOOST_FOREACH(int i, list) {
list.push_back(convertToInt<I>(i));
}
@@ -493,9 +493,11 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const Recurrenc
}
if (!r.bysecond().empty()) {
- RecurType::bysecond_sequence bysecond;
- recur.bysecond(toList<RecurType::bysecond_type, xml_schema::non_negative_integer>(bysecond, r.bysecond()));
+ recur.bysecond(fromList<RecurType::bysecond_sequence, xml_schema::non_negative_integer>(r.bysecond()));
}
+
+ //TODO remainting by rules
+
return rruleProp;
}
@@ -504,22 +506,28 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
{
using namespace icalendar_2_0;
+ typedef T properties;
+
prop.sequence(fromInt<xml_schema::integer>(inc.sequence()));
switch (inc.classification()) {
case Kolab::Confidential:
- prop.class_(properties::class_type("CONFIDENTIAL"));
+ prop.class_(typename properties::class_type("CONFIDENTIAL"));
break;
case Kolab::Private:
- prop.class_(properties::class_type("PRIVATE"));
+ prop.class_(typename properties::class_type("PRIVATE"));
break;
default:
- prop.class_(properties::class_type("PUBLIC"));
+ prop.class_(typename properties::class_type("PUBLIC"));
break;
}
+
+ if (!inc.categories().empty()) {
+ prop.categories(*fromStringList<typename properties::categories_type>(inc.categories()));
+ }
if (inc.start().isValid()) {
- properties::dtstart_type dtstart;
+ typename properties::dtstart_type dtstart;
setDateTimeProperty<KolabTypes>(dtstart, inc.start());
prop.dtstart(dtstart);
}
@@ -531,6 +539,82 @@ void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form
//TODO check if startdate matches the one of the event (it MUST)
}
+ if (!inc.recurrenceDates().empty()) {
+ //TODO
+ }
+
+ if (!inc.exceptionDates().empty()) {
+ //TODO
+ }
+
+ if (inc.recurrenceID().isValid()) {
+ //TODO
+ }
+
+ if (!inc.summary().empty()) {
+ prop.summary(typename properties::summary_type(inc.summary()));
+ }
+
+ if (!inc.description().empty()) {
+ prop.description(typename properties::description_type(inc.description()));
+ }
+
+ if (inc.priority() != 0) {
+ prop.priority(typename properties::priority_type(fromInt<typename properties::priority_type::integer_type>(inc.priority())));
+ }
+
+ if (inc.status() != UndefinedStatus) {
+ switch (inc.status()) {
+ case NeedsAction:
+ prop.status(typename properties::status_type("NEEDS-ACTION"));
+ break;
+ case Completed:
+ prop.status(typename properties::status_type("COMPLETED"));
+ break;
+ case InProcess:
+ prop.status(typename properties::status_type("IN-PROCESS"));
+ break;
+ case Cancelled:
+ prop.status(typename properties::status_type("CANCELLED"));
+ break;
+ case Tentative:
+ prop.status(typename properties::status_type("TENTATIVE"));
+ break;
+ case Confirmed:
+ prop.status(typename properties::status_type("CONFIRMED"));
+ break;
+ case Draft:
+ prop.status(typename properties::status_type("DRAFT"));
+ break;
+ case Final:
+ prop.status(typename properties::status_type("FINAL"));
+ break;
+ default:
+ std::cout << "unhandled status " << inc.status() << std::endl;
+ }
+
+ }
+
+ if (!inc.location().empty()) {
+ prop.location(typename properties::location_type(inc.location()));
+ }
+
+ if (!inc.organizerEmail().empty()) { //email is required
+ //TODO
+ }
+
+ if (!inc.attendees().empty()) {
+ //TODO
+ }
+
+ if (!inc.attachments().empty()) {
+ //TODO
+ }
+
+ if (!inc.customProperties().empty()) {
+ //TODO
+ }
+
}
template <> struct IncidenceConverter < Incidence >
@@ -568,7 +652,7 @@ template < > struct IncidenceTrait <Kolab::Event>
setDateTimeProperty<KolabTypes>(dtend, event.end());
prop.dtend(dtend);
}/* else if (event.duration().isValid()) {
-
+ //TODO
}*/
}
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 3a6e33a..fbd0c3c 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -97,6 +97,69 @@ void BindingsTest::BenchmarkRoundtrip()
}
}
+// void BindingsTest::eventCompletness_data()
+
+
+void BindingsTest::eventCompletness()
+{
+ Kolab::Event ev;
+ ev.setUid("UID");
+ ev.setCreated(Kolab::DateTime(2006,1,6,12,0,0)); //UTC
+ ev.setLastModified(Kolab::DateTime(2006,1,6,12,0,0));
+ ev.setSequence(1);
+ ev.setClassification(Kolab::Confidential);
+ ev.addCategory("Category");
+ ev.setStart(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
+ ev.setEnd(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
+ //TODO duration
+ ev.setTransparency(true);
+ Kolab::RecurrenceRule rule;
+ rule.setFrequency(Kolab::RecurrenceRule::Daily);
+ rule.setCount(5);
+ ev.setRecurrenceRule(rule);
+ ev.addRecurrenceDate(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
+ ev.addExceptionDate(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
+ ev.setRecurrenceID(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0), false);
+ ev.setSummary("summary");
+ ev.setDescription("description");
+ ev.setPriority(3);
+ ev.setStatus(Kolab::Confirmed);
+ ev.setLocation("location");
+ ev.setOrganizer("email","organizer");
+ //Attendee
+ //attach
+ //x-prop
+
+ std::string result = Kolab::writeKolabEvent(ev);
+ std::cout << result << endl;
+ boost::shared_ptr<Kolab::Event> e = Kolab::readKolabEvent(result, false);
+ const Kolab::Event &re = *e;
+
+ QCOMPARE(ev.uid(), re.uid());
+ QCOMPARE(ev.created(), re.created());
+ QCOMPARE(ev.lastModified(), re.lastModified());
+ QCOMPARE(ev.sequence(), re.sequence());
+ QCOMPARE(ev.classification(), re.classification());
+ QCOMPARE(ev.categories().size(), re.categories().size());
+ QCOMPARE(ev.categories().at(0), re.categories().at(0));
+ QCOMPARE(ev.start(), re.start());
+ QCOMPARE(ev.end(), re.end());
+ QCOMPARE(ev.transparency(), re.transparency());
+// QCOMPARE(ev.recurrenceRule(), re.recurrenceRule());
+ QCOMPARE(ev.recurrenceDates().size(), re.recurrenceDates().size());
+ QCOMPARE(ev.recurrenceDates().at(0), re.recurrenceDates().at(0));
+ QCOMPARE(ev.exceptionDates().size(), re.exceptionDates().size());
+ QCOMPARE(ev.exceptionDates().at(0), re.exceptionDates().at(0));
+ QCOMPARE(ev.recurrenceID(), re.recurrenceID());
+ QCOMPARE(ev.summary(), re.summary());
+ QCOMPARE(ev.description(), re.description());
+ QCOMPARE(ev.priority(), re.priority());
+ QCOMPARE(ev.status(), re.status());
+ QCOMPARE(ev.location(), re.location());
+
+}
+
+
QTEST_MAIN( BindingsTest )
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index 8fa93bc..e9ef0ed 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -15,6 +15,7 @@ class BindingsTest : public QObject
void roundtripEvent();
void roundtripReverseEvent();
void BenchmarkRoundtrip();
+ void eventCompletness();
};
#endif
\ No newline at end of file
commit af9d9ff9b72961c8e4709e31370830773cab6070
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Mon Dec 26 17:54:51 2011 +0100
use back_inserter
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 4634636..2f822b7 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -42,16 +42,16 @@ struct KolabTypes
std::vector<std::string> toStringList(const icalendar_2_0::TextListPropertyType &s)
{
std::vector<std::string> d;
- const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
- for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
- d.push_back(*it);
- }
+ std::copy(s.text().begin(), s.text().end(), std::back_inserter(d));
return d;
}
-std::string toString(const icalendar_2_0::TextPropertyType &s)
+template <typename T>
+std::auto_ptr<T> fromStringList(const std::vector<std::string> &list)
{
- return s.text();
+ std::auto_ptr<T> ptr(new T());
+ std::copy(list.begin(), list.end(), std::back_inserter(ptr->text()));
+ return ptr;
}
void setString(icalendar_2_0::TextPropertyType &p, const std::string &s)
commit 1f014ddc157718799091d128df444fb9ad1cf6db
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Mon Dec 26 17:53:56 2011 +0100
Don't pass around pointers of local objects
diff --git a/c++/compiled/XMLParserWrapper.cpp b/c++/compiled/XMLParserWrapper.cpp
index 4ac45fe..aef1b5a 100644
--- a/c++/compiled/XMLParserWrapper.cpp
+++ b/c++/compiled/XMLParserWrapper.cpp
@@ -27,6 +27,7 @@
#include "grammar-input-stream.hxx"
XMLParserWrapper::XMLParserWrapper()
+: ehp(eh)
{
// We need to initialize the Xerces-C++ runtime because we
// are doing the XML-to-DOM parsing ourselves.
@@ -149,7 +150,7 @@ void XMLParserWrapper::init()
// Set error handler.
//
// tree::error_handler<char> eh;
- xml::dom::bits::error_handler_proxy<char> ehp (eh);
+// xml::dom::bits::error_handler_proxy<char> ehp (eh);
conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp); //TODO does conf take a copy or should the ehp object live on?
#else // _XERCES_VERSION >= 30000
@@ -173,7 +174,7 @@ void XMLParserWrapper::init()
parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true);
//tree::error_handler<char> eh;
- xml::dom::bits::error_handler_proxy<char> ehp (eh);
+// xml::dom::bits::error_handler_proxy<char> ehp (eh);
parser->setErrorHandler (&ehp);
#endif // _XERCES_VERSION >= 30000
@@ -208,7 +209,7 @@ xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument > XMLParserWrapper::parse
xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument > XMLParserWrapper::parseString(const std::string& s)
{
std::istringstream is(s);
- return parse(is, "");
+ return parse(is, ""); //TODO set identifier?
}
diff --git a/c++/compiled/XMLParserWrapper.h b/c++/compiled/XMLParserWrapper.h
index a416097..8351cf9 100644
--- a/c++/compiled/XMLParserWrapper.h
+++ b/c++/compiled/XMLParserWrapper.h
@@ -6,6 +6,7 @@
#include <bindings/kolabformat-xcal.hxx>
#include <xsd/cxx/tree/error-handler.hxx>
#include <boost/scoped_ptr.hpp>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
#if _XERCES_VERSION >= 30000
# include <xercesc/dom/DOMLSParser.hpp>
@@ -38,15 +39,15 @@ class XMLParserWrapper {
public:
XMLParserWrapper();
~XMLParserWrapper();
-
+
xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseFile(const std::string &url);
xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseString(const std::string &s);
xml_schema::dom::auto_ptr<xercesc::DOMDocument> parse(std::istream &ifs, const std::string &name);
private:
void init();
-
xsd::cxx::tree::error_handler<char> eh;
-
+ xsd::cxx::xml::dom::bits::error_handler_proxy<char> ehp;
+
#if _XERCES_VERSION >= 30000
boost::scoped_ptr<xercesc::DOMLSParser> parser;
#else
commit 513176c5d03333010beb4f556c36bf9c99971e96
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 18:23:44 2011 +0100
comments
diff --git a/c++/compiled/XMLParserWrapper.h b/c++/compiled/XMLParserWrapper.h
index 643b61e..a416097 100644
--- a/c++/compiled/XMLParserWrapper.h
+++ b/c++/compiled/XMLParserWrapper.h
@@ -21,6 +21,19 @@
# include <xercesc/internal/XMLGrammarPool.hpp>
#endif
+/**
+ * This wrapper controls the lifetime of the parser object.
+ *
+ * Initializing the parser is much more expensive than parsing a single XML document, therefore the parser should be reused if possible.
+ *
+ * It might make sense to use a singleton internally to keep the parser alive between usages. Alternatively this object can be kept alive for as long as it makes sense.
+ *
+ * This class also encapsulates the initialization of the whole parser, which must be done manually because precomiled schemas are used (which greatly improves the initialization performance).
+ *
+ * Writing the document is static and doesn't need any initialization and is therefore not wrapped by this object.
+ *
+ */
+
class XMLParserWrapper {
public:
XMLParserWrapper();
commit fb047d2cab523de8e8fcfdade7e1101cbe55995f
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 18:23:25 2011 +0100
recompile if interface changed
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index 9ab88fc..ebce0f6 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -5,7 +5,7 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE
COMMAND swig -v -c++ -python -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE} kolabformat.i
COMMENT "Generating python bindings"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
- DEPENDS kolabformat.i
+ DEPENDS kolabformat.i kolabcontainers.h
VERBATIM
)
@@ -18,7 +18,7 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FI
COMMAND swig -v -c++ -php -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE} kolabformat.i
COMMENT "Generating php bindings"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
- DEPENDS kolabformat.i
+ DEPENDS kolabformat.i kolabcontainers.h
VERBATIM
)
SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PHP_SOURCE_FILE} PROPERTIES GENERATED 1)
commit fc1d2a09fb5ed9e7f614ca53d7a5acd19f95ea36
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 18:23:15 2011 +0100
remaining event setters/getters
diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index 32e9dd9..289e831 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -377,9 +377,17 @@ struct Event::Private
int priority;
Status status;
std::string location;
+ bool isTransparent;
RecurrenceRule rrule;
std::vector< DateTime > recurrenceDates;
std::vector< DateTime > exceptionDates;
+ std::string organizerEmail;
+ std::string organizerName;
+ Duration duration;
+
+ std::vector<Attendee> attendees;
+ std::vector<Attachment> attachments;
+ std::vector<CustomProperty> customProperties;
};
Event::Event()
@@ -484,6 +492,17 @@ DateTime Event::end() const
return d->end;
}
+void Event::setDuration(const Duration &duration)
+{
+ d->duration = duration;
+}
+
+Duration Event::duration() const
+{
+ return d->duration;
+}
+
+
void Event::setRecurrenceID(const Kolab::DateTime &rID, bool thisandfuture)
{
d->recurrenceID = rID;
@@ -590,10 +609,61 @@ std::vector< DateTime > Event::exceptionDates() const
return d->exceptionDates;
}
+void Event::setTransparency(bool isTransparent)
+{
+ d->isTransparent = isTransparent;
+}
+
+bool Event::transparency() const
+{
+ return d->isTransparent;
+}
+
+void Event::setOrganizer(const std::string& email, const std::string& name)
+{
+ d->organizerEmail = email;
+ d->organizerName = name;
+}
+
+std::string Event::organizerEmail() const
+{
+ return d->organizerEmail;
+}
+
+std::string Event::organizerName() const
+{
+ return d->organizerName;
+}
+
+void Event::setAttendees(const std::vector< Attendee > &attendees)
+{
+ d->attendees = attendees;
+}
+
+std::vector< Attendee > Event::attendees() const
+{
+ return d->attendees;
+}
+void Event::setAttachments(const std::vector< Attachment > &attach)
+{
+ d->attachments = attach;
+}
+std::vector< Attachment > Event::attachments() const
+{
+ return d->attachments;
+}
+void Event::setCustomProperties(const std::vector< CustomProperty > &prop)
+{
+ d->customProperties = prop;
+}
+std::vector< CustomProperty > Event::customProperties() const
+{
+ return d->customProperties;
+}
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index 118c597..a9e1498 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -62,6 +62,7 @@ enum Status {
struct DayPos
{
void operator=(const DayPos &){};
+ //TODO
};
@@ -141,6 +142,10 @@ private:
boost::scoped_ptr<Private> d;
};
+class Duration {
+ //TODO
+};
+
class Attendee {
//TODO
};
@@ -185,11 +190,11 @@ public:
void setEnd(const DateTime &);
DateTime end() const;
- void setDuration(int){}; //TODO duration type
- int duration() const{};
+ void setDuration(const Duration &);
+ Duration duration() const;
- void setTransparency(bool isTransparent){};
- bool transparency() const{};
+ void setTransparency(bool isTransparent);
+ bool transparency() const;
void setRecurrenceRule(const RecurrenceRule &);
RecurrenceRule recurrenceRule() const;
@@ -221,18 +226,18 @@ public:
void setLocation(const std::string &);
std::string location() const;
- void setOrganizer(const std::string &email, const std::string &name){};
- std::string organizerEmail() const{};
- std::string organizerName() const{};
+ void setOrganizer(const std::string &email, const std::string &name);
+ std::string organizerEmail() const;
+ std::string organizerName() const;
- void setAttendee(const std::vector<Attendee> &){};
- std::vector<Attendee> attendee() const{};
+ void setAttendees(const std::vector<Attendee> &);
+ std::vector<Attendee> attendees() const;
- void setAttachment(const std::vector<Attachment> &){};
- std::vector<Attachment> attachments() const {};
+ void setAttachments(const std::vector<Attachment> &);
+ std::vector<Attachment> attachments() const;
- void setCustomProperty(const std::vector<CustomProperty> &){};
- std::vector<CustomProperty> customProperties() const{};
+ void setCustomProperties(const std::vector<CustomProperty> &);
+ std::vector<CustomProperty> customProperties() const;
private:
struct Private;
boost::scoped_ptr<Private> d;
commit 503c7d9b22f74b190211a3f25824b3e035020e37
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 17:33:25 2011 +0100
fixed php bindings compilation
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index eddd649..9ab88fc 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -38,13 +38,13 @@ SET_TARGET_PROPERTIES(pythonbindings PROPERTIES OUTPUT_NAME "_kolabformat")
SET_TARGET_PROPERTIES(pythonbindings PROPERTIES PREFIX "")
-
-
#PHP
-#set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} `php-config --includes`" )
-# find_package(PHP4)
-# include_directories(${PHP4_INCLUDE_PATH})
-# add_library(phpbindings SHARED ${KOLAB_SWIG_SOURCE_FILES} ${KOLAB_SWIG_PHP_SOURCE_FILE})
-# # ADD_DEPENDENCIES(bindings generate_python_bindings)
-# SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
-# SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
+# set( PHP_INCLUDES "`php-config --includes`")
+set( CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${PHP_INCLUDES} )
+find_package(PHP4)
+include_directories(${PHP4_INCLUDE_PATH})
+add_library(phpbindings SHARED ${KOLAB_SWIG_PHP_SOURCE_FILE})
+target_link_libraries(phpbindings kolabxml xerces-c)
+# ADD_DEPENDENCIES(bindings generate_python_bindings)
+SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
+SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
commit a1ddd3cedf6fa73ef753ac2300743f3370cc401d
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 17:32:59 2011 +0100
testfiles for reference
diff --git a/c++/lib/test.php b/c++/lib/test.php
new file mode 100644
index 0000000..d477c46
--- /dev/null
+++ b/c++/lib/test.php
@@ -0,0 +1,16 @@
+//run using "php -d enable_dl=On -d extension=./kolabformat.so test.php"
+
+<?php
+include("kolabformat.php");
+
+$e = new Event();
+$d = new c_DateTime(1,1,1);
+print $e->exceptionDates()->size();
+$e->addExceptionDate( $d);
+print $e->exceptionDates()->size();
+
+?>
+
+
+
+
diff --git a/c++/lib/test.py b/c++/lib/test.py
new file mode 100644
index 0000000..821bc94
--- /dev/null
+++ b/c++/lib/test.py
@@ -0,0 +1,10 @@
+import kolabformat
+e = kolabformat.Event()
+
+ex = e.exceptionDates()
+ex.size()
+ex.push_back(kolabformat.DateTime(1,1,1))
+ex.size()
+e.exceptionDates().size()
+e.setExceptionDates(ex)
+e.exceptionDates().size()
commit 723c24a853e384e1cfeeff8bcd12163b9733f8b7
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 17:32:27 2011 +0100
check pointers
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index bcb81f6..59666a8 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -204,22 +204,23 @@ typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
typedef typename T::KolabType KolabType;
try {
- //TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
- xml_schema::properties props;
-
+// xml_schema::properties props;
std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
if (isUrl) {
- std::cout << "open file " << s;
XMLParserWrapper wrapper;
- xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = wrapper.parseFile(s);
- icalendar = icalendar_2_0::icalendar(doc);
+ xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = wrapper.parseFile(s);
+ if (doc.get()) {
+ icalendar = icalendar_2_0::icalendar(doc);
+ }
// props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../../schemas/ical/kolabformat-xcal.xsd"); //Force schema
// icalendar = icalendar_2_0::icalendar(s, 0, props);
} else {
- props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "/home/chrigi/work/kolab/xmlformat/libkolabxml/schemas/ical/kolabformat-xcal.xsd"); //Force schema
+// props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "/home/chrigi/work/kolab/xmlformat/libkolabxml/schemas/ical/kolabformat-xcal.xsd"); //Force schema
XMLParserWrapper wrapper;
xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = wrapper.parseString(s);
- icalendar = icalendar_2_0::icalendar(doc);
+ if (doc.get()) {
+ icalendar = icalendar_2_0::icalendar(doc);
+ }
// icalendar = readCompiledIncidence(is, "string");
// icalendar = icalendar_2_0::icalendar(is, 0, props);
}
commit 1361ff6aed4e1639e18b9997271a7e1a2d26a623
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 16:43:11 2011 +0100
fix python bindings
diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index c058719..22e1947 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -65,7 +65,9 @@ ADD_CUSTOM_TARGET(generate_bindings ALL DEPENDS ${SCHEMA_SOURCEFILES})
include_directories( ./ )
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
-add_library(kolabxml lib/kolabformat.cpp lib/kolabcontainers.cpp compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) #needed becuase the swig bindings need -fPIC
+
+add_library(kolabxml SHARED lib/kolabformat.cpp lib/kolabcontainers.cpp compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
target_link_libraries(kolabxml xerces-c)
add_library(kolabxmlkcal lib/kcalkolabformat.cpp ${SCHEMA_SOURCEFILES})
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index 58086b0..eddd649 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -1,14 +1,4 @@
-# add_custom_command(OUTPUT qt_wrap.c
-# COMMAND swig -c++ -python -I$QTPATH/include qt.i
-# COMMENT "Generating qt python bindings"
-# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-# DEPENDS qt.i
-# VERBATIM
-# )
-
-
-set(KOLAB_SWIG_SOURCE_FILES kolabformat.cpp conversions.h)
set(KOLAB_SWIG_PYTHON_SOURCE_FILE python_kolabformat_wrapper.cpp)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE}
@@ -18,14 +8,7 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE
DEPENDS kolabformat.i
VERBATIM
)
-add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/python_kolabcontainers_wrapper.cpp
- COMMAND swig -v -c++ -python -o ${CMAKE_CURRENT_BINARY_DIR}/python_kolabcontainers_wrapper.cpp kolabcontainers.i
- COMMENT "Generating python bindings"
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
- DEPENDS kolabcontainers.i
- VERBATIM
- )
-set(KOLAB_SWIG_PYTHON_SOURCE_FILE ${KOLAB_SWIG_PYTHON_SOURCE_FILE} python_kolabcontainers_wrapper.cpp)
+
SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PYTHON_SOURCE_FILE} PROPERTIES GENERATED 1)
ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
@@ -48,18 +31,20 @@ include_directories( ./ )
#PYTHON
find_package(PythonLibs)
include_directories(${PYTHON_INCLUDE_DIRS})
-add_library(pythonbindings SHARED ${KOLAB_SWIG_SOURCE_FILES} ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
+add_library(pythonbindings SHARED ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
+target_link_libraries(pythonbindings kolabxml xerces-c)
# ADD_DEPENDENCIES(bindings generate_python_bindings)
SET_TARGET_PROPERTIES(pythonbindings PROPERTIES OUTPUT_NAME "_kolabformat")
SET_TARGET_PROPERTIES(pythonbindings PROPERTIES PREFIX "")
+
#PHP
#set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} `php-config --includes`" )
-find_package(PHP4)
-include_directories(${PHP4_INCLUDE_PATH})
-add_library(phpbindings SHARED ${KOLAB_SWIG_SOURCE_FILES} ${KOLAB_SWIG_PHP_SOURCE_FILE})
-# ADD_DEPENDENCIES(bindings generate_python_bindings)
-SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
-SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
+# find_package(PHP4)
+# include_directories(${PHP4_INCLUDE_PATH})
+# add_library(phpbindings SHARED ${KOLAB_SWIG_SOURCE_FILES} ${KOLAB_SWIG_PHP_SOURCE_FILE})
+# # ADD_DEPENDENCIES(bindings generate_python_bindings)
+# SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
+# SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
diff --git a/c++/lib/DEVELOPMENT b/c++/lib/DEVELOPMENT
new file mode 100644
index 0000000..fe61d7d
--- /dev/null
+++ b/c++/lib/DEVELOPMENT
@@ -0,0 +1,13 @@
+
+
+== Kolab Containers ==
+
+While SWIG can handle all possible return values, the resulting code uses either a newly allocated object (return by value / or return by const reference), or passes back a pointer (return by reference/pointer).
+So return by const reference doesn't save anything for the bindings (it could potentially for c++ code).
+Returning references contains the danger of dangling pointers if the reference outlives the object.
+
+Datamembers are not directly exposed to provide binary compatibilty through the d-pointer.
+
+Providing non-const references to the value through an accessor function doesn't work because it couldn't be called on const objects (even to read the value).
+
+Therefore providing a setter + a getter which returns by copy seems the safest way. A const ref getter could be provided if needed (I doubt it would ever help).
diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index 973048c..32e9dd9 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -295,12 +295,12 @@ std::vector< int > RecurrenceRule::byhour() const
return d->byhour;
}
-void RecurrenceRule::setByday(const std::vector< RecurrenceRule::DayPos > &by)
+void RecurrenceRule::setByday(const std::vector< DayPos > &by)
{
d->byday = by;
}
-std::vector< RecurrenceRule::DayPos > RecurrenceRule::byday() const
+std::vector< DayPos > RecurrenceRule::byday() const
{
return d->byday;
}
@@ -378,6 +378,8 @@ struct Event::Private
Status status;
std::string location;
RecurrenceRule rrule;
+ std::vector< DateTime > recurrenceDates;
+ std::vector< DateTime > exceptionDates;
};
Event::Event()
@@ -386,6 +388,12 @@ Event::Event()
}
+Event::Event(const Event &other)
+: d(new Event::Private())
+{
+ *d = *other.d;
+}
+
Event::~Event()
{
@@ -552,6 +560,40 @@ RecurrenceRule Event::recurrenceRule() const
return d->rrule;
}
+void Event::setRecurrenceDates(const std::vector< DateTime > &dates)
+{
+ d->recurrenceDates = dates;
+}
+
+void Event::addRecurrenceDate(const Kolab::DateTime &dt)
+{
+ d->recurrenceDates.push_back(dt);
+}
+
+std::vector< DateTime > Event::recurrenceDates() const
+{
+ return d->recurrenceDates;
+}
+
+void Event::setExceptionDates(const std::vector< DateTime > &dates)
+{
+ d->exceptionDates = dates;
+}
+
+void Event::addExceptionDate(const Kolab::DateTime &dt)
+{
+ d->exceptionDates.push_back(dt);
+}
+
+std::vector< DateTime > Event::exceptionDates() const
+{
+ return d->exceptionDates;
+}
+
+
+
+
+
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index 7b11638..118c597 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -4,6 +4,7 @@
#include <vector>
#include <boost/scoped_ptr.hpp>
+
namespace Kolab {
class DateTime {
@@ -58,6 +59,12 @@ enum Status {
Final
};
+struct DayPos
+{
+ void operator=(const DayPos &){};
+};
+
+
class RecurrenceRule {
public:
@@ -112,11 +119,6 @@ public:
void setByhour(const std::vector<int> &);
std::vector<int> byhour() const;
- struct DayPos
- {
- void operator=(const DayPos &){};
- };
-
void setByday(const std::vector<DayPos> &);
std::vector<DayPos> byday() const;
@@ -183,19 +185,21 @@ public:
void setEnd(const DateTime &);
DateTime end() const;
- void setDuration(int); //TODO duration type
- int duration() const;
+ void setDuration(int){}; //TODO duration type
+ int duration() const{};
- void setTransparency(bool isTransparent);
- bool transparency() const;
+ void setTransparency(bool isTransparent){};
+ bool transparency() const{};
void setRecurrenceRule(const RecurrenceRule &);
RecurrenceRule recurrenceRule() const;
- void setRecrrenceDates(const std::vector<DateTime> &);
+ void setRecurrenceDates(const std::vector<DateTime> &);
+ void addRecurrenceDate(const DateTime &);
std::vector<DateTime> recurrenceDates() const;
void setExceptionDates(const std::vector<DateTime> &);
+ void addExceptionDate(const DateTime &);
std::vector<DateTime> exceptionDates() const;
void setRecurrenceID(const DateTime &, bool thisandfuture);
@@ -217,18 +221,18 @@ public:
void setLocation(const std::string &);
std::string location() const;
- void setOrganizer(const std::string &email, const std::string &name);
- std::string organizerEmail() const;
- std::string organizerName() const;
+ void setOrganizer(const std::string &email, const std::string &name){};
+ std::string organizerEmail() const{};
+ std::string organizerName() const{};
- void setAttendee(const std::vector<Attendee> &);
- std::vector<Attendee> attendee() const;
+ void setAttendee(const std::vector<Attendee> &){};
+ std::vector<Attendee> attendee() const{};
- void setAttachment(const std::vector<Attachment> &);
- std::vector<Attachment> attachments() const;
+ void setAttachment(const std::vector<Attachment> &){};
+ std::vector<Attachment> attachments() const {};
- void setCustomProperty(const std::vector<CustomProperty> &);
- std::vector<CustomProperty> customProperties() const;
+ void setCustomProperty(const std::vector<CustomProperty> &){};
+ std::vector<CustomProperty> customProperties() const{};
private:
struct Private;
boost::scoped_ptr<Private> d;
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 220e520..4634636 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -181,6 +181,7 @@ template <> struct RecurrenceConverter < RecurrenceRule >
default:
std::cout << "invalid unhandled recurrenc type";
}
+ return 0;
}
static void setWeekStart(Ptr r, const icalendar_2_0::RecurType::wkst_type &wkst)
@@ -258,7 +259,7 @@ template <> struct RecurrenceConverter < RecurrenceRule >
static void setByday(Ptr r, const icalendar_2_0::RecurType::byday_sequence &list)
{
- std::vector<RecurrenceRule::DayPos> by;
+ std::vector<DayPos> by;
for (icalendar_2_0::RecurType::byday_const_iterator it(list.begin()); it != list.end(); it++) {
//TODO implement parser for format
// switch () {
diff --git a/c++/lib/kolabformat.i b/c++/lib/kolabformat.i
index 3024baf..b4dd3f9 100644
--- a/c++/lib/kolabformat.i
+++ b/c++/lib/kolabformat.i
@@ -1,15 +1,26 @@
/* kolabformat.i */
- %module kolabformat
- %{
- /* Put header files here or function declarations like below */
- #include "kolabformat.h"
- %}
-%include "std_string.i"
+%module kolabformat
+%{
-/*%apply const std::string& {std::string* foo};*/
-namespace Kolab {
+ /* This macro ensures that return vectors remain a vector also in python and are note converted to tuples */
+ #define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS
+ /* Put header files here or function declarations like below */
+ #include "kolabformat.h"
+ #include "kolabcontainers.h"
-}
+%}
+
+%include "std_string.i"
+%include "std_vector.i"
+
+namespace std {
+ %template(vectori) vector<int>;
+ %template(vectors) vector<string>;
+ %template(vectordate) vector<Kolab::DateTime>;
+ %template(vectordaypos) vector<Kolab::DayPos>;
+};
+
+/*%apply const std::string& {std::string* foo};*/
-/*extern void readEvent(const QString &string, KCalCore::Event &); */
+%include "kolabcontainers.h"
commit 297bc90c6b42c3edf3685d7b427a51bf62b0a21d
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 16:41:35 2011 +0100
implement rdate /exdate parsing
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
index 98391e3..220e520 100644
--- a/c++/lib/kolabconversions.h
+++ b/c++/lib/kolabconversions.h
@@ -348,36 +348,51 @@ void setIncidenceProperties(Kolab::Event &inc, const T &prop)
KolabTypes::RecurrencePtr rrule = toRRule<KolabTypes>(prop.rrule()->recur());
inc.setRecurrenceRule(*rrule);
}
-//
-// if (prop.rdate()) {
-// const icalendar_2_0::KolabEvent::properties_type::rdate_type &rdate = *prop.rdate();
-// std::string tzid;
-// if (rdate.parameters()) {
-// tzid = getTimezone(*rdate.parameters());
-// }
-// if (rdate.date().size()) {
-// Q_FOREACH(const xml_schema::date &d, rdate.date()) {
-// recurrence->addRDate(DC::toDate(d)->date());
-// }
-// } else if (rdate.date_time().size()) {
-// Q_FOREACH(const xml_schema::date_time &d, rdate.date_time()) {
-// DC::Ptr date = DC::toDate(d);
-// if (tzid.size()) {
-// DC::setTimezone(date, tzid);
-// }
-// recurrence->addRDateTime(*date);
-// }
-// } else if (rdate.period().size()) {
-// kDebug() << "the period element must not be used, ignored.";
-// }
-// }
-//
-// if (prop.exdate()) {
-// //TODO
-// // recurrence->addExDate();
-// // recurrence->addExDateTime();
-// }
-//
+
+ if (prop.rdate()) {
+ const icalendar_2_0::KolabEvent::properties_type::rdate_type &rdate = *prop.rdate();
+ std::string tzid;
+ if (rdate.parameters()) {
+ tzid = getTimezone(*rdate.parameters());
+ }
+ if (!rdate.date().empty()) {
+ BOOST_FOREACH(const xml_schema::date &d, rdate.date()) {
+ inc.addRecurrenceDate(*DC::toDate(d));
+ }
+ } else if (!rdate.date_time().empty()) {
+ BOOST_FOREACH(const xml_schema::date_time &d, rdate.date_time()) {
+ DC::Ptr date = DC::toDate(d);
+ if (tzid.size()) {
+ date->setTimezone(tzid);
+ }
+ inc.addRecurrenceDate(*date);
+ }
+ } else if (!rdate.period().empty()) {
+ std::cout << "the period element must not be used, ignored." << std::endl;
+ }
+ }
+
+ if (prop.exdate()) {
+ const icalendar_2_0::KolabEvent::properties_type::exdate_type &exdate = *prop.exdate();
+ std::string tzid;
+ if (exdate.parameters()) {
+ tzid = getTimezone(*exdate.parameters());
+ }
+ if (!exdate.date().empty()) {
+ BOOST_FOREACH(const xml_schema::date &d, exdate.date()) {
+ inc.exceptionDates().push_back(*DC::toDate(d));
+ }
+ } else if (!exdate.date_time().empty()) {
+ BOOST_FOREACH(const xml_schema::date_time &d, exdate.date_time()) {
+ DC::Ptr date = DC::toDate(d);
+ if (tzid.size()) {
+ date->setTimezone(tzid);
+ }
+ inc.exceptionDates().push_back(*date);
+ }
+ }
+ }
+
if (prop.recurrence_id()) {
//TODO THISANDFUTURE range
bool thisandfuture = true;
commit 2d1862ad6dcf6e4837a5acfeb0227030b986781b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 16:41:08 2011 +0100
update testfile to not use unsupported properties
diff --git a/c++/tests/testfiles/icalEvent.xml b/c++/tests/testfiles/icalEvent.xml
index 8f6d8c7..1c72be8 100644
--- a/c++/tests/testfiles/icalEvent.xml
+++ b/c++/tests/testfiles/icalEvent.xml
@@ -40,15 +40,16 @@
<count>5</count>
</recur>
</rrule>
-<!-- <rdate>
+ <rdate>
<parameters>
- <tzid><text>US/Eastern</text></tzid>
+ <tzid><text>/kolab.org/US/Eastern</text></tzid>
</parameters>
- <period>
+ <date-time>2007-02-06T00:11:21</date-time>
+ <!-- <period>
<start>2006-01-02T15:00:00</start>
<duration>PT2H</duration>
- </period>
- </rdate>-->
+ </period>-->
+ </rdate>
<summary>
<text>Event #2</text>
</summary>
commit 9ba5c27e57caa2f249cf0b3a4e91dee12a4dfd68
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 16:40:51 2011 +0100
fix testfile position for out of source build
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 7b7e75e..3a6e33a 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -39,7 +39,7 @@ namespace QTest {
void BindingsTest::readEvent()
{
- boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("testfiles/icalEvent.xml", true);
+ boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("../../tests/testfiles/icalEvent.xml", true);
QVERIFY(event);
QCOMPARE(event->created(), Kolab::DateTime(2006,2,6,0,11,21,true));
QCOMPARE(event->start(), Kolab::DateTime("US/Eastern",2006,1,2,12,0,0));
@@ -81,7 +81,7 @@ void BindingsTest::roundtripEvent()
void BindingsTest::roundtripReverseEvent()
{
- boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("testfiles/icalEvent.xml", true);
+ boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("../../tests/testfiles/icalEvent.xml", true);
kDebug() << "-------------------";
std::cout << Kolab::writeKolabEvent(*event) << std::endl;
kDebug() << "-------------------";
@@ -89,7 +89,7 @@ void BindingsTest::roundtripReverseEvent()
void BindingsTest::BenchmarkRoundtrip()
{
- boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("testfiles/icalEvent.xml", true);
+ boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("../../tests/testfiles/icalEvent.xml", true);
std::string result;
QBENCHMARK {
result = Kolab::writeKolabEvent(*event);
commit 409bb56ef87f137608a252921cbf7787ded70e81
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 11:45:42 2011 +0100
handle exceptions, initialize only once
diff --git a/c++/compiled/XMLParserWrapper.cpp b/c++/compiled/XMLParserWrapper.cpp
index 43fe477..4ac45fe 100644
--- a/c++/compiled/XMLParserWrapper.cpp
+++ b/c++/compiled/XMLParserWrapper.cpp
@@ -46,7 +46,10 @@ XMLParserWrapper::~XMLParserWrapper()
void XMLParserWrapper::init()
{
using namespace std;
-
+
+ if (parser.get()) {
+ return;
+ }
try
{
using namespace xercesc;
@@ -179,13 +182,10 @@ void XMLParserWrapper::init()
//
}
- catch (const xml_schema::exception& e)
- {
+ catch (const xml_schema::exception& e) {
cout << "schema exception" << endl;
cerr << e << endl;
- }
- catch (const std::ios_base::failure&)
- {
+ } catch (const std::ios_base::failure&) {
cerr << ": unable to open or read failure" << endl;
}
@@ -193,10 +193,16 @@ void XMLParserWrapper::init()
xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument > XMLParserWrapper::parseFile(const std::string& url)
{
- std::ifstream ifs;
- ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit); //TODO handle exceptions
- ifs.open (url.c_str());
- return parse(ifs, url);
+ try {
+ std::ifstream ifs;
+ ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit); //TODO handle exceptions
+ ifs.open (url.c_str());
+ return parse(ifs, url);
+ } catch (const std::ios_base::failure&)
+ {
+ std::cerr << ": unable to open or read failure" << std::endl;
+ }
+ return xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument >();
}
xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument > XMLParserWrapper::parseString(const std::string& s)
commit 3f17f9f70979f227b84debac0eaf0ba43f766227
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 11:35:49 2011 +0100
build directory to gitignore
diff --git a/c++/.gitignore b/c++/.gitignore
index 51ea4cc..a007fea 100644
--- a/c++/.gitignore
+++ b/c++/.gitignore
@@ -1 +1 @@
-bindings/*
+build/*
commit 97ba08fe7c778946e85204d8d25b5412daa6e38b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 11:35:13 2011 +0100
fix compile
diff --git a/schemas/kolabformat.xsd b/schemas/kolabformat.xsd
index f780c2a..33d85c4 100644
--- a/schemas/kolabformat.xsd
+++ b/schemas/kolabformat.xsd
@@ -6,8 +6,8 @@
xmlns="http://kolab.org"
elementFormDefault="qualified">
- <xs:import schemaLocation="iCalendar.xsd" namespace="urn:ietf:params:xml:ns:icalendar-2.0"/>
- <xs:import schemaLocation="xCard.xsd" namespace="urn:ietf:params:xml:ns:vcard-4.0"/>
+<!-- <xs:import schemaLocation="iCalendar.xsd" namespace="urn:ietf:params:xml:ns:icalendar-2.0"/>
+ <xs:import schemaLocation="xCard.xsd" namespace="urn:ietf:params:xml:ns:vcard-4.0"/>-->
<xs:complexType name="KolabBase">
@@ -37,7 +37,7 @@
</xs:complexContent>
</xs:complexType>-->
- <xs:element name="note" type="Note"/>
+<!-- <xs:element name="note" type="Note"/>
<xs:complexType name="Note">
<xs:complexContent mixed="false">
<xs:extension base="KolabBase">
@@ -46,7 +46,7 @@
</xs:sequence>
</xs:extension>
</xs:complexContent>
- </xs:complexType>
+ </xs:complexType>-->
<!-- <xs:element name="contact" type="Contact"/>
<xs:complexType name="Contact">
commit c57363b0a795c5a730f3f2382a80bbcaeaef33e0
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 11:35:01 2011 +0100
out of source build
diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 64e4c12..c058719 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -8,8 +8,8 @@ include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
set(CMAKE_BUILD_TYPE Debug)
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" )
-
-file(MAKE_DIRECTORY bindings)
+set(CMAKE_BUILD_DIR build)
+file(MAKE_DIRECTORY ${CMAKE_BUILD_DIR}/bindings)
set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )
set( XSDCXX /usr/bin/xsdcxx)
@@ -37,7 +37,7 @@ set( SCHEMA_SOURCEFILES
# --generate-inline --extern-xml-schema xml-schema.xsd
# --cxx-suffix .cpp --hxx-suffix .h
add_custom_command(OUTPUT ${SCHEMA_SOURCEFILES}
- COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element icalendar --output-dir bindings ${SCHEMAS}
+ COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element icalendar --output-dir ${CMAKE_BUILD_DIR}/bindings ${SCHEMAS}
COMMENT "Generating XSD bindings"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS ${XCAL_SCHEMAS}
@@ -48,22 +48,22 @@ add_custom_command(OUTPUT ${SCHEMA_SOURCEFILES}
add_executable(xsdbin compiled/xsdbin.cxx)
target_link_libraries(xsdbin xerces-c)
-add_custom_command(OUTPUT compiled/kolabformat-xcal-schema.cxx
- COMMAND ${xsdbin} ./xsdbin --verbose --array-name iCalendar_schema --output-dir compiled/ ${SCHEMA_DIR}/ical/kolabformat-xcal.xsd ${SCHEMA_DIR}/ical/iCalendar-params.xsd ${SCHEMA_DIR}/ical/iCalendar-props.xsd ${SCHEMA_DIR}/ical/iCalendar-valtypes.xsd
+add_custom_command(OUTPUT kolabformat-xcal-schema.cxx
+ COMMAND ${CMAKE_BUILD_DIR}/xsdbin --verbose --array-name iCalendar_schema --output-dir ${CMAKE_BUILD_DIR} ${SCHEMA_DIR}/ical/kolabformat-xcal.xsd ${SCHEMA_DIR}/ical/iCalendar-params.xsd ${SCHEMA_DIR}/ical/iCalendar-props.xsd ${SCHEMA_DIR}/ical/iCalendar-valtypes.xsd
COMMENT "Compiling Kolab XSD schema"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS ${XCAL_SCHEMAS} xsdbin
VERBATIM
)
-set( SCHEMA_SOURCEFILES ${SCHEMA_SOURCEFILES} compiled/kolabformat-xcal-schema.cxx)
+set( SCHEMA_SOURCEFILES ${SCHEMA_SOURCEFILES} ${CMAKE_BUILD_DIR}/kolabformat-xcal-schema.cxx)
# ---------
SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
-
ADD_CUSTOM_TARGET(generate_bindings ALL DEPENDS ${SCHEMA_SOURCEFILES})
include_directories( ./ )
+include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
add_library(kolabxml lib/kolabformat.cpp lib/kolabcontainers.cpp compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
target_link_libraries(kolabxml xerces-c)
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index 9804106..58086b0 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -7,18 +7,19 @@
# VERBATIM
# )
+
set(KOLAB_SWIG_SOURCE_FILES kolabformat.cpp conversions.h)
set(KOLAB_SWIG_PYTHON_SOURCE_FILE python_kolabformat_wrapper.cpp)
-add_custom_command(OUTPUT ${KOLAB_SWIG_PYTHON_SOURCE_FILE}
- COMMAND swig -v -c++ -python -o ${KOLAB_SWIG_PYTHON_SOURCE_FILE} kolabformat.i
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE}
+ COMMAND swig -v -c++ -python -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PYTHON_SOURCE_FILE} kolabformat.i
COMMENT "Generating python bindings"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS kolabformat.i
VERBATIM
)
-add_custom_command(OUTPUT python_kolabcontainers_wrapper.cpp
- COMMAND swig -v -c++ -python -o python_kolabcontainers_wrapper.cpp kolabcontainers.i
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/python_kolabcontainers_wrapper.cpp
+ COMMAND swig -v -c++ -python -o ${CMAKE_CURRENT_BINARY_DIR}/python_kolabcontainers_wrapper.cpp kolabcontainers.i
COMMENT "Generating python bindings"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS kolabcontainers.i
@@ -30,8 +31,8 @@ ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_PYTHON_SOURC
set(KOLAB_SWIG_PHP_SOURCE_FILE php_kolabformat_wrapper.cpp)
-add_custom_command(OUTPUT ${KOLAB_SWIG_PHP_SOURCE_FILE}
- COMMAND swig -v -c++ -php -o ${KOLAB_SWIG_PHP_SOURCE_FILE} kolabformat.i
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE}
+ COMMAND swig -v -c++ -php -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE} kolabformat.i
COMMENT "Generating php bindings"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS kolabformat.i
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index a922628..822015d 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -1,5 +1,5 @@
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
-
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
# QT4_WRAP_CPP(kcalconversiontest_MOC kcalconversiontest.h)
#add_test("conversiontest" kcalconversiontest ${kolabproxy_shared_relative_SRCS} ${AKONADI_COLLECTIONATTRIBUTES_SHARED_SOURCES} kcalconversiontest.cpp)
@@ -8,7 +8,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
#QT4_WRAP_CPP(BINDINGSTEST_MOC bindingstest.cpp)
QT4_AUTOMOC(bindingstest.cpp)
-add_executable(bindingstest bindingstest.cpp ${BINDINGSTEST_MOC})
+add_executable(bindingstest bindingstest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabxml xerces-c kcalcore)
# QT4_AUTOMOC(kcalconversiontest.cpp)
commit e84d3476e911fab9d413fa25de74b5c99a2cfc79
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 10:16:25 2011 +0100
removed some old unused testcode
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 4a2d369..7b7e75e 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -3,8 +3,6 @@
#include <QObject>
#include <QtTest/QtTest>
-#include "bindings/note.hxx"
-#include "bindings/iCalendar.hxx"
#include "bindings/iCalendar-props.hxx"
#include "bindings/iCalendar-valtypes.hxx"
#include "bindings/kolabformat.hxx"
@@ -13,324 +11,10 @@
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
-#include <bindings/contact.hxx>
-#include <kcalcore/event.h>
#include <lib/kolabformat.h>
#include <kdebug.h>
-// void BindingsTest::writeNoteTest()
-// {
-// xml_schema::date_time datetime(2011, 11, 23, 12, 12, 12);
-// KolabXSD_test::XMLBase::sensitivity_type sensitivity = KolabXSD_test::Sensitivity::public_;
-// KolabXSD_test::Note::background_color_type bg = KolabXSD_test::Note::background_color_default_value();
-// KolabXSD_test::Note::foreground_color_type fg = KolabXSD_test::Note::foreground_color_default_value();
-// KolabXSD_test::Note note("test", "test", datetime, datetime, sensitivity, "", bg, fg);
-//
-// xml_schema::namespace_infomap map;
-// map[""].name = "http://kolab.org";
-// map[""].schema = "note.xsd";
-//
-// KolabXSD_test::note (std::cout, note, map);
-//
-// /* QFETCH(KCalCore::Recurrence, kcalrecurrence);
-//
-// KolabXSD::Recurrence ret = Kolab::KCalConversion::fromKCal( &kcalrecurrence );
-// QCOMPARE(frequency(ret), kcalrecurrence.rRules().first()->frequency());
-// */
-// }
-
-// void BindingsTest::readNoteTest()
-// {
-// try {
-// xml_schema::properties props;
-// // props.no_namespace_schema_location ("../../schemas/note.xsd");
-// // props.schema_location ("http://kolab.org", "../../schemas/note.xsd"); //Force schema
-// std::auto_ptr<KolabXSD_test::Note> note(KolabXSD_test::note("testfiles/testnote.xml", xml_schema::flags::keep_dom | xml_schema::flags::dont_validate, props));
-//
-// xml_schema::namespace_infomap map;
-// map[""].name = "http://kolab.org";
-// map[""].schema = "note.xsd";
-//
-// KolabXSD_test::note (std::cout, *note, map);
-// } catch (const xml_schema::exception& e) {
-// std::cout << e << endl;
-// QVERIFY(false);
-// }
-// }
-//
-// void BindingsTest::writeReadNoteTest()
-// {
-//
-// }
-//
-// void BindingsTest::writeKolabXCalEvent()
-// {
-// // try {
-// // //Components
-// // icalendar_2_0::EventTodoComponentType::components_type::valarm_type alarm;
-// //
-// // icalendar_2_0::ArrayOfEventTodoContainedComponents component;
-// // component.valarm().push_back(alarm);
-// //
-// // //Properties
-// //
-// // //Recurrence
-// // icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
-// // recur.count(2);
-// // recur.byhour().push_back("3");
-// // icalendar_2_0::RrulePropType rrule(recur);
-// //
-// // //Startdate
-// // xml_schema::date_time dt(2011,8,12,2,12,15);
-// // icalendar_2_0::DtstartPropType::date_time_type datetime(dt);
-// // icalendar_2_0::DtstartPropType startdate;
-// // startdate.date_time(datetime);
-// // //Startdate timezone
-// // ::icalendar_2_0::ArrayOfParameters parameters;
-// // ::icalendar_2_0::TzidParamType tzid("US/Eastern");
-// // parameters.baseParameter().push_back(tzid);
-// // startdate.parameters(parameters);
-// //
-// //
-// // //Custom value
-// // KolabXSD::CustomType custom("cusotomtypeidentifier", "sldjfldfj");
-// //
-// // //Assembling event properties
-// // ::icalendar_2_0::ArrayOfProperties properties;
-// // properties.baseProperty().push_back(startdate);
-// // properties.baseProperty().push_back(rrule);
-// // properties.baseProperty().push_back(custom);
-// //
-// // //Assembling the complete event
-// // icalendar_2_0::VeventType event(component);
-// // event.properties(properties);
-// //
-// // KolabXSD::Event kolabEvent(event);
-// // xml_schema::namespace_infomap map;
-// // map["kolab"].name = "http://kolab.org";
-// // map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-// // //map["xcal"].schema = "iCalendar.xsd";
-// //
-// // KolabXSD::event (std::cout, kolabEvent, map);
-// //
-// //
-// // // icalendar_2_0::VstrictTodoType todo;
-// // // icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
-// // // todo.rrule().;
-// //
-// // } catch (const xml_schema::exception& e) {
-// // std::cout << e << endl;
-// // QVERIFY(false);
-// // }
-// }
-//
-//
-// void BindingsTest::readKolabXCalEvent()
-// {
-// // try {
-// // // xml_schema::properties props;
-// // // props.no_namespace_schema_location ("../../../schemas/ical/kolabevent.xsd");
-// // // props.schema_location ("http://kolab.org", "../../../schemas/ical/kolabevent.xsd"); //Force schema
-// // // std::auto_ptr<KolabXSD::Event> event(KolabXSD::kolabevent("testfiles/testkolabevent.xml", 0, props));
-// //
-// // std::auto_ptr<KolabXSD::Event> event(KolabXSD::event("testfiles/testkolabevent.xml", xml_schema::flags::dont_validate));
-// //
-// // const icalendar_2_0::BaseComponentType::properties_type& properties = *event->vevent().properties();
-// // const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
-// //
-// // /*for(int i = 0; i < propertyList.size(); i++) {
-// // const icalendar_2_0::ArrayOfProperties::baseProperty_type prop = propertyList.at(i);
-// // }*/
-// // std::cout << propertyList.size() << std::endl;
-// // for (icalendar_2_0::ArrayOfProperties::baseProperty_sequence::const_iterator i (propertyList.begin ()); i != propertyList.end (); ++i) {
-// // if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*i))) {
-// // std::cout << "Rrule" << std::endl;
-// // std::cout << d->recur().freq() << std::endl;
-// // std::cout << d->recur().count() << std::endl;
-// // //std::cout << d->recur().byhour() << std::endl;
-// // } else {
-// // std::cout << "other" << std::endl;
-// // const icalendar_2_0::BasePropertyType &baseProperty = (*i);
-// // }
-// // }
-// //
-// // xml_schema::namespace_infomap map;
-// // map["kolab"].name = "http://kolab.org";
-// // // map[""].schema = "kolabevent.xsd";
-// // map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-// // // map["xcal"].schema = "iCalendar.xsd";
-// //
-// // KolabXSD::event (std::cout, *event, map);
-// //
-// // } catch (const xml_schema::exception& e) {
-// // std::cout << e << std::endl;
-// // QVERIFY(false);
-// // }
-// }
-//
-// #if 0
-// void BindingsTest::writeXCalEvent()
-// {
-// try {
-// //Components
-// icalendar_2_0::EventTodoComponentType::components_type::valarm_type alarm;
-//
-// icalendar_2_0::ArrayOfEventTodoContainedComponents component;
-// component.valarm().push_back(alarm);
-//
-// //Properties
-//
-// //Recurrence
-// icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
-// recur.count(2);
-// recur.byhour().push_back("3");
-// icalendar_2_0::RrulePropType rrule(recur);
-//
-// //Startdate
-// icalendar_2_0::DtstartPropType::date_type date(2011, 11, 10, 10, 10);
-// icalendar_2_0::DtstartPropType startdate;
-// startdate.date(date);
-//
-// ::icalendar_2_0::ArrayOfProperties properties;
-// properties.baseProperty().push_back(startdate);
-// properties.baseProperty().push_back(rrule);
-//
-//
-// //Assembling the complete event
-// icalendar_2_0::VeventType event(component);
-// event.properties(properties);
-//
-//
-// icalendar_2_0::VcalendarType::components_type comp;
-// comp.vcalendarContainedComponent().push_back(event);
-//
-// icalendar_2_0::VcalendarType vcalendar(comp);
-//
-// icalendar_2_0::IcalendarType icalendar;
-// icalendar.vcalendar().push_back(vcalendar);
-//
-// /*
-// * We need the namespacemap, otherwise we get elements with a prefix ns1:vevent:components
-// * and at least xerces doesn't like prefixes with a ":" inside (only a single prefix is allowed).
-// * No idea why this happens though.
-// */
-// xml_schema::namespace_infomap map;
-// map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-// //map[""].schema = "iCalendar.xsd";
-//
-// icalendar_2_0::vevent (std::cout, event, map);
-//
-// } catch (const xml_schema::exception& e) {
-// std::cout << e << endl;
-// QVERIFY(false);
-// }
-// #if 0
-// catch (const xercesc_3_1::DOMException &e) {
-// std::cout << "Xerces dom exception: " /*<< std::basic_string<XMLCh>(e.getMessage())*/ << " Code: " << e.code << std::endl;
-// return;
-// }
-// #endif
-// }
-//
-//
-// void BindingsTest::readXCalEvent()
-// {
-//
-// try {
-// xml_schema::properties props;
-// // props.no_namespace_schema_location ("../../schemas/ical/iCalendar.xsd");
-// // props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../schemas/ical/iCalendar.xsd"); //Force schema
-//
-// std::auto_ptr<icalendar_2_0::VeventType > event(icalendar_2_0::vevent("testfiles/testevent.xml", xml_schema::flags::dont_validate, props));
-//
-// xml_schema::namespace_infomap map;
-// map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-// map[""].schema = "iCalendar.xsd";
-//
-// icalendar_2_0::vevent (std::cout, *event, map);
-//
-// } catch (const xml_schema::exception& e) {
-// std::cout << e << std::endl;
-// QVERIFY(false);
-// }
-//
-// }
-//
-// #endif
-//
-// void BindingsTest::xercesException()
-// {
-// xercesc::XMLPlatformUtils::Initialize();
-// XMLCh tempStr[100];
-//
-// xercesc::DOMImplementation* impl = xercesc::DOMImplementation::getImplementation();
-//
-// xercesc::XMLString::transcode("root", tempStr, 99);
-// xercesc::DOMDocument* doc = impl->createDocument(0, tempStr, 0);
-//
-// /* XMLCh n[100];
-// XMLCh ns[100];
-// xercesc::XMLString::transcode("components", n, 99);
-// xercesc::XMLString::transcode("urn:ietf:params:xml:ns:icalendar-2.0", ns, 99);*/
-// try {
-// xercesc::DOMElement* e = doc->createElementNS (xsd::cxx::xml::string("urn:ietf:params:xml:ns:icalendar-2.0").c_str(), xsd::cxx::xml::string("components").c_str());
-// QVERIFY(e);
-//
-// /*
-// xercesc::DOMElement& s (
-// ::xsd::cxx::xml::dom::create_element (
-// "components",
-// "http://icalnamespace.org",
-// e));
-// */
-//
-// } catch (const xercesc_3_1::DOMException &e) {
-// std::cout << "Xerces dom exception: " /*<< std::basic_string<XMLCh>(e.getMessage())*/ << " Code: " << e.code << std::endl;
-// return;
-// }
-//
-// doc->release();
-// }
-//
-// void BindingsTest::writeContact()
-// {
-// try {
-// // KolabXSD::Contact::vcard_type vcard;
-// //
-// // vcard_4_0::fnPropType fn("Fritz Muster");
-// // vcard.baseProperty().push_back(fn);
-// //
-// // vcard_4_0::nPropType n;
-// // n.given().push_back("john");
-// // n.surname().push_back("doe");
-// // vcard.baseProperty().push_back(n);
-// //
-// // vcard_4_0::bdayPropType bday;
-// // vcard_4_0::bdayPropType::date_type date(1988,12,12);
-// // bday.date(date);
-// // vcard.baseProperty().push_back(bday);
-// //
-// // KolabXSD::Contact contact(vcard);
-// // xml_schema::namespace_infomap map;
-// // map["kolab"].name = "http://kolab.org";
-// // map[""].name = "urn:ietf:params:xml:ns:vcard-4.0";
-// // //map["xcal"].schema = "iCalendar.xsd";
-// //
-// // KolabXSD::contact (std::cout, contact, map);
-//
-//
-// } catch (const xml_schema::exception& e) {
-// std::cout << e << endl;
-// QVERIFY(false);
-// }
-// }
-//
-// void BindingsTest::readContact()
-// {
-//
-// }
-
namespace QTest {
template<>
char *toString(const Kolab::DateTime &dt)
@@ -407,9 +91,8 @@ void BindingsTest::BenchmarkRoundtrip()
{
boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("testfiles/icalEvent.xml", true);
std::string result;
- result = Kolab::writeKolabEvent(*event);
QBENCHMARK {
-
+ result = Kolab::writeKolabEvent(*event);
Kolab::readKolabEvent(result, false);
}
}
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index f5aac9e..8fa93bc 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -8,21 +8,7 @@ class BindingsTest : public QObject
{
Q_OBJECT
private slots:
-
-// void writeKolabXCalEvent();
-// void readKolabXCalEvent();
-// //void writeXCalEvent();
-// //void readXCalEvent();
-//
-// void writeNoteTest();
-// void readNoteTest();
-// void writeReadNoteTest();
-// void xercesException();
-//
-// void writeContact();
-// void readContact();
-
-
+
//Kolabformat
void readEvent();
void writeEvent();
commit 18e4788542e44966b751e3de0032cdf4b46d9fef
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 10:13:11 2011 +0100
reorganize schemas
diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index dd1512e..64e4c12 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -15,57 +15,36 @@ set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )
set( XSDCXX /usr/bin/xsdcxx)
-# Generate Kolab bindings
-file(GLOB KOLAB_SCHEMAS ${SCHEMA_DIR}/*.xsd)
-set( KOLAB_SCHEMA_SOURCEFILES
- bindings/base.cxx
- bindings/incidence.cxx
- bindings/event.cxx
- bindings/note.cxx )
-
-add_custom_command(OUTPUT ${KOLAB_SCHEMA_SOURCEFILES}
- COMMAND ${XSDCXX} cxx-tree --generate-serialization --namespace-map http://kolab.org=KolabXSD_test --output-dir bindings ${KOLAB_SCHEMAS}
- COMMENT "Generating Kolab XSD bindings"
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
- DEPENDS ${KOLAB_SCHEMAS}
- VERBATIM
- )
-
-
-
-
-# Generate XCal bindings
+# Generate bindings
file(GLOB XCAL_SCHEMAS ${SCHEMA_DIR}/ical/*.xsd)
-set( XCAL_SCHEMA_SOURCEFILES
+file(GLOB SCHEMAS ${SCHEMA_DIR}/*.xsd)
+set( SCHEMAS ${SCHEMAS} ${XCAL_SCHEMAS})
+
+set( SCHEMA_SOURCEFILES
bindings/xCard.cxx
-# bindings/kolabformat.cxx
bindings/kolabformat-xcal.cxx
bindings/kolabformat-xcard.cxx
-# bindings/iCalendar.cxx
bindings/iCalendar-params.cxx
bindings/iCalendar-props.cxx
bindings/iCalendar-valtypes.cxx
bindings/iCalendar-link-extension.cxx
bindings/iCalendar-bw-extensions.cxx
bindings/iCalendar-ms-extensions.cxx
-# bindings/iCalendar-availability-extension.cxx
-# bindings/iCalendar-wscal-extensions.cxx
)
#xsdcxx cxx-tree --generate-xml-schema --generate-serialization --custom-type date_time --hxx-epilogue '#include "bindings/customtypes/xml-schema-custom.hxx"' xml-schema.xsd
# --generate-inline --extern-xml-schema xml-schema.xsd
# --cxx-suffix .cpp --hxx-suffix .h
-add_custom_command(OUTPUT ${XCAL_SCHEMA_SOURCEFILES}
- COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element icalendar --output-dir bindings ${XCAL_SCHEMAS}
- COMMENT "Generating xCal XSD bindings"
+add_custom_command(OUTPUT ${SCHEMA_SOURCEFILES}
+ COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element icalendar --output-dir bindings ${SCHEMAS}
+ COMMENT "Generating XSD bindings"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS ${XCAL_SCHEMAS}
VERBATIM
)
-set( SCHEMA_SOURCEFILES ${XCAL_SCHEMA_SOURCEFILES} ${KOLAB_SCHEMA_SOURCEFILES})
-# Compile Schema
+# Compile Schemas
add_executable(xsdbin compiled/xsdbin.cxx)
target_link_libraries(xsdbin xerces-c)
diff --git a/schemas/ical/kolabformat-xcard.xsd b/schemas/ical/kolabformat-xcard.xsd
deleted file mode 100644
index e0abc67..0000000
--- a/schemas/ical/kolabformat-xcard.xsd
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:xcard="urn:ietf:params:xml:ns:vcard-4.0"
- targetNamespace="urn:ietf:params:xml:ns:vcard-4.0"
- xmlns="urn:ietf:params:xml:ns:vcard-4.0"
- elementFormDefault="qualified">
-
- <xs:include schemaLocation="xCard.xsd" />
-
- <xs:complexType name="KolabVersion" >
- <xs:complexContent mixed="false">
- <xs:extension base="BasePropertyType">
- <xs:sequence>
- <xs:element name="version" minOccurs="0" maxOccurs="1" type="xs:string" default="3.0dev1"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
- <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" />
-
- <xs:complexType name="CustomType" >
- <xs:complexContent mixed="false">
- <xs:extension base="BasePropertyType">
- <xs:sequence>
- <xs:element name="identifier" type="xs:string"/>
- <xs:element name="value" type="xs:string"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
- <xs:element name="x-kolab-custom" type="CustomType" substitutionGroup="baseProperty" />
-
-</xs:schema>
\ No newline at end of file
diff --git a/schemas/ical/kolabformat.xsd b/schemas/ical/kolabformat.xsd
deleted file mode 100644
index f780c2a..0000000
--- a/schemas/ical/kolabformat.xsd
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:xcal="urn:ietf:params:xml:ns:icalendar-2.0"
- xmlns:xcard="urn:ietf:params:xml:ns:vcard-4.0"
- targetNamespace="http://kolab.org"
- xmlns="http://kolab.org"
- elementFormDefault="qualified">
-
- <xs:import schemaLocation="iCalendar.xsd" namespace="urn:ietf:params:xml:ns:icalendar-2.0"/>
- <xs:import schemaLocation="xCard.xsd" namespace="urn:ietf:params:xml:ns:vcard-4.0"/>
-
-
- <xs:complexType name="KolabBase">
- <xs:attribute name="version" type="xs:string" fixed="3.0dev1" />
- </xs:complexType>
-
-<!-- <xs:element ref="xcal:vevent"/> -->
-
-<!-- <xs:complexType name="Event">
- <xs:complexContent mixed="false">
- <xs:extension base="KolabBase">
- <xs:sequence>
- <xs:element ref="xcal:vevent" minOccurs="1" maxOccurs="1"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>-->
-
-<!-- <xs:element name="todo" type="Todo"/>
- <xs:complexType name="Todo">
- <xs:complexContent mixed="false">
- <xs:extension base="KolabBase">
- <xs:sequence>
- <xs:element ref="xcal:vtodo" minOccurs="1" maxOccurs="1"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>-->
-
- <xs:element name="note" type="Note"/>
- <xs:complexType name="Note">
- <xs:complexContent mixed="false">
- <xs:extension base="KolabBase">
- <xs:sequence>
- <xs:element ref="xcal:vjournal" minOccurs="1" maxOccurs="1"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
-<!-- <xs:element name="contact" type="Contact"/>
- <xs:complexType name="Contact">
- <xs:complexContent mixed="false">
- <xs:extension base="KolabBase">
- <xs:sequence>
- <xs:element ref="xcard:vcard" minOccurs="1" maxOccurs="1"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>-->
-
-<!-- <xs:element name="distlist" type="DistributionList"/>
-
- <xs:complexType name="DistributionList">
- <xs:sequence>
- <xs:element ref="xcard:vcard" minOccurs="1" maxOccurs="1"/>
- </xs:sequence>
- </xs:complexType>-->
-
- <xs:complexType name="CustomType" >
- <xs:sequence>
- <xs:element name="identifier" type="xs:string"/>
- <xs:element name="value" type="xs:string"/>
- </xs:sequence>
- </xs:complexType>
-
- <xs:element name="x-kolab-custom" type="CustomType" />
-
-</xs:schema>
\ No newline at end of file
diff --git a/schemas/ical/xCard.xsd b/schemas/ical/xCard.xsd
deleted file mode 100644
index e7f4603..0000000
--- a/schemas/ical/xCard.xsd
+++ /dev/null
@@ -1,126 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!-- iCalendar base schema is intended to work in conjunction
- with conformant implementations of IETF RFC 5545
- ( http://www.rfc-editor.org/rfc/rfc5545.txt ),
- the normative specification of iCalendar. -->
-
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xcard="urn:ietf:params:xml:ns:vcard-4.0" targetNamespace="urn:ietf:params:xml:ns:vcard-4.0" elementFormDefault="qualified">
-
-<!-- Plain Types -->
-
- <xs:element name="text" type="xs:string"/>
- <!-- 3.3.4 DATE -->
- <xs:element name="date" type="xs:date"/>
-
- <!-- 3.3.5 DATE-TIME -->
- <!--
- <xs:element name="date-time" type="xs:string"/>
- -->
- <xs:simpleType name="DateTimeType">
- <xs:restriction base="xs:dateTime">
- <xs:pattern value="(\-|\+)?\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}(\.\d*)?Z?"/>
- </xs:restriction>
- </xs:simpleType>
-
- <xs:element name="date-time" type="xcard:DateTimeType"/>
-
-<!-- Parameters -->
-
-<xs:complexType name="BaseParameterType" abstract="true"/>
- <xs:element name="baseParameter" type="xcard:BaseParameterType"/>
- <xs:complexType name="ArrayOfParameters">
- <xs:sequence>
- <xs:element ref="xcard:baseParameter" minOccurs="0" maxOccurs="unbounded"/>
- </xs:sequence>
- </xs:complexType>
-
-<!-- Properties -->
- <xs:complexType name="BasePropertyType" abstract="true" >
- <xs:sequence>
- <xs:element ref="xcard:parameters"
- minOccurs="0" />
- </xs:sequence>
- </xs:complexType>
-
- <xs:element name="parameters" type="xcard:ArrayOfParameters"/>
-
- <xs:element name="baseProperty" type="xcard:BasePropertyType" />
-
- <xs:element name="fn" type="xcard:fnPropType"
- substitutionGroup="xcard:baseProperty" />
-
- <xs:element name="n" type="xcard:nPropType"
- substitutionGroup="xcard:baseProperty" />
-
- <xs:element name="bday" type="xcard:bdayPropType"
- substitutionGroup="xcard:baseProperty" />
-
-
-
- <!-- Properties that take a simple text value -->
- <xs:complexType name="TextPropertyType" >
- <xs:complexContent mixed="false">
- <xs:extension base="xcard:BasePropertyType">
- <xs:sequence>
- <xs:element ref="xcard:text" />
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
- <!-- Properties that take a date or date-time value -->
- <xs:complexType name="DateDatetimePropertyType" >
- <xs:complexContent mixed="false">
- <xs:extension base="xcard:BasePropertyType">
- <xs:sequence>
- <xs:choice>
- <xs:element ref="xcard:date-time"/>
- <xs:element ref="xcard:date"/>
- </xs:choice>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
-
-
- <xs:complexType name="fnPropType">
- <xs:complexContent mixed="false">
- <xs:extension base="xcard:TextPropertyType"/>
- </xs:complexContent>
- </xs:complexType>
-
- <xs:complexType name="nPropType">
- <xs:complexContent mixed="false">
- <xs:extension base="xcard:BasePropertyType">
- <xs:sequence>
- <xs:element name="surname" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
- <xs:element name="given" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
- <xs:element name="additional" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
- <xs:element name="prefix" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
- <xs:element name="suffix" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
- <xs:complexType name="bdayPropType">
- <xs:complexContent mixed="false">
- <xs:extension base="xcard:DateDatetimePropertyType"/>
- </xs:complexContent>
- </xs:complexType>
-
-
-<!-- <xs:include schemaLocation="iCalendar-props.xsd"/> -->
-<!-- Base -->
-
- <xs:element name="vcard" type="xcard:VcardType" />
- <xs:complexType name="VcardType" mixed="false">
- <xs:sequence>
- <xs:element ref="xcard:baseProperty" minOccurs="0" maxOccurs="unbounded"/>
- </xs:sequence>
- </xs:complexType>
-
-
-</xs:schema>
diff --git a/schemas/kolabformat-xcard.xsd b/schemas/kolabformat-xcard.xsd
new file mode 100644
index 0000000..e0abc67
--- /dev/null
+++ b/schemas/kolabformat-xcard.xsd
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:xcard="urn:ietf:params:xml:ns:vcard-4.0"
+ targetNamespace="urn:ietf:params:xml:ns:vcard-4.0"
+ xmlns="urn:ietf:params:xml:ns:vcard-4.0"
+ elementFormDefault="qualified">
+
+ <xs:include schemaLocation="xCard.xsd" />
+
+ <xs:complexType name="KolabVersion" >
+ <xs:complexContent mixed="false">
+ <xs:extension base="BasePropertyType">
+ <xs:sequence>
+ <xs:element name="version" minOccurs="0" maxOccurs="1" type="xs:string" default="3.0dev1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" />
+
+ <xs:complexType name="CustomType" >
+ <xs:complexContent mixed="false">
+ <xs:extension base="BasePropertyType">
+ <xs:sequence>
+ <xs:element name="identifier" type="xs:string"/>
+ <xs:element name="value" type="xs:string"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="x-kolab-custom" type="CustomType" substitutionGroup="baseProperty" />
+
+</xs:schema>
\ No newline at end of file
diff --git a/schemas/kolabformat.xsd b/schemas/kolabformat.xsd
new file mode 100644
index 0000000..f780c2a
--- /dev/null
+++ b/schemas/kolabformat.xsd
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:xcal="urn:ietf:params:xml:ns:icalendar-2.0"
+ xmlns:xcard="urn:ietf:params:xml:ns:vcard-4.0"
+ targetNamespace="http://kolab.org"
+ xmlns="http://kolab.org"
+ elementFormDefault="qualified">
+
+ <xs:import schemaLocation="iCalendar.xsd" namespace="urn:ietf:params:xml:ns:icalendar-2.0"/>
+ <xs:import schemaLocation="xCard.xsd" namespace="urn:ietf:params:xml:ns:vcard-4.0"/>
+
+
+ <xs:complexType name="KolabBase">
+ <xs:attribute name="version" type="xs:string" fixed="3.0dev1" />
+ </xs:complexType>
+
+<!-- <xs:element ref="xcal:vevent"/> -->
+
+<!-- <xs:complexType name="Event">
+ <xs:complexContent mixed="false">
+ <xs:extension base="KolabBase">
+ <xs:sequence>
+ <xs:element ref="xcal:vevent" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>-->
+
+<!-- <xs:element name="todo" type="Todo"/>
+ <xs:complexType name="Todo">
+ <xs:complexContent mixed="false">
+ <xs:extension base="KolabBase">
+ <xs:sequence>
+ <xs:element ref="xcal:vtodo" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>-->
+
+ <xs:element name="note" type="Note"/>
+ <xs:complexType name="Note">
+ <xs:complexContent mixed="false">
+ <xs:extension base="KolabBase">
+ <xs:sequence>
+ <xs:element ref="xcal:vjournal" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+<!-- <xs:element name="contact" type="Contact"/>
+ <xs:complexType name="Contact">
+ <xs:complexContent mixed="false">
+ <xs:extension base="KolabBase">
+ <xs:sequence>
+ <xs:element ref="xcard:vcard" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>-->
+
+<!-- <xs:element name="distlist" type="DistributionList"/>
+
+ <xs:complexType name="DistributionList">
+ <xs:sequence>
+ <xs:element ref="xcard:vcard" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>-->
+
+ <xs:complexType name="CustomType" >
+ <xs:sequence>
+ <xs:element name="identifier" type="xs:string"/>
+ <xs:element name="value" type="xs:string"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="x-kolab-custom" type="CustomType" />
+
+</xs:schema>
\ No newline at end of file
diff --git a/schemas/xCard.xsd b/schemas/xCard.xsd
new file mode 100644
index 0000000..e7f4603
--- /dev/null
+++ b/schemas/xCard.xsd
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- iCalendar base schema is intended to work in conjunction
+ with conformant implementations of IETF RFC 5545
+ ( http://www.rfc-editor.org/rfc/rfc5545.txt ),
+ the normative specification of iCalendar. -->
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xcard="urn:ietf:params:xml:ns:vcard-4.0" targetNamespace="urn:ietf:params:xml:ns:vcard-4.0" elementFormDefault="qualified">
+
+<!-- Plain Types -->
+
+ <xs:element name="text" type="xs:string"/>
+ <!-- 3.3.4 DATE -->
+ <xs:element name="date" type="xs:date"/>
+
+ <!-- 3.3.5 DATE-TIME -->
+ <!--
+ <xs:element name="date-time" type="xs:string"/>
+ -->
+ <xs:simpleType name="DateTimeType">
+ <xs:restriction base="xs:dateTime">
+ <xs:pattern value="(\-|\+)?\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}(\.\d*)?Z?"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="date-time" type="xcard:DateTimeType"/>
+
+<!-- Parameters -->
+
+<xs:complexType name="BaseParameterType" abstract="true"/>
+ <xs:element name="baseParameter" type="xcard:BaseParameterType"/>
+ <xs:complexType name="ArrayOfParameters">
+ <xs:sequence>
+ <xs:element ref="xcard:baseParameter" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+<!-- Properties -->
+ <xs:complexType name="BasePropertyType" abstract="true" >
+ <xs:sequence>
+ <xs:element ref="xcard:parameters"
+ minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="parameters" type="xcard:ArrayOfParameters"/>
+
+ <xs:element name="baseProperty" type="xcard:BasePropertyType" />
+
+ <xs:element name="fn" type="xcard:fnPropType"
+ substitutionGroup="xcard:baseProperty" />
+
+ <xs:element name="n" type="xcard:nPropType"
+ substitutionGroup="xcard:baseProperty" />
+
+ <xs:element name="bday" type="xcard:bdayPropType"
+ substitutionGroup="xcard:baseProperty" />
+
+
+
+ <!-- Properties that take a simple text value -->
+ <xs:complexType name="TextPropertyType" >
+ <xs:complexContent mixed="false">
+ <xs:extension base="xcard:BasePropertyType">
+ <xs:sequence>
+ <xs:element ref="xcard:text" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Properties that take a date or date-time value -->
+ <xs:complexType name="DateDatetimePropertyType" >
+ <xs:complexContent mixed="false">
+ <xs:extension base="xcard:BasePropertyType">
+ <xs:sequence>
+ <xs:choice>
+ <xs:element ref="xcard:date-time"/>
+ <xs:element ref="xcard:date"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+
+
+ <xs:complexType name="fnPropType">
+ <xs:complexContent mixed="false">
+ <xs:extension base="xcard:TextPropertyType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="nPropType">
+ <xs:complexContent mixed="false">
+ <xs:extension base="xcard:BasePropertyType">
+ <xs:sequence>
+ <xs:element name="surname" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="given" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="additional" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="prefix" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="suffix" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="bdayPropType">
+ <xs:complexContent mixed="false">
+ <xs:extension base="xcard:DateDatetimePropertyType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+
+<!-- <xs:include schemaLocation="iCalendar-props.xsd"/> -->
+<!-- Base -->
+
+ <xs:element name="vcard" type="xcard:VcardType" />
+ <xs:complexType name="VcardType" mixed="false">
+ <xs:sequence>
+ <xs:element ref="xcard:baseProperty" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+
+</xs:schema>
commit 1fba5623d0ffa0725425768c67a420f02fd78429
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 10:01:04 2011 +0100
Deleted the old schema files which we don't need anymore
diff --git a/schemas/base.xsd b/schemas/base.xsd
deleted file mode 100644
index 18b0a9f..0000000
--- a/schemas/base.xsd
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- targetNamespace="http://kolab.org"
- xmlns="http://kolab.org"
- elementFormDefault="qualified">
-
- <xs:complexType name="XMLBase" abstract="true">
- <xs:sequence>
- <!--
- Mandatory elements
- //-->
- <xs:element name="uid" type="UID" />
- <xs:element name="product-id" type="xs:string" />
- <xs:element name="creation-date" type="xs:dateTime" />
- <xs:element name="last-modification-date" type="xs:dateTime" />
-
- <!--
- Elements that do not require to be set by a client application,
- as a default is provided.
- //-->
- <xs:element name="sensitivity" type="Sensitivity" default="public" />
-
- <!--
- Optional elements
- //-->
- <xs:element name="body" type="xs:string" minOccurs="0" />
- <xs:element name="categories" type="Category" minOccurs="0" />
- <xs:element name="inline-attachment" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
- <xs:element name="link-attachment" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
- </xs:sequence>
-
- <!--
- Version of the XML and bindings generated with this XSD.
-
- Note: Does not seem to pass through to generated XML from PyXB
- bindings.
- //-->
- <xs:attribute name="version" type="xs:string" fixed="3.0dev1" />
-
- </xs:complexType>
-
- <xs:simpleType name="UID">
- <!--
- Note^1 that a UID restriction that is too short increases the risk of
- duplicate UIDs.
-
- Note^2 that we may also want to restrict the contents of the UID to
- allow only alphanumeric characters.
- //-->
- <xs:restriction base="xs:string">
- <xs:minLength value="1" />
- <xs:whiteSpace value="collapse" />
- </xs:restriction>
- </xs:simpleType>
-
- <xs:simpleType name="Category">
- <xs:restriction base="xs:string">
- <xs:pattern value="(\w+(,\w+)+)?" />
- </xs:restriction>
- </xs:simpleType>
-
- <xs:simpleType name="Color">
- <xs:restriction base="xs:string">
- <xs:length value="7" />
- <xs:pattern value="#([a-f;0-9]){6}" />
- </xs:restriction>
- </xs:simpleType>
-
- <xs:simpleType name="Sensitivity">
- <xs:restriction base="xs:string">
- <xs:enumeration value="private"/>
- <xs:enumeration value="confidential"/>
- <xs:enumeration value="public"/>
- </xs:restriction>
- </xs:simpleType>
-
- <xs:complexType name="SMTPContact">
- <xs:sequence>
- <xs:element name="smtp-address" type="xs:string" />
- <xs:element name="display-name" type="xs:string" minOccurs="0" />
- </xs:sequence>
- </xs:complexType>
-
- <!--
- Version of the XML and bindings generated with this XSD.
-
- Note: Does not seem to pass through to generated XML from PyXB
- bindings.
- //-->
- <xs:attribute name="version" type="xs:string" fixed="3.0dev1" />
-
-</xs:schema>
\ No newline at end of file
diff --git a/schemas/contact.xsd b/schemas/contact.xsd
deleted file mode 100644
index 1b7c8fe..0000000
--- a/schemas/contact.xsd
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- targetNamespace="http://kolab.org"
- xmlns="http://kolab.org"
- elementFormDefault="qualified">
-
- <xs:include schemaLocation="base.xsd" />
-
- <xs:element name="contact" type="Contact"/>
-
- <xs:complexType name="Contact">
- <xs:complexContent>
- <xs:extension base="XMLBase">
- <xs:sequence>
- <xs:element name="name" type="Name" minOccurs="0" />
- <xs:element name="free-busy-url" type="xs:string" minOccurs="0" />
- <xs:element name="organization" type="xs:string" minOccurs="0" />
- <xs:element name="web-page" type="xs:string" minOccurs="0" />
- <xs:element name="im-address" type="xs:string" minOccurs="0" />
- <xs:element name="department" type="xs:string" minOccurs="0" />
- <xs:element name="office-location" type="xs:string" minOccurs="0" />
- <xs:element name="profession" type="xs:string" minOccurs="0" />
- <xs:element name="job-title" type="xs:string" minOccurs="0" />
- <xs:element name="manager-name" type="xs:string" minOccurs="0" />
- <xs:element name="assistant" type="xs:string" minOccurs="0" />
- <xs:element name="nick-name" type="xs:string" minOccurs="0" />
- <xs:element name="spouse-name" type="xs:string" minOccurs="0" />
- <xs:element name="birthday" type="xs:string" minOccurs="0" />
- <xs:element name="anniversary" type="xs:string" minOccurs="0" />
- <xs:element name="picture" type="xs:string" minOccurs="0" />
- <xs:element name="children" type="xs:string" minOccurs="0" />
- <xs:element name="gender" type="xs:string" minOccurs="0" />
- <xs:element name="language" type="xs:string" minOccurs="0" />
- <xs:element name="phone" type="PhoneNumber" minOccurs="0" maxOccurs="unbounded" />
- <xs:element name="email" type="SMTPContact" minOccurs="0" maxOccurs="unbounded" />
- <xs:element name="address" type="Address" minOccurs="0" maxOccurs="unbounded" />
- <xs:element name="preferred-address" type="xs:string" minOccurs="0" />
- <xs:element name="latitude" type="xs:float" minOccurs="0" />
- <xs:element name="longitude" type="xs:float" minOccurs="0" />
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
- <xs:complexType name="Name">
- <xs:sequence>
- <xs:element name="given-name" type="xs:string" minOccurs="0" />
- <xs:element name="middle-names" type="xs:string" minOccurs="0" />
- <xs:element name="last-name" type="xs:string" minOccurs="0" />
- <xs:element name="full-name" type="xs:string" minOccurs="0" />
- <xs:element name="initials" type="xs:string" minOccurs="0" />
- <xs:element name="prefix" type="xs:string" minOccurs="0" />
- <xs:element name="suffix" type="xs:string" minOccurs="0" />
- </xs:sequence>
- </xs:complexType>
-
- <xs:complexType name="PhoneNumber">
- <xs:sequence>
- <xs:element name="type" type="xs:string" minOccurs="0" />
- <xs:element name="number" type="xs:string" />
- </xs:sequence>
- </xs:complexType>
-
- <xs:complexType name="Address">
- <!--
- 'type' is a reserved keyword... can we use 'label' instead, perhaps?
-
- Note: I have not actually experienced any trouble with this yet.
- //-->
- <xs:sequence>
- <xs:element name="type" type="xs:string" default="home" />
- <xs:element name="street" type="xs:string" minOccurs="0" />
- <xs:element name="postal-code" type="xs:string" minOccurs="0" />
- <!--
- Is locality supposed to mean city?
- //-->
- <xs:element name="locality" type="xs:string" minOccurs="0" />
- <xs:element name="region" type="xs:string" minOccurs="0" />
- <xs:element name="country" type="xs:string" minOccurs="0" />
- </xs:sequence>
- </xs:complexType>
-</xs:schema>
\ No newline at end of file
diff --git a/schemas/event.xsd b/schemas/event.xsd
deleted file mode 100644
index b77f1b6..0000000
--- a/schemas/event.xsd
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- targetNamespace="http://kolab.org"
- xmlns="http://kolab.org"
- elementFormDefault="qualified">
-
- <xs:include schemaLocation="incidence.xsd" />
-
- <xs:element name="event" type="Event"/>
-
- <xs:complexType name="Event">
- <xs:complexContent>
- <xs:extension base="Incidence">
- <xs:sequence>
-
- <xs:element name="show-time-as" type="xs:string"></xs:element>
- <xs:element name="color-label" type="xs:string"></xs:element>
- <xs:element name="start-date" type="xs:dateTime"></xs:element>
- <xs:element name="end-date" type="xs:dateTime"></xs:element>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
-</xs:schema>
\ No newline at end of file
diff --git a/schemas/incidence.xsd b/schemas/incidence.xsd
deleted file mode 100644
index 1db62a5..0000000
--- a/schemas/incidence.xsd
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- targetNamespace="http://kolab.org"
- xmlns="http://kolab.org"
- elementFormDefault="qualified">
-
- <xs:include schemaLocation="base.xsd" />
-
- <xs:complexType name="Incidence">
- <xs:complexContent>
- <xs:extension base="XMLBase">
- <xs:sequence>
- <xs:element name="summary" type="xs:string" />
- <xs:element name="location" type="xs:string" />
- <xs:element name="creator" type="SMTPContact" />
- <xs:element name="organizer" type="SMTPContact" />
- <xs:element name="alarm" type="xs:string" />
- <xs:element name="recurrence" type="Recurrence" minOccurs="0" maxOccurs="1"/>
- <xs:element name="attendee" type="Attendee" />
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
- <xs:complexType name="Attendee">
- <xs:complexContent>
- <xs:extension base="SMTPContact">
- <xs:sequence>
- <xs:element name="status" type="Status" />
- <xs:element name="request-response" type="xs:string" />
- <xs:element name="role" type="Role" />
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
- <xs:simpleType name="Status">
- <xs:restriction base="xs:string">
- <xs:enumeration value="none" />
- <xs:enumeration value="tentative" />
- <xs:enumeration value="accepted" />
- <xs:enumeration value="declined" />
- </xs:restriction>
- </xs:simpleType>
-
- <xs:simpleType name="Role">
- <xs:restriction base="xs:string">
- <xs:enumeration value="required" />
- <xs:enumeration value="optional" />
- <xs:enumeration value="resource" />
- </xs:restriction>
- </xs:simpleType>
-
-
- <xs:complexType name="Recurrence">
- <xs:sequence>
- <xs:element name="rule" type="Rule" maxOccurs="unbounded" minOccurs="0" />
- <xs:element name="date" type="xs:dateTime" maxOccurs="unbounded" minOccurs="0" />
- <xs:element name="exception" type="Exception" maxOccurs="unbounded" minOccurs="0" />
- </xs:sequence>
- </xs:complexType>
-
- <xs:complexType name="Interval">
- <xs:choice>
- <xs:element name="interval" type="xs:int"/>
- <xs:element name="list" type="xs:int" maxOccurs="unbounded" minOccurs="1" />
- </xs:choice>
- </xs:complexType>
-
- <xs:complexType name="Exception">
- <xs:sequence>
- <xs:element name="rule" type="Rule" />
- <xs:element name="date" type="xs:dateTime" />
- <xs:element name="subevent" type="xs:string" />
- </xs:sequence>
- </xs:complexType>
-
- <xs:complexType name="Rule">
- <xs:sequence>
- <xs:element name="yearly" type="Interval" maxOccurs="1" minOccurs="0" />
- <xs:element name="monthly" type="Interval" maxOccurs="1" minOccurs="0" />
- <xs:element name="weekly" type="Interval" maxOccurs="1" minOccurs="0" />
- <xs:element name="daily" type="Interval" maxOccurs="1" minOccurs="0" />
- <xs:element name="hourly" type="Interval" maxOccurs="1" minOccurs="0" />
- <xs:element name="minutely" type="Interval" maxOccurs="1" minOccurs="0" />
- <xs:element name="secondly" type="Interval" maxOccurs="1" minOccurs="0" />
- <xs:element name="occurence" type="xs:int" maxOccurs="unbounded" minOccurs="0" />
- <xs:element name="weekstart" type="xs:int" maxOccurs="1" minOccurs="0" />
- <xs:choice maxOccurs="1" minOccurs="0">
- <xs:element name="count" type="xs:int" />
- <xs:element name="enddate" type="xs:dateTime" />
- </xs:choice>
- </xs:sequence>
- </xs:complexType>
-</xs:schema>
\ No newline at end of file
diff --git a/schemas/note.xsd b/schemas/note.xsd
deleted file mode 100644
index 06765f9..0000000
--- a/schemas/note.xsd
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- targetNamespace="http://kolab.org"
- xmlns="http://kolab.org"
- elementFormDefault="qualified">
-
- <xs:include schemaLocation="base.xsd" />
-
- <xs:element name="note" type="Note"/>
-
- <xs:complexType name="Note">
- <xs:complexContent>
- <xs:extension base="XMLBase">
- <xs:sequence>
- <xs:element name="summary" type="xs:string" default=""/>
- <xs:element name="background-color" type="Color" default="#000000"/>
- <xs:element name="foreground-color" type="Color" default="#ffff00"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
- <!-- xs:complexType name="ExtendedNote">
- <xs:complexContent>
- <xs:extension base="Note">
- <xs:sequence>
- <xs:any namespace="##any" processContents="skip"
- minOccurs="0" maxOccurs="unbounded"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType-->
-</xs:schema>
diff --git a/schemas/task.xsd b/schemas/task.xsd
deleted file mode 100644
index 009b779..0000000
--- a/schemas/task.xsd
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- targetNamespace="http://kolab.org"
- xmlns="http://kolab.org"
- elementFormDefault="qualified">
-
- <xs:include schemaLocation="incidence.xsd" />
-
- <xs:element name="task" type="Task"/>
-
- <xs:complexType name="Task">
- <xs:complexContent>
- <xs:extension base="Incidence">
- <xs:sequence>
-
- <xs:element name="priority" type="xs:int"></xs:element>
- <xs:element name="completed" type="xs:int"></xs:element>
- <xs:element name="status" type="xs:string"></xs:element>
- <xs:element name="start-date" type="xs:dateTime" maxOccurs="1" minOccurs="0"></xs:element>
- <xs:element name="due-date" type="xs:dateTime"
- maxOccurs="1" minOccurs="0">
- </xs:element>
- <xs:element name="parent" type="xs:string"></xs:element>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
-</xs:schema>
\ No newline at end of file
commit 1463199dc6ef1e64d0d4e80f0fba78cf8b93f0dc
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 01:42:42 2011 +0100
Fixed cardinalities of Rdate and structure of exception date (schemas)
diff --git a/schemas/ical/iCalendar-props.xsd b/schemas/ical/iCalendar-props.xsd
index c31f344..86130ab 100644
--- a/schemas/ical/iCalendar-props.xsd
+++ b/schemas/ical/iCalendar-props.xsd
@@ -658,7 +658,14 @@
<!-- 3.8.5.1 Exception Date/Times -->
<xs:complexType name="ExdatePropType">
<xs:complexContent mixed="false">
- <xs:extension base="xcal:DateDatetimePropertyType"/>
+ <xs:extension base="xcal:BasePropertyType">
+ <xs:sequence>
+ <xs:choice>
+ <xs:element ref="xcal:date-time" maxOccurs="unbounded"/>
+ <xs:element ref="xcal:date" maxOccurs="unbounded"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:extension>
</xs:complexContent>
</xs:complexType>
@@ -668,9 +675,9 @@
<xs:extension base="xcal:BasePropertyType">
<xs:sequence>
<xs:choice>
- <xs:element ref="xcal:date"/>
- <xs:element ref="xcal:date-time"/>
- <xs:element ref="xcal:period"/>
+ <xs:element ref="xcal:date" maxOccurs="unbounded"/>
+ <xs:element ref="xcal:date-time" maxOccurs="unbounded"/>
+ <xs:element ref="xcal:period" maxOccurs="unbounded"/>
</xs:choice>
</xs:sequence>
</xs:extension>
commit 6a6710999e18a2753c7a27caa0f7985cbcc1716d
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 01:41:53 2011 +0100
bindingstest/kolabformat only for KolabContainers, kcalconversiontest/kolabkcalformat for KCalCore containers
Reading with compiled schemas.
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 3f9f736..bcb81f6 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -1,11 +1,18 @@
#ifndef KOLAB_CONVERSIONS_H
#define KOLAB_CONVERSIONS_H
+#include <bindings/kolabformat-xcal.hxx>
#include <bindings/iCalendar-props.hxx>
+#include <compiled/XMLParserWrapper.h>
+
#include <boost/shared_ptr.hpp>
#include <boost/numeric/conversion/converter_policies.hpp>
#include <boost/numeric/conversion/cast.hpp>
+#include <fstream>
+#include <iostream>
+
+
#define TZ_PREFIX "/kolab.org/"
namespace Kolab {
@@ -47,11 +54,25 @@ int toInt(const icalendar_2_0::IntegerPropertyType &prop)
return convertToInt<icalendar_2_0::IntegerPropertyType::integer_type>(prop.integer());
}
-
-
+///trait to convert date-time values
template <typename T>
struct DateTimeConverter;
+std::string getTimezone(const icalendar_2_0::ArrayOfParameters ¶meters) {
+ for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
+ if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
+ std::string tzid = tz->text();
+ if (tzid.find(TZ_PREFIX) != std::string::npos) {
+ tzid.erase(0, strlen(TZ_PREFIX));
+ } else {
+ std::cout << "/kolab.org/ timezone prefix is missing";
+ }
+ return tzid;
+ }
+ }
+ return std::string();
+}
+
template <typename T>
typename T::DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
{
@@ -64,16 +85,9 @@ typename T::DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProp
}
if (dtProperty.parameters()) {
- for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
- if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
- std::string tzid = tz->text();
- if (tzid.find(TZ_PREFIX) != std::string::npos) {
- tzid.erase(0, strlen(TZ_PREFIX));
- } else {
- std::cout << "/kolab.org/ timezone prefix is missing";
- }
- DC::setTimezone(date, tzid);
- }
+ const std::string &tzid = getTimezone(*dtProperty.parameters());
+ if (tzid.size()) {
+ DC::setTimezone(date, tzid);
}
}
return date;
@@ -109,7 +123,7 @@ void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const ty
date.date(DC::fromDate(dt));
} else {
date.date_time(DC::fromDateTime(dt));
-
+
const std::string &timezone = DC::getTimezone(dt);
if (timezone.size() != 0) {
std::string tz(TZ_PREFIX);
@@ -122,6 +136,7 @@ void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const ty
}
}
+///trait to convert recurrence properties
template <typename T>
struct RecurrenceConverter;
@@ -169,52 +184,128 @@ typename T::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
return r;
}
-
+///Trait for Incidence object
template <typename T>
struct IncidenceConverter;
+///Trait for incidence properties specialized for Event/Todo/Journal
+template <typename T> struct IncidenceTrait;
-// template <typename T> struct StringConverter
-// {
-// QString toString(const xml_schema::string &s)
-// {
-// return QString::fromStdString(s);
-// }
-//
-// void append(StringListType &list, const StringType &string) {
-//
-// }
-// }
-//
-// template <typename T> typename T::StringListType toStringList(const icalendar_2_0::TextListPropertyType &s)
-// {
-// using namespace icalendar_2_0;
-//
-// typedef StringConverter< typename T::RecurrenceType> SC;
-// typedef typename T::StringListType StringListType;
-//
-// StringListType list;
-// const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
-// for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
-// SC::append(list, SC::toString(*it));
-// }
-// return list;
-// }
+template <typename T>
+typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
+{
+ typedef typename T::IncidencePtr IncidencePtr;
+ typedef typename T::IncidenceType IncidenceType;
+ typedef typename T::KolabType KolabType;
+
+ try {
+ //TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
+ xml_schema::properties props;
+
+ std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
+ if (isUrl) {
+ std::cout << "open file " << s;
+ XMLParserWrapper wrapper;
+ xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = wrapper.parseFile(s);
+ icalendar = icalendar_2_0::icalendar(doc);
+// props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../../schemas/ical/kolabformat-xcal.xsd"); //Force schema
+// icalendar = icalendar_2_0::icalendar(s, 0, props);
+ } else {
+ props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "/home/chrigi/work/kolab/xmlformat/libkolabxml/schemas/ical/kolabformat-xcal.xsd"); //Force schema
+ XMLParserWrapper wrapper;
+ xsd::cxx::xml::dom::auto_ptr <xercesc_3_1::DOMDocument > doc = wrapper.parseString(s);
+ icalendar = icalendar_2_0::icalendar(doc);
+// icalendar = readCompiledIncidence(is, "string");
+// icalendar = icalendar_2_0::icalendar(is, 0, props);
+ }
+
+ if (!icalendar.get()) {
+ std::cerr << "failed to parse calendar!";
+ return IncidencePtr();
+ }
+ const icalendar_2_0::VcalendarType &vcalendar = icalendar->vcalendar();
+
+ std::vector < IncidencePtr > incidences;
+ for (typename xsd::cxx::tree::sequence< KolabType >::const_iterator it(T::begin(vcalendar.components())); it != T::end(vcalendar.components()); it++) {
+ IncidencePtr e = IncidencePtr(new IncidenceType);
+ const KolabType &event = *it;
+ T::readIncidence(*e, event);
+ incidences.push_back(e);
+ }
+
+ //TODO resolve events, exceptions can be identified based on the recurrence-id attribute
+// foreach (KCalCore::Event * event, events) {
+// if (!event->hasRecurrenceId()) {
+// return event;
+// }
+// }
+
+
+ return *incidences.begin();
+ } catch (const xml_schema::exception& e) {
+ std::cout << e << std::endl;
+ std::cout << "Failed to read incidence!" << std::endl;
+ }
+
+ return IncidencePtr();
+
+}
+
+
+
+template <typename T>
+std::string writeIncidence(const typename T::IncidenceType &incidence) {
+
+ using namespace icalendar_2_0;
+ typedef IncidenceConverter< typename T::Incidence > IC;
+ typedef typename T::KolabType KolabType;
+
+ try {
+
+ typename KolabType::components_type eventComponents;
+
+ typename KolabType::properties_type::uid_type uid(IC::uid(incidence));//TODO thats possibly the kontact internal uid?
+ typename KolabType::properties_type::dtstamp_type dtstamp;
+ dtstamp.date_time(IC::dtstamp(incidence));
+ typename KolabType::properties_type::created_type created;
+ created.date_time(IC::created(incidence));
+ typename KolabType::properties_type eventProps(uid, created, dtstamp);
+
+ KolabType inc(eventProps, eventComponents);
+ T::writeIncidence(inc, incidence);
+
+ VcalendarType::components_type components;
+ T::addIncidence(components, inc);
+
+ VcalendarType::properties_type::prodid_type prodid(std::string("libakonadi")); //TODO take from caller plus add libakonadi
+ VcalendarType::properties_type::version_type version(std::string("2.0")); //TODO define globally
+ VcalendarType::properties_type::x_kolab_version_type x_kolab_version(std::string("2.9.0")); //TODO define globally
+
+ VcalendarType::properties_type properties(prodid, version, x_kolab_version);
+
+ VcalendarType vcalendar(properties, components);
+
+ IcalendarType icalendar(vcalendar);
+
+ xml_schema::namespace_infomap map;
+ map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
+
+ std::ostringstream ostringstream;
+ icalendar_2_0::icalendar(ostringstream, icalendar, map);
+ return ostringstream.str();
+ } catch (const xml_schema::exception& e) {
+ std::cout << "failed to write Incidence";
+ return std::string();
+ }
+}
-/*
-xml_schema::date fromDate(const KDateTime &dt)
-{
- const QDate &d = dt.date();
- xml_schema::date date(d.year(), d.month(), d.day());
- return date;
-}*/
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
index 676ee81..2c3f7a4 100644
--- a/c++/lib/kcalconversions.h
+++ b/c++/lib/kcalconversions.h
@@ -6,8 +6,10 @@
#include <KDE/KDebug>
#include <kcalcore/recurrencerule.h>
#include <kcalcore/recurrence.h>
-#include <bindings/kolabformat-xcal.hxx>
#include <kcalcore/incidence.h>
+#include <KDE/KCalCore/Event>
+#include <KDE/KCalCore/Todo>
+#include <kcalcore/person.h>
namespace Kolab {
@@ -37,6 +39,16 @@ QString toString(const icalendar_2_0::TextPropertyType &s)
return QString::fromStdString(s.text());
}
+void setString(icalendar_2_0::TextPropertyType &p, const QString &s)
+{
+ p.text(s.toStdString());
+}
+
+// std::auto_ptr<icalendar_2_0::TextPropertyType> fromString(const QString &s)
+// {
+// return std::auto_ptr<icalendar_2_0::TextPropertyType>(new icalendar_2_0::TextPropertyType(s.toStdString()));
+// }
+
typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
@@ -115,7 +127,6 @@ template <> struct DateTimeConverter<KDateTime>
template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
{
-
typedef typename KCalCoreTypes::RecurrenceType Type;
typedef typename KCalCoreTypes::RecurrencePtr& Ptr; //Pass by reference, otherwise auto_ptr deletes the pointer after the first pass to a function (unlike shared_ptr)
@@ -126,25 +137,25 @@ template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
switch (freq) {
case FreqRecurType::YEARLY:
- r->setRecurrenceType(RecurrenceRule::rYearly);
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
break;
case FreqRecurType::MONTHLY:
- r->setRecurrenceType(RecurrenceRule::rMonthly);
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
break;
case FreqRecurType::WEEKLY:
- r->setRecurrenceType(RecurrenceRule::rWeekly);
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
break;
case FreqRecurType::DAILY:
- r->setRecurrenceType(RecurrenceRule::rDaily);
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
break;
case FreqRecurType::HOURLY:
- r->setRecurrenceType(RecurrenceRule::rHourly);
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
break;
case FreqRecurType::MINUTELY:
- r->setRecurrenceType(RecurrenceRule::rMinutely);
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
break;
case FreqRecurType::SECONDLY:
- r->setRecurrenceType(RecurrenceRule::rSecondly);
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
break;
default:
kWarning() << "invalid unhandled recurrenc type" << freq;
@@ -157,23 +168,24 @@ template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
using namespace KCalCore;
switch (t.recurrenceType()) {
- case RecurrenceRule::rYearly:
+ case KCalCore::RecurrenceRule::rYearly:
return FreqRecurType::YEARLY;
- case RecurrenceRule::rMonthly:
+ case KCalCore::RecurrenceRule::rMonthly:
return FreqRecurType::MONTHLY;
- case RecurrenceRule::rWeekly:
+ case KCalCore::RecurrenceRule::rWeekly:
return FreqRecurType::WEEKLY;
- case RecurrenceRule::rDaily:
+ case KCalCore::RecurrenceRule::rDaily:
return FreqRecurType::DAILY;
- case RecurrenceRule::rHourly:
+ case KCalCore::RecurrenceRule::rHourly:
return FreqRecurType::HOURLY;
- case RecurrenceRule::rMinutely:
+ case KCalCore::RecurrenceRule::rMinutely:
return FreqRecurType::MINUTELY;
- case RecurrenceRule::rSecondly:
+ case KCalCore::RecurrenceRule::rSecondly:
return FreqRecurType::SECONDLY;
default:
kWarning() << "invalid unhandled recurrenc type";
}
+ return 0;
}
static void setWeekStart(Ptr r, const icalendar_2_0::RecurType::wkst_type &wkst)
@@ -374,6 +386,9 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const typename
template <typename T>
void setIncidenceProperties(KCalCore::Incidence &inc, const T &prop)
{
+ using namespace KCalCore;
+ typedef DateTimeConverter<KDateTime> DC;
+
inc.setUid(toString(prop.uid()));
inc.setCreated(*toDate<KCalCoreTypes>(prop.created()));
inc.setLastModified(*toDate<KCalCoreTypes>(prop.dtstamp()));
@@ -413,15 +428,37 @@ void setIncidenceProperties(KCalCore::Incidence &inc, const T &prop)
}
if (prop.rdate()) {
-
+ const icalendar_2_0::KolabEvent::properties_type::rdate_type &rdate = *prop.rdate();
+ std::string tzid;
+ if (rdate.parameters()) {
+ tzid = getTimezone(*rdate.parameters());
+ }
+ if (rdate.date().size()) {
+ Q_FOREACH(const xml_schema::date &d, rdate.date()) {
+ recurrence->addRDate(DC::toDate(d)->date());
+ }
+ } else if (rdate.date_time().size()) {
+ Q_FOREACH(const xml_schema::date_time &d, rdate.date_time()) {
+ DC::Ptr date = DC::toDate(d);
+ if (tzid.size()) {
+ DC::setTimezone(date, tzid);
+ }
+ recurrence->addRDateTime(*date);
+ }
+ } else if (rdate.period().size()) {
+ kDebug() << "the period element must not be used, ignored.";
+ }
}
if (prop.exdate()) {
-
+ //TODO
+// recurrence->addExDate();
+// recurrence->addExDateTime();
}
if (prop.recurrence_id()) {
-
+ //TODO THISANDFUTURE range
+ inc.setRecurrenceId(*toDate<KCalCoreTypes>(*prop.recurrence_id()));
}
if (prop.summary()) {
@@ -433,19 +470,38 @@ void setIncidenceProperties(KCalCore::Incidence &inc, const T &prop)
}
if (prop.priority()) {
-
+ inc.setPriority(toInt(*prop.priority()));
}
if (prop.status()) {
-
+ const QString &status = toString(*prop.status());
+ if (status == "NEEDS-ACTION") {
+ inc.setStatus(Incidence::StatusNeedsAction);
+ } else if (status == "COMPLETED") {
+ inc.setStatus(Incidence::StatusCompleted);
+ } else if (status == "IN-PROCESS") {
+ inc.setStatus(Incidence::StatusInProcess);
+ } else if (status == "CANCELLED") {
+ inc.setStatus(Incidence::StatusCanceled);
+ } else if (status == "TENTATIVE") {
+ inc.setStatus(Incidence::StatusTentative);
+ } else if (status == "CONFIRMED") {
+ inc.setStatus(Incidence::StatusConfirmed);
+ } else if (status == "DRAFT") {
+ inc.setStatus(Incidence::StatusDraft);
+ } else if (status == "FINAL") {
+ inc.setStatus(Incidence::StatusFinal);
+ }
}
if (prop.location()) {
-
+ inc.setLocation(toString(*prop.location()));
}
if (prop.organizer()) {
-
+// icalendar_2_0::KolabEvent::properties_type::organizer();
+// inc.
+// KCalCore::Person person;
}
if (prop.attendee().size()) {
@@ -459,7 +515,7 @@ void setIncidenceProperties(KCalCore::Incidence &inc, const T &prop)
if (prop.x_custom().size()) {
}
-
+
}
template <typename T>
@@ -472,15 +528,16 @@ void getIncidenceProperties(T &prop, const KCalCore::Incidence &inc)
switch (inc.secrecy()) {
case Incidence::SecrecyConfidential:
- prop.class_();
+ prop.class_(properties::class_type("CONFIDENTIAL"));
break;
- case Incidence::SecrecyPublic:
- prop.class_();
case Incidence::SecrecyPrivate:
- prop.class_();
+ prop.class_(properties::class_type("PRIVATE"));
+ break;
+ default:
+ prop.class_(properties::class_type("PUBLIC"));
+ break;
}
-
-
+
if (inc.dtStart().isValid()) {
properties::dtstart_type dtstart;
setDateTimeProperty<KCalCoreTypes>(dtstart, inc.dtStart());
@@ -488,12 +545,12 @@ void getIncidenceProperties(T &prop, const KCalCore::Incidence &inc)
}
if (inc.recurs()) {
- Recurrence *r = inc.recurrence();
+ KCalCore::Recurrence *r = inc.recurrence();
if (r->rRules().size() >= 1) {
if (r->rRules().size() != 1) {
kWarning() << "too many recurrences: " << r->rRules().size();
}
- RecurrenceRule *rule = r->rRules().first();
+ KCalCore::RecurrenceRule *rule = r->rRules().first();
//TODO check if startdate is allDay if recurrence is allDay
//TODO check if startdate matches the one of the event (it MUST)
prop.rrule(recurrenceProperty(*rule));
@@ -519,6 +576,90 @@ template <> struct IncidenceConverter < KCalCore::Incidence >
};
+template < > struct IncidenceTrait <KCalCore::Event>
+{
+ typedef typename icalendar_2_0::KolabEvent KolabType;
+ typedef typename KCalCore::Event IncidenceType;
+ typedef typename KCalCore::Event::Ptr IncidencePtr;
+ typedef typename KCalCore::Incidence Incidence;
+
+ static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
+ {
+ icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+
+ getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
+
+ if (event.hasEndDate() && event.dtEnd().isValid()) {
+ icalendar_2_0::properties::dtend_type dtend;
+ setDateTimeProperty<KCalCoreTypes>(dtend, event.dtEnd());
+ prop.dtend(dtend);
+ } else if (event.hasDuration()) {
+
+ }
+ }
+
+ static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc)
+ {
+ components.vevent().push_back(inc);
+ }
+
+ static void readIncidence(KCalCore::Event &event, const icalendar_2_0::KolabEvent& vevent)
+ {
+ const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+
+ setIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(event, prop);
+
+ if (prop.dtend()) {
+ event.setDtEnd(*toDate<KCalCoreTypes>(*prop.dtend()));
+ if (event.dtEnd().timeType() != event.dtStart().timeType()) {
+ kWarning() << "dtEnd has wrong timespec";
+ }
+ } else if (prop.duration()) {
+ //TODO implement
+ // KCalCore::Duration duration.;
+ // event.setDuration(duration << prop.duration());
+ }
+ //TODO check for equality of timespecs
+
+ if (prop.transp()) {
+ //TODO implement
+ }
+ }
+
+ static icalendar_2_0::components2::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
+ {
+ return components.vevent().begin();
+ }
+
+ static icalendar_2_0::components2::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
+ {
+ return components.vevent().end();
+ }
+
+};
+
+template < > struct IncidenceTrait <KCalCore::Todo>
+{
+ typedef typename icalendar_2_0::KolabTodo KolabType;
+ typedef typename KCalCore::Todo IncidenceType;
+ typedef typename KCalCore::Incidence Incidence;
+
+ static void writeIncidence(icalendar_2_0::KolabTodo& vtodo, const KCalCore::Todo &todo)
+ {
+ icalendar_2_0::KolabTodo::properties_type &prop = vtodo.properties();
+ getIncidenceProperties<icalendar_2_0::KolabTodo::properties_type>(prop, todo);
+ //TODO implement remaining todo properties
+
+ }
+
+ static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc)
+ {
+ components.vtodo().push_back(inc);
+ }
+
+ //TODO implement reading
+};
+
} //Namespace
#endif
\ No newline at end of file
diff --git a/c++/lib/kcalkolabformat.cpp b/c++/lib/kcalkolabformat.cpp
new file mode 100644
index 0000000..82d9995
--- /dev/null
+++ b/c++/lib/kcalkolabformat.cpp
@@ -0,0 +1,31 @@
+#include "kolabformat.h"
+
+#include <kcalcore/event.h>
+#include <KDE/KCalCore/Todo>
+
+#include "kcalconversions.h"
+
+namespace Kolab {
+
+KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
+{
+ return readIncidence< IncidenceTrait<KCalCore::Event> >(s, isUrl);
+}
+
+KCalCore::Todo::Ptr readTodo(const std::string& s, bool isUrl)
+{
+
+}
+
+
+std::string writeEvent(KCalCore::Event::Ptr event)
+{
+ return writeIncidence< IncidenceTrait<KCalCore::Event> >(*event);
+}
+
+std::string writeTodo(KCalCore::Todo::Ptr todo)
+{
+// return writeIncidence< IncidenceTrait<KCalCore::Todo> >(*todo);
+}
+
+}
\ No newline at end of file
diff --git a/c++/lib/kcalkolabformat.h b/c++/lib/kcalkolabformat.h
new file mode 100644
index 0000000..d47802a
--- /dev/null
+++ b/c++/lib/kcalkolabformat.h
@@ -0,0 +1,19 @@
+
+#ifndef KCALKOLABFORMAT_H
+#define KCALKOLABFORMAT_H
+
+#include <string>
+#include <KDE/KCalCore/Event>
+#include <KDE/KCalCore/Todo>
+
+namespace Kolab {
+
+KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl = true);
+KCalCore::Todo::Ptr readTodo(const std::string& s, bool isUrl = true);
+
+std::string writeEvent(KCalCore::Event::Ptr);
+std::string writeTodo(KCalCore::Todo::Ptr);
+
+}
+
+#endif // KCALKOLABFORMAT_H
diff --git a/c++/lib/kolabconversions.h b/c++/lib/kolabconversions.h
new file mode 100644
index 0000000..98391e3
--- /dev/null
+++ b/c++/lib/kolabconversions.h
@@ -0,0 +1,601 @@
+// template <> struct DateTimeConverter<DateTime>
+// {
+// typedef typename boost::shared_ptr<DateTime> Ptr;
+// Ptr toDate(const xml_schema::date &dt)
+// {
+// Ptr date(new DateTime());
+//
+// return date;
+// }
+// Ptr toDate(const xml_schema::date_time &dt)
+// {
+// Ptr date(new DateTime());
+// return date;
+// }
+//
+// void setTimezone(Ptr date, const std::string &tzid )
+// {
+// date->setTimezone(tzid);
+// }
+// };
+
+
+#include "conversions.h"
+
+#include "kolabcontainers.h"
+#include <boost/foreach.hpp>
+
+namespace Kolab {
+
+class Incidence;
+
+struct KolabTypes
+{
+ typedef DateTime DateType;
+ typedef typename boost::shared_ptr<DateTime> DatePtr;
+ typedef RecurrenceRule RecurrenceType;
+ typedef typename std::auto_ptr<RecurrenceRule> RecurrencePtr;
+ typedef std::string StringType;
+ typedef Incidence IncidenceType;
+};
+
+std::vector<std::string> toStringList(const icalendar_2_0::TextListPropertyType &s)
+{
+ std::vector<std::string> d;
+ const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
+ for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
+ d.push_back(*it);
+ }
+ return d;
+}
+
+std::string toString(const icalendar_2_0::TextPropertyType &s)
+{
+ return s.text();
+}
+
+void setString(icalendar_2_0::TextPropertyType &p, const std::string &s)
+{
+ p.text(s);
+}
+
+template <> struct DateTimeConverter<DateTime>
+{
+ typedef DateTime Type;
+ typedef typename boost::shared_ptr<DateTime> Ptr;
+
+ static Ptr toDate(const xml_schema::date &dt)
+ {
+ Ptr date(new DateTime());
+ date->setDate(dt.year(), dt.month(), dt.day());
+ return date;
+ }
+
+ static Ptr toDate(const xml_schema::date_time &dt)
+ {
+ Ptr date(new DateTime());
+ date->setDate(dt.year(), dt.month(), dt.day());
+ date->setTime(dt.hours(), dt.minutes(), dt.seconds());
+ if (dt.zone_present()) {
+ date->setUTC(true);
+ }
+ return date;
+ }
+
+ static xml_schema::date_time fromDateTime(const DateTime &d)
+ {
+ xml_schema::date_time date(d.year(), d.month(), d.day(), d.hour(), d.minute(), d.second());
+ if (d.isUTC()) {
+ //Setting both zone hours/and zone minutes to zero results in a Z being appended to indicate UTC
+ date.zone_hours(0);
+ date.zone_minutes(0);
+ }
+ return date;
+ }
+
+ static xml_schema::date fromDate(const DateTime &d)
+ {
+ xml_schema::date date(d.year(), d.month(), d.day());
+ return date;
+ }
+
+ static void setTimezone(Ptr date, const std::string &tzid)
+ {
+ date->setTimezone(tzid);
+ }
+
+ static std::string getTimezone(const DateTime &dt)
+ {
+ return dt.timezone();
+ }
+
+ static void setUTC(Ptr date)
+ {
+ date->setUTC(true);
+ }
+
+ static bool isDateOnly(Type date)
+ {
+ return date.isDateOnly();
+ }
+
+};
+
+
+template <> struct RecurrenceConverter < RecurrenceRule >
+{
+
+ typedef typename KolabTypes::RecurrenceType Type;
+ typedef typename KolabTypes::RecurrencePtr& Ptr; //Pass by reference, otherwise auto_ptr deletes the pointer after the first pass to a function (unlike shared_ptr)
+
+ static void setType(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
+ {
+ using namespace icalendar_2_0;
+
+ switch (freq) {
+ case FreqRecurType::YEARLY:
+ r->setFrequency(RecurrenceRule::Yearly);
+ break;
+ case FreqRecurType::MONTHLY:
+ r->setFrequency(RecurrenceRule::Monthly);
+ break;
+ case FreqRecurType::WEEKLY:
+ r->setFrequency(RecurrenceRule::Weekly);
+ break;
+ case FreqRecurType::DAILY:
+ r->setFrequency(RecurrenceRule::Daily);
+ break;
+ case FreqRecurType::HOURLY:
+ r->setFrequency(RecurrenceRule::Hourly);
+ break;
+ case FreqRecurType::MINUTELY:
+ r->setFrequency(RecurrenceRule::Minutely);
+ break;
+ case FreqRecurType::SECONDLY:
+ r->setFrequency(RecurrenceRule::Secondly);
+ break;
+ default:
+ std::cout << "invalid unhandled recurrenc type" << freq;
+ }
+ }
+
+ static icalendar_2_0::RecurType::freq_type type(const Type &t)
+ {
+ using namespace icalendar_2_0;
+
+ switch (t.frequency()) {
+ case RecurrenceRule::Yearly:
+ return FreqRecurType::YEARLY;
+ case RecurrenceRule::Monthly:
+ return FreqRecurType::MONTHLY;
+ case RecurrenceRule::Weekly:
+ return FreqRecurType::WEEKLY;
+ case RecurrenceRule::Daily:
+ return FreqRecurType::DAILY;
+ case RecurrenceRule::Hourly:
+ return FreqRecurType::HOURLY;
+ case RecurrenceRule::Minutely:
+ return FreqRecurType::MINUTELY;
+ case RecurrenceRule::Secondly:
+ return FreqRecurType::SECONDLY;
+ default:
+ std::cout << "invalid unhandled recurrenc type";
+ }
+ }
+
+ static void setWeekStart(Ptr r, const icalendar_2_0::RecurType::wkst_type &wkst)
+ {
+ using namespace icalendar_2_0;
+
+ switch (wkst) {
+ case WeekdayRecurType::MO:
+ r->setWeekStart(RecurrenceRule::Monday);
+ break;
+ case WeekdayRecurType::TU:
+ r->setWeekStart(RecurrenceRule::Tuesday);
+ break;
+ case WeekdayRecurType::WE:
+ r->setWeekStart(RecurrenceRule::Wednesday);
+ break;
+ case WeekdayRecurType::TH:
+ r->setWeekStart(RecurrenceRule::Thursday);
+ break;
+ case WeekdayRecurType::FR:
+ r->setWeekStart(RecurrenceRule::Friday);
+ break;
+ case WeekdayRecurType::SA:
+ r->setWeekStart(RecurrenceRule::Saturday);
+ break;
+ case WeekdayRecurType::SU:
+ r->setWeekStart(RecurrenceRule::Sunday);
+ break;
+ default:
+ std::cout << "invalid unhandled weekday" << wkst;
+ }
+ }
+
+ static void setEndDt(Ptr r, KolabTypes::DatePtr date )
+ {
+ r->setEnd(*date);
+ }
+
+ static void setCount(Ptr r, int count )
+ {
+ r->setCount(count);
+ }
+
+ static void setInterval(Ptr r, int interval )
+ {
+ r->setInterval(interval);
+ }
+
+ static void setBysecond(Ptr r, const icalendar_2_0::RecurType::bysecond_sequence &list)
+ {
+ std::vector<int> by;
+ for (icalendar_2_0::RecurType::bysecond_const_iterator it(list.begin()); it != list.end(); it++) {
+ by.push_back(convertToInt<xml_schema::non_negative_integer>(*it));
+ }
+ r->setBysecond(by);
+ }
+
+ static void setByminute(Ptr r, const icalendar_2_0::RecurType::byminute_sequence &list)
+ {
+ std::vector<int> by;
+ for (icalendar_2_0::RecurType::byminute_const_iterator it(list.begin()); it != list.end(); it++) {
+ by.push_back(convertToInt<xml_schema::non_negative_integer>(*it));
+ }
+ r->setByminute(by);
+ }
+
+ static void setByhour(Ptr r, const icalendar_2_0::RecurType::byhour_sequence &list)
+ {
+ std::vector<int> by;
+ for (icalendar_2_0::RecurType::byhour_const_iterator it(list.begin()); it != list.end(); it++) {
+ by.push_back(convertToInt<xml_schema::non_negative_integer>(*it));
+ }
+ r->setByhour(by);
+ }
+
+ static void setByday(Ptr r, const icalendar_2_0::RecurType::byday_sequence &list)
+ {
+ std::vector<RecurrenceRule::DayPos> by;
+ for (icalendar_2_0::RecurType::byday_const_iterator it(list.begin()); it != list.end(); it++) {
+ //TODO implement parser for format
+// switch () {
+//
+// }
+ //by.append(convertToInt<xml_schema::non_negative_integer>(*it));
+ }
+ r->setByday(by);
+ }
+
+ static void setBymonthday(Ptr r, const icalendar_2_0::RecurType::bymonthday_sequence &list)
+ {
+ std::vector<int> by;
+ for (icalendar_2_0::RecurType::bymonth_const_iterator it(list.begin()); it != list.end(); it++) {
+ by.push_back(convertToInt<xml_schema::integer>(*it));
+ }
+ r->setBymonthday(by);
+ }
+
+ static void setByyearday(Ptr r, const icalendar_2_0::RecurType::byyearday_sequence &list)
+ {
+ std::vector<int> by;
+ for (icalendar_2_0::RecurType::byyearday_const_iterator it(list.begin()); it != list.end(); it++) {
+ by.push_back(convertToInt<xml_schema::integer>(*it));
+ }
+ r->setByyearday(by);
+ }
+
+ static void setByweekno(Ptr r, const icalendar_2_0::RecurType::byweekno_sequence &list)
+ {
+ std::vector<int> by;
+ for (icalendar_2_0::RecurType::byweekno_const_iterator it(list.begin()); it != list.end(); it++) {
+ by.push_back(convertToInt<xml_schema::integer>(*it));
+ }
+ r->setByweekno(by);
+ }
+
+ static void setBymonth(Ptr r, const icalendar_2_0::RecurType::bymonth_sequence &list)
+ {
+ std::vector<int> by;
+ for (icalendar_2_0::RecurType::bymonth_const_iterator it(list.begin()); it != list.end(); it++) {
+ by.push_back(convertToInt<xml_schema::integer>(*it));
+ }
+ r->setBymonth(by);
+ }
+};
+
+
+
+
+
+
+template <typename KolabType, typename T>
+void setIncidenceProperties(Kolab::Event &inc, const T &prop)
+{
+ typedef DateTimeConverter<Kolab::DateTime> DC;
+
+ inc.setUid(toString(prop.uid()));
+ inc.setCreated(*toDate<KolabTypes>(prop.created()));
+ inc.setLastModified(*toDate<KolabTypes>(prop.dtstamp()));
+
+ if (prop.sequence()) {
+ inc.setSequence(toInt(*prop.sequence()));
+ }
+
+ if (prop.class_()) {
+ std::string string(toString(*prop.class_()));
+ Kolab::Classification sec = Public;
+ if (string == "PRIVATE") {
+ sec = Private;
+ } else if (string == "CONFIDENTIAL") {
+ sec = Confidential;
+ }
+ inc.setClassification(sec);
+ }
+
+ if (prop.categories()) {
+ inc.setCategories(toStringList(*prop.categories()));
+ }
+
+ if (prop.dtstart()) {
+ const KolabTypes::DatePtr date = toDate<KolabTypes>(*prop.dtstart());
+ inc.setStart(*date); //TODO add to specification that allday depends on start date format
+ }
+
+ if (prop.rrule()) {
+ KolabTypes::RecurrencePtr rrule = toRRule<KolabTypes>(prop.rrule()->recur());
+ inc.setRecurrenceRule(*rrule);
+ }
+//
+// if (prop.rdate()) {
+// const icalendar_2_0::KolabEvent::properties_type::rdate_type &rdate = *prop.rdate();
+// std::string tzid;
+// if (rdate.parameters()) {
+// tzid = getTimezone(*rdate.parameters());
+// }
+// if (rdate.date().size()) {
+// Q_FOREACH(const xml_schema::date &d, rdate.date()) {
+// recurrence->addRDate(DC::toDate(d)->date());
+// }
+// } else if (rdate.date_time().size()) {
+// Q_FOREACH(const xml_schema::date_time &d, rdate.date_time()) {
+// DC::Ptr date = DC::toDate(d);
+// if (tzid.size()) {
+// DC::setTimezone(date, tzid);
+// }
+// recurrence->addRDateTime(*date);
+// }
+// } else if (rdate.period().size()) {
+// kDebug() << "the period element must not be used, ignored.";
+// }
+// }
+//
+// if (prop.exdate()) {
+// //TODO
+// // recurrence->addExDate();
+// // recurrence->addExDateTime();
+// }
+//
+ if (prop.recurrence_id()) {
+ //TODO THISANDFUTURE range
+ bool thisandfuture = true;
+ inc.setRecurrenceID(*toDate<KolabTypes>(*prop.recurrence_id()), thisandfuture);
+ }
+
+ if (prop.summary()) {
+ inc.setSummary(toString(*prop.summary())); //TODO detect richtext and set flag accordingly
+ }
+
+ if (prop.description()) {
+ inc.setDescription(toString(*prop.description())); //TODO detect richtext and set flag accordingly
+ }
+
+ if (prop.priority()) {
+ inc.setPriority(toInt(*prop.priority()));
+ }
+
+ if (prop.status()) {
+ const std::string &status = toString(*prop.status());
+ if (status == "NEEDS-ACTION") {
+ inc.setStatus(NeedsAction);
+ } else if (status == "COMPLETED") {
+ inc.setStatus(Completed);
+ } else if (status == "IN-PROCESS") {
+ inc.setStatus(InProcess);
+ } else if (status == "CANCELLED") {
+ inc.setStatus(Cancelled);
+ } else if (status == "TENTATIVE") {
+ inc.setStatus(Tentative);
+ } else if (status == "CONFIRMED") {
+ inc.setStatus(Confirmed);
+ } else if (status == "DRAFT") {
+ inc.setStatus(Draft);
+ } else if (status == "FINAL") {
+ inc.setStatus(Final);
+ }
+ }
+
+ if (prop.location()) {
+ inc.setLocation(toString(*prop.location()));
+ }
+
+ if (prop.organizer()) {
+// icalendar_2_0::KolabEvent::properties_type::organizer();
+// inc.
+// KCalCore::Person person;
+ }
+
+ if (prop.attendee().size()) {
+
+ }
+
+ if (prop.attach().size()) {
+
+ }
+
+ if (prop.x_custom().size()) {
+
+ }
+
+}
+
+template <typename T, typename I>
+xsd::cxx::tree::sequence <T> &toList(xsd::cxx::tree::sequence <T> &list, const std::vector<int> &input) {
+ BOOST_FOREACH(int i, list) {
+ list.push_back(convertToInt<I>(i));
+ }
+ return list;
+}
+
+std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const RecurrenceRule &r)
+{
+ using namespace icalendar_2_0;
+
+ typedef RecurrenceConverter< RecurrenceRule > RC;
+ typedef DateTimeConverter< DateTime> DC;
+
+ std::auto_ptr< RrulePropType > rruleProp(new RrulePropType(RC::type(r)));
+
+ RecurPropertyType::recur_type &recur = rruleProp->recur();
+ const DateTime &endDate = r.end();
+ if (endDate.isValid()) {
+ RecurPropertyType::recur_type::until_type until;
+ if (endDate.isDateOnly()) {
+ until.date(DC::fromDate(endDate));
+ } else {
+ until.date_time(DC::fromDateTime(endDate));
+ }
+ recur.until(until);
+ } else if (r.count() > 0) {
+ recur.count(fromInt<RecurType::count_type>(r.count()));
+ }
+
+ if (r.interval() > 1) {
+ recur.interval(fromInt<RecurType::interval_type>(r.interval()));
+ }
+
+ if (!r.bysecond().empty()) {
+ RecurType::bysecond_sequence bysecond;
+ recur.bysecond(toList<RecurType::bysecond_type, xml_schema::non_negative_integer>(bysecond, r.bysecond()));
+ }
+ return rruleProp;
+}
+
+template <typename T>
+void getIncidenceProperties(T &prop, const Kolab::Event &inc) //TODO switch form Event to template
+{
+ using namespace icalendar_2_0;
+
+ prop.sequence(fromInt<xml_schema::integer>(inc.sequence()));
+
+ switch (inc.classification()) {
+ case Kolab::Confidential:
+ prop.class_(properties::class_type("CONFIDENTIAL"));
+ break;
+ case Kolab::Private:
+ prop.class_(properties::class_type("PRIVATE"));
+ break;
+ default:
+ prop.class_(properties::class_type("PUBLIC"));
+ break;
+ }
+
+ if (inc.start().isValid()) {
+ properties::dtstart_type dtstart;
+ setDateTimeProperty<KolabTypes>(dtstart, inc.start());
+ prop.dtstart(dtstart);
+ }
+
+ if (inc.recurrenceRule().isValid()) {
+ const RecurrenceRule &r = inc.recurrenceRule();
+ prop.rrule(recurrenceProperty(r));
+ //TODO check if startdate is allDay if recurrence is allDay
+ //TODO check if startdate matches the one of the event (it MUST)
+ }
+
+}
+
+template <> struct IncidenceConverter < Incidence >
+{
+ typedef DateTimeConverter< DateTime> DC;
+ static std::string uid(const Event &inc) {
+ return inc.uid();
+ }
+
+ static xml_schema::date_time dtstamp(const Event &inc) {
+ return DC::fromDateTime(inc.lastModified());
+ }
+
+ static xml_schema::date_time created(const Event &inc) {
+ return DC::fromDateTime(inc.created());
+ }
+
+};
+
+template < > struct IncidenceTrait <Kolab::Event>
+{
+ typedef typename icalendar_2_0::KolabEvent KolabType;
+ typedef typename Kolab::Event IncidenceType;
+ typedef typename boost::shared_ptr<Kolab::Event> IncidencePtr;
+ typedef typename Kolab::Incidence Incidence;
+
+ static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const Kolab::Event &event)
+ {
+ icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+
+ getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
+
+ if (event.end().isValid()) {
+ icalendar_2_0::properties::dtend_type dtend;
+ setDateTimeProperty<KolabTypes>(dtend, event.end());
+ prop.dtend(dtend);
+ }/* else if (event.duration().isValid()) {
+
+ }*/
+ }
+
+ static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc) //TODO to base trait
+ {
+ components.vevent().push_back(inc);
+ }
+
+ static void readIncidence(Kolab::Event &event, const icalendar_2_0::KolabEvent& vevent)
+ {
+ const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+
+ setIncidenceProperties<Kolab::Event, icalendar_2_0::KolabEvent::properties_type>(event, prop);
+
+ if (prop.dtend()) {
+ event.setEnd(*toDate<KolabTypes>(*prop.dtend()));
+// event.setDtEnd(*toDate<KCalCoreTypes>(*prop.dtend()));
+// if (event.dtEnd().timeType() != event.dtStart().timeType()) {
+// kWarning() << "dtEnd has wrong timespec";
+// }
+ } else if (prop.duration()) {
+ //TODO implement
+ // KCalCore::Duration duration.;
+ // event.setDuration(duration << prop.duration());
+ }
+ //TODO check for equality of timespecs
+
+ if (prop.transp()) {
+ //TODO implement
+ }
+ }
+
+ static icalendar_2_0::components2::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components) //TODO to base trait
+ {
+ return components.vevent().begin();
+ }
+
+ static icalendar_2_0::components2::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components) //TODO to base trait
+ {
+ return components.vevent().end();
+ }
+
+};
+
+
+}//Namespace
\ No newline at end of file
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 0bb9303..ab43acc 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -1,295 +1,22 @@
-
-
#include "kolabformat.h"
-#include <kcalcore/event.h>
#include <iostream>
#include <bindings/kolabformat-xcal.hxx>
-//#include "note.h"
-#include <kdebug.h>
-#include <limits>
-#include <kcalcore/recurrencerule.h>
-#include "kcalconversions.h"
-#include </home/chrigi/devel/kde/kdepim-runtime/resources/kcal/kcalresource.h>
-#include <KDE/KCalCore/Todo>
+#include "kolabcontainers.h"
+#include "kolabconversions.h"
namespace Kolab {
-
-// xml_schema::date::operator Date(Date &d, const xml_schema::date &dt) {
-// Date d;
-// d.year = year();
-// return d;
-// }; //conversion operator
-
-
-// bool isAvailable(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
-// {
-// if (dtProperty.date_time() || dtProperty.date()) {
-// return true;
-// }
-// return false;
-// }
-
-std::string serializeEvent()
+boost::shared_ptr<Kolab::Event> readKolabEvent(const std::string& s, bool isUrl)
{
- std::cout << "ksjdsldfj";
- return "bla";
+ return readIncidence< IncidenceTrait<Kolab::Event> >(s, isUrl);
}
-void readICalendar(const std::string &s)
+std::string writeKolabEvent(const Kolab::Event &event)
{
-
+ return writeIncidence< IncidenceTrait<Kolab::Event> >(event);
}
-void readEvent(Kolab::Event &event ,const icalendar_2_0::VeventType &vevent)
-{
-// try {
-// if (!vevent.properties())
-// return;
-// const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent.properties();
-// const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
-//
-// for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
-// if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&(*it))) {
-// std::cout << "Start" << std::endl;
-// if (d->date_time()) {
-// const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(d->date_time());
-// //datetime.day()
-// // (*(d->date_time()))
-// } else if (d->date()) {
-// const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(d->date());
-// event.date << date;
-// }
-//
-// } else if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*it))) {
-// std::cout << "Rrule" << std::endl;
-// std::cout << d->recur().freq() << std::endl;
-// std::cout << d->recur().count() << std::endl;
-// //std::cout << d->recur().byhour() << std::endl;
-// } else {
-// std::cout << "other" << std::endl;
-// const icalendar_2_0::BasePropertyType &baseProperty = *it;
-// }
-// }
-// } catch (const xml_schema::exception& e) {
-// std::cout << e << std::endl;
-// }
-}
-
-
-template <typename T> struct IncidenceTrait;
-
-template < > struct IncidenceTrait <KCalCore::Event>
-{
- typedef typename icalendar_2_0::KolabEvent KolabType;
- typedef typename KCalCore::Event IncidenceType;
- typedef typename KCalCore::Event::Ptr IncidencePtr;
- typedef typename KCalCore::Incidence Incidence;
-
- static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
- {
- icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
-
- getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
-
- if (event.dtEnd().isValid()) {
- icalendar_2_0::properties::dtend_type dtend;
- setDateTimeProperty<KCalCoreTypes>(dtend, event.dtStart());
- prop.dtend(dtend);
- } else if (event.duration() != KCalCore::Duration()) {
-
- }
- }
-
- static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc)
- {
- components.vevent().push_back(inc);
- }
-
-
- static void readIncidence(KCalCore::Event &event, const icalendar_2_0::KolabEvent& vevent)
- {
- const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
-
- setIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(event, prop);
-
- if (prop.dtend()) {
- KDateTime date;
- kDebug() << "dtend";
- event.setDtEnd(*toDate<KCalCoreTypes>(*prop.dtend()));
- if (event.dtEnd().timeType() != event.dtStart().timeType()) {
- kWarning() << "dtEnd has wrong timespec";
- }
- } else if (prop.duration()) {
- // KCalCore::Duration duration.;
- // event.setDuration(duration << prop.duration());
- }
- //TODO check for equality of timespecs
-
- if (prop.transp()) {
-
- }
- }
-
- static icalendar_2_0::components2::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
- {
- return components.vevent().begin();
- }
-
- static icalendar_2_0::components2::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
- {
- return components.vevent().end();
- }
-
-};
-
-template < > struct IncidenceTrait <KCalCore::Todo>
-{
- typedef typename icalendar_2_0::KolabTodo KolabType;
- typedef typename KCalCore::Todo IncidenceType;
- typedef typename KCalCore::Incidence Incidence;
-
- static void writeIncidence(icalendar_2_0::KolabTodo& vtodo, const KCalCore::Todo &todo)
- {
- icalendar_2_0::KolabTodo::properties_type &prop = vtodo.properties();
- getIncidenceProperties<icalendar_2_0::KolabTodo::properties_type>(prop, todo);
-
- }
-
- static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc)
- {
- components.vtodo().push_back(inc);
- }
-};
-
-
-template <typename T>
-typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
-{
- typedef typename T::IncidencePtr IncidencePtr;
- typedef typename T::IncidenceType IncidenceType;
- typedef typename T::KolabType KolabType;
-
- try {
- //TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
- xml_schema::properties props;
-
- std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
- if (isUrl) {
- props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../../schemas/ical/kolabformat-xcal.xsd"); //Force schema
- icalendar = icalendar_2_0::icalendar(s, 0, props);
- } else {
- props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "/home/chrigi/work/kolab/xmlformat/libkolabxml/schemas/ical/kolabformat-xcal.xsd"); //Force schema
- std::istringstream is(s);
- icalendar = icalendar_2_0::icalendar(is, 0, props);
- }
-
- const icalendar_2_0::VcalendarType &vcalendar = icalendar->vcalendar();
-
- std::vector < IncidencePtr > incidences;
- for (typename xsd::cxx::tree::sequence< KolabType >::const_iterator it(T::begin(vcalendar.components())); it != T::end(vcalendar.components()); it++) {
- IncidencePtr e = IncidencePtr(new IncidenceType);
- const KolabType &event = *it;
- T::readIncidence(*e, event);
- incidences.push_back(e);
- }
-
- //TODO resolve events, exceptions can be identified based on the recurrence-id attribute
-// foreach (KCalCore::Event * event, events) {
-// if (!event->hasRecurrenceId()) {
-// return event;
-// }
-// }
- return *incidences.begin();
- } catch (const xml_schema::exception& e) {
- std::cout << e << std::endl;
- std::cout << "Failed to read incidence!" << std::endl;
- }
- return IncidencePtr();
-
-}
-
-
-KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
-{
- readIncidence< IncidenceTrait<KCalCore::Event> >(s, isUrl);
-}
-
-KCalCore::Todo::Ptr readTodo(const std::string& s, bool isUrl)
-{
-
-}
-
-
-
-template <typename T>
-std::string writeIncidence(const typename T::IncidenceType &incidence) {
-
- using namespace icalendar_2_0;
- typedef IncidenceConverter< typename T::Incidence > IC;
- typedef typename T::KolabType KolabType;
-
- try {
-
- typename KolabType::components_type eventComponents;
-
- typename KolabType::properties_type::uid_type uid(IC::uid(incidence));//TODO thats possibly the kontact internal uid?
- typename KolabType::properties_type::dtstamp_type dtstamp;
- dtstamp.date_time(IC::dtstamp(incidence));
- typename KolabType::properties_type::created_type created;
- created.date_time(IC::created(incidence));
- typename KolabType::properties_type eventProps(uid, created, dtstamp);
-
- KolabType inc(eventProps, eventComponents);
- T::writeIncidence(inc, incidence);
-
- VcalendarType::components_type components;
- T::addIncidence(components, inc);
-
- VcalendarType::properties_type::prodid_type prodid(std::string("libakonadi")); //TODO take from caller plus add libakonadi
- VcalendarType::properties_type::version_type version(std::string("2.0")); //TODO define globally
- VcalendarType::properties_type::x_kolab_version_type x_kolab_version(std::string("2.9.0")); //TODO define globally
-
- VcalendarType::properties_type properties(prodid, version, x_kolab_version);
-
- VcalendarType vcalendar(properties, components);
-
- IcalendarType icalendar(vcalendar);
-
- xml_schema::namespace_infomap map;
- map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-
- std::ostringstream ostringstream;
- icalendar_2_0::icalendar(ostringstream, icalendar, map);
- return ostringstream.str();
- } catch (const xml_schema::exception& e) {
- std::cout << "failed to write Incidence";
- return std::string();
- }
-}
-
-std::string writeEvent(KCalCore::Event::Ptr event)
-{
- return writeIncidence< IncidenceTrait<KCalCore::Event> >(*event);
-}
-
-std::string writeTodo(KCalCore::Todo::Ptr todo)
-{
- return writeIncidence< IncidenceTrait<KCalCore::Todo> >(*todo);
-}
-
-
-
-
-
-void Test::test()
-{
- std::cout << "test";
-}
-
-
-
}
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index 5c541c0..cb8064c 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -1,64 +1,16 @@
#ifndef KOLABFORMAT_H
#define KOLABFORMAT_H
-//#include <QString>
-#include <string>
-#include <xsd/cxx/tree/date-time.hxx>
-#include <KDE/KCalCore/Event>
-namespace KCalCore {
- class Event;
-}
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include "kolabcontainers.h"
-namespace icalendar_2_0 {
- class VeventType;
- class KolabEvent;
-}
namespace Kolab {
-//class Note;
-
-/*
-enum TYPE {
- NoteType,
- TodoType,
- EventType,
- ContactType
-};*/
-
-
-//QString serializeNote(const Note ¬e);
-
-class Test
-{
-public:
- void test();
-};
-
-
-struct Date {
- int year;
-};
-
-struct Event {
- Date date;
-};
-
-
-std::string serializeEvent();
-// void readEvent(const icalendar_2_0::VeventType &vevent);
-// void readEvent(Kolab::Event &,const icalendar_2_0::VeventType &vevent);
-void readEvent(KCalCore::Event &,const icalendar_2_0::KolabEvent &vevent);
-KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl = true);
-
-void writeEvent(icalendar_2_0::KolabEvent &vevent, const KCalCore::Event &);
-std::string writeEvent(KCalCore::Event::Ptr);
-
-void readICalendar(const std::string &s);
-
-//QString serializeEvent(const KCalCore::Event ¬e);
-//void readEvent(const QString &string, KCalCore::Event &);
+boost::shared_ptr<Kolab::Event> readKolabEvent(const std::string& s, bool isUrl);
+std::string writeKolabEvent(const Kolab::Event &);
}
diff --git a/c++/lib/kolabformat.i b/c++/lib/kolabformat.i
index d14ae8f..3024baf 100644
--- a/c++/lib/kolabformat.i
+++ b/c++/lib/kolabformat.i
@@ -9,19 +9,7 @@
/*%apply const std::string& {std::string* foo};*/
namespace Kolab {
-std::string serializeEvent();
-class Test {
-public:
- void test();
-};
-struct Date {
- int year;
-};
-
-struct Event {
- Date date;
-};
}
/*extern void readEvent(const QString &string, KCalCore::Event &); */
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index ce02581..a922628 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -10,3 +10,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
QT4_AUTOMOC(bindingstest.cpp)
add_executable(bindingstest bindingstest.cpp ${BINDINGSTEST_MOC})
target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabxml xerces-c kcalcore)
+
+# QT4_AUTOMOC(kcalconversiontest.cpp)
+# add_executable(kcalconversiontest kcalconversiontest.cpp ${KCALCONVERSIONTEST_MOC})
+# target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} kolabxmlkcal xerces-c kcalcore)
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 58fa3d1..4a2d369 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -17,55 +17,161 @@
#include <kcalcore/event.h>
#include <lib/kolabformat.h>
#include <kdebug.h>
-#include </home/chrigi/devel/kde/kdepim-runtime/resources/kcal/kcalresource.h>
-void BindingsTest::writeNoteTest()
-{
- xml_schema::date_time datetime(2011, 11, 23, 12, 12, 12);
- KolabXSD_test::XMLBase::sensitivity_type sensitivity = KolabXSD_test::Sensitivity::public_;
- KolabXSD_test::Note::background_color_type bg = KolabXSD_test::Note::background_color_default_value();
- KolabXSD_test::Note::foreground_color_type fg = KolabXSD_test::Note::foreground_color_default_value();
- KolabXSD_test::Note note("test", "test", datetime, datetime, sensitivity, "", bg, fg);
-
- xml_schema::namespace_infomap map;
- map[""].name = "http://kolab.org";
- map[""].schema = "note.xsd";
-
- KolabXSD_test::note (std::cout, note, map);
-
- /* QFETCH(KCalCore::Recurrence, kcalrecurrence);
-
- KolabXSD::Recurrence ret = Kolab::KCalConversion::fromKCal( &kcalrecurrence );
- QCOMPARE(frequency(ret), kcalrecurrence.rRules().first()->frequency());
- */
-}
-
-void BindingsTest::readNoteTest()
-{
- try {
- xml_schema::properties props;
-// props.no_namespace_schema_location ("../../schemas/note.xsd");
-// props.schema_location ("http://kolab.org", "../../schemas/note.xsd"); //Force schema
- std::auto_ptr<KolabXSD_test::Note> note(KolabXSD_test::note("testfiles/testnote.xml", xml_schema::flags::keep_dom | xml_schema::flags::dont_validate, props));
-
- xml_schema::namespace_infomap map;
- map[""].name = "http://kolab.org";
- map[""].schema = "note.xsd";
- KolabXSD_test::note (std::cout, *note, map);
- } catch (const xml_schema::exception& e) {
- std::cout << e << endl;
- QVERIFY(false);
- }
-}
-
-void BindingsTest::writeReadNoteTest()
-{
-
-}
+// void BindingsTest::writeNoteTest()
+// {
+// xml_schema::date_time datetime(2011, 11, 23, 12, 12, 12);
+// KolabXSD_test::XMLBase::sensitivity_type sensitivity = KolabXSD_test::Sensitivity::public_;
+// KolabXSD_test::Note::background_color_type bg = KolabXSD_test::Note::background_color_default_value();
+// KolabXSD_test::Note::foreground_color_type fg = KolabXSD_test::Note::foreground_color_default_value();
+// KolabXSD_test::Note note("test", "test", datetime, datetime, sensitivity, "", bg, fg);
+//
+// xml_schema::namespace_infomap map;
+// map[""].name = "http://kolab.org";
+// map[""].schema = "note.xsd";
+//
+// KolabXSD_test::note (std::cout, note, map);
+//
+// /* QFETCH(KCalCore::Recurrence, kcalrecurrence);
+//
+// KolabXSD::Recurrence ret = Kolab::KCalConversion::fromKCal( &kcalrecurrence );
+// QCOMPARE(frequency(ret), kcalrecurrence.rRules().first()->frequency());
+// */
+// }
-void BindingsTest::writeKolabXCalEvent()
-{
+// void BindingsTest::readNoteTest()
+// {
+// try {
+// xml_schema::properties props;
+// // props.no_namespace_schema_location ("../../schemas/note.xsd");
+// // props.schema_location ("http://kolab.org", "../../schemas/note.xsd"); //Force schema
+// std::auto_ptr<KolabXSD_test::Note> note(KolabXSD_test::note("testfiles/testnote.xml", xml_schema::flags::keep_dom | xml_schema::flags::dont_validate, props));
+//
+// xml_schema::namespace_infomap map;
+// map[""].name = "http://kolab.org";
+// map[""].schema = "note.xsd";
+//
+// KolabXSD_test::note (std::cout, *note, map);
+// } catch (const xml_schema::exception& e) {
+// std::cout << e << endl;
+// QVERIFY(false);
+// }
+// }
+//
+// void BindingsTest::writeReadNoteTest()
+// {
+//
+// }
+//
+// void BindingsTest::writeKolabXCalEvent()
+// {
+// // try {
+// // //Components
+// // icalendar_2_0::EventTodoComponentType::components_type::valarm_type alarm;
+// //
+// // icalendar_2_0::ArrayOfEventTodoContainedComponents component;
+// // component.valarm().push_back(alarm);
+// //
+// // //Properties
+// //
+// // //Recurrence
+// // icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
+// // recur.count(2);
+// // recur.byhour().push_back("3");
+// // icalendar_2_0::RrulePropType rrule(recur);
+// //
+// // //Startdate
+// // xml_schema::date_time dt(2011,8,12,2,12,15);
+// // icalendar_2_0::DtstartPropType::date_time_type datetime(dt);
+// // icalendar_2_0::DtstartPropType startdate;
+// // startdate.date_time(datetime);
+// // //Startdate timezone
+// // ::icalendar_2_0::ArrayOfParameters parameters;
+// // ::icalendar_2_0::TzidParamType tzid("US/Eastern");
+// // parameters.baseParameter().push_back(tzid);
+// // startdate.parameters(parameters);
+// //
+// //
+// // //Custom value
+// // KolabXSD::CustomType custom("cusotomtypeidentifier", "sldjfldfj");
+// //
+// // //Assembling event properties
+// // ::icalendar_2_0::ArrayOfProperties properties;
+// // properties.baseProperty().push_back(startdate);
+// // properties.baseProperty().push_back(rrule);
+// // properties.baseProperty().push_back(custom);
+// //
+// // //Assembling the complete event
+// // icalendar_2_0::VeventType event(component);
+// // event.properties(properties);
+// //
+// // KolabXSD::Event kolabEvent(event);
+// // xml_schema::namespace_infomap map;
+// // map["kolab"].name = "http://kolab.org";
+// // map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
+// // //map["xcal"].schema = "iCalendar.xsd";
+// //
+// // KolabXSD::event (std::cout, kolabEvent, map);
+// //
+// //
+// // // icalendar_2_0::VstrictTodoType todo;
+// // // icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
+// // // todo.rrule().;
+// //
+// // } catch (const xml_schema::exception& e) {
+// // std::cout << e << endl;
+// // QVERIFY(false);
+// // }
+// }
+//
+//
+// void BindingsTest::readKolabXCalEvent()
+// {
+// // try {
+// // // xml_schema::properties props;
+// // // props.no_namespace_schema_location ("../../../schemas/ical/kolabevent.xsd");
+// // // props.schema_location ("http://kolab.org", "../../../schemas/ical/kolabevent.xsd"); //Force schema
+// // // std::auto_ptr<KolabXSD::Event> event(KolabXSD::kolabevent("testfiles/testkolabevent.xml", 0, props));
+// //
+// // std::auto_ptr<KolabXSD::Event> event(KolabXSD::event("testfiles/testkolabevent.xml", xml_schema::flags::dont_validate));
+// //
+// // const icalendar_2_0::BaseComponentType::properties_type& properties = *event->vevent().properties();
+// // const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
+// //
+// // /*for(int i = 0; i < propertyList.size(); i++) {
+// // const icalendar_2_0::ArrayOfProperties::baseProperty_type prop = propertyList.at(i);
+// // }*/
+// // std::cout << propertyList.size() << std::endl;
+// // for (icalendar_2_0::ArrayOfProperties::baseProperty_sequence::const_iterator i (propertyList.begin ()); i != propertyList.end (); ++i) {
+// // if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*i))) {
+// // std::cout << "Rrule" << std::endl;
+// // std::cout << d->recur().freq() << std::endl;
+// // std::cout << d->recur().count() << std::endl;
+// // //std::cout << d->recur().byhour() << std::endl;
+// // } else {
+// // std::cout << "other" << std::endl;
+// // const icalendar_2_0::BasePropertyType &baseProperty = (*i);
+// // }
+// // }
+// //
+// // xml_schema::namespace_infomap map;
+// // map["kolab"].name = "http://kolab.org";
+// // // map[""].schema = "kolabevent.xsd";
+// // map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
+// // // map["xcal"].schema = "iCalendar.xsd";
+// //
+// // KolabXSD::event (std::cout, *event, map);
+// //
+// // } catch (const xml_schema::exception& e) {
+// // std::cout << e << std::endl;
+// // QVERIFY(false);
+// // }
+// }
+//
+// #if 0
+// void BindingsTest::writeXCalEvent()
+// {
// try {
// //Components
// icalendar_2_0::EventTodoComponentType::components_type::valarm_type alarm;
@@ -80,342 +186,232 @@ void BindingsTest::writeKolabXCalEvent()
// recur.count(2);
// recur.byhour().push_back("3");
// icalendar_2_0::RrulePropType rrule(recur);
-//
+//
// //Startdate
-// xml_schema::date_time dt(2011,8,12,2,12,15);
-// icalendar_2_0::DtstartPropType::date_time_type datetime(dt);
+// icalendar_2_0::DtstartPropType::date_type date(2011, 11, 10, 10, 10);
// icalendar_2_0::DtstartPropType startdate;
-// startdate.date_time(datetime);
-// //Startdate timezone
-// ::icalendar_2_0::ArrayOfParameters parameters;
-// ::icalendar_2_0::TzidParamType tzid("US/Eastern");
-// parameters.baseParameter().push_back(tzid);
-// startdate.parameters(parameters);
-//
+// startdate.date(date);
//
-// //Custom value
-// KolabXSD::CustomType custom("cusotomtypeidentifier", "sldjfldfj");
-//
-// //Assembling event properties
// ::icalendar_2_0::ArrayOfProperties properties;
// properties.baseProperty().push_back(startdate);
// properties.baseProperty().push_back(rrule);
-// properties.baseProperty().push_back(custom);
-//
+//
+//
// //Assembling the complete event
// icalendar_2_0::VeventType event(component);
// event.properties(properties);
//
-// KolabXSD::Event kolabEvent(event);
+//
+// icalendar_2_0::VcalendarType::components_type comp;
+// comp.vcalendarContainedComponent().push_back(event);
+//
+// icalendar_2_0::VcalendarType vcalendar(comp);
+//
+// icalendar_2_0::IcalendarType icalendar;
+// icalendar.vcalendar().push_back(vcalendar);
+//
+// /*
+// * We need the namespacemap, otherwise we get elements with a prefix ns1:vevent:components
+// * and at least xerces doesn't like prefixes with a ":" inside (only a single prefix is allowed).
+// * No idea why this happens though.
+// */
// xml_schema::namespace_infomap map;
-// map["kolab"].name = "http://kolab.org";
// map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-// //map["xcal"].schema = "iCalendar.xsd";
-//
-// KolabXSD::event (std::cout, kolabEvent, map);
+// //map[""].schema = "iCalendar.xsd";
//
-//
-// // icalendar_2_0::VstrictTodoType todo;
-// // icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
-// // todo.rrule().;
+// icalendar_2_0::vevent (std::cout, event, map);
//
// } catch (const xml_schema::exception& e) {
// std::cout << e << endl;
// QVERIFY(false);
// }
-}
-
-
-void BindingsTest::readKolabXCalEvent()
-{
+// #if 0
+// catch (const xercesc_3_1::DOMException &e) {
+// std::cout << "Xerces dom exception: " /*<< std::basic_string<XMLCh>(e.getMessage())*/ << " Code: " << e.code << std::endl;
+// return;
+// }
+// #endif
+// }
+//
+//
+// void BindingsTest::readXCalEvent()
+// {
+//
// try {
-// // xml_schema::properties props;
-// // props.no_namespace_schema_location ("../../../schemas/ical/kolabevent.xsd");
-// // props.schema_location ("http://kolab.org", "../../../schemas/ical/kolabevent.xsd"); //Force schema
-// // std::auto_ptr<KolabXSD::Event> event(KolabXSD::kolabevent("testfiles/testkolabevent.xml", 0, props));
+// xml_schema::properties props;
+// // props.no_namespace_schema_location ("../../schemas/ical/iCalendar.xsd");
+// // props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../schemas/ical/iCalendar.xsd"); //Force schema
//
-// std::auto_ptr<KolabXSD::Event> event(KolabXSD::event("testfiles/testkolabevent.xml", xml_schema::flags::dont_validate));
-//
-// const icalendar_2_0::BaseComponentType::properties_type& properties = *event->vevent().properties();
-// const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
+// std::auto_ptr<icalendar_2_0::VeventType > event(icalendar_2_0::vevent("testfiles/testevent.xml", xml_schema::flags::dont_validate, props));
//
-// /*for(int i = 0; i < propertyList.size(); i++) {
-// const icalendar_2_0::ArrayOfProperties::baseProperty_type prop = propertyList.at(i);
-// }*/
-// std::cout << propertyList.size() << std::endl;
-// for (icalendar_2_0::ArrayOfProperties::baseProperty_sequence::const_iterator i (propertyList.begin ()); i != propertyList.end (); ++i) {
-// if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*i))) {
-// std::cout << "Rrule" << std::endl;
-// std::cout << d->recur().freq() << std::endl;
-// std::cout << d->recur().count() << std::endl;
-// //std::cout << d->recur().byhour() << std::endl;
-// } else {
-// std::cout << "other" << std::endl;
-// const icalendar_2_0::BasePropertyType &baseProperty = (*i);
-// }
-// }
-//
// xml_schema::namespace_infomap map;
-// map["kolab"].name = "http://kolab.org";
-// // map[""].schema = "kolabevent.xsd";
// map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-// // map["xcal"].schema = "iCalendar.xsd";
+// map[""].schema = "iCalendar.xsd";
//
-// KolabXSD::event (std::cout, *event, map);
+// icalendar_2_0::vevent (std::cout, *event, map);
//
// } catch (const xml_schema::exception& e) {
// std::cout << e << std::endl;
// QVERIFY(false);
// }
-}
-
-#if 0
-void BindingsTest::writeXCalEvent()
-{
- try {
- //Components
- icalendar_2_0::EventTodoComponentType::components_type::valarm_type alarm;
-
- icalendar_2_0::ArrayOfEventTodoContainedComponents component;
- component.valarm().push_back(alarm);
-
- //Properties
-
- //Recurrence
- icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
- recur.count(2);
- recur.byhour().push_back("3");
- icalendar_2_0::RrulePropType rrule(recur);
-
- //Startdate
- icalendar_2_0::DtstartPropType::date_type date(2011, 11, 10, 10, 10);
- icalendar_2_0::DtstartPropType startdate;
- startdate.date(date);
-
- ::icalendar_2_0::ArrayOfProperties properties;
- properties.baseProperty().push_back(startdate);
- properties.baseProperty().push_back(rrule);
-
-
- //Assembling the complete event
- icalendar_2_0::VeventType event(component);
- event.properties(properties);
-
-
- icalendar_2_0::VcalendarType::components_type comp;
- comp.vcalendarContainedComponent().push_back(event);
-
- icalendar_2_0::VcalendarType vcalendar(comp);
-
- icalendar_2_0::IcalendarType icalendar;
- icalendar.vcalendar().push_back(vcalendar);
-
- /*
- * We need the namespacemap, otherwise we get elements with a prefix ns1:vevent:components
- * and at least xerces doesn't like prefixes with a ":" inside (only a single prefix is allowed).
- * No idea why this happens though.
- */
- xml_schema::namespace_infomap map;
- map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
- //map[""].schema = "iCalendar.xsd";
-
- icalendar_2_0::vevent (std::cout, event, map);
-
- } catch (const xml_schema::exception& e) {
- std::cout << e << endl;
- QVERIFY(false);
- }
- #if 0
- catch (const xercesc_3_1::DOMException &e) {
- std::cout << "Xerces dom exception: " /*<< std::basic_string<XMLCh>(e.getMessage())*/ << " Code: " << e.code << std::endl;
- return;
- }
-#endif
-}
-
-
-void BindingsTest::readXCalEvent()
-{
-
- try {
- xml_schema::properties props;
-// props.no_namespace_schema_location ("../../schemas/ical/iCalendar.xsd");
-// props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../schemas/ical/iCalendar.xsd"); //Force schema
-
- std::auto_ptr<icalendar_2_0::VeventType > event(icalendar_2_0::vevent("testfiles/testevent.xml", xml_schema::flags::dont_validate, props));
-
- xml_schema::namespace_infomap map;
- map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
- map[""].schema = "iCalendar.xsd";
-
- icalendar_2_0::vevent (std::cout, *event, map);
-
- } catch (const xml_schema::exception& e) {
- std::cout << e << std::endl;
- QVERIFY(false);
- }
-
-}
-
-#endif
+//
+// }
+//
+// #endif
+//
+// void BindingsTest::xercesException()
+// {
+// xercesc::XMLPlatformUtils::Initialize();
+// XMLCh tempStr[100];
+//
+// xercesc::DOMImplementation* impl = xercesc::DOMImplementation::getImplementation();
+//
+// xercesc::XMLString::transcode("root", tempStr, 99);
+// xercesc::DOMDocument* doc = impl->createDocument(0, tempStr, 0);
+//
+// /* XMLCh n[100];
+// XMLCh ns[100];
+// xercesc::XMLString::transcode("components", n, 99);
+// xercesc::XMLString::transcode("urn:ietf:params:xml:ns:icalendar-2.0", ns, 99);*/
+// try {
+// xercesc::DOMElement* e = doc->createElementNS (xsd::cxx::xml::string("urn:ietf:params:xml:ns:icalendar-2.0").c_str(), xsd::cxx::xml::string("components").c_str());
+// QVERIFY(e);
+//
+// /*
+// xercesc::DOMElement& s (
+// ::xsd::cxx::xml::dom::create_element (
+// "components",
+// "http://icalnamespace.org",
+// e));
+// */
+//
+// } catch (const xercesc_3_1::DOMException &e) {
+// std::cout << "Xerces dom exception: " /*<< std::basic_string<XMLCh>(e.getMessage())*/ << " Code: " << e.code << std::endl;
+// return;
+// }
+//
+// doc->release();
+// }
+//
+// void BindingsTest::writeContact()
+// {
+// try {
+// // KolabXSD::Contact::vcard_type vcard;
+// //
+// // vcard_4_0::fnPropType fn("Fritz Muster");
+// // vcard.baseProperty().push_back(fn);
+// //
+// // vcard_4_0::nPropType n;
+// // n.given().push_back("john");
+// // n.surname().push_back("doe");
+// // vcard.baseProperty().push_back(n);
+// //
+// // vcard_4_0::bdayPropType bday;
+// // vcard_4_0::bdayPropType::date_type date(1988,12,12);
+// // bday.date(date);
+// // vcard.baseProperty().push_back(bday);
+// //
+// // KolabXSD::Contact contact(vcard);
+// // xml_schema::namespace_infomap map;
+// // map["kolab"].name = "http://kolab.org";
+// // map[""].name = "urn:ietf:params:xml:ns:vcard-4.0";
+// // //map["xcal"].schema = "iCalendar.xsd";
+// //
+// // KolabXSD::contact (std::cout, contact, map);
+//
+//
+// } catch (const xml_schema::exception& e) {
+// std::cout << e << endl;
+// QVERIFY(false);
+// }
+// }
+//
+// void BindingsTest::readContact()
+// {
+//
+// }
+
+namespace QTest {
+ template<>
+ char *toString(const Kolab::DateTime &dt)
+ {
+ QByteArray ba = "DateTime(";
+ ba += QByteArray::number(dt.year()) + ", " + QByteArray::number(dt.month())+ ", " + QByteArray::number(dt.day()) + ", ";
+ ba += QByteArray::number(dt.hour()) + ", " + QByteArray::number(dt.minute()) + ", " + QByteArray::number(dt.second())+ ", ";
+ ba += QString(dt.isUTC()?QString("UTC"):QString("TZ: "+QString::fromStdString(dt.timezone()))).toAscii();
+ ba += ")";
+ return qstrdup(ba.data());
+ }
+
+ template<>
+ char *toString(const std::string &s)
+ {
+ QByteArray ba = "string(";
+ ba += QString::fromStdString(s).toAscii();
+ ba += ")";
+ return qstrdup(ba.data());
+ }
+ }
-void BindingsTest::xercesException()
+void BindingsTest::readEvent()
{
- xercesc::XMLPlatformUtils::Initialize();
- XMLCh tempStr[100];
-
- xercesc::DOMImplementation* impl = xercesc::DOMImplementation::getImplementation();
+ boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("testfiles/icalEvent.xml", true);
+ QVERIFY(event);
+ QCOMPARE(event->created(), Kolab::DateTime(2006,2,6,0,11,21,true));
+ QCOMPARE(event->start(), Kolab::DateTime("US/Eastern",2006,1,2,12,0,0));
- xercesc::XMLString::transcode("root", tempStr, 99);
- xercesc::DOMDocument* doc = impl->createDocument(0, tempStr, 0);
+ const Kolab::RecurrenceRule &rrule = event->recurrenceRule();
+ QCOMPARE(rrule.frequency(), Kolab::RecurrenceRule::Daily);
+ QCOMPARE(rrule.count(), 5);
+ QCOMPARE(rrule.interval(), 1);
-/* XMLCh n[100];
- XMLCh ns[100];
- xercesc::XMLString::transcode("components", n, 99);
- xercesc::XMLString::transcode("urn:ietf:params:xml:ns:icalendar-2.0", ns, 99);*/
- try {
- xercesc::DOMElement* e = doc->createElementNS (xsd::cxx::xml::string("urn:ietf:params:xml:ns:icalendar-2.0").c_str(), xsd::cxx::xml::string("components").c_str());
- QVERIFY(e);
-
- /*
- xercesc::DOMElement& s (
- ::xsd::cxx::xml::dom::create_element (
- "components",
- "http://icalnamespace.org",
- e));
- */
-
- } catch (const xercesc_3_1::DOMException &e) {
- std::cout << "Xerces dom exception: " /*<< std::basic_string<XMLCh>(e.getMessage())*/ << " Code: " << e.code << std::endl;
- return;
- }
-
- doc->release();
-}
-
-void BindingsTest::writeContact()
-{
- try {
-// KolabXSD::Contact::vcard_type vcard;
-//
-// vcard_4_0::fnPropType fn("Fritz Muster");
-// vcard.baseProperty().push_back(fn);
-//
-// vcard_4_0::nPropType n;
-// n.given().push_back("john");
-// n.surname().push_back("doe");
-// vcard.baseProperty().push_back(n);
-//
-// vcard_4_0::bdayPropType bday;
-// vcard_4_0::bdayPropType::date_type date(1988,12,12);
-// bday.date(date);
-// vcard.baseProperty().push_back(bday);
-//
-// KolabXSD::Contact contact(vcard);
-// xml_schema::namespace_infomap map;
-// map["kolab"].name = "http://kolab.org";
-// map[""].name = "urn:ietf:params:xml:ns:vcard-4.0";
-// //map["xcal"].schema = "iCalendar.xsd";
-//
-// KolabXSD::contact (std::cout, contact, map);
-
-
- } catch (const xml_schema::exception& e) {
- std::cout << e << endl;
- QVERIFY(false);
- }
+ QCOMPARE(event->summary(), std::string("Event #2"));
}
-void BindingsTest::readContact()
+void BindingsTest::writeEvent()
{
-
+ Kolab::Event event;
+ event.setStart(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
+ event.setEnd(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
+ Kolab::RecurrenceRule rrule;
+ rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+ rrule.setInterval(3);
+ rrule.setCount(5);
+ event.setRecurrenceRule(rrule);
+ std::cout << Kolab::writeKolabEvent(event) << std::endl;
}
-
-void BindingsTest::readEvent()
+void BindingsTest::roundtripEvent()
{
-
- KCalCore::Event::Ptr event = Kolab::readEvent("testfiles/icalEvent.xml");
- QVERIFY(event);
-
- //Check basics
- QCOMPARE(event->created(), KDateTime(QDate(2006, 2, 6), QTime(00, 11, 21), KDateTime::Spec(KDateTime::UTC)));
- QCOMPARE(event->created().timeSpec().type(), KDateTime::UTC);
- QCOMPARE(event->dtStart(), KDateTime(QDate(2006, 1, 2), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
- QCOMPARE(event->dtStart().timeZone().name(), KTimeZone(QString::fromLatin1("US/Eastern")).name());
-
- //Check recurrence
- //TODO do some "heavy" testing for recurrences, including possible edge cases.
-
- //Check recurrence rule
- foreach (const KCalCore::RecurrenceRule *rule, event->recurrence()->rRules()) {
- QCOMPARE(rule->startDt(), event->recurrence()->startDateTime());
- }
- QCOMPARE(event->recurrence()->rRules().size(), 1);
- KCalCore::RecurrenceRule *rule = event->recurrence()->rRules().first();
- QCOMPARE(rule->recurrenceType(), KCalCore::RecurrenceRule::rDaily);
- QCOMPARE(rule->duration(), 5);
- KDateTime start(event->dtStart());
- KDateTime end(QDate(2006, 12, 14), QTime(12, 0, 0));
- QCOMPARE(rule->timesInInterval(start, end).size(), 5); //count/duration limit
- QCOMPARE(rule->timesInInterval(start, KDateTime(QDate(2006, 1, 4))).size(), 3); //end date limit
- const KCalCore::DateTimeList &ruleList = rule->timesInInterval(start, end);
- foreach (const KDateTime &d, ruleList) {
- QCOMPARE(d.timeZone().name(), event->dtStart().timeZone().name());
-// kDebug() << d << d.timeZone().name();
- }
- QCOMPARE(ruleList.first(), event->dtStart());
- QCOMPARE(ruleList.last(), KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
-
- //Check complete recurrence
- const KCalCore::DateTimeList &list = event->recurrence()->timesInInterval(start, end);
- foreach (const KDateTime &d, list) {
- QCOMPARE(d.timeZone().name(), event->dtStart().timeZone().name());
-// kDebug() << d << d.timeZone().name();
- }
-
- QCOMPARE(event->summary(), QString::fromLatin1("Event #2"));
- kDebug() << event->summary();
-// QCOMPARE(event->summary(), QString::fromUtf8("Test.
Test.Test.")); //FIXME fix control character 
 (linefeed)
- kDebug() << event->description();
+ Kolab::Event event;
+ event.setStart(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
+ event.setEnd(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
+ Kolab::RecurrenceRule rrule;
+ rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+ rrule.setInterval(3);
+ rrule.setCount(5);
+ event.setRecurrenceRule(rrule);
+ std::string result = Kolab::writeKolabEvent(event);
+ std::cout << result << std::endl;
}
-void BindingsTest::writeEvent()
+void BindingsTest::roundtripReverseEvent()
{
- KCalCore::Event::Ptr event(new KCalCore::Event);
- event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
- event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
-
- KCalCore::Recurrence *recurrence = event->recurrence();
- KCalCore::RecurrenceRule *rule = new KCalCore::RecurrenceRule();
- rule->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
- rule->setFrequency(3);
- rule->setDuration(5);
- recurrence->addRRule(rule);
-
+ boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("testfiles/icalEvent.xml", true);
kDebug() << "-------------------";
- kDebug() << QString::fromStdString(Kolab::writeEvent(event));
+ std::cout << Kolab::writeKolabEvent(*event) << std::endl;
kDebug() << "-------------------";
}
-void BindingsTest::roundtripEvent()
+void BindingsTest::BenchmarkRoundtrip()
{
- KCalCore::Event::Ptr event(new KCalCore::Event);
- event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
- event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
-
- KCalCore::Recurrence *recurrence = event->recurrence();
- KCalCore::RecurrenceRule *rule = new KCalCore::RecurrenceRule();
- rule->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
- rule->setFrequency(3);
- rule->setDuration(5);
- recurrence->addRRule(rule);
-
- QString result = QString::fromStdString(Kolab::writeEvent(event));
- kDebug() << result;
- KCalCore::Event::Ptr resEvent = Kolab::readEvent(result.toStdString(), false);
- QVERIFY(resEvent);
- QCOMPARE(event->dtStart(), resEvent->dtStart());
+ boost::shared_ptr<Kolab::Event> event = Kolab::readKolabEvent("testfiles/icalEvent.xml", true);
+ std::string result;
+ result = Kolab::writeKolabEvent(*event);
+ QBENCHMARK {
+
+ Kolab::readKolabEvent(result, false);
+ }
}
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index bb63dd2..f5aac9e 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -9,25 +9,26 @@ class BindingsTest : public QObject
Q_OBJECT
private slots:
- void writeKolabXCalEvent();
- void readKolabXCalEvent();
- //void writeXCalEvent();
- //void readXCalEvent();
-
- void writeNoteTest();
- void readNoteTest();
- void writeReadNoteTest();
- void xercesException();
-
- void writeContact();
- void readContact();
+// void writeKolabXCalEvent();
+// void readKolabXCalEvent();
+// //void writeXCalEvent();
+// //void readXCalEvent();
+//
+// void writeNoteTest();
+// void readNoteTest();
+// void writeReadNoteTest();
+// void xercesException();
+//
+// void writeContact();
+// void readContact();
//Kolabformat
void readEvent();
void writeEvent();
void roundtripEvent();
-
+ void roundtripReverseEvent();
+ void BenchmarkRoundtrip();
};
#endif
\ No newline at end of file
diff --git a/c++/tests/kcalconversiontest.cpp b/c++/tests/kcalconversiontest.cpp
index 0599471..15d90fe 100644
--- a/c++/tests/kcalconversiontest.cpp
+++ b/c++/tests/kcalconversiontest.cpp
@@ -3,8 +3,130 @@
#include <QtCore/QObject>
#include <QtTest/QtTest>
#include <kcalcore/recurrence.h>
-#include <lib/kolabkcalconversion.h>
+#include <lib/kcalconversions.h>
+#include <lib/kcalkolabformat.h>
+
+
+void KCalConversionTest::testDate()
+{
+ KDateTime dt1(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+ xml_schema::date_time date1 = Kolab::DateTimeConverter<KDateTime>::fromDateTime(dt1);
+ QCOMPARE(date1.zone_present(), true);
+
+ KDateTime dt2(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0)));
+ xml_schema::date_time date2 = Kolab::DateTimeConverter<KDateTime>::fromDateTime(dt2);
+ QCOMPARE(date2.zone_present(), false);
+
+ KDateTime dt3(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KDateTime::UTC));
+ xml_schema::date_time date3 = Kolab::DateTimeConverter<KDateTime>::fromDateTime(dt3);
+ QCOMPARE(date3.zone_present(), false);
+}
+
+void KCalConversionTest::readEvent()
+{
+
+ KCalCore::Event::Ptr event = Kolab::readEvent("testfiles/icalEvent.xml");
+ QVERIFY(event);
+
+ //Check basics
+ QCOMPARE(event->created(), KDateTime(QDate(2006, 2, 6), QTime(00, 11, 21), KDateTime::Spec(KDateTime::UTC)));
+ QCOMPARE(event->created().timeSpec().type(), KDateTime::UTC);
+ QCOMPARE(event->dtStart(), KDateTime(QDate(2006, 1, 2), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+ QCOMPARE(event->dtStart().timeZone().name(), KTimeZone(QString::fromLatin1("US/Eastern")).name());
+
+ //Check recurrence
+ //TODO do some "heavy" testing for recurrences, including possible edge cases.
+
+ //Check recurrence rule
+ foreach (const KCalCore::RecurrenceRule *rule, event->recurrence()->rRules()) {
+ QCOMPARE(rule->startDt(), event->recurrence()->startDateTime());
+ }
+ QCOMPARE(event->recurrence()->rRules().size(), 1);
+ KCalCore::RecurrenceRule *rule = event->recurrence()->rRules().first();
+ QCOMPARE(rule->recurrenceType(), KCalCore::RecurrenceRule::rDaily);
+ QCOMPARE(rule->duration(), 5);
+ KDateTime start(event->dtStart());
+ KDateTime end(QDate(2006, 12, 14), QTime(12, 0, 0));
+ QCOMPARE(rule->timesInInterval(start, end).size(), 5); //count/duration limit
+ QCOMPARE(rule->timesInInterval(start, KDateTime(QDate(2006, 1, 4))).size(), 3); //end date limit
+ const KCalCore::DateTimeList &ruleList = rule->timesInInterval(start, end);
+ foreach (const KDateTime &d, ruleList) {
+ QCOMPARE(d.timeZone().name(), event->dtStart().timeZone().name());
+// kDebug() << d << d.timeZone().name();
+ }
+ QCOMPARE(ruleList.first(), event->dtStart());
+ QCOMPARE(ruleList.last(), KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+
+ //Check complete recurrence
+ const KCalCore::DateTimeList &list = event->recurrence()->timesInInterval(start, end);
+ foreach (const KDateTime &d, list) {
+ QCOMPARE(d.timeZone().name(), event->dtStart().timeZone().name());
+// kDebug() << d << d.timeZone().name();
+ }
+
+ QCOMPARE(event->summary(), QString::fromLatin1("Event #2"));
+ kDebug() << event->summary();
+// QCOMPARE(event->summary(), QString::fromUtf8("Test.
Test.Test.")); //FIXME fix control character 
 (linefeed)
+ kDebug() << event->description();
+}
+
+void KCalConversionTest::writeEvent()
+{
+
+ KCalCore::Event::Ptr event(new KCalCore::Event);
+ event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+ event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+
+ KCalCore::Recurrence *recurrence = event->recurrence();
+ KCalCore::RecurrenceRule *rule = new KCalCore::RecurrenceRule();
+ rule->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+ rule->setFrequency(3);
+ rule->setDuration(5);
+ recurrence->addRRule(rule);
+
+ kDebug() << "-------------------";
+ kDebug() << QString::fromStdString(Kolab::writeEvent(event));
+ kDebug() << "-------------------";
+}
+
+void KCalConversionTest::roundtripReverseEvent()
+{
+ KCalCore::Event::Ptr event = Kolab::readEvent("testfiles/icalEvent.xml");
+ kDebug() << "-------------------";
+ kDebug() << QString::fromStdString(Kolab::writeEvent(event));
+ kDebug() << "-------------------";
+}
+
+void KCalConversionTest::roundtripEvent()
+{
+ KCalCore::Event::Ptr event(new KCalCore::Event);
+ event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+ event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+
+ KCalCore::Recurrence *recurrence = event->recurrence();
+ KCalCore::RecurrenceRule *rule = new KCalCore::RecurrenceRule();
+ rule->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+ rule->setFrequency(3);
+ rule->setDuration(5);
+ recurrence->addRRule(rule);
+
+ QString result = QString::fromStdString(Kolab::writeEvent(event));
+ kDebug() << result;
+ KCalCore::Event::Ptr resEvent = Kolab::readEvent(result.toStdString(), false);
+ QVERIFY(resEvent);
+ QCOMPARE(event->dtStart(), resEvent->dtStart());
+}
+
+void KCalConversionTest::BenchmarkRoundtrip()
+{
+ KCalCore::Event::Ptr event = Kolab::readEvent("testfiles/icalEvent.xml");
+ std::string result;
+ QBENCHMARK {
+ result = Kolab::writeEvent(event);
+ Kolab::readEvent(result, false);
+ }
+}
void KCalConversionTest::testConversion_data()
{
@@ -18,12 +140,6 @@ void KCalConversionTest::testConversion_data()
QTest::newRow( "test1" ) << recurrence;
*/
}
-
-uint frequency(const KolabXSD::Recurrence &r)
-{
-
- return 2;
-}
void KCalConversionTest::testConversion()
{
@@ -221,6 +337,8 @@ class KCalConversionTest : public QObject
}*/
};
#endif
+
+
QTEST_MAIN( KCalConversionTest )
-//#include "moc_kcalconversiontest.cxx"
+#include "moc_kcalconversiontest.cxx"
diff --git a/c++/tests/kcalconversiontest.h b/c++/tests/kcalconversiontest.h
index 826147f..f1f5a32 100644
--- a/c++/tests/kcalconversiontest.h
+++ b/c++/tests/kcalconversiontest.h
@@ -12,6 +12,13 @@ class KCalConversionTest : public QObject
void testConversion_data();
void testConversion();
+ void testDate();
+
+ void readEvent();
+ void writeEvent();
+ void roundtripEvent();
+ void roundtripReverseEvent();
+ void BenchmarkRoundtrip();
};
#endif
\ No newline at end of file
commit c992cd574b01816550198f77613ca5a2c82b8063
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 01:37:35 2011 +0100
Preparations for compiled schemas
diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 2bc4fe1..dd1512e 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -14,6 +14,8 @@ file(MAKE_DIRECTORY bindings)
set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )
set( XSDCXX /usr/bin/xsdcxx)
+
+# Generate Kolab bindings
file(GLOB KOLAB_SCHEMAS ${SCHEMA_DIR}/*.xsd)
set( KOLAB_SCHEMA_SOURCEFILES
bindings/base.cxx
@@ -29,6 +31,11 @@ add_custom_command(OUTPUT ${KOLAB_SCHEMA_SOURCEFILES}
VERBATIM
)
+
+
+
+# Generate XCal bindings
+
file(GLOB XCAL_SCHEMAS ${SCHEMA_DIR}/ical/*.xsd)
set( XCAL_SCHEMA_SOURCEFILES
bindings/xCard.cxx
@@ -45,7 +52,10 @@ set( XCAL_SCHEMA_SOURCEFILES
# bindings/iCalendar-availability-extension.cxx
# bindings/iCalendar-wscal-extensions.cxx
)
-# --cxx-suffix .cpp --hxx-suffix .h
+
+#xsdcxx cxx-tree --generate-xml-schema --generate-serialization --custom-type date_time --hxx-epilogue '#include "bindings/customtypes/xml-schema-custom.hxx"' xml-schema.xsd
+# --generate-inline --extern-xml-schema xml-schema.xsd
+# --cxx-suffix .cpp --hxx-suffix .h
add_custom_command(OUTPUT ${XCAL_SCHEMA_SOURCEFILES}
COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element icalendar --output-dir bindings ${XCAL_SCHEMAS}
COMMENT "Generating xCal XSD bindings"
@@ -53,15 +63,34 @@ add_custom_command(OUTPUT ${XCAL_SCHEMA_SOURCEFILES}
DEPENDS ${XCAL_SCHEMAS}
VERBATIM
)
-
set( SCHEMA_SOURCEFILES ${XCAL_SCHEMA_SOURCEFILES} ${KOLAB_SCHEMA_SOURCEFILES})
+# Compile Schema
+add_executable(xsdbin compiled/xsdbin.cxx)
+target_link_libraries(xsdbin xerces-c)
+
+add_custom_command(OUTPUT compiled/kolabformat-xcal-schema.cxx
+ COMMAND ${xsdbin} ./xsdbin --verbose --array-name iCalendar_schema --output-dir compiled/ ${SCHEMA_DIR}/ical/kolabformat-xcal.xsd ${SCHEMA_DIR}/ical/iCalendar-params.xsd ${SCHEMA_DIR}/ical/iCalendar-props.xsd ${SCHEMA_DIR}/ical/iCalendar-valtypes.xsd
+ COMMENT "Compiling Kolab XSD schema"
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ DEPENDS ${XCAL_SCHEMAS} xsdbin
+ VERBATIM
+ )
+set( SCHEMA_SOURCEFILES ${SCHEMA_SOURCEFILES} compiled/kolabformat-xcal-schema.cxx)
+
+# ---------
+
SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
ADD_CUSTOM_TARGET(generate_bindings ALL DEPENDS ${SCHEMA_SOURCEFILES})
include_directories( ./ )
-add_library(kolabxml lib/kolabformat.cpp ${SCHEMA_SOURCEFILES})
-target_link_libraries(${kolabxml} xerces-c)
+
+add_library(kolabxml lib/kolabformat.cpp lib/kolabcontainers.cpp compiled/XMLParserWrapper.cpp compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+target_link_libraries(kolabxml xerces-c)
+
+add_library(kolabxmlkcal lib/kcalkolabformat.cpp ${SCHEMA_SOURCEFILES})
+target_link_libraries(kolabxmlkcal xerces-c)
+
add_subdirectory(tests)
add_subdirectory(lib)
diff --git a/c++/compiled/README b/c++/compiled/README
new file mode 100644
index 0000000..d3a07b8
--- /dev/null
+++ b/c++/compiled/README
@@ -0,0 +1,18 @@
+According to the xsd example in xsd/examples/cxx/tree/embedded/
+
+xsdbin.cxx
+ Tool for converting one or more XML Schema files to the compressed binary
+ representation. The output is written as a pair of C++ source files
+ containing the array with the binary data. Use the --help option to see
+ the tool's usage information.
+
+library-schema.hxx
+library-schema.cxx
+ Binary representation of the library.xsd schema. These files are generated
+ by the xsdbin tool.
+
+grammar-input-stream.hxx
+grammar-input-stream.cxx
+ Input stream implementation with the special-purpose schema grammar
+ decompression algorithm. It is used to load the binary schema representation
+ produced by the xsdbin tool.
diff --git a/c++/compiled/XMLParserWrapper.cpp b/c++/compiled/XMLParserWrapper.cpp
new file mode 100644
index 0000000..43fe477
--- /dev/null
+++ b/c++/compiled/XMLParserWrapper.cpp
@@ -0,0 +1,250 @@
+#include "XMLParserWrapper.h"
+
+#include <memory> // std::auto_ptr
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/XMLUniDefs.hpp> // chLatin_*
+#include <xercesc/util/PlatformUtils.hpp>
+#include <xercesc/validators/common/Grammar.hpp> // xercesc::Grammar
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#if _XERCES_VERSION >= 30000
+# include <xercesc/framework/XMLGrammarPoolImpl.hpp>
+#else
+# include <xercesc/internal/XMLGrammarPoolImpl.hpp>
+#endif
+
+#include <xsd/cxx/xml/string.hxx>
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+
+#include <xsd/cxx/tree/error-handler.hxx>
+
+#include "kolabformat-xcal-schema.hxx"
+#include "grammar-input-stream.hxx"
+
+XMLParserWrapper::XMLParserWrapper()
+{
+ // We need to initialize the Xerces-C++ runtime because we
+ // are doing the XML-to-DOM parsing ourselves.
+ //
+ xercesc::XMLPlatformUtils::Initialize ();
+ init();
+}
+
+
+XMLParserWrapper::~XMLParserWrapper()
+{
+// xercesc::XMLPlatformUtils::Terminate ();
+//FIXME if this is enabled we get a segfault, maybe because the scope_ptr are note yet destructed?
+}
+
+
+void XMLParserWrapper::init()
+{
+ using namespace std;
+
+ try
+ {
+ using namespace xercesc;
+ namespace xml = xsd::cxx::xml;
+ namespace tree = xsd::cxx::tree;
+ // Create and load the grammar pool.
+ //
+ MemoryManager* mm (XMLPlatformUtils::fgMemoryManager);
+
+ gp.reset (new XMLGrammarPoolImpl (mm));
+
+ try
+ {
+ grammar_input_stream is (iCalendar_schema, sizeof (iCalendar_schema));
+ gp->deserializeGrammars(&is);
+ }
+ catch(const XSerializationException& e)
+ {
+ cerr << "unable to load schema: " << xml::transcode<char> (e.getMessage ()) << endl;
+ return;
+ }
+
+ // Lock the grammar pool. This is necessary if we plan to use the
+ // same grammar pool in multiple threads (this way we can reuse the
+ // same grammar in multiple parsers). Locking the pool disallows any
+ // modifications to the pool, such as an attempt by one of the threads
+ // to cache additional schemas.
+ //
+ gp->lockPool ();
+
+ // Get an implementation of the Load-Store (LS) interface.
+ //
+ const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
+
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+ #if _XERCES_VERSION >= 30000
+
+ // Xerces-C++ 3.0.0 and later.
+ //
+ parser.reset(impl->createLSParser (
+ DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp.get ()));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Discard comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, false);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ // Enable validation.
+ //
+ conf->setParameter (XMLUni::fgDOMValidate, true);
+ conf->setParameter (XMLUni::fgXercesSchema, true);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // Xerces-C++ 3.1.0 is the first version with working multi import
+ // support.
+ //
+ #if _XERCES_VERSION >= 30100
+ conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
+ #endif
+
+ // Use the loaded grammar during parsing.
+ //
+ conf->setParameter (XMLUni::fgXercesUseCachedGrammarInParse, true);
+
+ // Disable loading schemas via other means (e.g., schemaLocation).
+ //
+ conf->setParameter (XMLUni::fgXercesLoadSchema, false);
+
+ // We will release the DOM document ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+
+
+ // Set error handler.
+ //
+// tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp); //TODO does conf take a copy or should the ehp object live on?
+
+ #else // _XERCES_VERSION >= 30000
+
+ // Same as above but for Xerces-C++ 2 series.
+ //
+ parser.reset (
+ impl->createDOMBuilder(
+ DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp.get ()));
+
+
+ parser->setFeature (XMLUni::fgDOMComments, false);
+ parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true);
+ parser->setFeature (XMLUni::fgDOMEntities, false);
+ parser->setFeature (XMLUni::fgDOMNamespaces, true);
+ parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false);
+ parser->setFeature (XMLUni::fgDOMValidation, true);
+ parser->setFeature (XMLUni::fgXercesSchema, true);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+ parser->setFeature (XMLUni::fgXercesUseCachedGrammarInParse, true);
+ parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ //tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ parser->setErrorHandler (&ehp);
+
+ #endif // _XERCES_VERSION >= 30000
+
+ // Parse XML documents.
+ //
+
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cout << "schema exception" << endl;
+ cerr << e << endl;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << ": unable to open or read failure" << endl;
+ }
+
+}
+
+xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument > XMLParserWrapper::parseFile(const std::string& url)
+{
+ std::ifstream ifs;
+ ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit); //TODO handle exceptions
+ ifs.open (url.c_str());
+ return parse(ifs, url);
+}
+
+xsd::cxx::xml::dom::auto_ptr< xercesc_3_1::DOMDocument > XMLParserWrapper::parseString(const std::string& s)
+{
+ std::istringstream is(s);
+ return parse(is, "");
+}
+
+
+xml_schema::dom::auto_ptr<xercesc::DOMDocument> XMLParserWrapper::parse(std::istream &ifs, const std::string &name)
+{
+ using namespace std;
+
+ try
+ {
+ using namespace xercesc;
+ namespace xml = xsd::cxx::xml;
+ namespace tree = xsd::cxx::tree;
+
+ // Parse XML documents.
+ //
+ {
+ // Wrap the standard input stream.
+ //
+ xml::sax::std_input_source isrc (ifs, name);
+ Wrapper4InputSource wrap (&isrc, false);
+
+ // Parse XML to DOM.
+ //
+ #if _XERCES_VERSION >= 30000
+ xml_schema::dom::auto_ptr<DOMDocument> doc (parser->parse (&wrap));
+ #else
+ xml_schema::dom::auto_ptr<DOMDocument> doc (parser->parse (wrap));
+ #endif
+
+ eh.throw_if_failed<xml_schema::parsing> ();
+ return doc;
+ }
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cout << "schema exception" << endl;
+ cerr << e << endl;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << ": unable to open or read failure" << endl;
+ }
+
+ return xml_schema::dom::auto_ptr<xercesc::DOMDocument>();
+}
\ No newline at end of file
diff --git a/c++/compiled/XMLParserWrapper.h b/c++/compiled/XMLParserWrapper.h
new file mode 100644
index 0000000..643b61e
--- /dev/null
+++ b/c++/compiled/XMLParserWrapper.h
@@ -0,0 +1,62 @@
+#ifndef XMLPARSER_WRAPPER_H
+#define XMLPARSER_WRAPPER_H
+
+#include <string>
+#include <auto_ptr.h>
+#include <bindings/kolabformat-xcal.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+#include <boost/scoped_ptr.hpp>
+
+#if _XERCES_VERSION >= 30000
+# include <xercesc/dom/DOMLSParser.hpp>
+# include <xercesc/dom/DOMLSException.hpp>
+#else
+# include <xercesc/dom/DOMBuilder.hpp>
+#endif
+
+
+#if _XERCES_VERSION >= 30000
+# include <xercesc/framework/XMLGrammarPool.hpp>
+#else
+# include <xercesc/internal/XMLGrammarPool.hpp>
+#endif
+
+class XMLParserWrapper {
+public:
+ XMLParserWrapper();
+ ~XMLParserWrapper();
+
+ xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseFile(const std::string &url);
+ xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseString(const std::string &s);
+ xml_schema::dom::auto_ptr<xercesc::DOMDocument> parse(std::istream &ifs, const std::string &name);
+private:
+ void init();
+
+ xsd::cxx::tree::error_handler<char> eh;
+
+ #if _XERCES_VERSION >= 30000
+ boost::scoped_ptr<xercesc::DOMLSParser> parser;
+ #else
+ boost::scoped_ptr<xercesc::DOMBuilder> parser;
+ #endif
+
+ boost::scoped_ptr<xercesc::XMLGrammarPool> gp;
+};
+
+// static XMLParserWrapper inst(){
+// static XMLParserWrapper instance;
+// return instance;
+// };
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
diff --git a/c++/compiled/grammar-input-stream.cxx b/c++/compiled/grammar-input-stream.cxx
new file mode 100644
index 0000000..0c94ea6
--- /dev/null
+++ b/c++/compiled/grammar-input-stream.cxx
@@ -0,0 +1,115 @@
+// file : examples/cxx/tree/embedded/grammar-input-stream.cxx
+// author : Boris Kolpackov <boris at codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <cassert>
+#include "grammar-input-stream.hxx"
+
+grammar_input_stream::
+grammar_input_stream (const XMLByte* data, std::size_t size)
+ : data_ (data),
+ size_ (size),
+ pos_ (0),
+ vpos_ (0),
+ cseq_ (0),
+ add_zero_ (false)
+{
+}
+
+#if _XERCES_VERSION >= 30000
+XMLFilePos grammar_input_stream::
+curPos () const
+{
+ return static_cast<XMLFilePos> (vpos_);
+}
+#else
+unsigned int grammar_input_stream::
+curPos () const
+{
+ return static_cast<unsigned int> (vpos_);
+}
+#endif
+
+#if _XERCES_VERSION >= 30000
+XMLSize_t grammar_input_stream::
+readBytes (XMLByte* const buf, const XMLSize_t size)
+#else
+unsigned int grammar_input_stream::
+readBytes (XMLByte* const buf, const unsigned int size)
+#endif
+{
+ std::size_t i (0);
+
+ // Add a zero from the alternating sequence if it didn't
+ // fit on the previous read.
+ //
+ if (add_zero_)
+ {
+ buf[i++] = 0;
+ add_zero_ = false;
+ }
+
+ // If have an unfinished sequential sequence, output it now.
+ //
+ if (cseq_ != 0 && !alt_)
+ {
+ for (; cseq_ != 0 && i < size; --cseq_)
+ buf[i++] = 0;
+ }
+
+ for (; i < size && pos_ < size_;)
+ {
+ XMLByte b = buf[i++] = data_[pos_++];
+
+ // See if we are in a compression sequence.
+ //
+ if (cseq_ != 0)
+ {
+ if (i < size)
+ buf[i++] = 0;
+ else
+ add_zero_ = true; // Add it on the next read.
+
+ cseq_--;
+ continue;
+ }
+
+ // If we are not in a compression sequence and this byte is
+ // not zero then we are done.
+ //
+ if (b != 0)
+ continue;
+
+ // We have a zero.
+ //
+ assert (pos_ < size_); // There has to be another byte.
+ unsigned char v (static_cast<unsigned char> (data_[pos_++]));
+ alt_ = (v & 128) != 0;
+ cseq_ = v & 127;
+
+ // If it is a sequential sequence, output as many zeros as
+ // we can.
+ //
+ if (!alt_)
+ {
+ for (; cseq_ != 0 && i < size; --cseq_)
+ buf[i++] = 0;
+ }
+ }
+
+ vpos_ += i;
+
+#if _XERCES_VERSION >= 30000
+ return static_cast<XMLSize_t> (i);
+#else
+ return static_cast<unsigned int> (i);
+#endif
+}
+
+#if _XERCES_VERSION >= 30000
+const XMLCh* grammar_input_stream::
+getContentType () const
+{
+ return 0;
+}
+#endif
diff --git a/c++/compiled/grammar-input-stream.hxx b/c++/compiled/grammar-input-stream.hxx
new file mode 100644
index 0000000..a1b73c6
--- /dev/null
+++ b/c++/compiled/grammar-input-stream.hxx
@@ -0,0 +1,53 @@
+// file : examples/cxx/tree/embedded/grammar-input-stream.hxx
+// author : Boris Kolpackov <boris at codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#ifndef GRAMMAR_INPUT_STREAM_HXX
+#define GRAMMAR_INPUT_STREAM_HXX
+
+#include <cstddef>
+#include <xercesc/util/BinInputStream.hpp>
+
+// Memory buffer input stream with the special-purpose schema
+// grammar decompression.
+//
+class grammar_input_stream: public xercesc::BinInputStream
+{
+public :
+ grammar_input_stream (const XMLByte* data, std::size_t size);
+
+#if _XERCES_VERSION >= 30000
+
+ virtual XMLFilePos
+ curPos () const;
+
+ virtual XMLSize_t
+ readBytes (XMLByte* const buf, const XMLSize_t size);
+
+ virtual const XMLCh*
+ getContentType () const;
+
+#else
+
+ virtual unsigned int
+ curPos () const;
+
+ virtual unsigned int
+ readBytes (XMLByte* const buf, const unsigned int size);
+
+#endif
+
+private :
+ const XMLByte* data_;
+ std::size_t size_;
+ std::size_t pos_;
+ std::size_t vpos_;
+
+ // Compression data.
+ //
+ size_t cseq_; // Number of bytes left in a compression sequence.
+ bool alt_; // Alternating or sequential sequence.
+ bool add_zero_; // Add a zero on the next read.
+};
+
+#endif // GRAMMAR_INPUT_STREAM_HXX
diff --git a/c++/compiled/xsdbin.cxx b/c++/compiled/xsdbin.cxx
new file mode 100644
index 0000000..53e2533
--- /dev/null
+++ b/c++/compiled/xsdbin.cxx
@@ -0,0 +1,505 @@
+// file : examples/cxx/tree/embedded/xsdbin.cxx
+// author : Boris Kolpackov <boris at codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// This program loads the XML Schema file(s) and converts them to
+// the Xerces-C++ binary schema format which can then be embedded
+// into C++ programs and used to validate XML documents. The output
+// is written as a C++ source file containing the array with the
+// binary data.
+//
+
+#include <string>
+#include <memory> // std::auto_ptr
+#include <cstddef> // std::size_t
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/util/XMLUni.hpp>
+#include <xercesc/util/XMLString.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+#include <xercesc/util/XercesVersion.hpp>
+
+#include <xercesc/internal/BinMemOutputStream.hpp>
+#include <xercesc/validators/common/Grammar.hpp>
+
+#include <xercesc/sax/ErrorHandler.hpp>
+#include <xercesc/sax/SAXParseException.hpp>
+#include <xercesc/sax2/SAX2XMLReader.hpp>
+#include <xercesc/sax2/XMLReaderFactory.hpp>
+
+#if _XERCES_VERSION >= 30000
+# include <xercesc/framework/XMLGrammarPoolImpl.hpp>
+#else
+# include <xercesc/internal/XMLGrammarPoolImpl.hpp>
+#endif
+
+using namespace std;
+using namespace xercesc;
+
+class error_handler: public ErrorHandler
+{
+public:
+ error_handler ()
+ : failed_ (false)
+ {
+ }
+
+ bool
+ failed () const
+ {
+ return failed_;
+ }
+
+ enum severity {s_warning, s_error, s_fatal};
+
+ virtual void
+ warning (const SAXParseException&);
+
+ virtual void
+ error (const SAXParseException&);
+
+ virtual void
+ fatalError (const SAXParseException&);
+
+ virtual void
+ resetErrors ()
+ {
+ failed_ = false;
+ }
+
+ void
+ handle (const SAXParseException&, severity);
+
+private:
+ bool failed_;
+};
+
+void
+cxx_escape (string&);
+
+int
+main (int argc, char* argv[])
+{
+ const char* hxx_suffix = "-schema.hxx";
+ const char* cxx_suffix = "-schema.cxx";
+
+ string name;
+ string base;
+ string outdir;
+
+ class usage {};
+
+ int argi (1);
+ bool help (false);
+ bool multi_import (true);
+ bool verbose (false);
+
+ try
+ {
+ for (; argi < argc; ++argi)
+ {
+ string a (argv[argi]);
+
+ if (a == "--help")
+ {
+ help = true;
+ throw usage ();
+ }
+ else if (a == "--verbose")
+ {
+ verbose = true;
+ }
+ else if (a == "--hxx-suffix")
+ {
+ if (++argi >= argc)
+ throw usage ();
+
+ hxx_suffix = argv[argi];
+ }
+ else if (a == "--cxx-suffix")
+ {
+ if (++argi >= argc)
+ throw usage ();
+
+ cxx_suffix = argv[argi];
+ }
+ else if (a == "--output-dir")
+ {
+ if (++argi >= argc)
+ throw usage ();
+
+ outdir = argv[argi];
+ }
+ else if (a == "--array-name")
+ {
+ if (++argi >= argc)
+ throw usage ();
+
+ name = argv[argi];
+ }
+ else if (a == "--disable-multi-import")
+ {
+ multi_import = false;
+ }
+ else
+ break;
+ }
+
+ if (argi >= argc)
+ {
+ cerr << "no input file specified" << endl;
+ throw usage ();
+ }
+
+ base = argv[argi];
+ }
+ catch (usage const&)
+ {
+ cerr << "Usage: " << argv[0] << " [options] <files>" << endl
+ << "Options:" << endl
+ << " --help Print usage information and exit." << endl
+ << " --verbose Print progress information." << endl
+ << " --output-dir <dir> Write generated files to <dir>." << endl
+ << " --hxx-suffix <sfx> Header file suffix instead of '-schema.hxx'." << endl
+ << " --cxx-suffix <sfx> Source file suffix instead of '-schema.cxx'." << endl
+ << " --array-name <name> Binary data array name." << endl
+ << " --disable-multi-import Disable multiple import support." << endl
+ << endl;
+
+ return help ? 0 : 1;
+ }
+
+ XMLPlatformUtils::Initialize ();
+
+ {
+ MemoryManager* mm (XMLPlatformUtils::fgMemoryManager);
+
+ auto_ptr<XMLGrammarPool> gp (new XMLGrammarPoolImpl (mm));
+
+ // Load the schemas into grammar pool.
+ //
+ {
+ auto_ptr<SAX2XMLReader> parser (
+ XMLReaderFactory::createXMLReader (mm, gp.get ()));
+
+ parser->setFeature (XMLUni::fgSAX2CoreNameSpaces, true);
+ parser->setFeature (XMLUni::fgSAX2CoreNameSpacePrefixes, true);
+ parser->setFeature (XMLUni::fgSAX2CoreValidation, true);
+ parser->setFeature (XMLUni::fgXercesSchema, true);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, true);
+ parser->setFeature (XMLUni::fgXercesValidationErrorAsFatal, true);
+
+ // Xerces-C++ 3.1.0 is the first version with working multi import
+ // support.
+ //
+#if _XERCES_VERSION >= 30100
+ parser->setFeature (XMLUni::fgXercesHandleMultipleImports, multi_import);
+#endif
+
+ error_handler eh;
+ parser->setErrorHandler (&eh);
+
+ for (; argi < argc; ++argi)
+ {
+ if (verbose)
+ cerr << "loading " << argv[argi] << endl;
+
+ if (!parser->loadGrammar (argv[argi], Grammar::SchemaGrammarType, true))
+ {
+ cerr << argv[argi] << ": error: unable to load" << endl;
+ return 1;
+ }
+
+ if (eh.failed ())
+ return 1;
+ }
+ }
+
+ // Get the binary representation.
+ //
+ BinMemOutputStream data;
+
+ try
+ {
+ gp->serializeGrammars (&data);
+ }
+ catch (const XSerializationException& e)
+ {
+ char* msg (XMLString::transcode (e.getMessage ()));
+ cerr << "error: " << msg << endl;
+ XMLString::release (&msg);
+ return 1;
+ }
+
+ size_t n (static_cast<size_t> (data.curPos ()));
+ const unsigned char* buf (
+ static_cast<const unsigned char*> (data.getRawBuffer ()));
+
+ if (verbose)
+ cerr << "uncomressed data size " << n << " bytes" << endl;
+
+ // Compress zeros.
+ //
+ size_t cn (0);
+ unsigned char* cbuf = new unsigned char[n];
+
+ size_t cseq (0); // Number of bytes left in a compression sequence.
+ bool alt (false); // Alternating or sequential sequence.
+
+ for (size_t i (0); i < n;)
+ {
+ unsigned char v (buf[i++]);
+
+ // See if we are in a compression sequence.
+ //
+ if (cseq != 0)
+ {
+ // See if this byte needs to be copied.
+ //
+ if (alt && cseq % 2 == 0)
+ cbuf[cn++] = v;
+
+ cseq--;
+ continue;
+ }
+
+ // If we are not in a compression sequence and this byte is
+ // not zero then simply copy it.
+ //
+ if (v != 0)
+ {
+ cbuf[cn++] = v;
+ continue;
+ }
+
+ // We have a zero.
+ //
+ cbuf[cn++] = 0;
+
+ // See if we can start a new compression sequence.
+ //
+ if (i < n)
+ {
+ if (buf[i] == 0)
+ {
+ // Sequential sequence. See how far it runs.
+ //
+ alt = false;
+
+ for (cseq = 1; cseq < 127 && cseq + i < n; cseq++)
+ if (buf[cseq + i] != 0)
+ break;
+ }
+ else if (i + 1 < n && buf[i + 1] == 0)
+ {
+ // Alternating sequence. See how far it runs.
+ //
+ alt = true;
+
+ for (cseq = 1; cseq < 127 && cseq * 2 + i + 1 < n; cseq++)
+ {
+ if (buf[cseq * 2 + i + 1] != 0)
+ break;
+
+ // For longer sequences prefer sequential to alternating.
+ //
+ if (cseq > 2 &&
+ buf[cseq * 2 + i] == 0 &&
+ buf[(cseq - 1) * 2 + i] == 0 &&
+ buf[(cseq - 2) * 2 + i] == 0)
+ {
+ cseq -= 2;
+ break;
+ }
+ }
+
+ cseq *= 2;
+ }
+ }
+
+ if (cseq != 0)
+ {
+ cbuf[cn++] = static_cast<unsigned char> (
+ alt ? (128 | cseq / 2) : cseq);
+ }
+ else
+ cbuf[cn++] = 0;
+ }
+
+ if (verbose)
+ cerr << "comressed data size " << cn << " bytes" << endl;
+
+ buf = cbuf;
+ n = cn;
+
+ // Figure out the file names.
+ //
+ string::size_type p (base.rfind ('/')), p1 (base.rfind ('\\'));
+
+ if (p1 != string::npos && p1 > p)
+ p = p1;
+
+ if (p != string::npos)
+ base = string (base, p + 1);
+
+ p = base.rfind ('.');
+
+ if (p != string::npos)
+ base.resize (p);
+
+ string hxx (base + hxx_suffix);
+ string cxx (base + cxx_suffix);
+
+ if (!outdir.empty ())
+ {
+#if defined (WIN32) || defined (__WIN32__)
+ hxx = outdir + '\\' + hxx;
+ cxx = outdir + '\\' + cxx;
+#else
+ hxx = outdir + '/' + hxx;
+ cxx = outdir + '/' + cxx;
+#endif
+ }
+
+ if (name.empty ())
+ {
+ name = base + "_schema";
+ cxx_escape (name);
+ }
+
+ // Write header.
+ //
+ {
+ ofstream os (hxx.c_str ());
+
+ if (!os.is_open ())
+ {
+ cerr << hxx << ": error: unable to open" << endl;
+ return 1;
+ }
+
+ os << "// Automatically generated. Do not edit." << endl
+ << "//" << endl
+ << endl
+ << "#include <xercesc/util/XercesDefs.hpp>" << endl
+ << endl
+ << "extern const XMLByte " << name << "[" << n << "UL];" << endl;
+ }
+
+ {
+ ofstream os (cxx.c_str ());
+
+ if (!os.is_open ())
+ {
+ cerr << cxx << ": error: unable to open" << endl;
+ return 1;
+ }
+
+ os << "// Automatically generated. Do not edit." << endl
+ << "//" << endl
+ << endl
+ << "#include <xercesc/util/XercesDefs.hpp>" << endl
+ << "#include <xercesc/util/XercesVersion.hpp>" << endl
+ << endl
+ << "#if XERCES_GRAMMAR_SERIALIZATION_LEVEL != " <<
+ XERCES_GRAMMAR_SERIALIZATION_LEVEL << endl
+ << "# error incompatible Xerces-C++ version detected" << endl
+ << "#endif" << endl
+ << endl
+ << "extern const XMLByte " << name << "[" << n << "UL] =" << endl
+ << "{";
+
+ for (size_t i (0); i < n; ++i)
+ {
+ if (i != 0)
+ os << ',';
+
+ os << (i % 12 == 0 ? "\n " : " ") << "0x";
+ os.width (2);
+ os.fill ('0');
+ os << hex << static_cast<unsigned short> (buf[i]);
+ }
+
+ os << endl
+ << "};" << endl
+ << endl;
+ }
+
+ delete[] cbuf;
+ }
+
+ XMLPlatformUtils::Terminate ();
+}
+
+void
+cxx_escape (string& s)
+{
+ for (string::size_type i (0); i < s.size (); ++i)
+ {
+ char& c (s[i]);
+
+ if (i == 0)
+ {
+ if (!((c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ c == '_'))
+ c = '_';
+ }
+ else
+ {
+ if (!((c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= '0' && c <= '9') ||
+ c == '_'))
+ c = '_';
+ }
+ }
+}
+
+void error_handler::
+warning (const SAXParseException& e)
+{
+ handle (e, s_warning);
+}
+
+void error_handler::
+error (const SAXParseException& e)
+{
+ failed_ = true;
+ handle (e, s_error);
+}
+
+void error_handler::
+fatalError (const SAXParseException& e)
+{
+ failed_ = true;
+ handle (e, s_fatal);
+}
+
+void error_handler::
+handle (const SAXParseException& e, severity s)
+{
+ const XMLCh* xid (e.getPublicId ());
+
+ if (xid == 0)
+ xid = e.getSystemId ();
+
+ char* id (XMLString::transcode (xid));
+ char* msg (XMLString::transcode (e.getMessage ()));
+
+ cerr << id << ":";
+
+#if _XERCES_VERSION >= 30000
+ cerr << e.getLineNumber () << ":" << e.getColumnNumber () << " ";
+#else
+ XMLSSize_t l (e.getLineNumber ());
+ XMLSSize_t c (e.getColumnNumber ());
+ cerr << (l == -1 ? 0 : l) << ":" << (c == -1 ? 0 : c) << " ";
+#endif
+
+ cerr << (s == s_warning ? "warning: " : "error: ") << msg << endl;
+
+ XMLString::release (&id);
+ XMLString::release (&msg);
+}
commit ea4c6f58b615398f3b148aa6142572a03392509a
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 01:08:28 2011 +0100
wall
diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 24bea1e..2bc4fe1 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -7,6 +7,8 @@ include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR} QtCore)
set(CMAKE_BUILD_TYPE Debug)
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" )
+
file(MAKE_DIRECTORY bindings)
set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/../schemas )
commit ee3f2e620658928d9e6bbb672ed46516a8b07f97
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 23 01:08:17 2011 +0100
containers
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index c109067..9804106 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -17,6 +17,14 @@ add_custom_command(OUTPUT ${KOLAB_SWIG_PYTHON_SOURCE_FILE}
DEPENDS kolabformat.i
VERBATIM
)
+add_custom_command(OUTPUT python_kolabcontainers_wrapper.cpp
+ COMMAND swig -v -c++ -python -o python_kolabcontainers_wrapper.cpp kolabcontainers.i
+ COMMENT "Generating python bindings"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ DEPENDS kolabcontainers.i
+ VERBATIM
+ )
+set(KOLAB_SWIG_PYTHON_SOURCE_FILE ${KOLAB_SWIG_PYTHON_SOURCE_FILE} python_kolabcontainers_wrapper.cpp)
SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PYTHON_SOURCE_FILE} PROPERTIES GENERATED 1)
ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
new file mode 100644
index 0000000..973048c
--- /dev/null
+++ b/c++/lib/kolabcontainers.cpp
@@ -0,0 +1,558 @@
+#include "kolabcontainers.h"
+
+namespace Kolab {
+
+struct DateTime::Private {
+ Private()
+ : year(-1),
+ month(-1),
+ day(-1),
+ hour(-1),
+ minute(-1),
+ second(-1),
+ isUtc(false){}
+
+ int year;
+ int month;
+ int day;
+ int hour;
+ int minute;
+ int second;
+ bool isUtc;
+ std::string timezone;
+};
+
+DateTime::DateTime()
+: d(new DateTime::Private())
+{
+
+}
+
+DateTime::DateTime(int year, int month, int day, int hour, int minute, int second, bool isUtc)
+: d(new DateTime::Private())
+{
+ d->year = year;
+ d->month = month;
+ d->day = day;
+ d->hour = hour;
+ d->minute = minute;
+ d->second = second;
+ d->isUtc = isUtc;
+ std::cout << "utc";
+}
+
+DateTime::DateTime(const std::string& timezone, int year, int month, int day, int hour, int minute, int second)
+: d(new DateTime::Private())
+{
+ d->year = year;
+ d->month = month;
+ d->day = day;
+ d->hour = hour;
+ d->minute = minute;
+ d->second = second;
+ d->timezone = timezone;
+ std::cout << "tz";
+}
+
+DateTime::DateTime(int year, int month, int day)
+: d(new DateTime::Private())
+{
+ d->year = year;
+ d->month = month;
+ d->day = day;
+}
+
+DateTime::DateTime(const Kolab::DateTime &other)
+: d(new DateTime::Private())
+{
+ *d = *other.d;
+}
+
+DateTime::~DateTime()
+{
+
+}
+
+
+void DateTime::operator=(const Kolab::DateTime &other)
+{
+ *d = *other.d;
+}
+
+bool DateTime::operator==(const Kolab::DateTime &other) const
+{
+ if ( d->year == other.year() &&
+ d->month == other.month() &&
+ d->day == other.day() &&
+ d->hour == other.hour() &&
+ d->minute == other.minute() &&
+ d->second== other.second() &&
+ d->isUtc== other.isUTC() &&
+ d->timezone== other.timezone()) {
+ return true;
+ }
+ return false;
+}
+
+
+
+int DateTime::year() const
+{
+ return d->year;
+}
+
+int DateTime::month() const
+{
+ return d->month;
+}
+
+int DateTime::day() const
+{
+ return d->day;
+}
+
+int DateTime::hour() const
+{
+ return d->hour;
+}
+
+int DateTime::minute() const
+{
+ return d->minute;
+}
+
+int DateTime::second() const
+{
+ return d->second;
+}
+
+bool DateTime::isDateOnly() const
+{
+ if ((d->hour < 0) && (d->minute < 0) && (d->second < 0)) {
+ return true;
+ }
+ return false;
+}
+
+void DateTime::setDate(int year, int month, int day)
+{
+ d->year = year;
+ d->month = month;
+ d->day = day;
+}
+void DateTime::setTime(int hour, int minute, int second)
+{
+ d->hour = hour;
+ d->minute = minute;
+ d->second = second;
+}
+void DateTime::setTimezone(const std::string &tz)
+{
+ d->timezone = tz;
+}
+void DateTime::setUTC(bool utc)
+{
+ d->isUtc = utc;
+}
+
+bool DateTime::isUTC() const
+{
+ return d->isUtc;
+}
+
+std::string DateTime::timezone() const
+{
+ return d->timezone;
+}
+
+bool DateTime::isValid() const
+{
+ if (d->year >= 0 && d->month >= 0 && d->day >= 0) {
+ return true;
+ }
+ return false;
+}
+
+struct RecurrenceRule::Private
+{
+ Frequencey freq;
+ Weekday weekstart;
+ DateTime end;
+ int count;
+ int interval;
+ std::vector<int> bysecond;
+ std::vector<int> byminute;
+ std::vector<int> byhour;
+ std::vector<DayPos> byday;
+ std::vector<int> bymonthday;
+ std::vector<int> byyearday;
+ std::vector<int> byweekno;
+ std::vector<int> bymonth;
+};
+
+RecurrenceRule::RecurrenceRule()
+: d(new RecurrenceRule::Private)
+{
+
+}
+
+RecurrenceRule::RecurrenceRule(const Kolab::RecurrenceRule &other)
+: d(new RecurrenceRule::Private)
+{
+ *d = *other.d;
+}
+
+void RecurrenceRule::operator=(const Kolab::RecurrenceRule &other)
+{
+ *d = *other.d;
+}
+
+
+
+RecurrenceRule::~RecurrenceRule()
+{
+
+}
+
+void RecurrenceRule::setFrequency(RecurrenceRule::Frequencey freq)
+{
+ d->freq = freq;
+}
+
+RecurrenceRule::Frequencey RecurrenceRule::frequency() const
+{
+ return d->freq;
+}
+
+void RecurrenceRule::setWeekStart(RecurrenceRule::Weekday weekstart)
+{
+ d->weekstart = weekstart;
+}
+
+RecurrenceRule::Weekday RecurrenceRule::weekStart() const
+{
+ return d->weekstart;
+}
+
+void RecurrenceRule::setEnd(const Kolab::DateTime &end)
+{
+ d->end = end;
+}
+
+DateTime RecurrenceRule::end() const
+{
+ return d->end;
+}
+
+void RecurrenceRule::setCount(int count)
+{
+ d->count = count;
+}
+
+int RecurrenceRule::count() const
+{
+ return d->count;
+}
+
+void RecurrenceRule::setInterval(int interval)
+{
+ d->interval = interval;
+}
+
+int RecurrenceRule::interval() const
+{
+ return d->interval;
+}
+
+void RecurrenceRule::setBysecond(const std::vector< int >&by)
+{
+ d->bysecond = by;
+}
+
+
+std::vector< int > RecurrenceRule::bysecond() const
+{
+ return d->bysecond;
+}
+
+void RecurrenceRule::setByminute(const std::vector< int > &by)
+{
+ d->byminute = by;
+}
+
+std::vector< int > RecurrenceRule::byminute() const
+{
+ return d->byminute;
+}
+
+void RecurrenceRule::setByhour(const std::vector< int > &by)
+{
+ d->byhour = by;
+}
+
+std::vector< int > RecurrenceRule::byhour() const
+{
+ return d->byhour;
+}
+
+void RecurrenceRule::setByday(const std::vector< RecurrenceRule::DayPos > &by)
+{
+ d->byday = by;
+}
+
+std::vector< RecurrenceRule::DayPos > RecurrenceRule::byday() const
+{
+ return d->byday;
+}
+
+void RecurrenceRule::setBymonthday(const std::vector< int > &by)
+{
+ d->bymonthday = by;
+}
+
+std::vector< int > RecurrenceRule::bymonthday() const
+{
+ return d->bymonthday;
+}
+
+void RecurrenceRule::setByyearday(const std::vector< int > &by)
+{
+ d->byyearday = by;
+}
+
+std::vector< int > RecurrenceRule::byyearday() const
+{
+ return d->byyearday;
+}
+
+void RecurrenceRule::setByweekno(const std::vector< int > &by)
+{
+ d->byweekno = by;
+}
+
+std::vector< int > RecurrenceRule::byweekno() const
+{
+ return d->byweekno;
+}
+
+void RecurrenceRule::setBymonth(const std::vector< int > &by)
+{
+ d->bymonth = by;
+}
+
+std::vector< int > RecurrenceRule::bymonth() const
+{
+ return d->bymonth;
+}
+
+bool RecurrenceRule::isValid() const
+{
+ if (d->freq == None) {
+ return false;
+ }
+ return true;
+}
+
+
+
+
+struct Event::Private
+{
+ Private()
+ : classification(Public){}
+
+ std::string uid;
+ DateTime created;
+ DateTime lastModified;
+ int sequence;
+ Classification classification;
+ std::vector< std::string > categories;
+ DateTime start;
+ DateTime end;
+
+ DateTime recurrenceID;
+ bool thisAndFuture;
+ std::string summary;
+ std::string description;
+ int priority;
+ Status status;
+ std::string location;
+ RecurrenceRule rrule;
+};
+
+Event::Event()
+: d(new Event::Private())
+{
+
+}
+
+Event::~Event()
+{
+
+}
+
+void Event::setUid(const std::string &uid)
+{
+ d->uid = uid;
+}
+
+std::string Event::uid() const
+{
+ return d->uid;
+}
+
+void Event::setCreated(const Kolab::DateTime &created)
+{
+ d->created = created;
+}
+
+DateTime Event::created() const
+{
+ return d->created;
+}
+
+void Event::setLastModified(const Kolab::DateTime &lastMod)
+{
+ d->lastModified = lastMod;
+}
+
+DateTime Event::lastModified() const
+{
+ return d->lastModified;
+}
+
+void Event::setSequence(int sequence)
+{
+ d->sequence = sequence;
+}
+
+int Event::sequence() const
+{
+ return d->sequence;
+}
+
+void Event::setClassification(Classification class_)
+{
+ d->classification = class_;
+}
+
+Classification Event::classification() const
+{
+ return d->classification;
+}
+
+void Event::setCategories(const std::vector< std::string > &categories)
+{
+ d->categories = categories;
+}
+
+void Event::addCategory(const std::string &cat)
+{
+ d->categories.push_back(cat);
+}
+
+std::vector< std::string > Event::categories() const
+{
+ return d->categories;
+}
+
+void Event::setStart(const Kolab::DateTime &start)
+{
+ d->start = start;
+}
+
+DateTime Event::start() const
+{
+ return d->start;
+}
+
+void Event::setEnd(const Kolab::DateTime &end)
+{
+ d->end = end;
+}
+
+DateTime Event::end() const
+{
+ return d->end;
+}
+
+void Event::setRecurrenceID(const Kolab::DateTime &rID, bool thisandfuture)
+{
+ d->recurrenceID = rID;
+ d->thisAndFuture = thisandfuture;
+}
+
+DateTime Event::recurrenceID() const
+{
+ return d->recurrenceID;
+}
+
+bool Event::thisAndFuture() const
+{
+ return d->thisAndFuture;
+}
+
+void Event::setSummary(const std::string &summary)
+{
+ d->summary = summary;
+}
+
+std::string Event::summary() const
+{
+ return d->summary;
+}
+
+void Event::setDescription(const std::string &description)
+{
+ d->description = description;
+}
+
+std::string Event::description() const
+{
+ return d->description;
+}
+
+void Event::setPriority(int priority)
+{
+ d->priority = priority;
+}
+
+int Event::priority() const
+{
+ return d->priority;
+}
+
+void Event::setStatus(Status status)
+{
+ d->status = status;
+}
+
+Status Event::status() const
+{
+ return d->status;
+}
+
+void Event::setLocation(const std::string &location)
+{
+ d->location = location;
+}
+
+std::string Event::location() const
+{
+ return d->location;
+}
+
+void Event::setRecurrenceRule(const Kolab::RecurrenceRule &rrule)
+{
+ d->rrule = rrule;
+}
+
+RecurrenceRule Event::recurrenceRule() const
+{
+ return d->rrule;
+}
+
+
+
+
+}//Namespace
\ No newline at end of file
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index 639789c..7b11638 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -2,112 +2,237 @@
#define KOLAB_CONTAINERS_H
#include <string>
#include <vector>
+#include <boost/scoped_ptr.hpp>
namespace Kolab {
+
+class DateTime {
+public:
+ DateTime();
+ DateTime(int year, int month, int day, int hour, int minute, int second, bool isUtc=true);
+ DateTime(const std::string &timezone, int year, int month, int day, int hour, int minute, int second);
+ DateTime(int year, int month, int day);
+ ~DateTime();
+ DateTime(const DateTime &);
+ void operator=(const DateTime &);
+ bool operator==(const DateTime &) const;
+
- /**
- * Datatypes:
- * -String
- * -DateTime
- * -
- *
- */
-
- class DateTime {
- void setDate(int year, int month, int day);
- int year();
- int month();
- int day();
-
- bool isDateOnly();
-
- void setTime(int hour, int minute, int second);
- int hour();
- int minute();
- int second();
-
- void setUTC(bool);
- void setTimezone(const std::string &);
- std::string getTimezone();
- };
+ void setDate(int year, int month, int day);
+ int year() const;
+ int month() const;
+ int day() const;
+
+ bool isDateOnly() const;
+
+ void setTime(int hour, int minute, int second);
+ int hour() const;
+ int minute() const;
+ int second() const;
- /**
+ void setUTC(bool);
+ bool isUTC() const;
+ void setTimezone(const std::string &);
+ std::string timezone() const;
+
+ bool isValid() const;
+private:
+ struct Private;
+ boost::scoped_ptr<Private> d;
+};
+
+enum Classification {
+ Public,
+ Private,
+ Confidential
+};
+
+enum Status {
+ NeedsAction,
+ Completed,
+ InProcess,
+ Cancelled,
+ Tentative,
+ Confirmed,
+ Draft,
+ Final
+};
- */
-
- class Event {
- public:
- void setUid(const std::string &);
- std::string uid() const;
-
- void setCreated(const DateTime &);
- DateTime created() const;
-
- void setLastModified(const DateTime &);
- DateTime lastModified() const;
-
- void setSequence(int);
- int sequence() const;
-
- void setClassification(int); //TODO enum?
- int classification() const;
+class RecurrenceRule {
+public:
+
+ RecurrenceRule();
+ RecurrenceRule(const RecurrenceRule &);
+ ~RecurrenceRule();
- void setCategories(const std::vector<std::string> &);
- void addCategory(const std::string &);
- std::vector<std::string> categories() const;
-
- void setStart(const DateTime &);
- DateTime start() const;
-
- void setEnd(const DateTime &);
- DateTime end() const;
-
- void setDuration();
- duration() const;
-
- void setTransparency(bool isTransparent);
- bool transparency() const;
-
- void setRecurrenceRule(const RecurrenceRule &);
- RecurrenceRule recurrenceRule() const;
-
- void setRecrrenceDates(const std::vector<DateTime> &);
- std::vector<DateTime> recurrenceDates() const;
-
- void setExceptionDates(const std::vector<DateTime> &);
- std::vector<DateTime> exceptionDates() const;
-
- void setRecurrenceID(const std::string &);
- std::string recurrenceID() const;
-
- void setSummary(const std::string &);
- std::string summary() const;
-
- void setDescription(const std::string &);
- std::string description() const;
-
- void setPriority(int);
- int priority() const;
-
- void setStatus(int); //TODO map to string
- int status() const;
-
- void setLocation(const std::string &);
- std::string location() const;
-
- void setOrganizer(const std::string email &, const std::string name &);
- std::string organizerEmail() const;
- std::string organizerName() const;
-
- void setAttendee(const std::vector<Attendee> &);
- std::vector<Attendee> attendee() const;
-
- void setAttachment(const std::vector<Attachment> &);
- std::vector<Attachment> attachments() const;
-
- void setCustomProperty(const std::vector<CustomProperty> &);
- std::vector<CustomProperty> customProperties() const;
+ void operator=(const RecurrenceRule &);
+
+ enum Frequencey {
+ None,
+ Yearly,
+ Monthly,
+ Weekly,
+ Daily,
+ Hourly,
+ Minutely,
+ Secondly
+ };
+
+ void setFrequency(Frequencey);
+ Frequencey frequency() const;
+
+ enum Weekday {
+ Monday,
+ Tuesday,
+ Wednesday,
+ Thursday,
+ Friday,
+ Saturday,
+ Sunday
+ };
+
+ void setWeekStart(Weekday);
+ Weekday weekStart() const;
+
+ void setEnd(const DateTime &);
+ DateTime end() const;
+
+ void setCount(int count);
+ int count() const;
+
+ void setInterval(int);
+ int interval() const;
+
+ void setBysecond(const std::vector<int> &);
+ std::vector<int> bysecond() const;
+
+ void setByminute(const std::vector<int> &);
+ std::vector<int> byminute() const;
+
+ void setByhour(const std::vector<int> &);
+ std::vector<int> byhour() const;
+
+ struct DayPos
+ {
+ void operator=(const DayPos &){};
};
+
+ void setByday(const std::vector<DayPos> &);
+ std::vector<DayPos> byday() const;
+
+ void setBymonthday(const std::vector<int> &);
+ std::vector<int> bymonthday() const;
+
+ void setByyearday(const std::vector<int> &);
+ std::vector<int> byyearday() const;
+
+ void setByweekno(const std::vector<int> &);
+ std::vector<int> byweekno() const;
+
+ void setBymonth(const std::vector<int> &);
+ std::vector<int> bymonth() const;
+
+ bool isValid() const;
+
+private:
+ struct Private;
+ boost::scoped_ptr<Private> d;
+};
+
+class Attendee {
+ //TODO
+};
+
+class Attachment {
+ //TODO
+};
+
+class CustomProperty {
+ //TODO
+};
+
+class Event {
+public:
+ Event();
+ ~Event();
+ Event(const Event &);
+ void operator=(const Event &);
+
+ void setUid(const std::string &);
+ std::string uid() const;
+
+ void setCreated(const DateTime &);
+ DateTime created() const;
+
+ void setLastModified(const DateTime &);
+ DateTime lastModified() const;
+
+ void setSequence(int);
+ int sequence() const;
+
+ void setClassification(Classification);
+ Classification classification() const;
+
+ void setCategories(const std::vector<std::string> &);
+ void addCategory(const std::string &);
+ std::vector<std::string> categories() const;
+
+ void setStart(const DateTime &);
+ DateTime start() const;
+
+ void setEnd(const DateTime &);
+ DateTime end() const;
+
+ void setDuration(int); //TODO duration type
+ int duration() const;
+
+ void setTransparency(bool isTransparent);
+ bool transparency() const;
+
+ void setRecurrenceRule(const RecurrenceRule &);
+ RecurrenceRule recurrenceRule() const;
+
+ void setRecrrenceDates(const std::vector<DateTime> &);
+ std::vector<DateTime> recurrenceDates() const;
+
+ void setExceptionDates(const std::vector<DateTime> &);
+ std::vector<DateTime> exceptionDates() const;
+
+ void setRecurrenceID(const DateTime &, bool thisandfuture);
+ DateTime recurrenceID() const;
+ bool thisAndFuture() const;
+
+ void setSummary(const std::string &);
+ std::string summary() const;
+
+ void setDescription(const std::string &);
+ std::string description() const;
+
+ void setPriority(int);
+ int priority() const;
+
+ void setStatus(Status);
+ Status status() const;
+
+ void setLocation(const std::string &);
+ std::string location() const;
+
+ void setOrganizer(const std::string &email, const std::string &name);
+ std::string organizerEmail() const;
+ std::string organizerName() const;
+
+ void setAttendee(const std::vector<Attendee> &);
+ std::vector<Attendee> attendee() const;
+
+ void setAttachment(const std::vector<Attachment> &);
+ std::vector<Attachment> attachments() const;
+
+ void setCustomProperty(const std::vector<CustomProperty> &);
+ std::vector<CustomProperty> customProperties() const;
+private:
+ struct Private;
+ boost::scoped_ptr<Private> d;
+};
}
diff --git a/c++/lib/kolabcontainers.i b/c++/lib/kolabcontainers.i
new file mode 100644
index 0000000..74638f6
--- /dev/null
+++ b/c++/lib/kolabcontainers.i
@@ -0,0 +1,11 @@
+/* kolabformat.i */
+ %module kolabcontainers
+ %{
+ /* Put header files here or function declarations like below */
+ #include "kolabcontainers.h"
+ %}
+%include "std_string.i"
+
+/*%apply const std::string& {std::string* foo};*/
+
+%include "kolabcontainers.h"
commit 2409376669d3692c8a924d6e668f883df69f1ca7
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Tue Dec 20 15:00:41 2011 +0100
share code between all incidences
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
index 425930a..676ee81 100644
--- a/c++/lib/kcalconversions.h
+++ b/c++/lib/kcalconversions.h
@@ -371,8 +371,8 @@ std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const typename
return rruleProp;
}
-
-void setIncidenceProperties(KCalCore::Incidence &inc, const icalendar_2_0::properties &prop)
+template <typename T>
+void setIncidenceProperties(KCalCore::Incidence &inc, const T &prop)
{
inc.setUid(toString(prop.uid()));
inc.setCreated(*toDate<KCalCoreTypes>(prop.created()));
@@ -462,7 +462,8 @@ void setIncidenceProperties(KCalCore::Incidence &inc, const icalendar_2_0::prope
}
-void getIncidenceProperties(icalendar_2_0::properties &prop, const KCalCore::Incidence &inc)
+template <typename T>
+void getIncidenceProperties(T &prop, const KCalCore::Incidence &inc)
{
using namespace KCalCore;
using namespace icalendar_2_0;
@@ -503,9 +504,20 @@ void getIncidenceProperties(icalendar_2_0::properties &prop, const KCalCore::Inc
template <> struct IncidenceConverter < KCalCore::Incidence >
{
+ typedef DateTimeConverter< KDateTime> DC;
+ static std::string uid(const KCalCore::Incidence &inc) {
+ return inc.uid().toStdString();
+ }
+
+ static xml_schema::date_time dtstamp(const KCalCore::Incidence &inc) {
+ return DC::fromDateTime(inc.lastModified());
+ }
+
+ static xml_schema::date_time created(const KCalCore::Incidence &inc) {
+ return DC::fromDateTime(inc.created());
+ }
-
-
+};
} //Namespace
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 543468b..0bb9303 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -11,6 +11,7 @@
#include <kcalcore/recurrencerule.h>
#include "kcalconversions.h"
#include </home/chrigi/devel/kde/kdepim-runtime/resources/kcal/kcalresource.h>
+#include <KDE/KCalCore/Todo>
namespace Kolab {
@@ -77,8 +78,100 @@ void readEvent(Kolab::Event &event ,const icalendar_2_0::VeventType &vevent)
// }
}
-KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
+
+template <typename T> struct IncidenceTrait;
+
+template < > struct IncidenceTrait <KCalCore::Event>
{
+ typedef typename icalendar_2_0::KolabEvent KolabType;
+ typedef typename KCalCore::Event IncidenceType;
+ typedef typename KCalCore::Event::Ptr IncidencePtr;
+ typedef typename KCalCore::Incidence Incidence;
+
+ static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
+ {
+ icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+
+ getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
+
+ if (event.dtEnd().isValid()) {
+ icalendar_2_0::properties::dtend_type dtend;
+ setDateTimeProperty<KCalCoreTypes>(dtend, event.dtStart());
+ prop.dtend(dtend);
+ } else if (event.duration() != KCalCore::Duration()) {
+
+ }
+ }
+
+ static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc)
+ {
+ components.vevent().push_back(inc);
+ }
+
+
+ static void readIncidence(KCalCore::Event &event, const icalendar_2_0::KolabEvent& vevent)
+ {
+ const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+
+ setIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(event, prop);
+
+ if (prop.dtend()) {
+ KDateTime date;
+ kDebug() << "dtend";
+ event.setDtEnd(*toDate<KCalCoreTypes>(*prop.dtend()));
+ if (event.dtEnd().timeType() != event.dtStart().timeType()) {
+ kWarning() << "dtEnd has wrong timespec";
+ }
+ } else if (prop.duration()) {
+ // KCalCore::Duration duration.;
+ // event.setDuration(duration << prop.duration());
+ }
+ //TODO check for equality of timespecs
+
+ if (prop.transp()) {
+
+ }
+ }
+
+ static icalendar_2_0::components2::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
+ {
+ return components.vevent().begin();
+ }
+
+ static icalendar_2_0::components2::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
+ {
+ return components.vevent().end();
+ }
+
+};
+
+template < > struct IncidenceTrait <KCalCore::Todo>
+{
+ typedef typename icalendar_2_0::KolabTodo KolabType;
+ typedef typename KCalCore::Todo IncidenceType;
+ typedef typename KCalCore::Incidence Incidence;
+
+ static void writeIncidence(icalendar_2_0::KolabTodo& vtodo, const KCalCore::Todo &todo)
+ {
+ icalendar_2_0::KolabTodo::properties_type &prop = vtodo.properties();
+ getIncidenceProperties<icalendar_2_0::KolabTodo::properties_type>(prop, todo);
+
+ }
+
+ static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, KolabType inc)
+ {
+ components.vtodo().push_back(inc);
+ }
+};
+
+
+template <typename T>
+typename T::IncidencePtr readIncidence(const std::string& s, bool isUrl)
+{
+ typedef typename T::IncidencePtr IncidencePtr;
+ typedef typename T::IncidenceType IncidenceType;
+ typedef typename T::KolabType KolabType;
+
try {
//TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
xml_schema::properties props;
@@ -95,13 +188,12 @@ KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
const icalendar_2_0::VcalendarType &vcalendar = icalendar->vcalendar();
- QList <KCalCore::Event::Ptr> events;
-
- for (icalendar_2_0::VcalendarType::components_type::vevent_const_iterator it(vcalendar.components().vevent().begin()); it != vcalendar.components().vevent().end(); it++) {
- KCalCore::Event::Ptr e = KCalCore::Event::Ptr(new KCalCore::Event());
- const icalendar_2_0::KolabEvent &event = *it;
- readEvent(*e, event);
- events.append(e);
+ std::vector < IncidencePtr > incidences;
+ for (typename xsd::cxx::tree::sequence< KolabType >::const_iterator it(T::begin(vcalendar.components())); it != T::end(vcalendar.components()); it++) {
+ IncidencePtr e = IncidencePtr(new IncidenceType);
+ const KolabType &event = *it;
+ T::readIncidence(*e, event);
+ incidences.push_back(e);
}
//TODO resolve events, exceptions can be identified based on the recurrence-id attribute
@@ -110,65 +202,51 @@ KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
// return event;
// }
// }
- return events.first();
+ return *incidences.begin();
} catch (const xml_schema::exception& e) {
std::cout << e << std::endl;
- std::cout << "Failed to read event!" << std::endl;
+ std::cout << "Failed to read incidence!" << std::endl;
}
- return KCalCore::Event::Ptr();
+ return IncidencePtr();
+
}
-
-void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
+KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
{
- const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
-
- setIncidenceProperties(event, prop);
+ readIncidence< IncidenceTrait<KCalCore::Event> >(s, isUrl);
+}
- if (prop.dtend()) {
- KDateTime date;
- kDebug() << "dtend";
- event.setDtEnd(*toDate<KCalCoreTypes>(*prop.dtend()));
- if (event.dtEnd().timeType() != event.dtStart().timeType()) {
- kWarning() << "dtEnd has wrong timespec";
- }
- } else if (prop.duration()) {
-// KCalCore::Duration duration.;
-// event.setDuration(duration << prop.duration());
- }
- //TODO check for equality of timespecs
+KCalCore::Todo::Ptr readTodo(const std::string& s, bool isUrl)
+{
- if (prop.transp()) {
-
- }
-
}
+
+
template <typename T>
-std::string writeEvent(typename T::EventType event) {
+std::string writeIncidence(const typename T::IncidenceType &incidence) {
+
using namespace icalendar_2_0;
+ typedef IncidenceConverter< typename T::Incidence > IC;
+ typedef typename T::KolabType KolabType;
+
try {
+
+ typename KolabType::components_type eventComponents;
+
+ typename KolabType::properties_type::uid_type uid(IC::uid(incidence));//TODO thats possibly the kontact internal uid?
+ typename KolabType::properties_type::dtstamp_type dtstamp;
+ dtstamp.date_time(IC::dtstamp(incidence));
+ typename KolabType::properties_type::created_type created;
+ created.date_time(IC::created(incidence));
+ typename KolabType::properties_type eventProps(uid, created, dtstamp);
- typedef DateTimeConverter< typename T::DateType > DC;
- typedef IncidenceConverter< typename T::IncidenceType > IC;
-
- KolabEvent::components_type eventComponents;
- IC::uid(event);
- IC::dtstamp(event);
- IC::created(event);
- KolabEvent::properties_type::uid_type uid(event->uid().toStdString());//TODO thats possibly the kontact internal uid?
- KolabEvent::properties_type::dtstamp_type dtstamp;
- dtstamp.date_time(DC::fromDateTime(event->lastModified()));
- KolabEvent::properties_type::created_type created;
- created.date_time(DC::fromDateTime(event->created()));
- KolabEvent::properties_type eventProps(uid, created, dtstamp);
-
- KolabEvent vevent(eventProps, eventComponents);
- writeEvent(vevent, *event);
+ KolabType inc(eventProps, eventComponents);
+ T::writeIncidence(inc, incidence);
VcalendarType::components_type components;
- components.vevent().push_back(vevent);
+ T::addIncidence(components, inc);
VcalendarType::properties_type::prodid_type prodid(std::string("libakonadi")); //TODO take from caller plus add libakonadi
VcalendarType::properties_type::version_type version(std::string("2.0")); //TODO define globally
@@ -182,37 +260,27 @@ std::string writeEvent(typename T::EventType event) {
xml_schema::namespace_infomap map;
map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-// map[""].schema = "note.xsd";
std::ostringstream ostringstream;
icalendar_2_0::icalendar(ostringstream, icalendar, map);
return ostringstream.str();
} catch (const xml_schema::exception& e) {
+ std::cout << "failed to write Incidence";
return std::string();
}
}
std::string writeEvent(KCalCore::Event::Ptr event)
{
- return writeEvent<KCalCoreTypes>(event);
+ return writeIncidence< IncidenceTrait<KCalCore::Event> >(*event);
}
-void writeEvent(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
+std::string writeTodo(KCalCore::Todo::Ptr todo)
{
-
- icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
-
- getIncidenceProperties(prop, event);
+ return writeIncidence< IncidenceTrait<KCalCore::Todo> >(*todo);
+}
- if (event.dtEnd().isValid()) {
- icalendar_2_0::properties::dtend_type dtend;
- setDateTimeProperty<KCalCoreTypes>(dtend, event.dtStart());
- prop.dtend(dtend);
- } else if (event.duration() != KCalCore::Duration()) {
-
- }
-}
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index 16a7cc5..10baba3 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -80,6 +80,19 @@
<xs:element name="class" type="ClassPropType" minOccurs="0"/>
<xs:element name="categories" type="CategoriesPropType" minOccurs="0"/>
<xs:element name="dtstart" type="DtstartPropType" minOccurs="0"/>
+ <xs:element name="rrule" type="RrulePropType" minOccurs="0"/>
+ <xs:element name="rdate" type="RdatePropType" minOccurs="0"/>
+ <xs:element name="exdate" type="ExdatePropType" minOccurs="0"/>
+ <xs:element name="recurrence-id" type="RecurrenceIdPropType" minOccurs="0"/>
+ <xs:element name="summary" type="SummaryPropType" minOccurs="0"/>
+ <xs:element name="description" type="DescriptionPropType" minOccurs="0"/>
+ <xs:element name="priority" type="PriorityPropType" minOccurs="0"/>
+ <xs:element name="status" type="StatusPropType" minOccurs="0"/>
+ <xs:element name="location" type="LocationPropType" minOccurs="0"/>
+ <xs:element name="organizer" type="OrganizerPropType" minOccurs="0"/>
+ <xs:element name="attendee" type="AttendeePropType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="attach" type="AttachPropType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="x-custom" type="CustomType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
commit f77f6163d4064f93fcb57dd02a241630a60dd0ae
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Tue Dec 20 11:40:08 2011 +0100
temp
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index d064bcc..3f9f736 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -10,7 +10,8 @@
namespace Kolab {
-int toInt(xml_schema::integer integer)
+template <typename T>
+int convertToInt(T integer)
{
try {
int i = boost::numeric_cast<int>(integer);
@@ -25,9 +26,25 @@ int toInt(xml_schema::integer integer)
return 0;
}
+template <typename T>
+T fromInt(int integer)
+{
+ try {
+ T i = boost::numeric_cast<T>(integer);
+ return i;
+ } catch(boost::numeric::negative_overflow& e) {
+ std::cout << e.what();
+ } catch(boost::numeric::positive_overflow& e) {
+ std::cout << e.what();
+ } catch(boost::numeric::bad_numeric_cast& e) {
+ std::cout << e.what();
+ }
+ return 0;
+}
+
int toInt(const icalendar_2_0::IntegerPropertyType &prop)
{
- return toInt(prop.integer());
+ return convertToInt<icalendar_2_0::IntegerPropertyType::integer_type>(prop.integer());
}
@@ -111,75 +128,50 @@ struct RecurrenceConverter;
template <typename T>
typename T::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
{
- using namespace icalendar_2_0;
-
- typedef RecurrenceConverter< typename T::RecurrenceType> RC;
- typedef DateTimeConverter< typename T::DateType> DC;
- typedef typename T::DatePtr DatePtr;
- typedef typename T::RecurrencePtr RecurrencePtr;
- typedef typename T::RecurrenceType RecurrenceType;
-
- RecurrencePtr r(new RecurrenceType());
- assert(r.get());
- RC::setType(r, rrule.freq());
- if (rrule.until()) {
- DatePtr date;
- if ((*rrule.until()).date_time()) {
- date = DC::toDate(*(*rrule.until()).date_time());
- } else if ((*rrule.until()).date()) {
- date = DC::toDate(*(*rrule.until()).date());
- }
- RC::setEndDt(r, date);
- } else if (rrule.count()) {
- RC::setCount(r, toInt(*rrule.count()));
- }
- if (rrule.interval()) {
- RC::setInterval(r, toInt(*rrule.interval()));
- } else {
- RC::setInterval(r, 1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
- }
- /*
- {
- QList<int> bysec;
- for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
- Q_ASSERT(*it <= std::numeric_limits<int>::max());
- bysec.append(*it);
- }
- if (!bysec.isEmpty()) {
- d.setBySeconds(bysec);
- }
+ using namespace icalendar_2_0;
+
+ typedef RecurrenceConverter< typename T::RecurrenceType> RC;
+ typedef DateTimeConverter< typename T::DateType> DC;
+ typedef typename T::DatePtr DatePtr;
+ typedef typename T::RecurrencePtr RecurrencePtr;
+ typedef typename T::RecurrenceType RecurrenceType;
+
+ RecurrencePtr r(new RecurrenceType());
+ RC::setType(r, rrule.freq());
+ if (rrule.until()) {
+ DatePtr date;
+ if ((*rrule.until()).date_time()) {
+ date = DC::toDate(*(*rrule.until()).date_time());
+ } else if ((*rrule.until()).date()) {
+ date = DC::toDate(*(*rrule.until()).date());
}
- //TODO implement all the other by*** lists
- if (rrule.wkst()) {
- switch (*rrule.wkst()) {
- case WeekdayRecurType::MO:
- d.setWeekStart(1);
- break;
- case WeekdayRecurType::TU:
- d.setWeekStart(2);
- break;
- case WeekdayRecurType::WE:
- d.setWeekStart(3);
- break;
- case WeekdayRecurType::TH:
- d.setWeekStart(4);
- break;
- case WeekdayRecurType::FR:
- d.setWeekStart(5);
- break;
- case WeekdayRecurType::SA:
- d.setWeekStart(6);
- break;
- case WeekdayRecurType::SU:
- d.setWeekStart(7);
- break;
- default:
- kWarning() << "invalid unhandled weekday" << *rrule.wkst();
- }
- }*/
- return r;
+ RC::setEndDt(r, date);
+ } else if (rrule.count()) {
+ RC::setCount(r, toInt(*rrule.count()));
+ }
+ if (rrule.interval()) {
+ RC::setInterval(r, toInt(*rrule.interval()));
+ } else {
+ RC::setInterval(r, 1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+ }
+ RC::setBysecond(r, rrule.bysecond());
+ RC::setByminute(r, rrule.byminute());
+ RC::setByhour(r, rrule.byhour());
+ RC::setByday(r, rrule.byday());
+ RC::setBymonthday(r, rrule.bymonthday());
+ RC::setByyearday(r, rrule.byyearday());
+ RC::setByweekno(r, rrule.byweekno());
+ RC::setBymonth(r, rrule.bymonth());
+ if (rrule.wkst()) {
+ RC::setWeekStart(r, *rrule.wkst());
}
+ return r;
+}
+
+
+template <typename T>
+struct IncidenceConverter;
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
index 7fb8ea4..425930a 100644
--- a/c++/lib/kcalconversions.h
+++ b/c++/lib/kcalconversions.h
@@ -5,6 +5,9 @@
#include <KDE/KDateTime>
#include <KDE/KDebug>
#include <kcalcore/recurrencerule.h>
+#include <kcalcore/recurrence.h>
+#include <bindings/kolabformat-xcal.hxx>
+#include <kcalcore/incidence.h>
namespace Kolab {
@@ -15,8 +18,26 @@ struct KCalCoreTypes
typedef typename KCalCore::RecurrenceRule RecurrenceType;
typedef typename std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr;
typedef QString StringType;
+ typedef typename KCalCore::Incidence IncidenceType;
};
+
+QStringList toStringList(const icalendar_2_0::TextListPropertyType &s)
+{
+ QStringList d;
+ const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
+ for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
+ d.append(QString::fromStdString(*it));
+ }
+ return d;
+}
+
+QString toString(const icalendar_2_0::TextPropertyType &s)
+{
+ return QString::fromStdString(s.text());
+}
+
+
typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
template <> struct DateTimeConverter<KDateTime>
@@ -91,6 +112,7 @@ template <> struct DateTimeConverter<KDateTime>
};
+
template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
{
@@ -99,34 +121,92 @@ template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
static void setType(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
{
+ using namespace icalendar_2_0;
+ using namespace KCalCore;
+
switch (freq) {
- case icalendar_2_0::FreqRecurType::YEARLY:
- r->setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+ case FreqRecurType::YEARLY:
+ r->setRecurrenceType(RecurrenceRule::rYearly);
break;
- case icalendar_2_0::FreqRecurType::MONTHLY:
- r->setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+ case FreqRecurType::MONTHLY:
+ r->setRecurrenceType(RecurrenceRule::rMonthly);
break;
- case icalendar_2_0::FreqRecurType::WEEKLY:
- r->setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+ case FreqRecurType::WEEKLY:
+ r->setRecurrenceType(RecurrenceRule::rWeekly);
break;
- case icalendar_2_0::FreqRecurType::DAILY:
- kDebug() << "daily";
- r->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+ case FreqRecurType::DAILY:
+ r->setRecurrenceType(RecurrenceRule::rDaily);
break;
- case icalendar_2_0::FreqRecurType::HOURLY:
- r->setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+ case FreqRecurType::HOURLY:
+ r->setRecurrenceType(RecurrenceRule::rHourly);
break;
- case icalendar_2_0::FreqRecurType::MINUTELY:
- r->setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+ case FreqRecurType::MINUTELY:
+ r->setRecurrenceType(RecurrenceRule::rMinutely);
break;
- case icalendar_2_0::FreqRecurType::SECONDLY:
- r->setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+ case FreqRecurType::SECONDLY:
+ r->setRecurrenceType(RecurrenceRule::rSecondly);
break;
default:
kWarning() << "invalid unhandled recurrenc type" << freq;
}
}
+ static icalendar_2_0::RecurType::freq_type type(const Type &t)
+ {
+ using namespace icalendar_2_0;
+ using namespace KCalCore;
+
+ switch (t.recurrenceType()) {
+ case RecurrenceRule::rYearly:
+ return FreqRecurType::YEARLY;
+ case RecurrenceRule::rMonthly:
+ return FreqRecurType::MONTHLY;
+ case RecurrenceRule::rWeekly:
+ return FreqRecurType::WEEKLY;
+ case RecurrenceRule::rDaily:
+ return FreqRecurType::DAILY;
+ case RecurrenceRule::rHourly:
+ return FreqRecurType::HOURLY;
+ case RecurrenceRule::rMinutely:
+ return FreqRecurType::MINUTELY;
+ case RecurrenceRule::rSecondly:
+ return FreqRecurType::SECONDLY;
+ default:
+ kWarning() << "invalid unhandled recurrenc type";
+ }
+ }
+
+ static void setWeekStart(Ptr r, const icalendar_2_0::RecurType::wkst_type &wkst)
+ {
+ using namespace icalendar_2_0;
+
+ switch (wkst) {
+ case WeekdayRecurType::MO:
+ r->setWeekStart(1);
+ break;
+ case WeekdayRecurType::TU:
+ r->setWeekStart(2);
+ break;
+ case WeekdayRecurType::WE:
+ r->setWeekStart(3);
+ break;
+ case WeekdayRecurType::TH:
+ r->setWeekStart(4);
+ break;
+ case WeekdayRecurType::FR:
+ r->setWeekStart(5);
+ break;
+ case WeekdayRecurType::SA:
+ r->setWeekStart(6);
+ break;
+ case WeekdayRecurType::SU:
+ r->setWeekStart(7);
+ break;
+ default:
+ kWarning() << "invalid unhandled weekday" << wkst;
+ }
+ }
+
static void setEndDt(Ptr r, KCalCoreTypes::DatePtr date )
{
r->setEndDt(*date);
@@ -141,120 +221,291 @@ template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
{
r->setFrequency(interval);
}
-
-};
-/*
-typename KCalCoreTypes::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
-{
- typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
- typedef typename KCalCoreTypes::DatePtr DatePtr;
- typedef DateTimeConverter<typename KCalCoreTypes::DateType> DC;
- RecurrencePtr r(new KCalCore::RecurrenceRule());
- KCalCore::RecurrenceRule &d = *r;
- using namespace icalendar_2_0;
- switch (rrule.freq()) {
- case FreqRecurType::YEARLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
- break;
- case FreqRecurType::MONTHLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
- break;
- case FreqRecurType::WEEKLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
- break;
- case FreqRecurType::DAILY:
- kDebug() << "daily";
- d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
- break;
- case FreqRecurType::HOURLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
- break;
- case FreqRecurType::MINUTELY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
- break;
- case FreqRecurType::SECONDLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
- break;
- default:
- kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
- }
- if (rrule.until()) {
- DatePtr date;
- if ((*rrule.until()).date_time()) {
- date = DC::toDate(*(*rrule.until()).date_time());
- } else if ((*rrule.until()).date()) {
- date = DC::toDate(*(*rrule.until()).date());
+ static void setBysecond(Ptr r, const icalendar_2_0::RecurType::bysecond_sequence &list)
+ {
+ QList<int> by;
+ for (icalendar_2_0::RecurType::bysecond_const_iterator it(list.begin()); it != list.end(); it++) {
+ by.append(convertToInt<xml_schema::non_negative_integer>(*it));
+ }
+ if (!by.isEmpty()) {
+ r->setBySeconds(by);
}
- d.setEndDt(*date);
- } else if (rrule.count()) {
- Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
- d.setDuration(*rrule.count());
}
- if (rrule.interval()) {
- Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
- d.setFrequency(*rrule.interval());
- } else {
- d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+ static void setByminute(Ptr r, const icalendar_2_0::RecurType::byminute_sequence &list)
+ {
+ QList<int> by;
+ for (icalendar_2_0::RecurType::byminute_const_iterator it(list.begin()); it != list.end(); it++) {
+ by.append(convertToInt<xml_schema::non_negative_integer>(*it));
+ }
+ if (!by.isEmpty()) {
+ r->setByMinutes(by);
+ }
}
+
+ static void setByhour(Ptr r, const icalendar_2_0::RecurType::byhour_sequence &list)
{
- QList<int> bysec;
- for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
- Q_ASSERT(*it <= std::numeric_limits<int>::max());
- bysec.append(*it);
+ QList<int> by;
+ for (icalendar_2_0::RecurType::byhour_const_iterator it(list.begin()); it != list.end(); it++) {
+ by.append(convertToInt<xml_schema::non_negative_integer>(*it));
}
- if (!bysec.isEmpty()) {
- d.setBySeconds(bysec);
+ if (!by.isEmpty()) {
+ r->setByHours(by);
}
}
- //TODO implement all the other by*** lists
- if (rrule.wkst()) {
- switch (*rrule.wkst()) {
- case WeekdayRecurType::MO:
- d.setWeekStart(1);
- break;
- case WeekdayRecurType::TU:
- d.setWeekStart(2);
- break;
- case WeekdayRecurType::WE:
- d.setWeekStart(3);
- break;
- case WeekdayRecurType::TH:
- d.setWeekStart(4);
- break;
- case WeekdayRecurType::FR:
- d.setWeekStart(5);
- break;
- case WeekdayRecurType::SA:
- d.setWeekStart(6);
- break;
- case WeekdayRecurType::SU:
- d.setWeekStart(7);
- break;
- default:
- kWarning() << "invalid unhandled weekday" << *rrule.wkst();
+
+ static void setByday(Ptr r, const icalendar_2_0::RecurType::byday_sequence &list)
+ {
+ QList<KCalCore::RecurrenceRule::WDayPos> by;
+ for (icalendar_2_0::RecurType::byday_const_iterator it(list.begin()); it != list.end(); it++) {
+ KCalCore::RecurrenceRule::WDayPos pos;
+ //TODO implement parser for format
+// switch () {
+//
+// }
+ //by.append(convertToInt<xml_schema::non_negative_integer>(*it));
+ }
+ if (!by.isEmpty()) {
+ r->setByDays(by);
+ }
+ }
+
+ static void setBymonthday(Ptr r, const icalendar_2_0::RecurType::bymonthday_sequence &list)
+ {
+ QList<int> by;
+ for (icalendar_2_0::RecurType::bymonth_const_iterator it(list.begin()); it != list.end(); it++) {
+ by.append(convertToInt<xml_schema::integer>(*it));
+ }
+ if (!by.isEmpty()) {
+ r->setByMonthDays(by);
+ }
+ }
+
+ static void setByyearday(Ptr r, const icalendar_2_0::RecurType::byyearday_sequence &list)
+ {
+ QList<int> by;
+ for (icalendar_2_0::RecurType::byyearday_const_iterator it(list.begin()); it != list.end(); it++) {
+ by.append(convertToInt<xml_schema::integer>(*it));
+ }
+ if (!by.isEmpty()) {
+ r->setByYearDays(by);
}
}
- return r;
-}*/
+
+ static void setByweekno(Ptr r, const icalendar_2_0::RecurType::byweekno_sequence &list)
+ {
+ QList<int> by;
+ for (icalendar_2_0::RecurType::byweekno_const_iterator it(list.begin()); it != list.end(); it++) {
+ by.append(convertToInt<xml_schema::integer>(*it));
+ }
+ if (!by.isEmpty()) {
+ r->setByWeekNumbers(by);
+ }
+ }
+
+ static void setBymonth(Ptr r, const icalendar_2_0::RecurType::bymonth_sequence &list)
+ {
+ QList<int> by;
+ for (icalendar_2_0::RecurType::bymonth_const_iterator it(list.begin()); it != list.end(); it++) {
+ by.append(convertToInt<xml_schema::integer>(*it));
+ }
+ if (!by.isEmpty()) {
+ r->setByMonths(by);
+ }
+ }
+};
+// template <typename T, typename I>
+// QList <int> &toList(QList<int> &list, const xsd::cxx::tree::sequence <T> &input) {
+// for (icalendar_2_0::RecurType::bysecond_const_iterator it(list.begin()); it != list.end(); it++) {
+// bysec.append(convertToInt<I>(*it));
+// }
+// Q_FOREACH (I i, list) {
+// list.push_back(fromInt<I>(i));
+// }
+// return list;
+// }
-QStringList toStringList(const icalendar_2_0::TextListPropertyType &s)
+template <typename T, typename I>
+xsd::cxx::tree::sequence <T> &toList(xsd::cxx::tree::sequence <T> &list, const QList<int> &input) {
+ Q_FOREACH (int i, list) {
+ list.push_back(convertToInt<I>(i));
+ }
+ return list;
+}
+
+
+std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const typename KCalCore::RecurrenceRule &r)
{
- QStringList d;
- const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
- for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
- d.append(QString::fromStdString(*it));
+ using namespace icalendar_2_0;
+
+ typedef RecurrenceConverter< typename KCalCore::RecurrenceRule > RC;
+ typedef DateTimeConverter< KDateTime> DC;
+
+ std::auto_ptr< RrulePropType > rruleProp(new RrulePropType(RC::type(r)));
+
+ RecurPropertyType::recur_type &recur = rruleProp->recur();
+ bool ok;
+ const KDateTime &endDate = r.endDt(&ok);
+ if (ok) {
+ RecurPropertyType::recur_type::until_type until;
+ if (endDate.isDateOnly()) {
+ until.date(DC::fromDate(endDate));
+ } else {
+ until.date_time(DC::fromDateTime(endDate));
+ }
+ recur.until(until);
+ } else if (r.duration() > 0) {
+ recur.count(fromInt<RecurType::count_type>(r.duration()));
}
- return d;
+
+ if (r.frequency() > 1) {
+ recur.interval(fromInt<RecurType::interval_type>(r.frequency()));
+ }
+
+ if (!r.bySeconds().isEmpty()) {
+ RecurType::bysecond_sequence bysecond;
+ recur.bysecond(toList<RecurType::bysecond_type, xml_schema::non_negative_integer>(bysecond, r.bySeconds()));
+ }
+ return rruleProp;
}
-QString toString(const icalendar_2_0::TextPropertyType &s)
+
+void setIncidenceProperties(KCalCore::Incidence &inc, const icalendar_2_0::properties &prop)
{
- return QString::fromStdString(s.text());
+ inc.setUid(toString(prop.uid()));
+ inc.setCreated(*toDate<KCalCoreTypes>(prop.created()));
+ inc.setLastModified(*toDate<KCalCoreTypes>(prop.dtstamp()));
+
+ if (prop.sequence()) {
+ inc.setRevision(toInt(*prop.sequence()));
+ }
+
+ if (prop.class_()) {
+ QString string(toString(*prop.class_()));
+ KCalCore::Incidence::Secrecy sec;
+ if (string == "PRIVATE") {
+ sec = KCalCore::Incidence::SecrecyPrivate;
+ } else if (string == "CONFIDENTIAL") {
+ sec = KCalCore::Incidence::SecrecyConfidential;
+ } else {
+ sec = KCalCore::Incidence::SecrecyPublic;
+ }
+ inc.setSecrecy(sec);
+ }
+
+ if (prop.categories()) {
+ inc.setCategories(toStringList(*prop.categories()));
+ }
+
+ if (prop.dtstart()) {
+ const KCalCoreTypes::DatePtr date = toDate<KCalCoreTypes>(*prop.dtstart());
+ inc.setDtStart(*date);
+ inc.setAllDay(date->isDateOnly()); //TODO add to specification that allday depends on start date format
+ }
+
+ KCalCore::Recurrence *recurrence = inc.recurrence();
+ if (prop.rrule()) {
+ RecurrencePtr rrule = toRRule<KCalCoreTypes>(prop.rrule()->recur());
+ rrule->setStartDt(recurrence->startDateTime());
+ recurrence->addRRule(rrule.release());
+ }
+
+ if (prop.rdate()) {
+
+ }
+
+ if (prop.exdate()) {
+
+ }
+
+ if (prop.recurrence_id()) {
+
+ }
+
+ if (prop.summary()) {
+ inc.setSummary(toString(*prop.summary())); //TODO detect richtext and set flag accordingly
+ }
+
+ if (prop.description()) {
+ inc.setDescription(toString(*prop.description())); //TODO detect richtext and set flag accordingly
+ }
+
+ if (prop.priority()) {
+
+ }
+
+ if (prop.status()) {
+
+ }
+
+ if (prop.location()) {
+
+ }
+
+ if (prop.organizer()) {
+
+ }
+
+ if (prop.attendee().size()) {
+
+ }
+
+ if (prop.attach().size()) {
+
+ }
+
+ if (prop.x_custom().size()) {
+
+ }
+
+}
+
+void getIncidenceProperties(icalendar_2_0::properties &prop, const KCalCore::Incidence &inc)
+{
+ using namespace KCalCore;
+ using namespace icalendar_2_0;
+
+ prop.sequence(fromInt<xml_schema::integer>(inc.revision()));
+
+ switch (inc.secrecy()) {
+ case Incidence::SecrecyConfidential:
+ prop.class_();
+ break;
+ case Incidence::SecrecyPublic:
+ prop.class_();
+ case Incidence::SecrecyPrivate:
+ prop.class_();
+ }
+
+
+ if (inc.dtStart().isValid()) {
+ properties::dtstart_type dtstart;
+ setDateTimeProperty<KCalCoreTypes>(dtstart, inc.dtStart());
+ prop.dtstart(dtstart);
+ }
+
+ if (inc.recurs()) {
+ Recurrence *r = inc.recurrence();
+ if (r->rRules().size() >= 1) {
+ if (r->rRules().size() != 1) {
+ kWarning() << "too many recurrences: " << r->rRules().size();
+ }
+ RecurrenceRule *rule = r->rRules().first();
+ //TODO check if startdate is allDay if recurrence is allDay
+ //TODO check if startdate matches the one of the event (it MUST)
+ prop.rrule(recurrenceProperty(*rule));
+ }
+ }
+
}
+template <> struct IncidenceConverter < KCalCore::Incidence >
+{
+
+
+
} //Namespace
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index feb5e01..543468b 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -10,6 +10,7 @@
#include <limits>
#include <kcalcore/recurrencerule.h>
#include "kcalconversions.h"
+#include </home/chrigi/devel/kde/kdepim-runtime/resources/kcal/kcalresource.h>
namespace Kolab {
@@ -76,14 +77,22 @@ void readEvent(Kolab::Event &event ,const icalendar_2_0::VeventType &vevent)
// }
}
-KCalCore::Event::Ptr readEvent(const std::string& s)
+KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl)
{
try {
//TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
xml_schema::properties props;
- props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../../schemas/ical/kolabformat-xcal.xsd"); //Force schema
- std::auto_ptr<icalendar_2_0::IcalendarType> icalendar(icalendar_2_0::icalendar(s/*, xml_schema::flags::dont_validate*/, 0, props));
+ std::auto_ptr<icalendar_2_0::IcalendarType> icalendar;
+ if (isUrl) {
+ props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../../schemas/ical/kolabformat-xcal.xsd"); //Force schema
+ icalendar = icalendar_2_0::icalendar(s, 0, props);
+ } else {
+ props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "/home/chrigi/work/kolab/xmlformat/libkolabxml/schemas/ical/kolabformat-xcal.xsd"); //Force schema
+ std::istringstream is(s);
+ icalendar = icalendar_2_0::icalendar(is, 0, props);
+ }
+
const icalendar_2_0::VcalendarType &vcalendar = icalendar->vcalendar();
QList <KCalCore::Event::Ptr> events;
@@ -104,6 +113,7 @@ KCalCore::Event::Ptr readEvent(const std::string& s)
return events.first();
} catch (const xml_schema::exception& e) {
std::cout << e << std::endl;
+ std::cout << "Failed to read event!" << std::endl;
}
return KCalCore::Event::Ptr();
}
@@ -114,19 +124,7 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
{
const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
- event.setUid(toString(prop.uid()));
- event.setCreated(*toDate<KCalCoreTypes>(prop.created()));
- event.setLastModified(*toDate<KCalCoreTypes>(prop.dtstamp()));
-
- if (prop.sequence()) {
- event.setRevision(toInt(*prop.sequence()));
- }
-
- if (prop.dtstart()) {
- const KCalCoreTypes::DatePtr date = toDate<KCalCoreTypes>(*prop.dtstart());
- event.setDtStart(*date);
- event.setAllDay(date->isDateOnly()); //TODO add to specification that allday depends on start date format
- }
+ setIncidenceProperties(event, prop);
if (prop.dtend()) {
KDateTime date;
@@ -141,53 +139,28 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
}
//TODO check for equality of timespecs
- if (prop.categories()) {
- event.setCategories(toStringList(*prop.categories()));
- }
- if (prop.class_()) {
- QString string(toString(*prop.class_()));
- KCalCore::Incidence::Secrecy sec;
- if (string == "PRIVATE") {
- sec = KCalCore::Incidence::SecrecyPrivate;
- } else if (string == "CONFIDENTIAL") {
- sec = KCalCore::Incidence::SecrecyConfidential;
- } else {
- sec = KCalCore::Incidence::SecrecyPublic;
- }
- event.setSecrecy(sec);
- }
-
- KCalCore::Recurrence *recurrence = event.recurrence();
- if (prop.rrule()) {
- RecurrencePtr rrule = toRRule<KCalCoreTypes>(prop.rrule()->recur());
- rrule->setStartDt(recurrence->startDateTime());
- recurrence->addRRule(rrule.release());
- }
-
- if (prop.summary()) {
- event.setSummary(toString(*prop.summary())); //TODO detect richtext and set flag accordingly
+ if (prop.transp()) {
+
}
- if (prop.description()) {
- event.setDescription(toString(*prop.description())); //TODO detect richtext and set flag accordingly
- }
}
-std::string writeEvent(KCalCore::Event::Ptr event)
-{
+template <typename T>
+std::string writeEvent(typename T::EventType event) {
using namespace icalendar_2_0;
try {
- typedef DateTimeConverter<KDateTime> DC;
+ typedef DateTimeConverter< typename T::DateType > DC;
+ typedef IncidenceConverter< typename T::IncidenceType > IC;
KolabEvent::components_type eventComponents;
-
+ IC::uid(event);
+ IC::dtstamp(event);
+ IC::created(event);
KolabEvent::properties_type::uid_type uid(event->uid().toStdString());//TODO thats possibly the kontact internal uid?
KolabEvent::properties_type::dtstamp_type dtstamp;
- kDebug() << "dtstamp";
dtstamp.date_time(DC::fromDateTime(event->lastModified()));
KolabEvent::properties_type::created_type created;
- kDebug() << "created";
created.date_time(DC::fromDateTime(event->created()));
KolabEvent::properties_type eventProps(uid, created, dtstamp);
@@ -219,16 +192,18 @@ std::string writeEvent(KCalCore::Event::Ptr event)
}
}
+std::string writeEvent(KCalCore::Event::Ptr event)
+{
+ return writeEvent<KCalCoreTypes>(event);
+}
+
void writeEvent(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
{
+
icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
- prop.sequence(event.revision());
- if (event.dtStart().isValid()) {
- icalendar_2_0::properties::dtstart_type dtstart;
- setDateTimeProperty<KCalCoreTypes>(dtstart, event.dtStart());
- prop.dtstart(dtstart);
- }
+ getIncidenceProperties(prop, event);
+
if (event.dtEnd().isValid()) {
icalendar_2_0::properties::dtend_type dtend;
setDateTimeProperty<KCalCoreTypes>(dtend, event.dtStart());
@@ -236,6 +211,7 @@ void writeEvent(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
} else if (event.duration() != KCalCore::Duration()) {
}
+
}
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index e5e70a0..5c541c0 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -50,7 +50,7 @@ std::string serializeEvent();
// void readEvent(const icalendar_2_0::VeventType &vevent);
// void readEvent(Kolab::Event &,const icalendar_2_0::VeventType &vevent);
void readEvent(KCalCore::Event &,const icalendar_2_0::KolabEvent &vevent);
-KCalCore::Event::Ptr readEvent(const std::string& s);
+KCalCore::Event::Ptr readEvent(const std::string& s, bool isUrl = true);
void writeEvent(icalendar_2_0::KolabEvent &vevent, const KCalCore::Event &);
std::string writeEvent(KCalCore::Event::Ptr);
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index b999f27..58fa3d1 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -17,6 +17,7 @@
#include <kcalcore/event.h>
#include <lib/kolabformat.h>
#include <kdebug.h>
+#include </home/chrigi/devel/kde/kdepim-runtime/resources/kcal/kcalresource.h>
void BindingsTest::writeNoteTest()
{
@@ -385,11 +386,38 @@ void BindingsTest::writeEvent()
event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+ KCalCore::Recurrence *recurrence = event->recurrence();
+ KCalCore::RecurrenceRule *rule = new KCalCore::RecurrenceRule();
+ rule->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+ rule->setFrequency(3);
+ rule->setDuration(5);
+ recurrence->addRRule(rule);
+
kDebug() << "-------------------";
kDebug() << QString::fromStdString(Kolab::writeEvent(event));
kDebug() << "-------------------";
}
+void BindingsTest::roundtripEvent()
+{
+ KCalCore::Event::Ptr event(new KCalCore::Event);
+ event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+ event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+
+ KCalCore::Recurrence *recurrence = event->recurrence();
+ KCalCore::RecurrenceRule *rule = new KCalCore::RecurrenceRule();
+ rule->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+ rule->setFrequency(3);
+ rule->setDuration(5);
+ recurrence->addRRule(rule);
+
+ QString result = QString::fromStdString(Kolab::writeEvent(event));
+ kDebug() << result;
+ KCalCore::Event::Ptr resEvent = Kolab::readEvent(result.toStdString(), false);
+ QVERIFY(resEvent);
+ QCOMPARE(event->dtStart(), resEvent->dtStart());
+}
+
QTEST_MAIN( BindingsTest )
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index 520843b..bb63dd2 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -26,6 +26,7 @@ class BindingsTest : public QObject
//Kolabformat
void readEvent();
void writeEvent();
+ void roundtripEvent();
};
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index 37ba686..16a7cc5 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -16,7 +16,7 @@
</xs:complexContent>
</xs:complexType>
-<!-- <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" />
+ <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" />
<xs:complexType name="CustomType" >
<xs:complexContent mixed="false">
@@ -29,8 +29,6 @@
</xs:complexContent>
</xs:complexType>
- <xs:element name="x-kolab-custom" type="CustomType" substitutionGroup="baseProperty" />-->
-
<xs:complexType name="KolabEvent" >
<xs:sequence>
<xs:element name="properties">
@@ -45,9 +43,20 @@
<xs:element name="dtstart" type="DtstartPropType" minOccurs="0"/>
<xs:element name="dtend" type="DtendPropType" minOccurs="0"/>
<xs:element name="duration" type="DurationPropType" minOccurs="0"/>
+ <xs:element name="transp" type="TranspPropType" minOccurs="0"/>
<xs:element name="rrule" type="RrulePropType" minOccurs="0"/>
+ <xs:element name="rdate" type="RdatePropType" minOccurs="0"/>
+ <xs:element name="exdate" type="ExdatePropType" minOccurs="0"/>
+ <xs:element name="recurrence-id" type="RecurrenceIdPropType" minOccurs="0"/>
<xs:element name="summary" type="SummaryPropType" minOccurs="0"/>
<xs:element name="description" type="DescriptionPropType" minOccurs="0"/>
+ <xs:element name="priority" type="PriorityPropType" minOccurs="0"/>
+ <xs:element name="status" type="StatusPropType" minOccurs="0"/>
+ <xs:element name="location" type="LocationPropType" minOccurs="0"/>
+ <xs:element name="organizer" type="OrganizerPropType" minOccurs="0"/>
+ <xs:element name="attendee" type="AttendeePropType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="attach" type="AttachPropType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="x-custom" type="CustomType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
commit 68823e7499becba936b31d20297384f9eaa20044
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Mon Dec 19 16:12:39 2011 +0100
temp
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index 542568d..d064bcc 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -1,44 +1,42 @@
#ifndef KOLAB_CONVERSIONS_H
#define KOLAB_CONVERSIONS_H
-#include "kolabformat.h"
#include <bindings/iCalendar-props.hxx>
-#include <kdebug.h>
#include <boost/shared_ptr.hpp>
-#include <kdatetime.h>
-// #include "kolabcontainers.h"
-// #include "kolabcontainers.h"
+#include <boost/numeric/conversion/converter_policies.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#define TZ_PREFIX "/kolab.org/"
namespace Kolab {
-
-template <typename T> struct DateTimeConverter;
-
-// template <> struct DateTimeConverter<DateTime>
-// {
-// typedef typename boost::shared_ptr<DateTime> Ptr;
-// Ptr toDate(const xml_schema::date &dt)
-// {
-// Ptr date(new DateTime());
-//
-// return date;
-// }
-// Ptr toDate(const xml_schema::date_time &dt)
-// {
-// Ptr date(new DateTime());
-// return date;
-// }
-//
-// void setTimezone(Ptr date, const std::string &tzid )
-// {
-// date->setTimezone(tzid);
-// }
-// };
+int toInt(xml_schema::integer integer)
+{
+ try {
+ int i = boost::numeric_cast<int>(integer);
+ return i;
+ } catch(boost::numeric::negative_overflow& e) {
+ std::cout << e.what();
+ } catch(boost::numeric::positive_overflow& e) {
+ std::cout << e.what();
+ } catch(boost::numeric::bad_numeric_cast& e) {
+ std::cout << e.what();
+ }
+ return 0;
+}
+int toInt(const icalendar_2_0::IntegerPropertyType &prop)
+{
+ return toInt(prop.integer());
+}
-
-
-template <typename T> typename T::DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+
+
+template <typename T>
+struct DateTimeConverter;
+
+template <typename T>
+typename T::DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
{
typedef DateTimeConverter<typename T::DateType> DC;
typename T::DatePtr date;
@@ -47,18 +45,16 @@ template <typename T> typename T::DatePtr toDate(const icalendar_2_0::DateDateti
} else if (dtProperty.date()) {
date = DC::toDate(*dtProperty.date());
}
-
+
if (dtProperty.parameters()) {
for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
std::string tzid = tz->text();
- //TODO
-// QString tzid(toString());
-// if (tzid.contains("/kolab.org/")) {
-// tzid.remove("/kolab.org/");
-// } else {
-// kWarning() << "/kolab.org/ timezone prefix is missing";
-// }
+ if (tzid.find(TZ_PREFIX) != std::string::npos) {
+ tzid.erase(0, strlen(TZ_PREFIX));
+ } else {
+ std::cout << "/kolab.org/ timezone prefix is missing";
+ }
DC::setTimezone(date, tzid);
}
}
@@ -70,7 +66,6 @@ template <typename T> typename T::DatePtr toDate(const icalendar_2_0::UtcDatetim
{
typedef typename T::DateType DateType;
typedef typename T::DatePtr DatePtr;
-
typedef DateTimeConverter<DateType> DC;
typename T::DatePtr date;
@@ -78,18 +73,43 @@ template <typename T> typename T::DatePtr toDate(const icalendar_2_0::UtcDatetim
date = DC::toDate(*dtProperty.date_time());
} else { //The utc-date-time element shouldn't even exist
date = DatePtr(new DateType());
- kWarning() << "This element shouldn't even be existing";
- Q_ASSERT(0);
+ std::cout << "This element shouldn't even be existing";
+ assert(0); //TODO implement anyways?
}
DC::setUTC(date);
return date;
}
-template <typename T> struct RecurrenceConverter;
+template <typename T>
+void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const typename T::DateType &dt)
+{
+ typedef typename T::DateType DateType;
+ typedef typename T::DatePtr DatePtr;
+ typedef DateTimeConverter<DateType> DC;
+
+ if (DC::isDateOnly(dt)) {
+ date.date(DC::fromDate(dt));
+ } else {
+ date.date_time(DC::fromDateTime(dt));
+
+ const std::string &timezone = DC::getTimezone(dt);
+ if (timezone.size() != 0) {
+ std::string tz(TZ_PREFIX);
+ tz.append(timezone);
+ icalendar_2_0::TzidParamType tzidParam(tz);
+ icalendar_2_0::ArrayOfParameters parameters;
+ parameters.baseParameter().push_back(tzidParam);
+ date.parameters(parameters);
+ }
+ }
+}
+template <typename T>
+struct RecurrenceConverter;
-template <typename T> typename T::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
+template <typename T>
+typename T::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
{
using namespace icalendar_2_0;
@@ -99,31 +119,26 @@ template <typename T> typename T::RecurrencePtr toRRule(const icalendar_2_0::Rec
typedef typename T::RecurrencePtr RecurrencePtr;
typedef typename T::RecurrenceType RecurrenceType;
- RecurrencePtr r(new RecurrenceType);
-
+ RecurrencePtr r(new RecurrenceType());
+ assert(r.get());
RC::setType(r, rrule.freq());
if (rrule.until()) {
- RC::setUntil(r, *rrule.until());
DatePtr date;
if ((*rrule.until()).date_time()) {
date = DC::toDate(*(*rrule.until()).date_time());
} else if ((*rrule.until()).date()) {
date = DC::toDate(*(*rrule.until()).date());
}
- RC::setEndDt(date);
+ RC::setEndDt(r, date);
} else if (rrule.count()) {
- RC::setCount(r, *rrule.count());
-/*TODO
- Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
- d.setDuration(*rrule.count());*/
+ RC::setCount(r, toInt(*rrule.count()));
}
- /*
if (rrule.interval()) {
- Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
- d.setFrequency(*rrule.interval());
+ RC::setInterval(r, toInt(*rrule.interval()));
} else {
- d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+ RC::setInterval(r, 1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
}
+ /*
{
QList<int> bysec;
for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
@@ -168,131 +183,38 @@ template <typename T> typename T::RecurrencePtr toRRule(const icalendar_2_0::Rec
-
-
-
-
-// namespace KCalCore {
-
- typedef boost::shared_ptr<KDateTime> DatePtr;
-
- QString toString(const xml_schema::string &s)
- {
- return QString::fromStdString(s);
- }
-
- QString toString(const icalendar_2_0::TextPropertyType &s)
- {
- return toString(s.text());
- }
-
- QStringList toStringList(const icalendar_2_0::TextListPropertyType &s)
- {
- QStringList d;
- const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
- for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
- d.append(QString::fromStdString(*it));
- }
- return d;
- }
-
- DatePtr toDate(const xml_schema::date &dt)
- {
- DatePtr date(new KDateTime());
- date->setDateOnly(true);
- date->setDate(QDate(dt.year(), dt.month(), dt.day()));
- return date;
- }
-
- DatePtr toDate(const xml_schema::date_time &dt)
- {
- DatePtr date(new KDateTime());
- // kDebug() << dt.year() << dt. month() << dt.day() << dt.hours();
- date->setDate(QDate(dt.year(), dt.month(), dt.day()));
- date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
- if (dt.zone_present()) {
- date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
- }
- // kDebug() << date->date() << *date << dt.zone_present();
- return date;
- }
-
-
-
-
-
-
-
-
-// }
-
-
-
-int toInt(const icalendar_2_0::IntegerPropertyType &prop)
-{
- Q_ASSERT(prop.integer() <= std::numeric_limits<int>::max());
- int i = prop.integer();
- return i;
-}
-
-
-// template <class ValueType, class ReturnType> struct ConversionTraits {
-// // typedef typename T::ReturnType ReturnType;
-// // typedef typename T::ValueType ValueType;
-// //
-// static ReturnType to(ValueType v)
+// template <typename T> struct StringConverter
+// {
+// QString toString(const xml_schema::string &s)
// {
-// return v;
+// return QString::fromStdString(s);
// }
-// static ValueType from(ReturnType v)
-// {
-// return v;
+//
+// void append(StringListType &list, const StringType &string) {
+//
// }
-// };
-
-
-
+// }
+//
+// template <typename T> typename T::StringListType toStringList(const icalendar_2_0::TextListPropertyType &s)
+// {
+// using namespace icalendar_2_0;
+//
+// typedef StringConverter< typename T::RecurrenceType> SC;
+// typedef typename T::StringListType StringListType;
+//
+// StringListType list;
+// const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
+// for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
+// SC::append(list, SC::toString(*it));
+// }
+// return list;
+// }
-xml_schema::date_time fromDateTime(const KDateTime &dt)
-{
- const QDate &d = dt.date();
- const QTime &t = dt.time();
- xml_schema::date_time date(d.year(), d.month(), d.day(), t.hour(), t.minute(), t.second());
-// date.zone_reset();
- //TODO timezone
- return date;
-}
-xml_schema::date fromDate(const KDateTime &dt)
-{
- const QDate &d = dt.date();
- xml_schema::date date(d.year(), d.month(), d.day());
- return date;
-}
-std::auto_ptr<icalendar_2_0::DateDatetimePropertyType> fromDateProperty(const KDateTime &dt)
-{
- std::auto_ptr<icalendar_2_0::DateDatetimePropertyType> date(new ::icalendar_2_0::DateDatetimePropertyType);
- if (dt.isDateOnly()) {
- date->date(fromDate(dt)); //setDateOnly
- } else {
- date->date_time(fromDateTime(dt)); //setDateTime
- }
- //TODO add timezone information //setTimeZone
- return date;
-}
-void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const KDateTime &dt)
-{
- if (dt.isDateOnly()) {
- date.date(fromDate(dt));
- } else {
- date.date_time(fromDateTime(dt));
- }
- //TODO add timezone information
-}
/*
xml_schema::date fromDate(const KDateTime &dt)
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
index 82070ec..7fb8ea4 100644
--- a/c++/lib/kcalconversions.h
+++ b/c++/lib/kcalconversions.h
@@ -2,6 +2,9 @@
#define KOLAB_KCALCONVERSIONS_H
#include "conversions.h"
+#include <KDE/KDateTime>
+#include <KDE/KDebug>
+#include <kcalcore/recurrencerule.h>
namespace Kolab {
@@ -11,15 +14,16 @@ struct KCalCoreTypes
typedef typename boost::shared_ptr<KDateTime> DatePtr;
typedef typename KCalCore::RecurrenceRule RecurrenceType;
typedef typename std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr;
+ typedef QString StringType;
};
typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
-
template <> struct DateTimeConverter<KDateTime>
{
typedef KDateTime Type;
typedef typename boost::shared_ptr<KDateTime> Ptr;
+
static Ptr toDate(const xml_schema::date &dt)
{
Ptr date(new KDateTime());
@@ -27,7 +31,7 @@ template <> struct DateTimeConverter<KDateTime>
date->setDate(QDate(dt.year(), dt.month(), dt.day()));
return date;
}
-
+
static Ptr toDate(const xml_schema::date_time &dt)
{
Ptr date(new KDateTime());
@@ -38,6 +42,26 @@ template <> struct DateTimeConverter<KDateTime>
}
return date;
}
+
+ static xml_schema::date_time fromDateTime(const KDateTime &dt)
+ {
+ const QDate &d = dt.date();
+ const QTime &t = dt.time();
+ xml_schema::date_time date(d.year(), d.month(), d.day(), t.hour(), t.minute(), t.second());
+ if (dt.timeType() == KDateTime::UTC) {
+ //Setting both zone hours/and zone minutes to zero results in a Z being appended to indicate UTC
+ date.zone_hours(0);
+ date.zone_minutes(0);
+ }
+ return date;
+ }
+
+ static xml_schema::date fromDate(const KDateTime &dt)
+ {
+ const QDate &d = dt.date();
+ xml_schema::date date(d.year(), d.month(), d.day());
+ return date;
+ }
static void setTimezone(Ptr date, const std::string &tzid)
{
@@ -45,7 +69,12 @@ template <> struct DateTimeConverter<KDateTime>
KDateTime::Spec spec(timezone);
date->setTimeSpec(spec);
}
-
+
+ static std::string getTimezone(const KDateTime &dt)
+ {
+ return dt.timeZone().name().toStdString();
+ }
+
static void setUTC(Ptr date)
{
if (date->timeSpec().type() != KDateTime::UTC) {
@@ -53,15 +82,21 @@ template <> struct DateTimeConverter<KDateTime>
date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
}
}
+
+ static bool isDateOnly(Type date)
+ {
+ return date.isDateOnly();
+ }
+
};
+
template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
{
-// using namespace icalendar_2_0;
-
- typedef typename KCalCore::RecurrenceRule Type;
- typedef typename std::auto_ptr<KCalCore::RecurrenceRule> Ptr;
-
+
+ typedef typename KCalCoreTypes::RecurrenceType Type;
+ typedef typename KCalCoreTypes::RecurrencePtr& Ptr; //Pass by reference, otherwise auto_ptr deletes the pointer after the first pass to a function (unlike shared_ptr)
+
static void setType(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
{
switch (freq) {
@@ -92,108 +127,135 @@ template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
}
}
- static void setUntil(Ptr r, KCalCoreTypes::DatePtr date )
+ static void setEndDt(Ptr r, KCalCoreTypes::DatePtr date )
{
r->setEndDt(*date);
}
-};
-
- //boost::shared_ptr would be safer but lacks the possiblity to release the pointer
-// typedef std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr;
+
+ static void setCount(Ptr r, int count )
+ {
+ r->setDuration(count);
+ }
+
+ static void setInterval(Ptr r, int interval )
+ {
+ r->setFrequency(interval);
+ }
- typename KCalCoreTypes::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
+};
+/*
+typename KCalCoreTypes::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
+{
+ typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
+ typedef typename KCalCoreTypes::DatePtr DatePtr;
+ typedef DateTimeConverter<typename KCalCoreTypes::DateType> DC;
+
+ RecurrencePtr r(new KCalCore::RecurrenceRule());
+ KCalCore::RecurrenceRule &d = *r;
+ using namespace icalendar_2_0;
+ switch (rrule.freq()) {
+ case FreqRecurType::YEARLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+ break;
+ case FreqRecurType::MONTHLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+ break;
+ case FreqRecurType::WEEKLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+ break;
+ case FreqRecurType::DAILY:
+ kDebug() << "daily";
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+ break;
+ case FreqRecurType::HOURLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+ break;
+ case FreqRecurType::MINUTELY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+ break;
+ case FreqRecurType::SECONDLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+ break;
+ default:
+ kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
+ }
+ if (rrule.until()) {
+ DatePtr date;
+ if ((*rrule.until()).date_time()) {
+ date = DC::toDate(*(*rrule.until()).date_time());
+ } else if ((*rrule.until()).date()) {
+ date = DC::toDate(*(*rrule.until()).date());
+ }
+ d.setEndDt(*date);
+ } else if (rrule.count()) {
+ Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+ d.setDuration(*rrule.count());
+ }
+
+ if (rrule.interval()) {
+ Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+ d.setFrequency(*rrule.interval());
+ } else {
+ d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+ }
{
- typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
-
- RecurrencePtr r(new KCalCore::RecurrenceRule());
- KCalCore::RecurrenceRule &d = *r;
- using namespace icalendar_2_0;
- switch (rrule.freq()) {
- case FreqRecurType::YEARLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+ QList<int> bysec;
+ for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
+ Q_ASSERT(*it <= std::numeric_limits<int>::max());
+ bysec.append(*it);
+ }
+ if (!bysec.isEmpty()) {
+ d.setBySeconds(bysec);
+ }
+ }
+ //TODO implement all the other by*** lists
+ if (rrule.wkst()) {
+ switch (*rrule.wkst()) {
+ case WeekdayRecurType::MO:
+ d.setWeekStart(1);
break;
- case FreqRecurType::MONTHLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+ case WeekdayRecurType::TU:
+ d.setWeekStart(2);
break;
- case FreqRecurType::WEEKLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+ case WeekdayRecurType::WE:
+ d.setWeekStart(3);
break;
- case FreqRecurType::DAILY:
- kDebug() << "daily";
- d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+ case WeekdayRecurType::TH:
+ d.setWeekStart(4);
break;
- case FreqRecurType::HOURLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+ case WeekdayRecurType::FR:
+ d.setWeekStart(5);
break;
- case FreqRecurType::MINUTELY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+ case WeekdayRecurType::SA:
+ d.setWeekStart(6);
break;
- case FreqRecurType::SECONDLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+ case WeekdayRecurType::SU:
+ d.setWeekStart(7);
break;
default:
- kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
- }
- if (rrule.until()) {
- DatePtr date;
- if ((*rrule.until()).date_time()) {
- date = toDate(*(*rrule.until()).date_time());
- } else if ((*rrule.until()).date()) {
- date = toDate(*(*rrule.until()).date());
- }
- d.setEndDt(*date);
- } else if (rrule.count()) {
- Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
- d.setDuration(*rrule.count());
- }
-
- if (rrule.interval()) {
- Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
- d.setFrequency(*rrule.interval());
- } else {
- d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+ kWarning() << "invalid unhandled weekday" << *rrule.wkst();
}
- {
- QList<int> bysec;
- for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
- Q_ASSERT(*it <= std::numeric_limits<int>::max());
- bysec.append(*it);
- }
- if (!bysec.isEmpty()) {
- d.setBySeconds(bysec);
- }
- }
- //TODO implement all the other by*** lists
- if (rrule.wkst()) {
- switch (*rrule.wkst()) {
- case WeekdayRecurType::MO:
- d.setWeekStart(1);
- break;
- case WeekdayRecurType::TU:
- d.setWeekStart(2);
- break;
- case WeekdayRecurType::WE:
- d.setWeekStart(3);
- break;
- case WeekdayRecurType::TH:
- d.setWeekStart(4);
- break;
- case WeekdayRecurType::FR:
- d.setWeekStart(5);
- break;
- case WeekdayRecurType::SA:
- d.setWeekStart(6);
- break;
- case WeekdayRecurType::SU:
- d.setWeekStart(7);
- break;
- default:
- kWarning() << "invalid unhandled weekday" << *rrule.wkst();
- }
- }
- return r;
}
+ return r;
+}*/
+
+
+QStringList toStringList(const icalendar_2_0::TextListPropertyType &s)
+{
+ QStringList d;
+ const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
+ for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
+ d.append(QString::fromStdString(*it));
+ }
+ return d;
+}
+QString toString(const icalendar_2_0::TextPropertyType &s)
+{
+ return QString::fromStdString(s.text());
}
+
+} //Namespace
+
#endif
\ No newline at end of file
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 09c6ae0..feb5e01 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -9,7 +9,6 @@
#include <kdebug.h>
#include <limits>
#include <kcalcore/recurrencerule.h>
-#include "conversions.h"
#include "kcalconversions.h"
namespace Kolab {
@@ -160,7 +159,7 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
KCalCore::Recurrence *recurrence = event.recurrence();
if (prop.rrule()) {
- RecurrencePtr rrule = toRRule(prop.rrule()->recur());
+ RecurrencePtr rrule = toRRule<KCalCoreTypes>(prop.rrule()->recur());
rrule->setStartDt(recurrence->startDateTime());
recurrence->addRRule(rrule.release());
}
@@ -179,13 +178,17 @@ std::string writeEvent(KCalCore::Event::Ptr event)
using namespace icalendar_2_0;
try {
+ typedef DateTimeConverter<KDateTime> DC;
+
KolabEvent::components_type eventComponents;
KolabEvent::properties_type::uid_type uid(event->uid().toStdString());//TODO thats possibly the kontact internal uid?
KolabEvent::properties_type::dtstamp_type dtstamp;
- dtstamp.date_time(fromDateTime(event->lastModified()));
+ kDebug() << "dtstamp";
+ dtstamp.date_time(DC::fromDateTime(event->lastModified()));
KolabEvent::properties_type::created_type created;
- created.date_time(fromDateTime(event->created()));
+ kDebug() << "created";
+ created.date_time(DC::fromDateTime(event->created()));
KolabEvent::properties_type eventProps(uid, created, dtstamp);
KolabEvent vevent(eventProps, eventComponents);
@@ -216,16 +219,23 @@ std::string writeEvent(KCalCore::Event::Ptr event)
}
}
-
void writeEvent(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
{
icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
prop.sequence(event.revision());
if (event.dtStart().isValid()) {
icalendar_2_0::properties::dtstart_type dtstart;
- setDateTimeProperty(dtstart, event.dtStart());
+ setDateTimeProperty<KCalCoreTypes>(dtstart, event.dtStart());
prop.dtstart(dtstart);
}
+
+ if (event.dtEnd().isValid()) {
+ icalendar_2_0::properties::dtend_type dtend;
+ setDateTimeProperty<KCalCoreTypes>(dtend, event.dtStart());
+ prop.dtend(dtend);
+ } else if (event.duration() != KCalCore::Duration()) {
+
+ }
}
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 7701cf9..b999f27 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -18,7 +18,6 @@
#include <lib/kolabformat.h>
#include <kdebug.h>
-
void BindingsTest::writeNoteTest()
{
xml_schema::date_time datetime(2011, 11, 23, 12, 12, 12);
@@ -380,7 +379,16 @@ void BindingsTest::readEvent()
kDebug() << event->description();
}
-
+void BindingsTest::writeEvent()
+{
+ KCalCore::Event::Ptr event(new KCalCore::Event);
+ event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+ event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+
+ kDebug() << "-------------------";
+ kDebug() << QString::fromStdString(Kolab::writeEvent(event));
+ kDebug() << "-------------------";
+}
QTEST_MAIN( BindingsTest )
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index 4afef3e..520843b 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -25,6 +25,8 @@ class BindingsTest : public QObject
//Kolabformat
void readEvent();
+ void writeEvent();
+
};
#endif
\ No newline at end of file
commit 4dbfad98ce19fb5e2334e3158b93f9bb5009c96b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 16 21:05:54 2011 +0100
temp, moving kcal dependedn converters to own file (to avoid a qt/kde dependency)
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index ef8d680..542568d 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -5,11 +5,13 @@
#include <bindings/iCalendar-props.hxx>
#include <kdebug.h>
#include <boost/shared_ptr.hpp>
-#include "kolabcontainers.h"
+#include <kdatetime.h>
+// #include "kolabcontainers.h"
// #include "kolabcontainers.h"
namespace Kolab {
+
template <typename T> struct DateTimeConverter;
// template <> struct DateTimeConverter<DateTime>
@@ -33,53 +35,17 @@ template <typename T> struct DateTimeConverter;
// }
// };
-template <> struct DateTimeConverter<KDateTime>
-{
- typedef typename KDateTime Type;
- typedef typename boost::shared_ptr<KDateTime> Ptr;
- static Ptr toDate(const xml_schema::date &dt)
- {
- Ptr date(new KDateTime());
- date->setDateOnly(true);
- date->setDate(QDate(dt.year(), dt.month(), dt.day()));
- return date;
- }
-
- static Ptr toDate(const xml_schema::date_time &dt)
- {
- Ptr date(new KDateTime());
- date->setDate(QDate(dt.year(), dt.month(), dt.day()));
- date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
- if (dt.zone_present()) {
- date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
- }
- return date;
- }
- static void setTimezone(Ptr date, const std::string &tzid)
- {
- KTimeZone timezone(QString::fromStdString(tzid));
- KDateTime::Spec spec(timezone);
- date->setTimeSpec(spec);
- }
-
- static void setUTC(Ptr date)
- {
- if (date->timeSpec().type() != KDateTime::UTC) {
- kWarning() << "utc date wrong formatting, corrected to utc";
- date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
- }
- }
-};
-template <typename T> typename DateTimeConverter<T>::Ptr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+template <typename T> typename T::DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
{
- typename DateTimeConverter<T>::Ptr date;
+ typedef DateTimeConverter<typename T::DateType> DC;
+ typename T::DatePtr date;
if (dtProperty.date_time()) {
- date = DateTimeConverter<T>::toDate(*dtProperty.date_time());
+ date = DC::toDate(*dtProperty.date_time());
} else if (dtProperty.date()) {
- date = DateTimeConverter<T>::toDate(*dtProperty.date());
+ date = DC::toDate(*dtProperty.date());
}
if (dtProperty.parameters()) {
@@ -93,97 +59,63 @@ template <typename T> typename DateTimeConverter<T>::Ptr toDate(const icalendar_
// } else {
// kWarning() << "/kolab.org/ timezone prefix is missing";
// }
- DateTimeConverter<T>::setTimezone(date, tzid);
+ DC::setTimezone(date, tzid);
}
}
}
return date;
}
-template <typename T> typename DateTimeConverter<T>::Ptr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
+template <typename T> typename T::DatePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
{
- typename DateTimeConverter<T>::Ptr date;
+ typedef typename T::DateType DateType;
+ typedef typename T::DatePtr DatePtr;
+
+ typedef DateTimeConverter<DateType> DC;
+
+ typename T::DatePtr date;
if (dtProperty.date_time()) {
- date = DateTimeConverter<T>::toDate(*dtProperty.date_time());
+ date = DC::toDate(*dtProperty.date_time());
} else { //The utc-date-time element shouldn't even exist
- date = DateTimeConverter<T>::Ptr(new DateTimeConverter<T>::Type());
+ date = DatePtr(new DateType());
kWarning() << "This element shouldn't even be existing";
Q_ASSERT(0);
}
- DateTimeConverter<T>::setUTC(date);
+ DC::setUTC(date);
return date;
}
template <typename T> struct RecurrenceConverter;
-template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
-{
- typedef typename KCalCore::RecurrenceRule Type;
- typedef typename std::auto_ptr<KCalCore::RecurrenceRule> Ptr;
- static void setType(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
- {
- switch (freq) {
- case FreqRecurType::YEARLY:
- r->setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
- break;
- case FreqRecurType::MONTHLY:
- r->setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
- break;
- case FreqRecurType::WEEKLY:
- r->setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
- break;
- case FreqRecurType::DAILY:
- kDebug() << "daily";
- r->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
- break;
- case FreqRecurType::HOURLY:
- r->setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
- break;
- case FreqRecurType::MINUTELY:
- r->setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
- break;
- case FreqRecurType::SECONDLY:
- r->setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
- break;
- default:
- kWarning() << "invalid unhandled recurrenc type" << freq;
- }
- }
- static void setUntil(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
- {
- DatePtr date;
- if ((*rrule.until()).date_time()) {
- date = toDate(*(*rrule.until()).date_time());
- } else if ((*rrule.until()).date()) {
- date = toDate(*(*rrule.until()).date());
- }
- d.setEndDt(*date);
- }
-
-};
-
-
-template <typename T> typename RecurrenceConverter<T>::Ptr toRRule(const icalendar_2_0::RecurType &rrule)
+
+template <typename T> typename T::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
{
- RecurrenceConverter<T>::Ptr r(new RecurrenceConverter<T>::Type());
using namespace icalendar_2_0;
-
- RecurrenceConverter<T>::setType(r, rrule.freq());
+
+ typedef RecurrenceConverter< typename T::RecurrenceType> RC;
+ typedef DateTimeConverter< typename T::DateType> DC;
+ typedef typename T::DatePtr DatePtr;
+ typedef typename T::RecurrencePtr RecurrencePtr;
+ typedef typename T::RecurrenceType RecurrenceType;
+
+ RecurrencePtr r(new RecurrenceType);
+
+ RC::setType(r, rrule.freq());
if (rrule.until()) {
- RecurrenceConverter<T>::setUntil(r, *rrule.until());
- DateTimeConverter<KCalCore>::DateType date;
+ RC::setUntil(r, *rrule.until());
+ DatePtr date;
if ((*rrule.until()).date_time()) {
- date = toDate(*(*rrule.until()).date_time());
+ date = DC::toDate(*(*rrule.until()).date_time());
} else if ((*rrule.until()).date()) {
- date = toDate(*(*rrule.until()).date());
+ date = DC::toDate(*(*rrule.until()).date());
}
- d.setEndDt(*date);
+ RC::setEndDt(date);
} else if (rrule.count()) {
- RecurrenceConverter<T>::setCount(r, *rrule.count());
-
+ RC::setCount(r, *rrule.count());
+/*TODO
Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
- d.setDuration(*rrule.count());
+ d.setDuration(*rrule.count());*/
}
/*
if (rrule.interval()) {
@@ -291,99 +223,7 @@ template <typename T> typename RecurrenceConverter<T>::Ptr toRRule(const icalend
- //boost::shared_ptr would be safer but lacks the possiblity to release the pointer
- typedef std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr;
- RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
- {
- RecurrencePtr r(new KCalCore::RecurrenceRule());
- KCalCore::RecurrenceRule &d = *r;
- using namespace icalendar_2_0;
- switch (rrule.freq()) {
- case FreqRecurType::YEARLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
- break;
- case FreqRecurType::MONTHLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
- break;
- case FreqRecurType::WEEKLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
- break;
- case FreqRecurType::DAILY:
- kDebug() << "daily";
- d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
- break;
- case FreqRecurType::HOURLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
- break;
- case FreqRecurType::MINUTELY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
- break;
- case FreqRecurType::SECONDLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
- break;
- default:
- kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
- }
- if (rrule.until()) {
- DatePtr date;
- if ((*rrule.until()).date_time()) {
- date = toDate(*(*rrule.until()).date_time());
- } else if ((*rrule.until()).date()) {
- date = toDate(*(*rrule.until()).date());
- }
- d.setEndDt(*date);
- } else if (rrule.count()) {
- Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
- d.setDuration(*rrule.count());
- }
-
- if (rrule.interval()) {
- Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
- d.setFrequency(*rrule.interval());
- } else {
- d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
- }
- {
- QList<int> bysec;
- for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
- Q_ASSERT(*it <= std::numeric_limits<int>::max());
- bysec.append(*it);
- }
- if (!bysec.isEmpty()) {
- d.setBySeconds(bysec);
- }
- }
- //TODO implement all the other by*** lists
- if (rrule.wkst()) {
- switch (*rrule.wkst()) {
- case WeekdayRecurType::MO:
- d.setWeekStart(1);
- break;
- case WeekdayRecurType::TU:
- d.setWeekStart(2);
- break;
- case WeekdayRecurType::WE:
- d.setWeekStart(3);
- break;
- case WeekdayRecurType::TH:
- d.setWeekStart(4);
- break;
- case WeekdayRecurType::FR:
- d.setWeekStart(5);
- break;
- case WeekdayRecurType::SA:
- d.setWeekStart(6);
- break;
- case WeekdayRecurType::SU:
- d.setWeekStart(7);
- break;
- default:
- kWarning() << "invalid unhandled weekday" << *rrule.wkst();
- }
- }
- return r;
- }
// }
@@ -396,16 +236,6 @@ int toInt(const icalendar_2_0::IntegerPropertyType &prop)
}
-template <class T> struct ConversionTypeTraits {
- typedef typename T::ReturnType ReturnType;
- typedef typename T::ValueType ValueType;
-};
-
-template <> struct ConversionTypeTraits<xml_schema::date_time> {
- typedef xml_schema::date_time ReturnType ;
- typedef KDateTime ValueType;
-};
-
// template <class ValueType, class ReturnType> struct ConversionTraits {
// // typedef typename T::ReturnType ReturnType;
// // typedef typename T::ValueType ValueType;
@@ -420,123 +250,8 @@ template <> struct ConversionTypeTraits<xml_schema::date_time> {
// }
// };
-template <class T> struct ConversionTraits {
- typedef typename T::ReturnType ReturnType;
- typedef typename T::ValueType ValueType;
-//
- static ReturnType to(ValueType v)
- {
- return ReturnType(0,0,0,0);
- }
- static ValueType from(ReturnType v)
- {
- return v;
- }
-};
-
-
-template < typename T > struct Convert;
-
-template <> struct Convert< KDateTime > {
-
- static xml_schema::date_time to(KDateTime v)
- {
- return xml_schema::date_time(0,0,0,0);
- }
-
- static DatePtr from(xml_schema::date_time dt)
- {
- DatePtr date(new KDateTime());
- date->setDate(QDate(dt.year(), dt.month(), dt.day()));
- date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
- if (dt.zone_present()) {
- date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
- }
- return date;
- }
-};
-template <> struct Convert< xml_schema::date_time > {
- static xml_schema::date_time to(xml_schema::date_time v)
- {
- return xml_schema::date_time(0,0,0,0);
- }
-
- static xml_schema::date_time from(xml_schema::date_time v)
- {
- //return T(0,0,0,0);
- }
-
- static xml_schema::date_time convert(KDateTime)
- {
- //return T(0,0,0,0);
- }
-
-};
-
-template <> struct Convert< KCalCore::RecurrenceRule > {
-
- static void to(KCalCore::RecurrenceRule &rule, icalendar_2_0::RecurType rrule)
- {
- if (rrule.until()) {
- DatePtr date;
- if ((*rrule.until()).date_time()) {
- date = Convert< KDateTime >::from(*(*rrule.until()).date_time());
- } else if ((*rrule.until()).date()) {
-// date = toDate(*(*rrule.until()).date());
- }
- rule.setEndDt(*date);
- } else if (rrule.count()) {
- Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
- rule.setDuration(*rrule.count());
- }
- }
-
-
-};
-
-// template <> struct Container< KCalCore::RecurrenceRule > {
-//
-// typedef KDateTime DateType;
-// KCalCore::RecurrenceRule rule;
-// };
-//
-/*
-template < typename T > void setRecurrence(T &rule, icalendar_2_0::RecurType rrule)
-{
- if (rrule.until()) {
- Convert<T::DateType>::setUntil(rrule,
- DatePtr date;
- if ((*rrule.until()).date_time()) {
- date = Convert< KDateTime >::from(*(*rrule.until()).date_time());
- } else if ((*rrule.until()).date()) {
-// date = toDate(*(*rrule.until()).date());
- }
- rule.setEndDt(*date);
- } else if (rrule.count()) {
- Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
- rule.setDuration(*rrule.count());
- }
-
-}*/
-
-void test()
-{
- KDateTime kdt;
- xml_schema::date_time dt(0,0,0,0);
- dt = ConversionTraits< ConversionTypeTraits< xml_schema::date_time > >::to(kdt);
-
- dt = Convert< KDateTime >::to(kdt);
-}
-// template <class Container>
-// typename Container::Return con(Container &c) {
-// typename Container::Value
-// };
-//
-// template <typename Container>
-// template <xml_schema::date_time>
-// xml_schema::date_time fromDate(const KDateTime &dt)
xml_schema::date_time fromDateTime(const KDateTime &dt)
diff --git a/c++/lib/kcalconversions.h b/c++/lib/kcalconversions.h
new file mode 100644
index 0000000..82070ec
--- /dev/null
+++ b/c++/lib/kcalconversions.h
@@ -0,0 +1,199 @@
+#ifndef KOLAB_KCALCONVERSIONS_H
+#define KOLAB_KCALCONVERSIONS_H
+
+#include "conversions.h"
+
+namespace Kolab {
+
+struct KCalCoreTypes
+{
+ typedef KDateTime DateType;
+ typedef typename boost::shared_ptr<KDateTime> DatePtr;
+ typedef typename KCalCore::RecurrenceRule RecurrenceType;
+ typedef typename std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr;
+};
+
+typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
+
+
+template <> struct DateTimeConverter<KDateTime>
+{
+ typedef KDateTime Type;
+ typedef typename boost::shared_ptr<KDateTime> Ptr;
+ static Ptr toDate(const xml_schema::date &dt)
+ {
+ Ptr date(new KDateTime());
+ date->setDateOnly(true);
+ date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+ return date;
+ }
+
+ static Ptr toDate(const xml_schema::date_time &dt)
+ {
+ Ptr date(new KDateTime());
+ date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+ date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
+ if (dt.zone_present()) {
+ date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+ }
+ return date;
+ }
+
+ static void setTimezone(Ptr date, const std::string &tzid)
+ {
+ KTimeZone timezone(QString::fromStdString(tzid));
+ KDateTime::Spec spec(timezone);
+ date->setTimeSpec(spec);
+ }
+
+ static void setUTC(Ptr date)
+ {
+ if (date->timeSpec().type() != KDateTime::UTC) {
+ kWarning() << "utc date wrong formatting, corrected to utc";
+ date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+ }
+ }
+};
+
+template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
+{
+// using namespace icalendar_2_0;
+
+ typedef typename KCalCore::RecurrenceRule Type;
+ typedef typename std::auto_ptr<KCalCore::RecurrenceRule> Ptr;
+
+ static void setType(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
+ {
+ switch (freq) {
+ case icalendar_2_0::FreqRecurType::YEARLY:
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+ break;
+ case icalendar_2_0::FreqRecurType::MONTHLY:
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+ break;
+ case icalendar_2_0::FreqRecurType::WEEKLY:
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+ break;
+ case icalendar_2_0::FreqRecurType::DAILY:
+ kDebug() << "daily";
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+ break;
+ case icalendar_2_0::FreqRecurType::HOURLY:
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+ break;
+ case icalendar_2_0::FreqRecurType::MINUTELY:
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+ break;
+ case icalendar_2_0::FreqRecurType::SECONDLY:
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+ break;
+ default:
+ kWarning() << "invalid unhandled recurrenc type" << freq;
+ }
+ }
+
+ static void setUntil(Ptr r, KCalCoreTypes::DatePtr date )
+ {
+ r->setEndDt(*date);
+ }
+};
+
+ //boost::shared_ptr would be safer but lacks the possiblity to release the pointer
+// typedef std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr;
+
+ typename KCalCoreTypes::RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
+ {
+ typedef typename KCalCoreTypes::RecurrencePtr RecurrencePtr;
+
+ RecurrencePtr r(new KCalCore::RecurrenceRule());
+ KCalCore::RecurrenceRule &d = *r;
+ using namespace icalendar_2_0;
+ switch (rrule.freq()) {
+ case FreqRecurType::YEARLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+ break;
+ case FreqRecurType::MONTHLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+ break;
+ case FreqRecurType::WEEKLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+ break;
+ case FreqRecurType::DAILY:
+ kDebug() << "daily";
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+ break;
+ case FreqRecurType::HOURLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+ break;
+ case FreqRecurType::MINUTELY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+ break;
+ case FreqRecurType::SECONDLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+ break;
+ default:
+ kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
+ }
+ if (rrule.until()) {
+ DatePtr date;
+ if ((*rrule.until()).date_time()) {
+ date = toDate(*(*rrule.until()).date_time());
+ } else if ((*rrule.until()).date()) {
+ date = toDate(*(*rrule.until()).date());
+ }
+ d.setEndDt(*date);
+ } else if (rrule.count()) {
+ Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+ d.setDuration(*rrule.count());
+ }
+
+ if (rrule.interval()) {
+ Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+ d.setFrequency(*rrule.interval());
+ } else {
+ d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+ }
+ {
+ QList<int> bysec;
+ for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
+ Q_ASSERT(*it <= std::numeric_limits<int>::max());
+ bysec.append(*it);
+ }
+ if (!bysec.isEmpty()) {
+ d.setBySeconds(bysec);
+ }
+ }
+ //TODO implement all the other by*** lists
+ if (rrule.wkst()) {
+ switch (*rrule.wkst()) {
+ case WeekdayRecurType::MO:
+ d.setWeekStart(1);
+ break;
+ case WeekdayRecurType::TU:
+ d.setWeekStart(2);
+ break;
+ case WeekdayRecurType::WE:
+ d.setWeekStart(3);
+ break;
+ case WeekdayRecurType::TH:
+ d.setWeekStart(4);
+ break;
+ case WeekdayRecurType::FR:
+ d.setWeekStart(5);
+ break;
+ case WeekdayRecurType::SA:
+ d.setWeekStart(6);
+ break;
+ case WeekdayRecurType::SU:
+ d.setWeekStart(7);
+ break;
+ default:
+ kWarning() << "invalid unhandled weekday" << *rrule.wkst();
+ }
+ }
+ return r;
+ }
+
+}
+
+#endif
\ No newline at end of file
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 233fec5..09c6ae0 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -10,6 +10,7 @@
#include <limits>
#include <kcalcore/recurrencerule.h>
#include "conversions.h"
+#include "kcalconversions.h"
namespace Kolab {
@@ -108,104 +109,22 @@ KCalCore::Event::Ptr readEvent(const std::string& s)
return KCalCore::Event::Ptr();
}
-template <class T, class P> struct Properties {
-// typedef typename T::ReturnType ReturnType;
-// typedef typename T::ValueType ValueType;
-//
- static void set(T &object, P &value)
- {
-
- }
-
-};
-
-template <> struct Properties < KCalCore::Event, icalendar_2_0::properties::uid_type > {
- static void set(KCalCore::Event &object, icalendar_2_0::properties::uid_type &uid)
- {
- object.setUid(toString(uid));
- }
-
-};
-
-template < typename P > struct PropertySetter
-{
- template < typename T >
- static void set( T t, P p ) {
- set(t, p);
- }
-};
-template < typename P > struct PropertySetter< P* >
-{
- template < typename T >
- static void set( T t, P *p ) {
- if (p) {
- set(t, *p);
- }
- }
-};
-
-// template< typename T >
-// struct is_pointer< T* >{
-// static const bool value = true;
-// };
-
-template< typename T >
-struct is_optional{
- static const bool value = false;
-};
-
-template< typename T >
-struct is_optional< T* > {
- static const bool value = true;
-};
-
-template< bool b >
-struct algorithm_selector {
- template< typename T, typename P >
- static void set( T& object, P &property )
- {
-
- }
-};
-
-template<>
-struct algorithm_selector< true > {
- template< typename T, typename P >
- static void set( T& object, P *property ) {
- if (property) {
-
- }
- }
-};
-
-template <typename T>
-void readEvent(T &event, const icalendar_2_0::KolabEvent &vevent)
-{
- const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
- Properties<T, icalendar_2_0::properties::uid_type>::set(event, prop.uid());
-
-
- algorithm_selector< is_optional< icalendar_2_0::properties::uid_type >::value >::set(event, prop.uid());
- PropertySetter<icalendar_2_0::properties::uid_type>::set<T>(event, prop.uid());
- PropertySetter<icalendar_2_0::properties::uid_type>::set<T>(event, prop.uid());
-
-}
void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
{
const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
event.setUid(toString(prop.uid()));
- event.setCreated(*toDate(prop.created()));
- event.setLastModified(*toDate(prop.dtstamp()));
+ event.setCreated(*toDate<KCalCoreTypes>(prop.created()));
+ event.setLastModified(*toDate<KCalCoreTypes>(prop.dtstamp()));
if (prop.sequence()) {
event.setRevision(toInt(*prop.sequence()));
}
if (prop.dtstart()) {
- const DatePtr date = toDate<KDateTime>(*prop.dtstart());
+ const KCalCoreTypes::DatePtr date = toDate<KCalCoreTypes>(*prop.dtstart());
event.setDtStart(*date);
event.setAllDay(date->isDateOnly()); //TODO add to specification that allday depends on start date format
}
@@ -213,7 +132,7 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
if (prop.dtend()) {
KDateTime date;
kDebug() << "dtend";
- event.setDtEnd(*toDate(*prop.dtend()));
+ event.setDtEnd(*toDate<KCalCoreTypes>(*prop.dtend()));
if (event.dtEnd().timeType() != event.dtStart().timeType()) {
kWarning() << "dtEnd has wrong timespec";
}
commit cbd39249827c5c42e75d0d88f606735c1509dac4
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 16 17:48:21 2011 +0100
first approach with templates
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index cd27c5b..ef8d680 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -5,6 +5,7 @@
#include <bindings/iCalendar-props.hxx>
#include <kdebug.h>
#include <boost/shared_ptr.hpp>
+#include "kolabcontainers.h"
// #include "kolabcontainers.h"
namespace Kolab {
@@ -34,6 +35,7 @@ template <typename T> struct DateTimeConverter;
template <> struct DateTimeConverter<KDateTime>
{
+ typedef typename KDateTime Type;
typedef typename boost::shared_ptr<KDateTime> Ptr;
static Ptr toDate(const xml_schema::date &dt)
{
@@ -53,13 +55,21 @@ template <> struct DateTimeConverter<KDateTime>
}
return date;
}
-
- static void setTimezone(Ptr date, const std::string &tzid )
+
+ static void setTimezone(Ptr date, const std::string &tzid)
{
KTimeZone timezone(QString::fromStdString(tzid));
KDateTime::Spec spec(timezone);
date->setTimeSpec(spec);
}
+
+ static void setUTC(Ptr date)
+ {
+ if (date->timeSpec().type() != KDateTime::UTC) {
+ kWarning() << "utc date wrong formatting, corrected to utc";
+ date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+ }
+ }
};
@@ -90,6 +100,146 @@ template <typename T> typename DateTimeConverter<T>::Ptr toDate(const icalendar_
return date;
}
+template <typename T> typename DateTimeConverter<T>::Ptr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
+{
+ typename DateTimeConverter<T>::Ptr date;
+ if (dtProperty.date_time()) {
+ date = DateTimeConverter<T>::toDate(*dtProperty.date_time());
+ } else { //The utc-date-time element shouldn't even exist
+ date = DateTimeConverter<T>::Ptr(new DateTimeConverter<T>::Type());
+ kWarning() << "This element shouldn't even be existing";
+ Q_ASSERT(0);
+ }
+ DateTimeConverter<T>::setUTC(date);
+ return date;
+}
+
+template <typename T> struct RecurrenceConverter;
+
+template <> struct RecurrenceConverter < KCalCore::RecurrenceRule >
+{
+ typedef typename KCalCore::RecurrenceRule Type;
+ typedef typename std::auto_ptr<KCalCore::RecurrenceRule> Ptr;
+ static void setType(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
+ {
+ switch (freq) {
+ case FreqRecurType::YEARLY:
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+ break;
+ case FreqRecurType::MONTHLY:
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+ break;
+ case FreqRecurType::WEEKLY:
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+ break;
+ case FreqRecurType::DAILY:
+ kDebug() << "daily";
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+ break;
+ case FreqRecurType::HOURLY:
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+ break;
+ case FreqRecurType::MINUTELY:
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+ break;
+ case FreqRecurType::SECONDLY:
+ r->setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+ break;
+ default:
+ kWarning() << "invalid unhandled recurrenc type" << freq;
+ }
+ }
+ static void setUntil(Ptr r, const icalendar_2_0::RecurType::freq_type &freq)
+ {
+ DatePtr date;
+ if ((*rrule.until()).date_time()) {
+ date = toDate(*(*rrule.until()).date_time());
+ } else if ((*rrule.until()).date()) {
+ date = toDate(*(*rrule.until()).date());
+ }
+ d.setEndDt(*date);
+ }
+
+
+};
+
+
+template <typename T> typename RecurrenceConverter<T>::Ptr toRRule(const icalendar_2_0::RecurType &rrule)
+{
+ RecurrenceConverter<T>::Ptr r(new RecurrenceConverter<T>::Type());
+ using namespace icalendar_2_0;
+
+ RecurrenceConverter<T>::setType(r, rrule.freq());
+ if (rrule.until()) {
+ RecurrenceConverter<T>::setUntil(r, *rrule.until());
+ DateTimeConverter<KCalCore>::DateType date;
+ if ((*rrule.until()).date_time()) {
+ date = toDate(*(*rrule.until()).date_time());
+ } else if ((*rrule.until()).date()) {
+ date = toDate(*(*rrule.until()).date());
+ }
+ d.setEndDt(*date);
+ } else if (rrule.count()) {
+ RecurrenceConverter<T>::setCount(r, *rrule.count());
+
+ Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+ d.setDuration(*rrule.count());
+ }
+ /*
+ if (rrule.interval()) {
+ Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+ d.setFrequency(*rrule.interval());
+ } else {
+ d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+ }
+ {
+ QList<int> bysec;
+ for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
+ Q_ASSERT(*it <= std::numeric_limits<int>::max());
+ bysec.append(*it);
+ }
+ if (!bysec.isEmpty()) {
+ d.setBySeconds(bysec);
+ }
+ }
+ //TODO implement all the other by*** lists
+ if (rrule.wkst()) {
+ switch (*rrule.wkst()) {
+ case WeekdayRecurType::MO:
+ d.setWeekStart(1);
+ break;
+ case WeekdayRecurType::TU:
+ d.setWeekStart(2);
+ break;
+ case WeekdayRecurType::WE:
+ d.setWeekStart(3);
+ break;
+ case WeekdayRecurType::TH:
+ d.setWeekStart(4);
+ break;
+ case WeekdayRecurType::FR:
+ d.setWeekStart(5);
+ break;
+ case WeekdayRecurType::SA:
+ d.setWeekStart(6);
+ break;
+ case WeekdayRecurType::SU:
+ d.setWeekStart(7);
+ break;
+ default:
+ kWarning() << "invalid unhandled weekday" << *rrule.wkst();
+ }
+ }*/
+ return r;
+ }
+
+
+
+
+
+
+
+
// namespace KCalCore {
typedef boost::shared_ptr<KDateTime> DatePtr;
@@ -135,54 +285,10 @@ template <typename T> typename DateTimeConverter<T>::Ptr toDate(const icalendar_
return date;
}
- DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
- {
- DatePtr date;
- if (dtProperty.date_time()) {
-
- date = DateTimeConverter<KDateTime>::toDate(*dtProperty.date_time());//toDate(*dtProperty.date_time());
- } else if (dtProperty.date()) {
- date = DateTimeConverter<KDateTime>::toDate(*dtProperty.date());//toDate(*dtProperty.date());
- kDebug() << "date";
- }
-
- if (dtProperty.parameters()) {
- for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
- if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
- QString tzid(toString(tz->text()));
- if (tzid.contains("/kolab.org/")) {
- tzid.remove("/kolab.org/");
- } else {
- kWarning() << "/kolab.org/ timezone prefix is missing";
- }
- KTimeZone timezone(tzid);
- KDateTime::Spec spec(timezone);
- date->setTimeSpec(spec);
- // kDebug() << tzid;
- }
- // kDebug() << "---------------_";
- }
- }
- return date;
- }
- DatePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
- {
- DatePtr date;
- if (dtProperty.date_time()) {
- date = toDate(*dtProperty.date_time());
- } else { //The utc-date-time element shouldn't even exist
- date = DatePtr(new KDateTime());
- kWarning() << "This element shouldn't even be existing";
- Q_ASSERT(0);
- }
- if (date->timeSpec().type() != KDateTime::UTC) {
- kWarning() << "utc date wrong formatting, corrected to utc";
- date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
- }
- return date;
- }
+
+
//boost::shared_ptr would be safer but lacks the possiblity to release the pointer
commit 08800b1f848ad50f33171e87b75046e7d93d31fc
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Fri Dec 16 17:12:25 2011 +0100
temp
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
index dcff7b3..cd27c5b 100644
--- a/c++/lib/conversions.h
+++ b/c++/lib/conversions.h
@@ -4,200 +4,485 @@
#include "kolabformat.h"
#include <bindings/iCalendar-props.hxx>
#include <kdebug.h>
+#include <boost/shared_ptr.hpp>
+// #include "kolabcontainers.h"
namespace Kolab {
+
+template <typename T> struct DateTimeConverter;
+
+// template <> struct DateTimeConverter<DateTime>
+// {
+// typedef typename boost::shared_ptr<DateTime> Ptr;
+// Ptr toDate(const xml_schema::date &dt)
+// {
+// Ptr date(new DateTime());
+//
+// return date;
+// }
+// Ptr toDate(const xml_schema::date_time &dt)
+// {
+// Ptr date(new DateTime());
+// return date;
+// }
+//
+// void setTimezone(Ptr date, const std::string &tzid )
+// {
+// date->setTimezone(tzid);
+// }
+// };
-typedef std::auto_ptr<KDateTime> DatePtr;
-
-QString toString(const xml_schema::string &s)
-{
- return QString::fromStdString(s);
-}
-
-QString toString(const icalendar_2_0::TextPropertyType &s)
-{
- return toString(s.text());
-}
-
-DatePtr toDate(const xml_schema::date &dt)
-{
- DatePtr date(new KDateTime());
- date->setDateOnly(true);
- date->setDate(QDate(dt.year(), dt.month(), dt.day()));
- return date;
-}
-
-DatePtr toDate(const xml_schema::date_time &dt)
-{
- DatePtr date(new KDateTime());
-// kDebug() << dt.year() << dt. month() << dt.day() << dt.hours();
- date->setDate(QDate(dt.year(), dt.month(), dt.day()));
- date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
- if (dt.zone_present()) {
- date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
- }
-// kDebug() << date->date() << *date << dt.zone_present();
- return date;
-}
-
-QStringList toStringList(const icalendar_2_0::TextListPropertyType &s)
+template <> struct DateTimeConverter<KDateTime>
{
- QStringList d;
- const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
- for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
- d.append(QString::fromStdString(*it));
+ typedef typename boost::shared_ptr<KDateTime> Ptr;
+ static Ptr toDate(const xml_schema::date &dt)
+ {
+ Ptr date(new KDateTime());
+ date->setDateOnly(true);
+ date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+ return date;
}
- return d;
-}
-
-int toInt(const icalendar_2_0::IntegerPropertyType &prop)
-{
- Q_ASSERT(prop.integer() <= std::numeric_limits<int>::max());
- int i = prop.integer();
- return i;
-}
-
-DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+
+ static Ptr toDate(const xml_schema::date_time &dt)
+ {
+ Ptr date(new KDateTime());
+ date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+ date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
+ if (dt.zone_present()) {
+ date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+ }
+ return date;
+ }
+
+ static void setTimezone(Ptr date, const std::string &tzid )
+ {
+ KTimeZone timezone(QString::fromStdString(tzid));
+ KDateTime::Spec spec(timezone);
+ date->setTimeSpec(spec);
+ }
+};
+
+
+template <typename T> typename DateTimeConverter<T>::Ptr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
{
- DatePtr date;
+ typename DateTimeConverter<T>::Ptr date;
if (dtProperty.date_time()) {
- date = toDate(*dtProperty.date_time());
+ date = DateTimeConverter<T>::toDate(*dtProperty.date_time());
} else if (dtProperty.date()) {
- date = toDate(*dtProperty.date());
- kDebug() << "date";
+ date = DateTimeConverter<T>::toDate(*dtProperty.date());
}
if (dtProperty.parameters()) {
for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
- QString tzid(toString(tz->text()));
- if (tzid.contains("/kolab.org/")) {
- tzid.remove("/kolab.org/");
- } else {
- kWarning() << "/kolab.org/ timezone prefix is missing";
- }
- KTimeZone timezone(tzid);
- KDateTime::Spec spec(timezone);
- date->setTimeSpec(spec);
-// kDebug() << tzid;
+ std::string tzid = tz->text();
+ //TODO
+// QString tzid(toString());
+// if (tzid.contains("/kolab.org/")) {
+// tzid.remove("/kolab.org/");
+// } else {
+// kWarning() << "/kolab.org/ timezone prefix is missing";
+// }
+ DateTimeConverter<T>::setTimezone(date, tzid);
}
-// kDebug() << "---------------_";
}
}
return date;
}
-DatePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
-{
- DatePtr date;
- if (dtProperty.date_time()) {
- date = toDate(*dtProperty.date_time());
- } else { //The utc-date-time element shouldn't even exist
- date = DatePtr(new KDateTime());
- kWarning() << "This element shouldn't even be existing";
- Q_ASSERT(0);
+// namespace KCalCore {
+
+ typedef boost::shared_ptr<KDateTime> DatePtr;
+
+ QString toString(const xml_schema::string &s)
+ {
+ return QString::fromStdString(s);
}
- if (date->timeSpec().type() != KDateTime::UTC) {
- kWarning() << "utc date wrong formatting, corrected to utc";
- date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+
+ QString toString(const icalendar_2_0::TextPropertyType &s)
+ {
+ return toString(s.text());
}
- return date;
-}
+ QStringList toStringList(const icalendar_2_0::TextListPropertyType &s)
+ {
+ QStringList d;
+ const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
+ for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
+ d.append(QString::fromStdString(*it));
+ }
+ return d;
+ }
+
+ DatePtr toDate(const xml_schema::date &dt)
+ {
+ DatePtr date(new KDateTime());
+ date->setDateOnly(true);
+ date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+ return date;
+ }
-void toRRule(KCalCore::RecurrenceRule &d, const icalendar_2_0::RecurType &rrule)
-{
- using namespace icalendar_2_0;
- switch (rrule.freq()) {
- case FreqRecurType::YEARLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
- break;
- case FreqRecurType::MONTHLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
- break;
- case FreqRecurType::WEEKLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
- break;
- case FreqRecurType::DAILY:
- kDebug() << "daily";
- d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
- break;
- case FreqRecurType::HOURLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
- break;
- case FreqRecurType::MINUTELY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
- break;
- case FreqRecurType::SECONDLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
- break;
- default:
- kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
+ DatePtr toDate(const xml_schema::date_time &dt)
+ {
+ DatePtr date(new KDateTime());
+ // kDebug() << dt.year() << dt. month() << dt.day() << dt.hours();
+ date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+ date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
+ if (dt.zone_present()) {
+ date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+ }
+ // kDebug() << date->date() << *date << dt.zone_present();
+ return date;
}
- if (rrule.until()) {
+
+ DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+ {
DatePtr date;
- if ((*rrule.until()).date_time()) {
- date = toDate(*(*rrule.until()).date_time());
- } else if ((*rrule.until()).date()) {
- date = toDate(*(*rrule.until()).date());
+ if (dtProperty.date_time()) {
+
+ date = DateTimeConverter<KDateTime>::toDate(*dtProperty.date_time());//toDate(*dtProperty.date_time());
+ } else if (dtProperty.date()) {
+ date = DateTimeConverter<KDateTime>::toDate(*dtProperty.date());//toDate(*dtProperty.date());
+ kDebug() << "date";
}
- d.setEndDt(*date);
- } else if (rrule.count()) {
- Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
- d.setDuration(*rrule.count());
- }
-
- if (rrule.interval()) {
- Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
- d.setFrequency(*rrule.interval());
- } else {
- d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+
+ if (dtProperty.parameters()) {
+ for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
+ if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
+ QString tzid(toString(tz->text()));
+ if (tzid.contains("/kolab.org/")) {
+ tzid.remove("/kolab.org/");
+ } else {
+ kWarning() << "/kolab.org/ timezone prefix is missing";
+ }
+ KTimeZone timezone(tzid);
+ KDateTime::Spec spec(timezone);
+ date->setTimeSpec(spec);
+ // kDebug() << tzid;
+ }
+ // kDebug() << "---------------_";
+ }
+ }
+ return date;
}
+
+
+ DatePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
{
- QList<int> bysec;
- for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
- Q_ASSERT(*it <= std::numeric_limits<int>::max());
- bysec.append(*it);
+ DatePtr date;
+ if (dtProperty.date_time()) {
+ date = toDate(*dtProperty.date_time());
+ } else { //The utc-date-time element shouldn't even exist
+ date = DatePtr(new KDateTime());
+ kWarning() << "This element shouldn't even be existing";
+ Q_ASSERT(0);
}
- if (!bysec.isEmpty()) {
- d.setBySeconds(bysec);
+ if (date->timeSpec().type() != KDateTime::UTC) {
+ kWarning() << "utc date wrong formatting, corrected to utc";
+ date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
}
+ return date;
}
- //TODO implement all the other by*** lists
- if (rrule.wkst()) {
- switch (*rrule.wkst()) {
- case WeekdayRecurType::MO:
- d.setWeekStart(1);
+
+
+ //boost::shared_ptr would be safer but lacks the possiblity to release the pointer
+ typedef std::auto_ptr<KCalCore::RecurrenceRule> RecurrencePtr;
+
+ RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
+ {
+ RecurrencePtr r(new KCalCore::RecurrenceRule());
+ KCalCore::RecurrenceRule &d = *r;
+ using namespace icalendar_2_0;
+ switch (rrule.freq()) {
+ case FreqRecurType::YEARLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
break;
- case WeekdayRecurType::TU:
- d.setWeekStart(2);
+ case FreqRecurType::MONTHLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
break;
- case WeekdayRecurType::WE:
- d.setWeekStart(3);
+ case FreqRecurType::WEEKLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
break;
- case WeekdayRecurType::TH:
- d.setWeekStart(4);
+ case FreqRecurType::DAILY:
+ kDebug() << "daily";
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
break;
- case WeekdayRecurType::FR:
- d.setWeekStart(5);
+ case FreqRecurType::HOURLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
break;
- case WeekdayRecurType::SA:
- d.setWeekStart(6);
+ case FreqRecurType::MINUTELY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
break;
- case WeekdayRecurType::SU:
- d.setWeekStart(7);
+ case FreqRecurType::SECONDLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
break;
default:
- kWarning() << "invalid unhandled weekday" << *rrule.wkst();
+ kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
+ }
+ if (rrule.until()) {
+ DatePtr date;
+ if ((*rrule.until()).date_time()) {
+ date = toDate(*(*rrule.until()).date_time());
+ } else if ((*rrule.until()).date()) {
+ date = toDate(*(*rrule.until()).date());
+ }
+ d.setEndDt(*date);
+ } else if (rrule.count()) {
+ Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+ d.setDuration(*rrule.count());
+ }
+
+ if (rrule.interval()) {
+ Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+ d.setFrequency(*rrule.interval());
+ } else {
+ d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+ }
+ {
+ QList<int> bysec;
+ for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
+ Q_ASSERT(*it <= std::numeric_limits<int>::max());
+ bysec.append(*it);
+ }
+ if (!bysec.isEmpty()) {
+ d.setBySeconds(bysec);
+ }
+ }
+ //TODO implement all the other by*** lists
+ if (rrule.wkst()) {
+ switch (*rrule.wkst()) {
+ case WeekdayRecurType::MO:
+ d.setWeekStart(1);
+ break;
+ case WeekdayRecurType::TU:
+ d.setWeekStart(2);
+ break;
+ case WeekdayRecurType::WE:
+ d.setWeekStart(3);
+ break;
+ case WeekdayRecurType::TH:
+ d.setWeekStart(4);
+ break;
+ case WeekdayRecurType::FR:
+ d.setWeekStart(5);
+ break;
+ case WeekdayRecurType::SA:
+ d.setWeekStart(6);
+ break;
+ case WeekdayRecurType::SU:
+ d.setWeekStart(7);
+ break;
+ default:
+ kWarning() << "invalid unhandled weekday" << *rrule.wkst();
+ }
}
+ return r;
}
+// }
+
+
+
+int toInt(const icalendar_2_0::IntegerPropertyType &prop)
+{
+ Q_ASSERT(prop.integer() <= std::numeric_limits<int>::max());
+ int i = prop.integer();
+ return i;
}
-void toRRule(KCalCore::RecurrenceRule &d, const icalendar_2_0::RrulePropType &rrule)
+
+template <class T> struct ConversionTypeTraits {
+ typedef typename T::ReturnType ReturnType;
+ typedef typename T::ValueType ValueType;
+};
+
+template <> struct ConversionTypeTraits<xml_schema::date_time> {
+ typedef xml_schema::date_time ReturnType ;
+ typedef KDateTime ValueType;
+};
+
+// template <class ValueType, class ReturnType> struct ConversionTraits {
+// // typedef typename T::ReturnType ReturnType;
+// // typedef typename T::ValueType ValueType;
+// //
+// static ReturnType to(ValueType v)
+// {
+// return v;
+// }
+// static ValueType from(ReturnType v)
+// {
+// return v;
+// }
+// };
+
+template <class T> struct ConversionTraits {
+ typedef typename T::ReturnType ReturnType;
+ typedef typename T::ValueType ValueType;
+//
+ static ReturnType to(ValueType v)
+ {
+ return ReturnType(0,0,0,0);
+ }
+ static ValueType from(ReturnType v)
+ {
+ return v;
+ }
+};
+
+
+template < typename T > struct Convert;
+
+template <> struct Convert< KDateTime > {
+
+ static xml_schema::date_time to(KDateTime v)
+ {
+ return xml_schema::date_time(0,0,0,0);
+ }
+
+ static DatePtr from(xml_schema::date_time dt)
+ {
+ DatePtr date(new KDateTime());
+ date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+ date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
+ if (dt.zone_present()) {
+ date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+ }
+ return date;
+ }
+};
+
+template <> struct Convert< xml_schema::date_time > {
+
+ static xml_schema::date_time to(xml_schema::date_time v)
+ {
+ return xml_schema::date_time(0,0,0,0);
+ }
+
+ static xml_schema::date_time from(xml_schema::date_time v)
+ {
+ //return T(0,0,0,0);
+ }
+
+ static xml_schema::date_time convert(KDateTime)
+ {
+ //return T(0,0,0,0);
+ }
+
+};
+
+template <> struct Convert< KCalCore::RecurrenceRule > {
+
+ static void to(KCalCore::RecurrenceRule &rule, icalendar_2_0::RecurType rrule)
+ {
+ if (rrule.until()) {
+ DatePtr date;
+ if ((*rrule.until()).date_time()) {
+ date = Convert< KDateTime >::from(*(*rrule.until()).date_time());
+ } else if ((*rrule.until()).date()) {
+// date = toDate(*(*rrule.until()).date());
+ }
+ rule.setEndDt(*date);
+ } else if (rrule.count()) {
+ Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+ rule.setDuration(*rrule.count());
+ }
+ }
+
+
+};
+
+// template <> struct Container< KCalCore::RecurrenceRule > {
+//
+// typedef KDateTime DateType;
+// KCalCore::RecurrenceRule rule;
+// };
+//
+/*
+template < typename T > void setRecurrence(T &rule, icalendar_2_0::RecurType rrule)
+{
+ if (rrule.until()) {
+ Convert<T::DateType>::setUntil(rrule,
+ DatePtr date;
+ if ((*rrule.until()).date_time()) {
+ date = Convert< KDateTime >::from(*(*rrule.until()).date_time());
+ } else if ((*rrule.until()).date()) {
+// date = toDate(*(*rrule.until()).date());
+ }
+ rule.setEndDt(*date);
+ } else if (rrule.count()) {
+ Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+ rule.setDuration(*rrule.count());
+ }
+
+}*/
+
+void test()
+{
+ KDateTime kdt;
+ xml_schema::date_time dt(0,0,0,0);
+ dt = ConversionTraits< ConversionTypeTraits< xml_schema::date_time > >::to(kdt);
+
+ dt = Convert< KDateTime >::to(kdt);
+}
+// template <class Container>
+// typename Container::Return con(Container &c) {
+// typename Container::Value
+// };
+//
+// template <typename Container>
+// template <xml_schema::date_time>
+// xml_schema::date_time fromDate(const KDateTime &dt)
+
+
+xml_schema::date_time fromDateTime(const KDateTime &dt)
+{
+ const QDate &d = dt.date();
+ const QTime &t = dt.time();
+ xml_schema::date_time date(d.year(), d.month(), d.day(), t.hour(), t.minute(), t.second());
+// date.zone_reset();
+ //TODO timezone
+ return date;
+}
+
+xml_schema::date fromDate(const KDateTime &dt)
+{
+ const QDate &d = dt.date();
+ xml_schema::date date(d.year(), d.month(), d.day());
+ return date;
+}
+
+
+std::auto_ptr<icalendar_2_0::DateDatetimePropertyType> fromDateProperty(const KDateTime &dt)
+{
+ std::auto_ptr<icalendar_2_0::DateDatetimePropertyType> date(new ::icalendar_2_0::DateDatetimePropertyType);
+ if (dt.isDateOnly()) {
+ date->date(fromDate(dt)); //setDateOnly
+ } else {
+ date->date_time(fromDateTime(dt)); //setDateTime
+ }
+ //TODO add timezone information //setTimeZone
+ return date;
+}
+
+void setDateTimeProperty(icalendar_2_0::DateDatetimePropertyType &date, const KDateTime &dt)
{
- toRRule(d, rrule.recur());
+ if (dt.isDateOnly()) {
+ date.date(fromDate(dt));
+ } else {
+ date.date_time(fromDateTime(dt));
+ }
+ //TODO add timezone information
}
+/*
+xml_schema::date fromDate(const KDateTime &dt)
+{
+ const QDate &d = dt.date();
+ xml_schema::date date(d.year(), d.month(), d.day());
+ return date;
+}*/
+
+
+
}
#endif
\ No newline at end of file
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
new file mode 100644
index 0000000..639789c
--- /dev/null
+++ b/c++/lib/kolabcontainers.h
@@ -0,0 +1,115 @@
+#ifndef KOLAB_CONTAINERS_H
+#define KOLAB_CONTAINERS_H
+#include <string>
+#include <vector>
+
+namespace Kolab {
+
+ /**
+ * Datatypes:
+ * -String
+ * -DateTime
+ * -
+ *
+ */
+
+ class DateTime {
+ void setDate(int year, int month, int day);
+ int year();
+ int month();
+ int day();
+
+ bool isDateOnly();
+
+ void setTime(int hour, int minute, int second);
+ int hour();
+ int minute();
+ int second();
+
+ void setUTC(bool);
+ void setTimezone(const std::string &);
+ std::string getTimezone();
+ };
+
+ /**
+
+ */
+
+ class Event {
+ public:
+ void setUid(const std::string &);
+ std::string uid() const;
+
+ void setCreated(const DateTime &);
+ DateTime created() const;
+
+ void setLastModified(const DateTime &);
+ DateTime lastModified() const;
+
+ void setSequence(int);
+ int sequence() const;
+
+ void setClassification(int); //TODO enum?
+ int classification() const;
+
+ void setCategories(const std::vector<std::string> &);
+ void addCategory(const std::string &);
+ std::vector<std::string> categories() const;
+
+ void setStart(const DateTime &);
+ DateTime start() const;
+
+ void setEnd(const DateTime &);
+ DateTime end() const;
+
+ void setDuration();
+ duration() const;
+
+ void setTransparency(bool isTransparent);
+ bool transparency() const;
+
+ void setRecurrenceRule(const RecurrenceRule &);
+ RecurrenceRule recurrenceRule() const;
+
+ void setRecrrenceDates(const std::vector<DateTime> &);
+ std::vector<DateTime> recurrenceDates() const;
+
+ void setExceptionDates(const std::vector<DateTime> &);
+ std::vector<DateTime> exceptionDates() const;
+
+ void setRecurrenceID(const std::string &);
+ std::string recurrenceID() const;
+
+ void setSummary(const std::string &);
+ std::string summary() const;
+
+ void setDescription(const std::string &);
+ std::string description() const;
+
+ void setPriority(int);
+ int priority() const;
+
+ void setStatus(int); //TODO map to string
+ int status() const;
+
+ void setLocation(const std::string &);
+ std::string location() const;
+
+ void setOrganizer(const std::string email &, const std::string name &);
+ std::string organizerEmail() const;
+ std::string organizerName() const;
+
+ void setAttendee(const std::vector<Attendee> &);
+ std::vector<Attendee> attendee() const;
+
+ void setAttachment(const std::vector<Attachment> &);
+ std::vector<Attachment> attachments() const;
+
+ void setCustomProperty(const std::vector<CustomProperty> &);
+ std::vector<CustomProperty> customProperties() const;
+ };
+
+
+}
+
+#endif
\ No newline at end of file
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 47305b7..233fec5 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -82,13 +82,12 @@ KCalCore::Event::Ptr readEvent(const std::string& s)
//TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
xml_schema::properties props;
props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../../schemas/ical/kolabformat-xcal.xsd"); //Force schema
-
- std::auto_ptr<icalendar_2_0::IcalendarType> icalendar(icalendar_2_0::icalendar(s/*, xml_schema::flags::dont_validate*/,0,props));
+
+ std::auto_ptr<icalendar_2_0::IcalendarType> icalendar(icalendar_2_0::icalendar(s/*, xml_schema::flags::dont_validate*/, 0, props));
const icalendar_2_0::VcalendarType &vcalendar = icalendar->vcalendar();
-
+
QList <KCalCore::Event::Ptr> events;
-
-
+
for (icalendar_2_0::VcalendarType::components_type::vevent_const_iterator it(vcalendar.components().vevent().begin()); it != vcalendar.components().vevent().end(); it++) {
KCalCore::Event::Ptr e = KCalCore::Event::Ptr(new KCalCore::Event());
const icalendar_2_0::KolabEvent &event = *it;
@@ -109,6 +108,90 @@ KCalCore::Event::Ptr readEvent(const std::string& s)
return KCalCore::Event::Ptr();
}
+template <class T, class P> struct Properties {
+// typedef typename T::ReturnType ReturnType;
+// typedef typename T::ValueType ValueType;
+//
+ static void set(T &object, P &value)
+ {
+
+ }
+
+};
+
+template <> struct Properties < KCalCore::Event, icalendar_2_0::properties::uid_type > {
+ static void set(KCalCore::Event &object, icalendar_2_0::properties::uid_type &uid)
+ {
+ object.setUid(toString(uid));
+ }
+
+};
+
+template < typename P > struct PropertySetter
+{
+ template < typename T >
+ static void set( T t, P p ) {
+ set(t, p);
+ }
+};
+
+template < typename P > struct PropertySetter< P* >
+{
+ template < typename T >
+ static void set( T t, P *p ) {
+ if (p) {
+ set(t, *p);
+ }
+ }
+};
+
+// template< typename T >
+// struct is_pointer< T* >{
+// static const bool value = true;
+// };
+
+template< typename T >
+struct is_optional{
+ static const bool value = false;
+};
+
+template< typename T >
+struct is_optional< T* > {
+ static const bool value = true;
+};
+
+template< bool b >
+struct algorithm_selector {
+ template< typename T, typename P >
+ static void set( T& object, P &property )
+ {
+
+ }
+};
+
+template<>
+struct algorithm_selector< true > {
+ template< typename T, typename P >
+ static void set( T& object, P *property ) {
+ if (property) {
+
+ }
+ }
+};
+
+template <typename T>
+void readEvent(T &event, const icalendar_2_0::KolabEvent &vevent)
+{
+ const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+ Properties<T, icalendar_2_0::properties::uid_type>::set(event, prop.uid());
+
+
+ algorithm_selector< is_optional< icalendar_2_0::properties::uid_type >::value >::set(event, prop.uid());
+ PropertySetter<icalendar_2_0::properties::uid_type>::set<T>(event, prop.uid());
+ PropertySetter<icalendar_2_0::properties::uid_type>::set<T>(event, prop.uid());
+
+}
+
void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
{
const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
@@ -122,7 +205,7 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
}
if (prop.dtstart()) {
- const DatePtr date = toDate(*prop.dtstart());
+ const DatePtr date = toDate<KDateTime>(*prop.dtstart());
event.setDtStart(*date);
event.setAllDay(date->isDateOnly()); //TODO add to specification that allday depends on start date format
}
@@ -158,10 +241,9 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
KCalCore::Recurrence *recurrence = event.recurrence();
if (prop.rrule()) {
- KCalCore::RecurrenceRule *rrule = new KCalCore::RecurrenceRule();
+ RecurrencePtr rrule = toRRule(prop.rrule()->recur());
rrule->setStartDt(recurrence->startDateTime());
- toRRule(*rrule, *prop.rrule());
- recurrence->addRRule(rrule);
+ recurrence->addRRule(rrule.release());
}
if (prop.summary()) {
@@ -182,11 +264,13 @@ std::string writeEvent(KCalCore::Event::Ptr event)
KolabEvent::properties_type::uid_type uid(event->uid().toStdString());//TODO thats possibly the kontact internal uid?
KolabEvent::properties_type::dtstamp_type dtstamp;
-// dtstamp.date_time(event->lastModified());
+ dtstamp.date_time(fromDateTime(event->lastModified()));
KolabEvent::properties_type::created_type created;
+ created.date_time(fromDateTime(event->created()));
KolabEvent::properties_type eventProps(uid, created, dtstamp);
KolabEvent vevent(eventProps, eventComponents);
+ writeEvent(vevent, *event);
VcalendarType::components_type components;
components.vevent().push_back(vevent);
@@ -214,9 +298,15 @@ std::string writeEvent(KCalCore::Event::Ptr event)
}
-void writeEvent(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event& )
+void writeEvent(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event &event)
{
-
+ icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+ prop.sequence(event.revision());
+ if (event.dtStart().isValid()) {
+ icalendar_2_0::properties::dtstart_type dtstart;
+ setDateTimeProperty(dtstart, event.dtStart());
+ prop.dtstart(dtstart);
+ }
}
commit b8001543be7cda76067460921d603a8e8ed24f8a
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Thu Dec 15 15:32:46 2011 +0100
conversions in separate file, no more usage of << operator, use of auto_ptr instead for non copyable types
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index 1049024..c109067 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -7,7 +7,7 @@
# VERBATIM
# )
-set(KOLAB_SWIG_SOURCE_FILES kolabformat.cpp)
+set(KOLAB_SWIG_SOURCE_FILES kolabformat.cpp conversions.h)
set(KOLAB_SWIG_PYTHON_SOURCE_FILE python_kolabformat_wrapper.cpp)
add_custom_command(OUTPUT ${KOLAB_SWIG_PYTHON_SOURCE_FILE}
diff --git a/c++/lib/conversions.h b/c++/lib/conversions.h
new file mode 100644
index 0000000..dcff7b3
--- /dev/null
+++ b/c++/lib/conversions.h
@@ -0,0 +1,203 @@
+#ifndef KOLAB_CONVERSIONS_H
+#define KOLAB_CONVERSIONS_H
+
+#include "kolabformat.h"
+#include <bindings/iCalendar-props.hxx>
+#include <kdebug.h>
+
+namespace Kolab {
+
+typedef std::auto_ptr<KDateTime> DatePtr;
+
+QString toString(const xml_schema::string &s)
+{
+ return QString::fromStdString(s);
+}
+
+QString toString(const icalendar_2_0::TextPropertyType &s)
+{
+ return toString(s.text());
+}
+
+DatePtr toDate(const xml_schema::date &dt)
+{
+ DatePtr date(new KDateTime());
+ date->setDateOnly(true);
+ date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+ return date;
+}
+
+DatePtr toDate(const xml_schema::date_time &dt)
+{
+ DatePtr date(new KDateTime());
+// kDebug() << dt.year() << dt. month() << dt.day() << dt.hours();
+ date->setDate(QDate(dt.year(), dt.month(), dt.day()));
+ date->setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
+ if (dt.zone_present()) {
+ date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+ }
+// kDebug() << date->date() << *date << dt.zone_present();
+ return date;
+}
+
+QStringList toStringList(const icalendar_2_0::TextListPropertyType &s)
+{
+ QStringList d;
+ const icalendar_2_0::TextListPropertyType::text_sequence &list = s.text();
+ for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = list.begin(); it != list.end(); it++) {
+ d.append(QString::fromStdString(*it));
+ }
+ return d;
+}
+
+int toInt(const icalendar_2_0::IntegerPropertyType &prop)
+{
+ Q_ASSERT(prop.integer() <= std::numeric_limits<int>::max());
+ int i = prop.integer();
+ return i;
+}
+
+DatePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+{
+ DatePtr date;
+ if (dtProperty.date_time()) {
+ date = toDate(*dtProperty.date_time());
+ } else if (dtProperty.date()) {
+ date = toDate(*dtProperty.date());
+ kDebug() << "date";
+ }
+
+ if (dtProperty.parameters()) {
+ for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
+ if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
+ QString tzid(toString(tz->text()));
+ if (tzid.contains("/kolab.org/")) {
+ tzid.remove("/kolab.org/");
+ } else {
+ kWarning() << "/kolab.org/ timezone prefix is missing";
+ }
+ KTimeZone timezone(tzid);
+ KDateTime::Spec spec(timezone);
+ date->setTimeSpec(spec);
+// kDebug() << tzid;
+ }
+// kDebug() << "---------------_";
+ }
+ }
+ return date;
+}
+
+DatePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
+{
+ DatePtr date;
+ if (dtProperty.date_time()) {
+ date = toDate(*dtProperty.date_time());
+ } else { //The utc-date-time element shouldn't even exist
+ date = DatePtr(new KDateTime());
+ kWarning() << "This element shouldn't even be existing";
+ Q_ASSERT(0);
+ }
+ if (date->timeSpec().type() != KDateTime::UTC) {
+ kWarning() << "utc date wrong formatting, corrected to utc";
+ date->setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+ }
+ return date;
+}
+
+
+void toRRule(KCalCore::RecurrenceRule &d, const icalendar_2_0::RecurType &rrule)
+{
+ using namespace icalendar_2_0;
+ switch (rrule.freq()) {
+ case FreqRecurType::YEARLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+ break;
+ case FreqRecurType::MONTHLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+ break;
+ case FreqRecurType::WEEKLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+ break;
+ case FreqRecurType::DAILY:
+ kDebug() << "daily";
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+ break;
+ case FreqRecurType::HOURLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+ break;
+ case FreqRecurType::MINUTELY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+ break;
+ case FreqRecurType::SECONDLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+ break;
+ default:
+ kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
+ }
+ if (rrule.until()) {
+ DatePtr date;
+ if ((*rrule.until()).date_time()) {
+ date = toDate(*(*rrule.until()).date_time());
+ } else if ((*rrule.until()).date()) {
+ date = toDate(*(*rrule.until()).date());
+ }
+ d.setEndDt(*date);
+ } else if (rrule.count()) {
+ Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+ d.setDuration(*rrule.count());
+ }
+
+ if (rrule.interval()) {
+ Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+ d.setFrequency(*rrule.interval());
+ } else {
+ d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+ }
+ {
+ QList<int> bysec;
+ for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
+ Q_ASSERT(*it <= std::numeric_limits<int>::max());
+ bysec.append(*it);
+ }
+ if (!bysec.isEmpty()) {
+ d.setBySeconds(bysec);
+ }
+ }
+ //TODO implement all the other by*** lists
+ if (rrule.wkst()) {
+ switch (*rrule.wkst()) {
+ case WeekdayRecurType::MO:
+ d.setWeekStart(1);
+ break;
+ case WeekdayRecurType::TU:
+ d.setWeekStart(2);
+ break;
+ case WeekdayRecurType::WE:
+ d.setWeekStart(3);
+ break;
+ case WeekdayRecurType::TH:
+ d.setWeekStart(4);
+ break;
+ case WeekdayRecurType::FR:
+ d.setWeekStart(5);
+ break;
+ case WeekdayRecurType::SA:
+ d.setWeekStart(6);
+ break;
+ case WeekdayRecurType::SU:
+ d.setWeekStart(7);
+ break;
+ default:
+ kWarning() << "invalid unhandled weekday" << *rrule.wkst();
+ }
+ }
+}
+
+void toRRule(KCalCore::RecurrenceRule &d, const icalendar_2_0::RrulePropType &rrule)
+{
+ toRRule(d, rrule.recur());
+}
+
+}
+
+#endif
\ No newline at end of file
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index d466f7a..47305b7 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -9,6 +9,7 @@
#include <kdebug.h>
#include <limits>
#include <kcalcore/recurrencerule.h>
+#include "conversions.h"
namespace Kolab {
@@ -18,225 +19,6 @@ namespace Kolab {
// return d;
// }; //conversion operator
-Date &operator <<(Date &d, const xml_schema::date &dt)
-{
- d.year = dt.year();
- return d;
-}
-
-// Date &operator =(Date &d, const xml_schema::date &dt)
-// {
-// d.year = dt.year();
-// return d;
-// }
-
-//Event & operator<<(const MyClass &rhs);
-Date &operator <<(Date &d, const icalendar_2_0::DateDatetimePropertyType &dtProperty)
-{
- if (dtProperty.date_time()) {
- const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(dtProperty.date_time());
- //datetime.day()
-// (*(d->date_time()))
- } else if (dtProperty.date()) {
- const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(dtProperty.date());
-// e.date = date;
- d.year = date.year();
-// const KDateTime dt(QDateTime(QDate(date.year(), date.month(), date.day()), QTime()));
-// // dt.setTimeSpec(spec);
-// event.setDtStart(dt);
- }
- return d;
-}
-
-
-KDateTime &operator <<(KDateTime &d, const xml_schema::date &dt)
-{
- d.setDateOnly(true);
- d.setDate(QDate(dt.year(), dt.month(), dt.day()));
- return d;
-}
-
-KDateTime &operator <<(KDateTime &d, const xml_schema::date_time &dt)
-{
- kDebug() << dt.year() << dt. month() << dt.day() << dt.hours();
- d.setDate(QDate(dt.year(), dt.month(), dt.day()));
- d.setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
- if (dt.zone_present()) {
- d.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
- }
- kDebug() << d.date() << d << dt.zone_present();
- return d;
-}
-
-QString &operator <<(QString &d, const xml_schema::string &s)
-{
- d.append(QString::fromStdString(s) );
- return d;
-}
-
-QStringList &operator <<(QStringList &d, const ::xsd::cxx::tree::sequence< xml_schema::string >&s)
-{
- for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = s.begin(); it != s.end(); it++) {
- d.append(QString::fromStdString(*it));
- }
- return d;
-}
-
-int &operator <<(int &i, const icalendar_2_0::IntegerPropertyType &prop) {
- Q_ASSERT(prop.integer() <= std::numeric_limits<int>::max());
- i = prop.integer();
-}
-
-KDateTime &operator <<(KDateTime &d, const icalendar_2_0::DateDatetimePropertyType &dtProperty)
-{
- if (dtProperty.date_time()) {
- d << *dtProperty.date_time();
- kDebug() << "date_time";
- } else if (dtProperty.date()) {
- d << *dtProperty.date();
- kDebug() << "date";
- }
-
- if (dtProperty.parameters()) {
- for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
- if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
- QString tzid;
- tzid << tz->text();
- if (tzid.contains("/kolab.org/")) {
- tzid.remove("/kolab.org/");
- } else {
- kWarning() << "/kolab.org/ timezone prefix is missing";
- }
- KTimeZone timezone(tzid);
- KDateTime::Spec spec(timezone);
- d.setTimeSpec(spec);
-// kDebug() << tzid;
- }
-// kDebug() << "---------------_";
- }
- }
- return d;
-}
-
-KDateTime &operator <<(KDateTime &d, const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
-{
- if (dtProperty.date_time()) {
- d << *dtProperty.date_time();
- } else { //The utc-date-time element shouldn't even exist
- kWarning() << "This element shouldn't even be existing";
- Q_ASSERT(0);
- }
- if (d.timeSpec().type() != KDateTime::UTC) {
- kWarning() << "utc date wrong formatting, corrected to utc";
- d.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
- }
- return d;
-}
-
-QStringList &operator <<(QStringList &d, const icalendar_2_0::TextListPropertyType &s)
-{
- return d << s.text();
-}
-
-QString &operator <<(QString &d, const icalendar_2_0::TextPropertyType &s)
-{
- return d << s.text();
-}
-
-
-KCalCore::RecurrenceRule &operator <<(KCalCore::RecurrenceRule &d, const icalendar_2_0::RecurType &rrule)
-{
- using namespace icalendar_2_0;
- switch (rrule.freq()) {
- case FreqRecurType::YEARLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
- break;
- case FreqRecurType::MONTHLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
- break;
- case FreqRecurType::WEEKLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
- break;
- case FreqRecurType::DAILY:
- kDebug() << "daily";
- d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
- break;
- case FreqRecurType::HOURLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
- break;
- case FreqRecurType::MINUTELY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
- break;
- case FreqRecurType::SECONDLY:
- d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
- break;
- default:
- kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
- }
- if (rrule.until()) {
- KDateTime date;
- if ((*rrule.until()).date_time()) {
- date << *(*rrule.until()).date_time();
- } else if ((*rrule.until()).date()) {
- date << *(*rrule.until()).date();
- }
- d.setEndDt(date);
- } else if (rrule.count()) {
- Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
- d.setDuration(*rrule.count());
- }
-
- if (rrule.interval()) {
- Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
- d.setFrequency(*rrule.interval());
- } else {
- d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
- }
- {
- QList<int> bysec;
- for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
- Q_ASSERT(*it <= std::numeric_limits<int>::max());
- bysec.append(*it);
- }
- if (!bysec.isEmpty()) {
- d.setBySeconds(bysec);
- }
- }
- //TODO implement all the other by*** lists
- if (rrule.wkst()) {
- switch (*rrule.wkst()) {
- case WeekdayRecurType::MO:
- d.setWeekStart(1);
- break;
- case WeekdayRecurType::TU:
- d.setWeekStart(2);
- break;
- case WeekdayRecurType::WE:
- d.setWeekStart(3);
- break;
- case WeekdayRecurType::TH:
- d.setWeekStart(4);
- break;
- case WeekdayRecurType::FR:
- d.setWeekStart(5);
- break;
- case WeekdayRecurType::SA:
- d.setWeekStart(6);
- break;
- case WeekdayRecurType::SU:
- d.setWeekStart(7);
- break;
- default:
- kWarning() << "invalid unhandled weekday" << *rrule.wkst();
- }
- }
- return d;
-}
-
-KCalCore::RecurrenceRule &operator <<(KCalCore::RecurrenceRule &d, const icalendar_2_0::RrulePropType &rrule)
-{
- return d << rrule.recur();
-}
// bool isAvailable(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
// {
@@ -329,37 +111,26 @@ KCalCore::Event::Ptr readEvent(const std::string& s)
void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
{
-
const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
- {
- QString string;
- event.setUid(string << prop.uid());
- }
- {
- KDateTime date;
- event.setCreated(date << prop.created());
- }
- kDebug() << "last mod";
- {
- KDateTime date;
- event.setLastModified(date << prop.dtstamp());
- }
+
+ event.setUid(toString(prop.uid()));
+ event.setCreated(*toDate(prop.created()));
+ event.setLastModified(*toDate(prop.dtstamp()));
+
if (prop.sequence()) {
- int i;
- event.setRevision(i << *prop.sequence());
+ event.setRevision(toInt(*prop.sequence()));
}
-
+
if (prop.dtstart()) {
- KDateTime date;
- kDebug() << "dtstart";
- event.setDtStart(date << *prop.dtstart());
- event.setAllDay(date.isDateOnly()); //TODO add to specification that allday depends on start date format
+ const DatePtr date = toDate(*prop.dtstart());
+ event.setDtStart(*date);
+ event.setAllDay(date->isDateOnly()); //TODO add to specification that allday depends on start date format
}
-
+
if (prop.dtend()) {
KDateTime date;
kDebug() << "dtend";
- event.setDtEnd(date << *prop.dtend());
+ event.setDtEnd(*toDate(*prop.dtend()));
if (event.dtEnd().timeType() != event.dtStart().timeType()) {
kWarning() << "dtEnd has wrong timespec";
}
@@ -370,12 +141,10 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
//TODO check for equality of timespecs
if (prop.categories()) {
- QStringList list;
- event.setCategories(list << *prop.categories());
+ event.setCategories(toStringList(*prop.categories()));
}
if (prop.class_()) {
- QString string;
- string << *prop.class_();
+ QString string(toString(*prop.class_()));
KCalCore::Incidence::Secrecy sec;
if (string == "PRIVATE") {
sec = KCalCore::Incidence::SecrecyPrivate;
@@ -389,30 +158,21 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
KCalCore::Recurrence *recurrence = event.recurrence();
if (prop.rrule()) {
- KCalCore::RecurrenceRule* rrule = new KCalCore::RecurrenceRule();
- rrule->setStartDt(recurrence->startDateTime()); //TODO shouldn't this happen as part of addRRule?
- *rrule << *prop.rrule();
+ KCalCore::RecurrenceRule *rrule = new KCalCore::RecurrenceRule();
+ rrule->setStartDt(recurrence->startDateTime());
+ toRRule(*rrule, *prop.rrule());
recurrence->addRRule(rrule);
}
if (prop.summary()) {
- QString string;
- string << *prop.summary();
- event.setSummary(string); //TODO detect richtext and set flag accordingly
+ event.setSummary(toString(*prop.summary())); //TODO detect richtext and set flag accordingly
}
-
+
if (prop.description()) {
- QString string;
- string << *prop.description();
- event.setDescription(string); //TODO detect richtext and set flag accordingly
+ event.setDescription(toString(*prop.description())); //TODO detect richtext and set flag accordingly
}
}
-std::string &operator <<(std::string &d, const QString &s)
-{
- return d = s.toStdString();
-}
-
std::string writeEvent(KCalCore::Event::Ptr event)
{
using namespace icalendar_2_0;
commit 48ec06505893ca38e3c19b40c2c2d3deae65d3cd
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Thu Dec 15 14:17:14 2011 +0100
write event started
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 02170f0..d466f7a 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -408,6 +408,58 @@ void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
}
}
+std::string &operator <<(std::string &d, const QString &s)
+{
+ return d = s.toStdString();
+}
+
+std::string writeEvent(KCalCore::Event::Ptr event)
+{
+ using namespace icalendar_2_0;
+ try {
+
+ KolabEvent::components_type eventComponents;
+
+ KolabEvent::properties_type::uid_type uid(event->uid().toStdString());//TODO thats possibly the kontact internal uid?
+ KolabEvent::properties_type::dtstamp_type dtstamp;
+// dtstamp.date_time(event->lastModified());
+ KolabEvent::properties_type::created_type created;
+ KolabEvent::properties_type eventProps(uid, created, dtstamp);
+
+ KolabEvent vevent(eventProps, eventComponents);
+
+ VcalendarType::components_type components;
+ components.vevent().push_back(vevent);
+
+ VcalendarType::properties_type::prodid_type prodid(std::string("libakonadi")); //TODO take from caller plus add libakonadi
+ VcalendarType::properties_type::version_type version(std::string("2.0")); //TODO define globally
+ VcalendarType::properties_type::x_kolab_version_type x_kolab_version(std::string("2.9.0")); //TODO define globally
+
+ VcalendarType::properties_type properties(prodid, version, x_kolab_version);
+
+ VcalendarType vcalendar(properties, components);
+
+ IcalendarType icalendar(vcalendar);
+
+ xml_schema::namespace_infomap map;
+ map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
+// map[""].schema = "note.xsd";
+
+ std::ostringstream ostringstream;
+ icalendar_2_0::icalendar(ostringstream, icalendar, map);
+ return ostringstream.str();
+ } catch (const xml_schema::exception& e) {
+ return std::string();
+ }
+}
+
+
+void writeEvent(icalendar_2_0::KolabEvent& vevent, const KCalCore::Event& )
+{
+
+}
+
+
void Test::test()
{
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index fa940f2..e5e70a0 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -51,6 +51,10 @@ std::string serializeEvent();
// void readEvent(Kolab::Event &,const icalendar_2_0::VeventType &vevent);
void readEvent(KCalCore::Event &,const icalendar_2_0::KolabEvent &vevent);
KCalCore::Event::Ptr readEvent(const std::string& s);
+
+void writeEvent(icalendar_2_0::KolabEvent &vevent, const KCalCore::Event &);
+std::string writeEvent(KCalCore::Event::Ptr);
+
void readICalendar(const std::string &s);
//QString serializeEvent(const KCalCore::Event ¬e);
diff --git a/c++/tests/testfiles/icalEvent.xml b/c++/tests/testfiles/icalEvent.xml
index 7cb8685..8f6d8c7 100644
--- a/c++/tests/testfiles/icalEvent.xml
+++ b/c++/tests/testfiles/icalEvent.xml
@@ -10,7 +10,7 @@
<text>2.0</text>
</version>
<x-kolab-version > <!--xmlns="http://kolab.org"-->
- <version>3.0dev1</version>
+ <text>3.0dev1</text>
</x-kolab-version>
</properties>
<components>
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index 519a279..37ba686 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -10,7 +10,7 @@
<xs:complexContent mixed="false">
<xs:extension base="BasePropertyType">
<xs:sequence>
- <xs:element name="version" minOccurs="0" maxOccurs="1" type="xs:string" default="3.0dev1"/>
+ <xs:element name="string" minOccurs="0" maxOccurs="1" type="xs:string" default="3.0dev1"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
@@ -89,7 +89,7 @@
<xs:sequence>
<xs:element name="prodid" type="ProdidPropType"/>
<xs:element name="version" type="VersionPropType"/>
- <xs:element name="x-kolab-version" type="KolabVersion"/>
+ <xs:element name="x-kolab-version" type="VersionPropType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
commit 17d1202bd30c5e9f8fef29fa38aec6db217f3cb1
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Wed Dec 14 17:30:20 2011 +0100
implemented by* recurrence types
diff --git a/schemas/ical/iCalendar-valtypes.xsd b/schemas/ical/iCalendar-valtypes.xsd
index d194837..b0ae12c 100644
--- a/schemas/ical/iCalendar-valtypes.xsd
+++ b/schemas/ical/iCalendar-valtypes.xsd
@@ -135,20 +135,20 @@
<xs:element ref="xcal:count" />
</xs:choice>
</xs:sequence>
- <xs:element name="interval" type="xs:string" minOccurs="0"/>
- <xs:element name="bysecond" type="xs:string"
+ <xs:element name="interval" type="xs:positiveInteger" minOccurs="0"/>
+ <xs:element name="bysecond" type="xcal:BysecondRecurType"
minOccurs="0" maxOccurs="unbounded" />
- <xs:element name="byminute" type="xs:string"
+ <xs:element name="byminute" type="xcal:ByminuteRecurType"
minOccurs="0" maxOccurs="unbounded" />
- <xs:element name="byhour" type="xs:string"
+ <xs:element name="byhour" type="xcal:ByhourRecurType"
minOccurs="0" maxOccurs="unbounded" />
- <xs:element name="byday" type="xs:string"
+ <xs:element name="byday" type="xcal:BydayRecurType"
minOccurs="0" maxOccurs="unbounded" />
- <xs:element name="byyearday" type="xs:string"
+ <xs:element name="byyearday" type="xcal:ByyeardayRecurType"
minOccurs="0" maxOccurs="unbounded" />
<xs:element name="bymonthday" type="xcal:BymonthdayRecurType"
minOccurs="0" maxOccurs="unbounded" />
- <xs:element name="byweekno" type="xs:string"
+ <xs:element name="byweekno" type="xcal:ByweeknoRecurType"
minOccurs="0" maxOccurs="unbounded" />
<xs:element name="bymonth" type="xcal:BymonthRecurType"
minOccurs="0" maxOccurs="unbounded" />
@@ -194,6 +194,48 @@
<xs:enumeration value="SA"/>
</xs:restriction>
</xs:simpleType>
+
+ <xs:simpleType name="BysecondRecurType">
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:maxInclusive value="60"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ByminuteRecurType">
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:maxInclusive value="59"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ByhourRecurType">
+ <xs:restriction base="xs:nonNegativeInteger">
+ <xs:maxInclusive value="23"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="BydayRecurType">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="((\-)?N)?(SU|MO|TU|WE|TH|FR|SA)"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- <xs:complexType name="BydayRecurType">
+ <xs:complexContent>
+ <xs:sequence>
+ <xs:element
+ <xs:element type="xs:integer" >
+ <xs:restriction base="xs:positiveInteger">
+ </xs:restriction>
+ </xs:sequence>
+ </xs:complexContent>
+ </xs:complexType>-->
+
+ <xs:simpleType name="ByyeardayRecurType">
+ <xs:restriction base="xs:integer">
+ <xs:minInclusive value="-366"/>
+ <xs:maxInclusive value="366"/>
+ </xs:restriction>
+ </xs:simpleType>
<xs:simpleType name="BymonthdayRecurType">
<xs:restriction base="xs:integer">
@@ -202,12 +244,20 @@
</xs:restriction>
</xs:simpleType>
+ <xs:simpleType name="ByweeknoRecurType">
+ <xs:restriction base="xs:integer">
+ <xs:minInclusive value="-53"/>
+ <xs:maxInclusive value="53"/>
+ </xs:restriction>
+ </xs:simpleType>
+
<xs:simpleType name="BymonthRecurType">
<xs:restriction base="xs:integer">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="12"/>
</xs:restriction>
</xs:simpleType>
+
<!-- 3.3.11 TEXT -->
<xs:element name="text" type="xs:string"/>
commit b67e051d5628dd03cb57eb09f8f724eb3ec69692
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Wed Dec 14 17:29:55 2011 +0100
Start of implementation according to new specification
diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 313939c..24bea1e 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -30,10 +30,10 @@ add_custom_command(OUTPUT ${KOLAB_SCHEMA_SOURCEFILES}
file(GLOB XCAL_SCHEMAS ${SCHEMA_DIR}/ical/*.xsd)
set( XCAL_SCHEMA_SOURCEFILES
bindings/xCard.cxx
- bindings/kolabformat.cxx
+# bindings/kolabformat.cxx
bindings/kolabformat-xcal.cxx
bindings/kolabformat-xcard.cxx
- bindings/iCalendar.cxx
+# bindings/iCalendar.cxx
bindings/iCalendar-params.cxx
bindings/iCalendar-props.cxx
bindings/iCalendar-valtypes.cxx
@@ -45,7 +45,7 @@ set( XCAL_SCHEMA_SOURCEFILES
)
# --cxx-suffix .cpp --hxx-suffix .h
add_custom_command(OUTPUT ${XCAL_SCHEMA_SOURCEFILES}
- COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element vevent --root-element todo --root-element contact --root-element vstricttodo --root-element icalendar --output-dir bindings ${XCAL_SCHEMAS}
+ COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element icalendar --output-dir bindings ${XCAL_SCHEMAS}
COMMENT "Generating xCal XSD bindings"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS ${XCAL_SCHEMAS}
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 71d77a4..02170f0 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -4,10 +4,11 @@
#include <kcalcore/event.h>
#include <iostream>
-#include <bindings/kolabformat.hxx>
+#include <bindings/kolabformat-xcal.hxx>
//#include "note.h"
#include <kdebug.h>
-#include "typeinfo"
+#include <limits>
+#include <kcalcore/recurrencerule.h>
namespace Kolab {
@@ -50,6 +51,7 @@ Date &operator <<(Date &d, const icalendar_2_0::DateDatetimePropertyType &dtPro
KDateTime &operator <<(KDateTime &d, const xml_schema::date &dt)
{
+ d.setDateOnly(true);
d.setDate(QDate(dt.year(), dt.month(), dt.day()));
return d;
}
@@ -59,17 +61,33 @@ KDateTime &operator <<(KDateTime &d, const xml_schema::date_time &dt)
kDebug() << dt.year() << dt. month() << dt.day() << dt.hours();
d.setDate(QDate(dt.year(), dt.month(), dt.day()));
d.setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
- kDebug() << d.date() << d;
+ if (dt.zone_present()) {
+ d.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+ }
+ kDebug() << d.date() << d << dt.zone_present();
return d;
}
-QString &operator <<(QString &d, const xml_schema::string &s)
+QString &operator <<(QString &d, const xml_schema::string &s)
{
d.append(QString::fromStdString(s) );
return d;
}
-KDateTime &operator <<(KDateTime &d, const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+QStringList &operator <<(QStringList &d, const ::xsd::cxx::tree::sequence< xml_schema::string >&s)
+{
+ for (::xsd::cxx::tree::sequence< xml_schema::string >::const_iterator it = s.begin(); it != s.end(); it++) {
+ d.append(QString::fromStdString(*it));
+ }
+ return d;
+}
+
+int &operator <<(int &i, const icalendar_2_0::IntegerPropertyType &prop) {
+ Q_ASSERT(prop.integer() <= std::numeric_limits<int>::max());
+ i = prop.integer();
+}
+
+KDateTime &operator <<(KDateTime &d, const icalendar_2_0::DateDatetimePropertyType &dtProperty)
{
if (dtProperty.date_time()) {
d << *dtProperty.date_time();
@@ -78,13 +96,17 @@ KDateTime &operator <<(KDateTime &d, const icalendar_2_0::DateDatetimePropertyT
d << *dtProperty.date();
kDebug() << "date";
}
+
if (dtProperty.parameters()) {
-
-
for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
QString tzid;
tzid << tz->text();
+ if (tzid.contains("/kolab.org/")) {
+ tzid.remove("/kolab.org/");
+ } else {
+ kWarning() << "/kolab.org/ timezone prefix is missing";
+ }
KTimeZone timezone(tzid);
KDateTime::Spec spec(timezone);
d.setTimeSpec(spec);
@@ -96,6 +118,135 @@ KDateTime &operator <<(KDateTime &d, const icalendar_2_0::DateDatetimePropertyT
return d;
}
+KDateTime &operator <<(KDateTime &d, const icalendar_2_0::UtcDatetimePropertyType &dtProperty)
+{
+ if (dtProperty.date_time()) {
+ d << *dtProperty.date_time();
+ } else { //The utc-date-time element shouldn't even exist
+ kWarning() << "This element shouldn't even be existing";
+ Q_ASSERT(0);
+ }
+ if (d.timeSpec().type() != KDateTime::UTC) {
+ kWarning() << "utc date wrong formatting, corrected to utc";
+ d.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
+ }
+ return d;
+}
+
+QStringList &operator <<(QStringList &d, const icalendar_2_0::TextListPropertyType &s)
+{
+ return d << s.text();
+}
+
+QString &operator <<(QString &d, const icalendar_2_0::TextPropertyType &s)
+{
+ return d << s.text();
+}
+
+
+KCalCore::RecurrenceRule &operator <<(KCalCore::RecurrenceRule &d, const icalendar_2_0::RecurType &rrule)
+{
+ using namespace icalendar_2_0;
+ switch (rrule.freq()) {
+ case FreqRecurType::YEARLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rYearly);
+ break;
+ case FreqRecurType::MONTHLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rMonthly);
+ break;
+ case FreqRecurType::WEEKLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rWeekly);
+ break;
+ case FreqRecurType::DAILY:
+ kDebug() << "daily";
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
+ break;
+ case FreqRecurType::HOURLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rHourly);
+ break;
+ case FreqRecurType::MINUTELY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rMinutely);
+ break;
+ case FreqRecurType::SECONDLY:
+ d.setRecurrenceType(KCalCore::RecurrenceRule::rSecondly);
+ break;
+ default:
+ kWarning() << "invalid unhandled recurrenc type" << rrule.freq();
+ }
+ if (rrule.until()) {
+ KDateTime date;
+ if ((*rrule.until()).date_time()) {
+ date << *(*rrule.until()).date_time();
+ } else if ((*rrule.until()).date()) {
+ date << *(*rrule.until()).date();
+ }
+ d.setEndDt(date);
+ } else if (rrule.count()) {
+ Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+ d.setDuration(*rrule.count());
+ }
+
+ if (rrule.interval()) {
+ Q_ASSERT(*rrule.interval() <= std::numeric_limits<int>::max());
+ d.setFrequency(*rrule.interval());
+ } else {
+ d.setFrequency(1); //FIXME should be initialized to 1 in RecurrenceRule class (default value of interval per RFC).
+ }
+ {
+ QList<int> bysec;
+ for (icalendar_2_0::RecurType::bysecond_const_iterator it(rrule.bysecond().begin()); it != rrule.bysecond().end(); it++) {
+ Q_ASSERT(*it <= std::numeric_limits<int>::max());
+ bysec.append(*it);
+ }
+ if (!bysec.isEmpty()) {
+ d.setBySeconds(bysec);
+ }
+ }
+ //TODO implement all the other by*** lists
+ if (rrule.wkst()) {
+ switch (*rrule.wkst()) {
+ case WeekdayRecurType::MO:
+ d.setWeekStart(1);
+ break;
+ case WeekdayRecurType::TU:
+ d.setWeekStart(2);
+ break;
+ case WeekdayRecurType::WE:
+ d.setWeekStart(3);
+ break;
+ case WeekdayRecurType::TH:
+ d.setWeekStart(4);
+ break;
+ case WeekdayRecurType::FR:
+ d.setWeekStart(5);
+ break;
+ case WeekdayRecurType::SA:
+ d.setWeekStart(6);
+ break;
+ case WeekdayRecurType::SU:
+ d.setWeekStart(7);
+ break;
+ default:
+ kWarning() << "invalid unhandled weekday" << *rrule.wkst();
+ }
+ }
+ return d;
+}
+
+KCalCore::RecurrenceRule &operator <<(KCalCore::RecurrenceRule &d, const icalendar_2_0::RrulePropType &rrule)
+{
+ return d << rrule.recur();
+}
+
+// bool isAvailable(const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+// {
+// if (dtProperty.date_time() || dtProperty.date()) {
+// return true;
+// }
+// return false;
+// }
+
+
std::string serializeEvent()
{
std::cout << "ksjdsldfj";
@@ -104,134 +255,157 @@ std::string serializeEvent()
void readICalendar(const std::string &s)
{
- try {
- std::auto_ptr<icalendar_2_0::IcalendarType> icalendar(icalendar_2_0::icalendar(s, xml_schema::flags::dont_validate));
- if (icalendar->vcalendar().size() != 1) {
- std::cout << "invalid amount vcalendars" << std::endl;
- }
- const icalendar_2_0::VcalendarType &vcalendar = *icalendar->vcalendar().begin();
-
-
- //TODO extract timezone information first, so we can pass that information to the rest
- for (icalendar_2_0::VcalendarType::components_type::vcalendarContainedComponent_const_iterator it(vcalendar.components().vcalendarContainedComponent().begin()); it != vcalendar.components().vcalendarContainedComponent().end(); it++) {
- if (const icalendar_2_0::VeventType* d = dynamic_cast<const icalendar_2_0::VeventType*> (&(*it))) {
- KCalCore::Event event;
- readEvent(event, *d);
- }
- }
- } catch (const xml_schema::exception& e) {
-
- std::cout <<"exceotuib" << e << std::endl;
- }/* catch (const xsd::cxx::tree::parsing_char<char> & e) {
- std::cout << e << std::endl;
- } */
+
}
void readEvent(Kolab::Event &event ,const icalendar_2_0::VeventType &vevent)
{
- try {
- if (!vevent.properties())
- return;
- const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent.properties();
- const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
-
- for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
- if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&(*it))) {
- std::cout << "Start" << std::endl;
- if (d->date_time()) {
- const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(d->date_time());
- //datetime.day()
- // (*(d->date_time()))
- } else if (d->date()) {
- const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(d->date());
- event.date << date;
- }
-
- } else if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*it))) {
- std::cout << "Rrule" << std::endl;
- std::cout << d->recur().freq() << std::endl;
- std::cout << d->recur().count() << std::endl;
- //std::cout << d->recur().byhour() << std::endl;
- } else {
- std::cout << "other" << std::endl;
- const icalendar_2_0::BasePropertyType &baseProperty = *it;
- }
- }
- } catch (const xml_schema::exception& e) {
- std::cout << e << std::endl;
- }
+// try {
+// if (!vevent.properties())
+// return;
+// const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent.properties();
+// const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
+//
+// for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
+// if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&(*it))) {
+// std::cout << "Start" << std::endl;
+// if (d->date_time()) {
+// const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(d->date_time());
+// //datetime.day()
+// // (*(d->date_time()))
+// } else if (d->date()) {
+// const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(d->date());
+// event.date << date;
+// }
+//
+// } else if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*it))) {
+// std::cout << "Rrule" << std::endl;
+// std::cout << d->recur().freq() << std::endl;
+// std::cout << d->recur().count() << std::endl;
+// //std::cout << d->recur().byhour() << std::endl;
+// } else {
+// std::cout << "other" << std::endl;
+// const icalendar_2_0::BasePropertyType &baseProperty = *it;
+// }
+// }
+// } catch (const xml_schema::exception& e) {
+// std::cout << e << std::endl;
+// }
}
-KCalCore::Event *readEvent(const std::string& s)
+KCalCore::Event::Ptr readEvent(const std::string& s)
{
try {
//TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
xml_schema::properties props;
- props.schema_location ("http://kolab.org", "../../../schemas/ical/kolabformat.xsd"); //Force schema
+ props.schema_location ("urn:ietf:params:xml:ns:icalendar-2.0", "../../../schemas/ical/kolabformat-xcal.xsd"); //Force schema
std::auto_ptr<icalendar_2_0::IcalendarType> icalendar(icalendar_2_0::icalendar(s/*, xml_schema::flags::dont_validate*/,0,props));
- if (icalendar->vcalendar().size() != 1) {
- std::cout << "invalid amount vcalendars" << std::endl;
- }
- const icalendar_2_0::VcalendarType &vcalendar = *icalendar->vcalendar().begin();
+ const icalendar_2_0::VcalendarType &vcalendar = icalendar->vcalendar();
- QList <KCalCore::Event*> events;
- QMap <QString, KTimeZone*> timezones;
-
- for (icalendar_2_0::VcalendarType::components_type::vcalendarContainedComponent_const_iterator it(vcalendar.components().vcalendarContainedComponent().begin()); it != vcalendar.components().vcalendarContainedComponent().end(); it++) {
- if (const icalendar_2_0::VeventType* d = dynamic_cast<const icalendar_2_0::VeventType*> (&*it)) {
- KCalCore::Event *e = new KCalCore::Event();
- readEvent(*e, *d);
- events.append(e);
- } else if (const icalendar_2_0::VtimezoneType* d = dynamic_cast<const icalendar_2_0::VtimezoneType*> (&*it)) {
- KTimeZone *tz = new KTimeZone();
- //readTimezone(event, *d);
- timezones.insert(tz->name(), tz);
- } else {
- kDebug() << "unknown component" << typeid(*it).name();
- }
+ QList <KCalCore::Event::Ptr> events;
+
+
+ for (icalendar_2_0::VcalendarType::components_type::vevent_const_iterator it(vcalendar.components().vevent().begin()); it != vcalendar.components().vevent().end(); it++) {
+ KCalCore::Event::Ptr e = KCalCore::Event::Ptr(new KCalCore::Event());
+ const icalendar_2_0::KolabEvent &event = *it;
+ readEvent(*e, event);
+ events.append(e);
}
- //Match timezones by name and apply correctly
+
//TODO resolve events, exceptions can be identified based on the recurrence-id attribute
- foreach (KCalCore::Event * event, events) {
- if (!event->hasRecurrenceId()) {
- return event;
- }
- }
+// foreach (KCalCore::Event * event, events) {
+// if (!event->hasRecurrenceId()) {
+// return event;
+// }
+// }
+ return events.first();
} catch (const xml_schema::exception& e) {
std::cout << e << std::endl;
}
- return 0;
+ return KCalCore::Event::Ptr();
}
-void readEvent(KCalCore::Event &event ,const icalendar_2_0::VeventType &vevent)
+void readEvent(KCalCore::Event &event, const icalendar_2_0::KolabEvent &vevent)
{
- if (!vevent.properties())
- return;
- const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent.properties();
- const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
-
- for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
- if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&*it)) {
- KDateTime date;
- event.setDtStart(date << *d);
-// kDebug() << "dtstart" << date;
- } if (const icalendar_2_0::DtendPropType* d = dynamic_cast<const icalendar_2_0::DtendPropType*> (&*it)) {
- KDateTime date;
- event.setDtEnd(date << *d);
-// kDebug() << "dtstart" << date;
- } else if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*it))) {
- std::cout << "Rrule" << std::endl;
- std::cout << d->recur().freq() << std::endl;
- std::cout << d->recur().count() << std::endl;
- //std::cout << d->recur().byhour() << std::endl;
+
+ const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
+ {
+ QString string;
+ event.setUid(string << prop.uid());
+ }
+ {
+ KDateTime date;
+ event.setCreated(date << prop.created());
+ }
+ kDebug() << "last mod";
+ {
+ KDateTime date;
+ event.setLastModified(date << prop.dtstamp());
+ }
+ if (prop.sequence()) {
+ int i;
+ event.setRevision(i << *prop.sequence());
+ }
+
+ if (prop.dtstart()) {
+ KDateTime date;
+ kDebug() << "dtstart";
+ event.setDtStart(date << *prop.dtstart());
+ event.setAllDay(date.isDateOnly()); //TODO add to specification that allday depends on start date format
+ }
+
+ if (prop.dtend()) {
+ KDateTime date;
+ kDebug() << "dtend";
+ event.setDtEnd(date << *prop.dtend());
+ if (event.dtEnd().timeType() != event.dtStart().timeType()) {
+ kWarning() << "dtEnd has wrong timespec";
+ }
+ } else if (prop.duration()) {
+// KCalCore::Duration duration.;
+// event.setDuration(duration << prop.duration());
+ }
+ //TODO check for equality of timespecs
+
+ if (prop.categories()) {
+ QStringList list;
+ event.setCategories(list << *prop.categories());
+ }
+ if (prop.class_()) {
+ QString string;
+ string << *prop.class_();
+ KCalCore::Incidence::Secrecy sec;
+ if (string == "PRIVATE") {
+ sec = KCalCore::Incidence::SecrecyPrivate;
+ } else if (string == "CONFIDENTIAL") {
+ sec = KCalCore::Incidence::SecrecyConfidential;
} else {
- std::cout << "other" << std::endl;
- const icalendar_2_0::BasePropertyType &baseProperty = *it;
+ sec = KCalCore::Incidence::SecrecyPublic;
}
+ event.setSecrecy(sec);
+ }
+
+ KCalCore::Recurrence *recurrence = event.recurrence();
+ if (prop.rrule()) {
+ KCalCore::RecurrenceRule* rrule = new KCalCore::RecurrenceRule();
+ rrule->setStartDt(recurrence->startDateTime()); //TODO shouldn't this happen as part of addRRule?
+ *rrule << *prop.rrule();
+ recurrence->addRRule(rrule);
+ }
+
+ if (prop.summary()) {
+ QString string;
+ string << *prop.summary();
+ event.setSummary(string); //TODO detect richtext and set flag accordingly
+ }
+
+ if (prop.description()) {
+ QString string;
+ string << *prop.description();
+ event.setDescription(string); //TODO detect richtext and set flag accordingly
}
-// const icalendar_2_0::
}
@@ -241,22 +415,6 @@ void Test::test()
}
-// QString Kolab::serializeEvent(const KCalCore::Event& event)
-// {
-// return event.summary();
-// }
-
-/*
-Kolab::readIncidence(const QString &string, KCalCore::Incidence &incidence)
-{
-
-}
-*/
-
-// void Kolab::readEvent(const QString &string, KCalCore::Event &event)
-// {
-// event.setSummary(string);
-// }
}
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index 24829f7..fa940f2 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -4,6 +4,7 @@
//#include <QString>
#include <string>
#include <xsd/cxx/tree/date-time.hxx>
+#include <KDE/KCalCore/Event>
namespace KCalCore {
class Event;
@@ -11,6 +12,7 @@ namespace KCalCore {
namespace icalendar_2_0 {
class VeventType;
+ class KolabEvent;
}
namespace Kolab {
@@ -45,10 +47,10 @@ struct Event {
std::string serializeEvent();
-void readEvent(const icalendar_2_0::VeventType &vevent);
-void readEvent(Kolab::Event &,const icalendar_2_0::VeventType &vevent);
-void readEvent(KCalCore::Event &,const icalendar_2_0::VeventType &vevent);
-KCalCore::Event *readEvent(const std::string& s);
+// void readEvent(const icalendar_2_0::VeventType &vevent);
+// void readEvent(Kolab::Event &,const icalendar_2_0::VeventType &vevent);
+void readEvent(KCalCore::Event &,const icalendar_2_0::KolabEvent &vevent);
+KCalCore::Event::Ptr readEvent(const std::string& s);
void readICalendar(const std::string &s);
//QString serializeEvent(const KCalCore::Event ¬e);
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 01602ad..7701cf9 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -335,13 +335,49 @@ void BindingsTest::readContact()
void BindingsTest::readEvent()
{
- KCalCore::Event *event = Kolab::readEvent("testfiles/icalEvent.xml");
+ KCalCore::Event::Ptr event = Kolab::readEvent("testfiles/icalEvent.xml");
QVERIFY(event);
- kDebug() << event->dtStart().date() << event->dtStart().time();
- QCOMPARE(event->dtStart().date(), QDate(2006, 1, 2));
- QCOMPARE(event->dtStart().time(), QTime(12, 0, 0));
- QCOMPARE(event->dtStart().timeZone().name(), QString::fromLatin1("US/Eastern"));
- delete event;
+
+ //Check basics
+ QCOMPARE(event->created(), KDateTime(QDate(2006, 2, 6), QTime(00, 11, 21), KDateTime::Spec(KDateTime::UTC)));
+ QCOMPARE(event->created().timeSpec().type(), KDateTime::UTC);
+ QCOMPARE(event->dtStart(), KDateTime(QDate(2006, 1, 2), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+ QCOMPARE(event->dtStart().timeZone().name(), KTimeZone(QString::fromLatin1("US/Eastern")).name());
+
+ //Check recurrence
+ //TODO do some "heavy" testing for recurrences, including possible edge cases.
+
+ //Check recurrence rule
+ foreach (const KCalCore::RecurrenceRule *rule, event->recurrence()->rRules()) {
+ QCOMPARE(rule->startDt(), event->recurrence()->startDateTime());
+ }
+ QCOMPARE(event->recurrence()->rRules().size(), 1);
+ KCalCore::RecurrenceRule *rule = event->recurrence()->rRules().first();
+ QCOMPARE(rule->recurrenceType(), KCalCore::RecurrenceRule::rDaily);
+ QCOMPARE(rule->duration(), 5);
+ KDateTime start(event->dtStart());
+ KDateTime end(QDate(2006, 12, 14), QTime(12, 0, 0));
+ QCOMPARE(rule->timesInInterval(start, end).size(), 5); //count/duration limit
+ QCOMPARE(rule->timesInInterval(start, KDateTime(QDate(2006, 1, 4))).size(), 3); //end date limit
+ const KCalCore::DateTimeList &ruleList = rule->timesInInterval(start, end);
+ foreach (const KDateTime &d, ruleList) {
+ QCOMPARE(d.timeZone().name(), event->dtStart().timeZone().name());
+// kDebug() << d << d.timeZone().name();
+ }
+ QCOMPARE(ruleList.first(), event->dtStart());
+ QCOMPARE(ruleList.last(), KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+
+ //Check complete recurrence
+ const KCalCore::DateTimeList &list = event->recurrence()->timesInInterval(start, end);
+ foreach (const KDateTime &d, list) {
+ QCOMPARE(d.timeZone().name(), event->dtStart().timeZone().name());
+// kDebug() << d << d.timeZone().name();
+ }
+
+ QCOMPARE(event->summary(), QString::fromLatin1("Event #2"));
+ kDebug() << event->summary();
+// QCOMPARE(event->summary(), QString::fromUtf8("Test.
Test.Test.")); //FIXME fix control character 
 (linefeed)
+ kDebug() << event->description();
}
diff --git a/c++/tests/testfiles/icalEvent.xml b/c++/tests/testfiles/icalEvent.xml
index ee2931e..7cb8685 100644
--- a/c++/tests/testfiles/icalEvent.xml
+++ b/c++/tests/testfiles/icalEvent.xml
@@ -9,76 +9,25 @@
<version>
<text>2.0</text>
</version>
- <x-kolab-version xmlns="http://kolab.org">
+ <x-kolab-version > <!--xmlns="http://kolab.org"-->
<version>3.0dev1</version>
</x-kolab-version>
</properties>
<components>
- <vtimezone>
- <!--This doesn't work right now because the tzid is commented in the schema (nameconflict with tzid component)-->
- <!--<properties>
- <last-modified>
- <date-time>2004-01-10T03:28:45Z</date-time>
- </last-modified>
- <tzid>US/Eastern</tzid>
- </properties>-->
- <components>
- <daylight>
- <properties>
- <dtstart>
- <date-time>2000-04-04T02:00:00</date-time>
- </dtstart>
- <rrule>
- <recur>
- <freq>YEARLY</freq>
- <byday>1SU</byday>
- <bymonth>4</bymonth>
- </recur>
- </rrule>
- <tzname>
- <text>EDT</text>
- </tzname>
- <tzoffsetfrom>
- <utc-offset>-05:00</utc-offset>
- </tzoffsetfrom>
- <tzoffsetto>
- <utc-offset>-04:00</utc-offset>
- </tzoffsetto>
- </properties>
- </daylight>
- <standard>
- <properties>
- <dtstart>
- <date-time>2000-10-26T02:00:00</date-time>
- </dtstart>
- <rrule>
- <recur>
- <freq>YEARLY</freq>
- <byday>-1SU</byday>
- <bymonth>10</bymonth>
- </recur>
- </rrule>
- <tzname>
- <text>EST</text>
- </tzname>
- <tzoffsetfrom>
- <utc-offset>-04:00</utc-offset>
- </tzoffsetfrom>
- <tzoffsetto>
- <utc-offset>-05:00</utc-offset>
- </tzoffsetto>
- </properties>
- </standard>
- </components>
- </vtimezone>
<vevent>
<properties>
+ <uid>
+ <text>00959BC664CA650E933C892C at example.com</text>
+ </uid>
+ <created>
+ <date-time>2006-02-06T00:11:21Z</date-time>
+ </created>
<dtstamp>
<date-time>2006-02-06T00:11:21Z</date-time>
</dtstamp>
<dtstart>
<parameters>
- <tzid><text>US/Eastern</text></tzid>
+ <tzid><text>/kolab.org/US/Eastern</text></tzid>
</parameters>
<date-time>2006-01-02T12:00:00</date-time>
</dtstart>
@@ -91,7 +40,7 @@
<count>5</count>
</recur>
</rrule>
- <rdate>
+<!-- <rdate>
<parameters>
<tzid><text>US/Eastern</text></tzid>
</parameters>
@@ -99,23 +48,19 @@
<start>2006-01-02T15:00:00</start>
<duration>PT2H</duration>
</period>
- </rdate>
+ </rdate>-->
<summary>
<text>Event #2</text>
</summary>
<description>
- <text>We are having a meeting all this week at 12
- pm for one hour, with an additional meeting on the first day
- 2 hours long.
Please bring your own lunch for the 12 pm
- meetings.</text>
+ <text>Test.
Test.
+Test.</text>
</description>
- <uid>
- <text>00959BC664CA650E933C892C at example.com</text>
- </uid>
+
</properties>
<components/>
</vevent>
- <vevent>
+<!-- <vevent>
<properties>
<dtstamp>
<date-time>2006-02-06T00:11:21Z</date-time>
@@ -138,12 +83,10 @@
<summary>
<text>Event #2 bis</text>
</summary>
- <uid>
- <text>00959BC664CA650E933C892C at example.com</text>
- </uid>
+
</properties>
<components/>
- </vevent>
+ </vevent>-->
</components>
</vcalendar>
</icalendar>
\ No newline at end of file
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index 1d91f90..519a279 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -4,7 +4,7 @@
xmlns="urn:ietf:params:xml:ns:icalendar-2.0"
elementFormDefault="qualified">
- <xs:include schemaLocation="iCalendar.xsd" />
+ <xs:include schemaLocation="iCalendar-props.xsd" />
<xs:complexType name="KolabVersion" >
<xs:complexContent mixed="false">
@@ -16,7 +16,7 @@
</xs:complexContent>
</xs:complexType>
- <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" />
+<!-- <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" />
<xs:complexType name="CustomType" >
<xs:complexContent mixed="false">
@@ -29,25 +29,89 @@
</xs:complexContent>
</xs:complexType>
- <xs:element name="x-kolab-custom" type="CustomType" substitutionGroup="baseProperty" />
+ <xs:element name="x-kolab-custom" type="CustomType" substitutionGroup="baseProperty" />-->
-
-
- <xs:element name="vevent" type="xcal:KolabEventType" substitutionGroup="xcal:vcalendarContainedComponent"/>
- <xs:complexType name="KolabEventType" mixed="false">
- <xs:complexContent>
- <xs:element name="components" />
-
-
+ <xs:complexType name="KolabEvent" >
+ <xs:sequence>
+ <xs:element name="properties">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="uid" type="UidPropType"/>
+ <xs:element name="created" type="CreatedPropType"/>
+ <xs:element name="dtstamp" type="DtstampPropType"/>
+ <xs:element name="sequence" type="SequencePropType" minOccurs="0"/>
+ <xs:element name="class" type="ClassPropType" minOccurs="0"/>
+ <xs:element name="categories" type="CategoriesPropType" minOccurs="0"/>
+ <xs:element name="dtstart" type="DtstartPropType" minOccurs="0"/>
+ <xs:element name="dtend" type="DtendPropType" minOccurs="0"/>
+ <xs:element name="duration" type="DurationPropType" minOccurs="0"/>
+ <xs:element name="rrule" type="RrulePropType" minOccurs="0"/>
+ <xs:element name="summary" type="SummaryPropType" minOccurs="0"/>
+ <xs:element name="description" type="DescriptionPropType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
</xs:element>
- <xs:extension base="xcal:VcalendarContainedComponentType">
- <xs:sequence>
-<!-- <xs:element ref="xcal:rdate" minOccurs="0" maxOccurs="unbounded"/> -->
- <xs:element name="rrule" type="xcal:RrulePropType" minOccurs="0" maxOccurs="1"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
+ <xs:element name="components">
+ <xs:complexType>
+ <!--TODO valarm-->
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
</xs:complexType>
+ <xs:complexType name="KolabTodo" >
+ <xs:sequence>
+ <xs:element name="properties">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="uid" type="UidPropType"/>
+ <xs:element name="created" type="CreatedPropType"/>
+ <xs:element name="dtstamp" type="DtstampPropType"/>
+ <xs:element name="sequence" type="SequencePropType" minOccurs="0"/>
+ <xs:element name="class" type="ClassPropType" minOccurs="0"/>
+ <xs:element name="categories" type="CategoriesPropType" minOccurs="0"/>
+ <xs:element name="dtstart" type="DtstartPropType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="components">
+ <xs:complexType>
+ <!--TODO valarm-->
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="VcalendarType" mixed="false">
+ <xs:sequence>
+ <xs:element name="properties">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="prodid" type="ProdidPropType"/>
+ <xs:element name="version" type="VersionPropType"/>
+ <xs:element name="x-kolab-version" type="KolabVersion"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="components">
+ <xs:complexType>
+ <xs:choice>
+ <xs:element name="vevent" type="KolabEvent" maxOccurs="unbounded"/>
+ <xs:element name="vtodo" type="KolabTodo" maxOccurs="unbounded"/>
+ </xs:choice>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="IcalendarType">
+ <xs:sequence>
+ <xs:element name="vcalendar" type="VcalendarType"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="icalendar" type="IcalendarType"/>
+
+
</xs:schema>
\ No newline at end of file
commit 2eb5d601daaa30ce7b1193a2fb3c49a0a1ff424b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Mon Dec 12 17:59:19 2011 +0100
iCalendar-props fix
diff --git a/schemas/ical/iCalendar-props.xsd b/schemas/ical/iCalendar-props.xsd
index c4dfc92..c31f344 100644
--- a/schemas/ical/iCalendar-props.xsd
+++ b/schemas/ical/iCalendar-props.xsd
@@ -280,7 +280,10 @@
<xs:complexContent mixed="false">
<xs:extension base="xcal:BasePropertyType">
<xs:sequence>
- <xs:element ref="xcal:utc-date-time"/>
+ <xs:choice>
+ <xs:element ref="xcal:utc-date-time"/>
+ <xs:element ref="xcal:date-time"/>
+ </xs:choice>
</xs:sequence>
</xs:extension>
</xs:complexContent>
@@ -662,7 +665,15 @@
<!-- 3.8.5.2 Recurrence Date/Times -->
<xs:complexType name="RdatePropType">
<xs:complexContent mixed="false">
- <xs:extension base="xcal:DateDatetimePropertyType"/>
+ <xs:extension base="xcal:BasePropertyType">
+ <xs:sequence>
+ <xs:choice>
+ <xs:element ref="xcal:date"/>
+ <xs:element ref="xcal:date-time"/>
+ <xs:element ref="xcal:period"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:extension>
</xs:complexContent>
</xs:complexType>
commit b8090c03ef8023865fb4c1041e3f3f88f85403b6
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Mon Dec 12 17:59:09 2011 +0100
temp
diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index edfbcb7..313939c 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -31,6 +31,8 @@ file(GLOB XCAL_SCHEMAS ${SCHEMA_DIR}/ical/*.xsd)
set( XCAL_SCHEMA_SOURCEFILES
bindings/xCard.cxx
bindings/kolabformat.cxx
+ bindings/kolabformat-xcal.cxx
+ bindings/kolabformat-xcard.cxx
bindings/iCalendar.cxx
bindings/iCalendar-params.cxx
bindings/iCalendar-props.cxx
@@ -43,7 +45,7 @@ set( XCAL_SCHEMA_SOURCEFILES
)
# --cxx-suffix .cpp --hxx-suffix .h
add_custom_command(OUTPUT ${XCAL_SCHEMA_SOURCEFILES}
- COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element vevent --root-element todo --root-element contact --root-element vstricttodo --output-dir bindings ${XCAL_SCHEMAS}
+ COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element vevent --root-element todo --root-element contact --root-element vstricttodo --root-element icalendar --output-dir bindings ${XCAL_SCHEMAS}
COMMENT "Generating xCal XSD bindings"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS ${XCAL_SCHEMAS}
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index e020abf..71d77a4 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -6,6 +6,8 @@
#include <iostream>
#include <bindings/kolabformat.hxx>
//#include "note.h"
+#include <kdebug.h>
+#include "typeinfo"
namespace Kolab {
@@ -44,48 +46,181 @@ Date &operator <<(Date &d, const icalendar_2_0::DateDatetimePropertyType &dtPro
}
return d;
}
-/*
-QString Kolab::serializeNote(const Kolab::Note& note)
+
+
+KDateTime &operator <<(KDateTime &d, const xml_schema::date &dt)
{
+ d.setDate(QDate(dt.year(), dt.month(), dt.day()));
+ return d;
+}
+KDateTime &operator <<(KDateTime &d, const xml_schema::date_time &dt)
+{
+ kDebug() << dt.year() << dt. month() << dt.day() << dt.hours();
+ d.setDate(QDate(dt.year(), dt.month(), dt.day()));
+ d.setTime(QTime(dt.hours(), dt.minutes(), dt.seconds()));
+ kDebug() << d.date() << d;
+ return d;
}
-*/
+
+QString &operator <<(QString &d, const xml_schema::string &s)
+{
+ d.append(QString::fromStdString(s) );
+ return d;
+}
+
+KDateTime &operator <<(KDateTime &d, const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+{
+ if (dtProperty.date_time()) {
+ d << *dtProperty.date_time();
+ kDebug() << "date_time";
+ } else if (dtProperty.date()) {
+ d << *dtProperty.date();
+ kDebug() << "date";
+ }
+ if (dtProperty.parameters()) {
+
+
+ for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it((*dtProperty.parameters()).baseParameter().begin()); it != (*dtProperty.parameters()).baseParameter().end(); it++) {
+ if (const icalendar_2_0::TzidParamType* tz = dynamic_cast<const icalendar_2_0::TzidParamType*> (&*it)) {
+ QString tzid;
+ tzid << tz->text();
+ KTimeZone timezone(tzid);
+ KDateTime::Spec spec(timezone);
+ d.setTimeSpec(spec);
+// kDebug() << tzid;
+ }
+// kDebug() << "---------------_";
+ }
+ }
+ return d;
+}
+
std::string serializeEvent()
{
std::cout << "ksjdsldfj";
return "bla";
}
-void readEvent(const std::string &s)
+void readICalendar(const std::string &s)
{
- std::auto_ptr<icalendar_2_0::VeventType> vevent(icalendar_2_0::vevent(s, xml_schema::flags::dont_validate));
+ try {
+ std::auto_ptr<icalendar_2_0::IcalendarType> icalendar(icalendar_2_0::icalendar(s, xml_schema::flags::dont_validate));
+ if (icalendar->vcalendar().size() != 1) {
+ std::cout << "invalid amount vcalendars" << std::endl;
+ }
+ const icalendar_2_0::VcalendarType &vcalendar = *icalendar->vcalendar().begin();
- const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent->properties();
- const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
-
- KCalCore::Event event;
-
- Kolab::Event e;
-
- for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
- if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&(*it))) {
- std::cout << "Start" << std::endl;
-
-// KDateTime::TimeZone tz;
-// KDateTime::Spec spec;
- if (d->date_time()) {
- const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(d->date_time());
- //datetime.day()
-// (*(d->date_time()))
- } else if (d->date()) {
- const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(d->date());
-// e.date = date;
- e.date << date;
- const KDateTime dt(QDateTime(QDate(date.year(), date.month(), date.day()), QTime()));
-// dt.setTimeSpec(spec);
- event.setDtStart(dt);
+
+ //TODO extract timezone information first, so we can pass that information to the rest
+ for (icalendar_2_0::VcalendarType::components_type::vcalendarContainedComponent_const_iterator it(vcalendar.components().vcalendarContainedComponent().begin()); it != vcalendar.components().vcalendarContainedComponent().end(); it++) {
+ if (const icalendar_2_0::VeventType* d = dynamic_cast<const icalendar_2_0::VeventType*> (&(*it))) {
+ KCalCore::Event event;
+ readEvent(event, *d);
+ }
+ }
+ } catch (const xml_schema::exception& e) {
+
+ std::cout <<"exceotuib" << e << std::endl;
+ }/* catch (const xsd::cxx::tree::parsing_char<char> & e) {
+ std::cout << e << std::endl;
+ } */
+}
+
+
+void readEvent(Kolab::Event &event ,const icalendar_2_0::VeventType &vevent)
+{
+ try {
+ if (!vevent.properties())
+ return;
+ const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent.properties();
+ const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
+
+ for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
+ if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&(*it))) {
+ std::cout << "Start" << std::endl;
+ if (d->date_time()) {
+ const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(d->date_time());
+ //datetime.day()
+ // (*(d->date_time()))
+ } else if (d->date()) {
+ const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(d->date());
+ event.date << date;
+ }
+
+ } else if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*it))) {
+ std::cout << "Rrule" << std::endl;
+ std::cout << d->recur().freq() << std::endl;
+ std::cout << d->recur().count() << std::endl;
+ //std::cout << d->recur().byhour() << std::endl;
+ } else {
+ std::cout << "other" << std::endl;
+ const icalendar_2_0::BasePropertyType &baseProperty = *it;
}
+ }
+ } catch (const xml_schema::exception& e) {
+ std::cout << e << std::endl;
+ }
+}
+KCalCore::Event *readEvent(const std::string& s)
+{
+ try {
+ //TODO compile schemas and embedd in binary, see xsdcxx/xsd/examples/cxx/tree/embedded
+ xml_schema::properties props;
+ props.schema_location ("http://kolab.org", "../../../schemas/ical/kolabformat.xsd"); //Force schema
+
+ std::auto_ptr<icalendar_2_0::IcalendarType> icalendar(icalendar_2_0::icalendar(s/*, xml_schema::flags::dont_validate*/,0,props));
+ if (icalendar->vcalendar().size() != 1) {
+ std::cout << "invalid amount vcalendars" << std::endl;
+ }
+ const icalendar_2_0::VcalendarType &vcalendar = *icalendar->vcalendar().begin();
+
+ QList <KCalCore::Event*> events;
+ QMap <QString, KTimeZone*> timezones;
+
+ for (icalendar_2_0::VcalendarType::components_type::vcalendarContainedComponent_const_iterator it(vcalendar.components().vcalendarContainedComponent().begin()); it != vcalendar.components().vcalendarContainedComponent().end(); it++) {
+ if (const icalendar_2_0::VeventType* d = dynamic_cast<const icalendar_2_0::VeventType*> (&*it)) {
+ KCalCore::Event *e = new KCalCore::Event();
+ readEvent(*e, *d);
+ events.append(e);
+ } else if (const icalendar_2_0::VtimezoneType* d = dynamic_cast<const icalendar_2_0::VtimezoneType*> (&*it)) {
+ KTimeZone *tz = new KTimeZone();
+ //readTimezone(event, *d);
+ timezones.insert(tz->name(), tz);
+ } else {
+ kDebug() << "unknown component" << typeid(*it).name();
+ }
+ }
+ //Match timezones by name and apply correctly
+ //TODO resolve events, exceptions can be identified based on the recurrence-id attribute
+ foreach (KCalCore::Event * event, events) {
+ if (!event->hasRecurrenceId()) {
+ return event;
+ }
+ }
+ } catch (const xml_schema::exception& e) {
+ std::cout << e << std::endl;
+ }
+ return 0;
+}
+
+void readEvent(KCalCore::Event &event ,const icalendar_2_0::VeventType &vevent)
+{
+ if (!vevent.properties())
+ return;
+ const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent.properties();
+ const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
+
+ for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
+ if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&*it)) {
+ KDateTime date;
+ event.setDtStart(date << *d);
+// kDebug() << "dtstart" << date;
+ } if (const icalendar_2_0::DtendPropType* d = dynamic_cast<const icalendar_2_0::DtendPropType*> (&*it)) {
+ KDateTime date;
+ event.setDtEnd(date << *d);
+// kDebug() << "dtstart" << date;
} else if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*it))) {
std::cout << "Rrule" << std::endl;
std::cout << d->recur().freq() << std::endl;
@@ -93,7 +228,7 @@ void readEvent(const std::string &s)
//std::cout << d->recur().byhour() << std::endl;
} else {
std::cout << "other" << std::endl;
- const icalendar_2_0::BasePropertyType &baseProperty = (*it);
+ const icalendar_2_0::BasePropertyType &baseProperty = *it;
}
}
// const icalendar_2_0::
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index 350d38a..24829f7 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -9,6 +9,10 @@ namespace KCalCore {
class Event;
}
+namespace icalendar_2_0 {
+ class VeventType;
+}
+
namespace Kolab {
//class Note;
@@ -41,7 +45,11 @@ struct Event {
std::string serializeEvent();
-void readEvent(const std::string&);
+void readEvent(const icalendar_2_0::VeventType &vevent);
+void readEvent(Kolab::Event &,const icalendar_2_0::VeventType &vevent);
+void readEvent(KCalCore::Event &,const icalendar_2_0::VeventType &vevent);
+KCalCore::Event *readEvent(const std::string& s);
+void readICalendar(const std::string &s);
//QString serializeEvent(const KCalCore::Event ¬e);
//void readEvent(const QString &string, KCalCore::Event &);
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index 0794b7e..ce02581 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -9,4 +9,4 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
#QT4_WRAP_CPP(BINDINGSTEST_MOC bindingstest.cpp)
QT4_AUTOMOC(bindingstest.cpp)
add_executable(bindingstest bindingstest.cpp ${BINDINGSTEST_MOC})
-target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabxml xerces-c)
+target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} kolabxml xerces-c kcalcore)
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 5c1157a..01602ad 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -14,6 +14,9 @@
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <bindings/contact.hxx>
+#include <kcalcore/event.h>
+#include <lib/kolabformat.h>
+#include <kdebug.h>
void BindingsTest::writeNoteTest()
@@ -293,28 +296,28 @@ void BindingsTest::xercesException()
void BindingsTest::writeContact()
{
try {
- KolabXSD::Contact::vcard_type vcard;
-
- vcard_4_0::fnPropType fn("Fritz Muster");
- vcard.baseProperty().push_back(fn);
-
- vcard_4_0::nPropType n;
- n.given().push_back("john");
- n.surname().push_back("doe");
- vcard.baseProperty().push_back(n);
-
- vcard_4_0::bdayPropType bday;
- vcard_4_0::bdayPropType::date_type date(1988,12,12);
- bday.date(date);
- vcard.baseProperty().push_back(bday);
-
- KolabXSD::Contact contact(vcard);
- xml_schema::namespace_infomap map;
- map["kolab"].name = "http://kolab.org";
- map[""].name = "urn:ietf:params:xml:ns:vcard-4.0";
- //map["xcal"].schema = "iCalendar.xsd";
-
- KolabXSD::contact (std::cout, contact, map);
+// KolabXSD::Contact::vcard_type vcard;
+//
+// vcard_4_0::fnPropType fn("Fritz Muster");
+// vcard.baseProperty().push_back(fn);
+//
+// vcard_4_0::nPropType n;
+// n.given().push_back("john");
+// n.surname().push_back("doe");
+// vcard.baseProperty().push_back(n);
+//
+// vcard_4_0::bdayPropType bday;
+// vcard_4_0::bdayPropType::date_type date(1988,12,12);
+// bday.date(date);
+// vcard.baseProperty().push_back(bday);
+//
+// KolabXSD::Contact contact(vcard);
+// xml_schema::namespace_infomap map;
+// map["kolab"].name = "http://kolab.org";
+// map[""].name = "urn:ietf:params:xml:ns:vcard-4.0";
+// //map["xcal"].schema = "iCalendar.xsd";
+//
+// KolabXSD::contact (std::cout, contact, map);
} catch (const xml_schema::exception& e) {
@@ -329,6 +332,20 @@ void BindingsTest::readContact()
}
+void BindingsTest::readEvent()
+{
+
+ KCalCore::Event *event = Kolab::readEvent("testfiles/icalEvent.xml");
+ QVERIFY(event);
+ kDebug() << event->dtStart().date() << event->dtStart().time();
+ QCOMPARE(event->dtStart().date(), QDate(2006, 1, 2));
+ QCOMPARE(event->dtStart().time(), QTime(12, 0, 0));
+ QCOMPARE(event->dtStart().timeZone().name(), QString::fromLatin1("US/Eastern"));
+ delete event;
+}
+
+
+
QTEST_MAIN( BindingsTest )
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index fd93cac..4afef3e 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -21,6 +21,10 @@ class BindingsTest : public QObject
void writeContact();
void readContact();
+
+
+ //Kolabformat
+ void readEvent();
};
#endif
\ No newline at end of file
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
new file mode 100644
index 0000000..1d91f90
--- /dev/null
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="urn:ietf:params:xml:ns:icalendar-2.0"
+ xmlns="urn:ietf:params:xml:ns:icalendar-2.0"
+ elementFormDefault="qualified">
+
+ <xs:include schemaLocation="iCalendar.xsd" />
+
+ <xs:complexType name="KolabVersion" >
+ <xs:complexContent mixed="false">
+ <xs:extension base="BasePropertyType">
+ <xs:sequence>
+ <xs:element name="version" minOccurs="0" maxOccurs="1" type="xs:string" default="3.0dev1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" />
+
+ <xs:complexType name="CustomType" >
+ <xs:complexContent mixed="false">
+ <xs:extension base="BasePropertyType">
+ <xs:sequence>
+ <xs:element name="identifier" type="xs:string"/>
+ <xs:element name="value" type="xs:string"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="x-kolab-custom" type="CustomType" substitutionGroup="baseProperty" />
+
+
+
+ <xs:element name="vevent" type="xcal:KolabEventType" substitutionGroup="xcal:vcalendarContainedComponent"/>
+ <xs:complexType name="KolabEventType" mixed="false">
+ <xs:complexContent>
+ <xs:element name="components" />
+
+
+ </xs:element>
+ <xs:extension base="xcal:VcalendarContainedComponentType">
+ <xs:sequence>
+<!-- <xs:element ref="xcal:rdate" minOccurs="0" maxOccurs="unbounded"/> -->
+ <xs:element name="rrule" type="xcal:RrulePropType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+
+</xs:schema>
\ No newline at end of file
diff --git a/schemas/ical/kolabformat-xcard.xsd b/schemas/ical/kolabformat-xcard.xsd
new file mode 100644
index 0000000..e0abc67
--- /dev/null
+++ b/schemas/ical/kolabformat-xcard.xsd
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:xcard="urn:ietf:params:xml:ns:vcard-4.0"
+ targetNamespace="urn:ietf:params:xml:ns:vcard-4.0"
+ xmlns="urn:ietf:params:xml:ns:vcard-4.0"
+ elementFormDefault="qualified">
+
+ <xs:include schemaLocation="xCard.xsd" />
+
+ <xs:complexType name="KolabVersion" >
+ <xs:complexContent mixed="false">
+ <xs:extension base="BasePropertyType">
+ <xs:sequence>
+ <xs:element name="version" minOccurs="0" maxOccurs="1" type="xs:string" default="3.0dev1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="x-kolab-version" type="KolabVersion" substitutionGroup="baseProperty" />
+
+ <xs:complexType name="CustomType" >
+ <xs:complexContent mixed="false">
+ <xs:extension base="BasePropertyType">
+ <xs:sequence>
+ <xs:element name="identifier" type="xs:string"/>
+ <xs:element name="value" type="xs:string"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="x-kolab-custom" type="CustomType" substitutionGroup="baseProperty" />
+
+</xs:schema>
\ No newline at end of file
diff --git a/schemas/ical/kolabformat.xsd b/schemas/ical/kolabformat.xsd
index aa27828..f780c2a 100644
--- a/schemas/ical/kolabformat.xsd
+++ b/schemas/ical/kolabformat.xsd
@@ -16,7 +16,7 @@
<!-- <xs:element ref="xcal:vevent"/> -->
- <xs:complexType name="Event">
+<!-- <xs:complexType name="Event">
<xs:complexContent mixed="false">
<xs:extension base="KolabBase">
<xs:sequence>
@@ -24,9 +24,9 @@
</xs:sequence>
</xs:extension>
</xs:complexContent>
- </xs:complexType>
+ </xs:complexType>-->
- <xs:element name="todo" type="Todo"/>
+<!-- <xs:element name="todo" type="Todo"/>
<xs:complexType name="Todo">
<xs:complexContent mixed="false">
<xs:extension base="KolabBase">
@@ -35,7 +35,7 @@
</xs:sequence>
</xs:extension>
</xs:complexContent>
- </xs:complexType>
+ </xs:complexType>-->
<xs:element name="note" type="Note"/>
<xs:complexType name="Note">
@@ -48,7 +48,7 @@
</xs:complexContent>
</xs:complexType>
- <xs:element name="contact" type="Contact"/>
+<!-- <xs:element name="contact" type="Contact"/>
<xs:complexType name="Contact">
<xs:complexContent mixed="false">
<xs:extension base="KolabBase">
@@ -57,7 +57,7 @@
</xs:sequence>
</xs:extension>
</xs:complexContent>
- </xs:complexType>
+ </xs:complexType>-->
<!-- <xs:element name="distlist" type="DistributionList"/>
@@ -66,19 +66,14 @@
<xs:element ref="xcard:vcard" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>-->
-
+
<xs:complexType name="CustomType" >
- <xs:complexContent mixed="false">
- <xs:extension base="xcal:BasePropertyType">
- <xs:sequence>
- <xs:element name="identifier" type="xs:string"/>
- <xs:element name="value" type="xs:string"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
+ <xs:sequence>
+ <xs:element name="identifier" type="xs:string"/>
+ <xs:element name="value" type="xs:string"/>
+ </xs:sequence>
</xs:complexType>
- <xs:element name="x-kolab-customproperty" type="CustomType" substitutionGroup="xcal:baseProperty" />
-<!-- <xs:element name="x-kolab-customproperty" type="xcardCustomType" substitutionGroup="xcard:baseProperty" /> -->
+ <xs:element name="x-kolab-custom" type="CustomType" />
</xs:schema>
\ No newline at end of file
diff --git a/testfiles/xcalCalendar.xml b/testfiles/xcalCalendar.xml
new file mode 100644
index 0000000..0ae17ef
--- /dev/null
+++ b/testfiles/xcalCalendar.xml
@@ -0,0 +1,142 @@
+ <?xml version="1.0" encoding="utf-8" ?>
+ <icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
+ <vcalendar>
+ <properties>
+ <prodid>
+ <text>-//Example Inc.//Example Client//EN</text>
+ </prodid>
+ <version>
+ <text>2.0</text>
+ </version>
+ </properties>
+ <components>
+ <vtimezone>
+ <properties>
+ <last-modified>
+ <date-time>2004-01-10T03:28:45Z</date-time>
+ </last-modified>
+ <tzid>US/Eastern</tzid>
+ </properties>
+ <components>
+ <daylight>
+ <properties>
+ <dtstart>
+ <date-time>2000-04-04T02:00:00</date-time>
+ </dtstart>
+ <rrule>
+ <recur>
+ <freq>YEARLY</freq>
+ <byday>1SU</byday>
+ <bymonth>4</bymonth>
+ </recur>
+ </rrule>
+ <tzname>
+ <text>EDT</text>
+ </tzname>
+ <tzoffsetfrom>
+ <utc-offset>-05:00</utc-offset>
+ </tzoffsetfrom>
+ <tzoffsetto>
+ <utc-offset>-04:00</utc-offset>
+ </tzoffsetto>
+ </properties>
+ </daylight>
+ <standard>
+ <properties>
+ <dtstart>
+ <date-time>2000-10-26T02:00:00</date-time>
+ </dtstart>
+ <rrule>
+ <recur>
+ <freq>YEARLY</freq>
+ <byday>-1SU</byday>
+ <bymonth>10</bymonth>
+ </recur>
+ </rrule>
+ <tzname>
+ <text>EST</text>
+ </tzname>
+ <tzoffsetfrom>
+ <utc-offset>-04:00</utc-offset>
+ </tzoffsetfrom>
+ <tzoffsetto>
+ <utc-offset>-05:00</utc-offset>
+ </tzoffsetto>
+ </properties>
+ </standard>
+ </components>
+ </vtimezone>
+ <vevent>
+ <properties>
+ <dtstamp>
+ <date-time>2006-02-06T00:11:21Z</date-time>
+ </dtstamp>
+ <dtstart>
+ <parameters>
+ <tzid><text>US/Eastern</text></tzid>
+ </parameters>
+ <date-time>2006-01-02T12:00:00</date-time>
+ </dtstart>
+ <duration>
+ <duration>PT1H</duration>
+ </duration>
+ <rrule>
+ <recur>
+ <freq>DAILY</freq>
+ <count>5</count>
+ </recur>
+ </rrule>
+ <rdate>
+ <parameters>
+ <tzid><text>US/Eastern</text></tzid>
+ </parameters>
+ <period>
+ <start>2006-01-02T15:00:00</start>
+ <duration>PT2H</duration>
+ </period>
+ </rdate>
+ <summary>
+ <text>Event #2</text>
+ </summary>
+ <description>
+ <text>We are having a meeting all this week at 12
+ pm for one hour, with an additional meeting on the first day
+ 2 hours long.
Please bring your own lunch for the 12 pm
+ meetings.</text>
+ </description>
+ <uid>
+ <text>00959BC664CA650E933C892C at example.com</text>
+ </uid>
+ </properties>
+ </vevent>
+ <vevent>
+ <properties>
+ <dtstamp>
+ <date-time>2006-02-06T00:11:21Z</date-time>
+ </dtstamp>
+ <dtstart>
+ <parameters>
+ <tzid><text>US/Eastern</text></tzid>
+ </parameters>
+ <date-time>2006-01-04T14:00:00</date-time>
+ </dtstart>
+ <duration>
+ <duration>PT1H</duration>
+ </duration>
+ <recurrence-id>
+ <parameters>
+ <tzid><text>US/Eastern</text></tzid>
+ </parameters>
+ <date-time>2006-01-04T12:00:00</date-time>
+ </recurrence-id>
+ <summary>
+ <text>Event #2 bis</text>
+ </summary>
+ <uid>
+ <text>00959BC664CA650E933C892C at example.com</text>
+ </uid>
+ </properties>
+ </vevent>
+ </components>
+ </vcalendar>
+ </icalendar>
\ No newline at end of file
diff --git a/testfiles/xcalEvent.xml b/testfiles/xcalEvent.xml
new file mode 100644
index 0000000..16c78c6
--- /dev/null
+++ b/testfiles/xcalEvent.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
+ <vcalendar>
+ <properties>
+ <calscale>
+ <text>GREGORIAN</text>
+ </calscale>
+ <prodid>
+ <text>-//Example Inc.//Example Calendar//EN</text>
+ </prodid>
+ <version>
+ <text>2.0</text>
+ </version>
+ </properties>
+ <components>
+ <vevent>
+ <properties>
+ <dtstamp>
+ <date-time>2008-02-05T19:12:24Z</date-time>
+ </dtstamp>
+ <dtstart>
+ <date>2008-10-06</date>
+ </dtstart>
+ <summary>
+ <text>Planning meeting</text>
+ </summary>
+ <uid>
+ <text>4088E990AD89CB3DBB484909</text>
+ </uid>
+ </properties>
+ </vevent>
+ </components>
+ </vcalendar>
+</icalendar>
\ No newline at end of file
commit 89ee425f65f04003b3cc605a29084c18136c65bf
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Thu Nov 24 17:00:14 2011 +0100
comment part of document which cannot be validated yet
diff --git a/c++/tests/testfiles/icalEvent.xml b/c++/tests/testfiles/icalEvent.xml
index 2c70272..ee2931e 100644
--- a/c++/tests/testfiles/icalEvent.xml
+++ b/c++/tests/testfiles/icalEvent.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--Copy of an example event from the xCal RFC-->
-<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
+<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0" >
<vcalendar>
<properties>
<prodid>
@@ -9,16 +9,19 @@
<version>
<text>2.0</text>
</version>
- <x-kolab-version><string>3.0dev1</string></x-kolab-version>
+ <x-kolab-version xmlns="http://kolab.org">
+ <version>3.0dev1</version>
+ </x-kolab-version>
</properties>
<components>
<vtimezone>
- <properties>
+ <!--This doesn't work right now because the tzid is commented in the schema (nameconflict with tzid component)-->
+ <!--<properties>
<last-modified>
<date-time>2004-01-10T03:28:45Z</date-time>
</last-modified>
<tzid>US/Eastern</tzid>
- </properties>
+ </properties>-->
<components>
<daylight>
<properties>
@@ -110,6 +113,7 @@
<text>00959BC664CA650E933C892C at example.com</text>
</uid>
</properties>
+ <components/>
</vevent>
<vevent>
<properties>
@@ -138,6 +142,7 @@
<text>00959BC664CA650E933C892C at example.com</text>
</uid>
</properties>
+ <components/>
</vevent>
</components>
</vcalendar>
commit 516fdc55b547832f1805db2872405377c8994051
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Wed Nov 23 21:43:12 2011 +0100
Copy of an example event from the xCal RFC
diff --git a/c++/tests/testfiles/icalEvent.xml b/c++/tests/testfiles/icalEvent.xml
new file mode 100644
index 0000000..2c70272
--- /dev/null
+++ b/c++/tests/testfiles/icalEvent.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--Copy of an example event from the xCal RFC-->
+<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
+ <vcalendar>
+ <properties>
+ <prodid>
+ <text>-//Example Inc.//Example Client//EN</text>
+ </prodid>
+ <version>
+ <text>2.0</text>
+ </version>
+ <x-kolab-version><string>3.0dev1</string></x-kolab-version>
+ </properties>
+ <components>
+ <vtimezone>
+ <properties>
+ <last-modified>
+ <date-time>2004-01-10T03:28:45Z</date-time>
+ </last-modified>
+ <tzid>US/Eastern</tzid>
+ </properties>
+ <components>
+ <daylight>
+ <properties>
+ <dtstart>
+ <date-time>2000-04-04T02:00:00</date-time>
+ </dtstart>
+ <rrule>
+ <recur>
+ <freq>YEARLY</freq>
+ <byday>1SU</byday>
+ <bymonth>4</bymonth>
+ </recur>
+ </rrule>
+ <tzname>
+ <text>EDT</text>
+ </tzname>
+ <tzoffsetfrom>
+ <utc-offset>-05:00</utc-offset>
+ </tzoffsetfrom>
+ <tzoffsetto>
+ <utc-offset>-04:00</utc-offset>
+ </tzoffsetto>
+ </properties>
+ </daylight>
+ <standard>
+ <properties>
+ <dtstart>
+ <date-time>2000-10-26T02:00:00</date-time>
+ </dtstart>
+ <rrule>
+ <recur>
+ <freq>YEARLY</freq>
+ <byday>-1SU</byday>
+ <bymonth>10</bymonth>
+ </recur>
+ </rrule>
+ <tzname>
+ <text>EST</text>
+ </tzname>
+ <tzoffsetfrom>
+ <utc-offset>-04:00</utc-offset>
+ </tzoffsetfrom>
+ <tzoffsetto>
+ <utc-offset>-05:00</utc-offset>
+ </tzoffsetto>
+ </properties>
+ </standard>
+ </components>
+ </vtimezone>
+ <vevent>
+ <properties>
+ <dtstamp>
+ <date-time>2006-02-06T00:11:21Z</date-time>
+ </dtstamp>
+ <dtstart>
+ <parameters>
+ <tzid><text>US/Eastern</text></tzid>
+ </parameters>
+ <date-time>2006-01-02T12:00:00</date-time>
+ </dtstart>
+ <duration>
+ <duration>PT1H</duration>
+ </duration>
+ <rrule>
+ <recur>
+ <freq>DAILY</freq>
+ <count>5</count>
+ </recur>
+ </rrule>
+ <rdate>
+ <parameters>
+ <tzid><text>US/Eastern</text></tzid>
+ </parameters>
+ <period>
+ <start>2006-01-02T15:00:00</start>
+ <duration>PT2H</duration>
+ </period>
+ </rdate>
+ <summary>
+ <text>Event #2</text>
+ </summary>
+ <description>
+ <text>We are having a meeting all this week at 12
+ pm for one hour, with an additional meeting on the first day
+ 2 hours long.
Please bring your own lunch for the 12 pm
+ meetings.</text>
+ </description>
+ <uid>
+ <text>00959BC664CA650E933C892C at example.com</text>
+ </uid>
+ </properties>
+ </vevent>
+ <vevent>
+ <properties>
+ <dtstamp>
+ <date-time>2006-02-06T00:11:21Z</date-time>
+ </dtstamp>
+ <dtstart>
+ <parameters>
+ <tzid><text>US/Eastern</text></tzid>
+ </parameters>
+ <date-time>2006-01-04T14:00:00</date-time>
+ </dtstart>
+ <duration>
+ <duration>PT1H</duration>
+ </duration>
+ <recurrence-id>
+ <parameters>
+ <tzid><text>US/Eastern</text></tzid>
+ </parameters>
+ <date-time>2006-01-04T12:00:00</date-time>
+ </recurrence-id>
+ <summary>
+ <text>Event #2 bis</text>
+ </summary>
+ <uid>
+ <text>00959BC664CA650E933C892C at example.com</text>
+ </uid>
+ </properties>
+ </vevent>
+ </components>
+ </vcalendar>
+</icalendar>
\ No newline at end of file
commit f5271da7096fe5b759de54331dab437a66a55096
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Wed Nov 23 15:37:51 2011 +0100
A copy paste minimal xCard schema version
diff --git a/schemas/ical/xCard.xsd b/schemas/ical/xCard.xsd
new file mode 100644
index 0000000..e7f4603
--- /dev/null
+++ b/schemas/ical/xCard.xsd
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- iCalendar base schema is intended to work in conjunction
+ with conformant implementations of IETF RFC 5545
+ ( http://www.rfc-editor.org/rfc/rfc5545.txt ),
+ the normative specification of iCalendar. -->
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xcard="urn:ietf:params:xml:ns:vcard-4.0" targetNamespace="urn:ietf:params:xml:ns:vcard-4.0" elementFormDefault="qualified">
+
+<!-- Plain Types -->
+
+ <xs:element name="text" type="xs:string"/>
+ <!-- 3.3.4 DATE -->
+ <xs:element name="date" type="xs:date"/>
+
+ <!-- 3.3.5 DATE-TIME -->
+ <!--
+ <xs:element name="date-time" type="xs:string"/>
+ -->
+ <xs:simpleType name="DateTimeType">
+ <xs:restriction base="xs:dateTime">
+ <xs:pattern value="(\-|\+)?\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}(\.\d*)?Z?"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="date-time" type="xcard:DateTimeType"/>
+
+<!-- Parameters -->
+
+<xs:complexType name="BaseParameterType" abstract="true"/>
+ <xs:element name="baseParameter" type="xcard:BaseParameterType"/>
+ <xs:complexType name="ArrayOfParameters">
+ <xs:sequence>
+ <xs:element ref="xcard:baseParameter" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+<!-- Properties -->
+ <xs:complexType name="BasePropertyType" abstract="true" >
+ <xs:sequence>
+ <xs:element ref="xcard:parameters"
+ minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="parameters" type="xcard:ArrayOfParameters"/>
+
+ <xs:element name="baseProperty" type="xcard:BasePropertyType" />
+
+ <xs:element name="fn" type="xcard:fnPropType"
+ substitutionGroup="xcard:baseProperty" />
+
+ <xs:element name="n" type="xcard:nPropType"
+ substitutionGroup="xcard:baseProperty" />
+
+ <xs:element name="bday" type="xcard:bdayPropType"
+ substitutionGroup="xcard:baseProperty" />
+
+
+
+ <!-- Properties that take a simple text value -->
+ <xs:complexType name="TextPropertyType" >
+ <xs:complexContent mixed="false">
+ <xs:extension base="xcard:BasePropertyType">
+ <xs:sequence>
+ <xs:element ref="xcard:text" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Properties that take a date or date-time value -->
+ <xs:complexType name="DateDatetimePropertyType" >
+ <xs:complexContent mixed="false">
+ <xs:extension base="xcard:BasePropertyType">
+ <xs:sequence>
+ <xs:choice>
+ <xs:element ref="xcard:date-time"/>
+ <xs:element ref="xcard:date"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+
+
+ <xs:complexType name="fnPropType">
+ <xs:complexContent mixed="false">
+ <xs:extension base="xcard:TextPropertyType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="nPropType">
+ <xs:complexContent mixed="false">
+ <xs:extension base="xcard:BasePropertyType">
+ <xs:sequence>
+ <xs:element name="surname" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="given" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="additional" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="prefix" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="suffix" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="bdayPropType">
+ <xs:complexContent mixed="false">
+ <xs:extension base="xcard:DateDatetimePropertyType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+
+<!-- <xs:include schemaLocation="iCalendar-props.xsd"/> -->
+<!-- Base -->
+
+ <xs:element name="vcard" type="xcard:VcardType" />
+ <xs:complexType name="VcardType" mixed="false">
+ <xs:sequence>
+ <xs:element ref="xcard:baseProperty" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+
+</xs:schema>
commit 73d8c72919b5a9f80e3fd7ffc365a4dd0511d61b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Wed Nov 23 15:37:16 2011 +0100
temp commit with SWIG bindings,
format vevent nested in kolab event
diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 350994d..edfbcb7 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -20,14 +20,16 @@ set( KOLAB_SCHEMA_SOURCEFILES
bindings/note.cxx )
add_custom_command(OUTPUT ${KOLAB_SCHEMA_SOURCEFILES}
- COMMAND ${XSDCXX} cxx-tree --generate-serialization --namespace-map http://kolab.org=KolabXSD --output-dir bindings ${KOLAB_SCHEMAS}
+ COMMAND ${XSDCXX} cxx-tree --generate-serialization --namespace-map http://kolab.org=KolabXSD_test --output-dir bindings ${KOLAB_SCHEMAS}
COMMENT "Generating Kolab XSD bindings"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ DEPENDS ${KOLAB_SCHEMAS}
VERBATIM
)
file(GLOB XCAL_SCHEMAS ${SCHEMA_DIR}/ical/*.xsd)
set( XCAL_SCHEMA_SOURCEFILES
+ bindings/xCard.cxx
bindings/kolabformat.cxx
bindings/iCalendar.cxx
bindings/iCalendar-params.cxx
@@ -36,14 +38,15 @@ set( XCAL_SCHEMA_SOURCEFILES
bindings/iCalendar-link-extension.cxx
bindings/iCalendar-bw-extensions.cxx
bindings/iCalendar-ms-extensions.cxx
- bindings/iCalendar-availability-extension.cxx
+# bindings/iCalendar-availability-extension.cxx
# bindings/iCalendar-wscal-extensions.cxx
)
# --cxx-suffix .cpp --hxx-suffix .h
add_custom_command(OUTPUT ${XCAL_SCHEMA_SOURCEFILES}
- COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element event --root-element todo --output-dir bindings ${XCAL_SCHEMAS}
+ COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://icalnamespace.org=xcalns --namespace-map http://kolab.org=KolabXSD --root-element vevent --root-element todo --root-element contact --root-element vstricttodo --output-dir bindings ${XCAL_SCHEMAS}
COMMENT "Generating xCal XSD bindings"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ DEPENDS ${XCAL_SCHEMAS}
VERBATIM
)
@@ -54,7 +57,7 @@ SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
ADD_CUSTOM_TARGET(generate_bindings ALL DEPENDS ${SCHEMA_SOURCEFILES})
include_directories( ./ )
-add_library(kolabxml lib/kolabkcalconversion.cpp ${SCHEMA_SOURCEFILES})
+add_library(kolabxml lib/kolabformat.cpp ${SCHEMA_SOURCEFILES})
target_link_libraries(${kolabxml} xerces-c)
add_subdirectory(tests)
add_subdirectory(lib)
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index 342e65a..1049024 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -7,25 +7,50 @@
# VERBATIM
# )
-set(KOLAB_SWIG_SOURCE_FILES kolabformat_wrap.cxx)
-add_custom_command(OUTPUT ${KOLAB_SWIG_SOURCE_FILES}
- COMMAND swig -v -c++ -python kolabformat.i
+set(KOLAB_SWIG_SOURCE_FILES kolabformat.cpp)
+
+set(KOLAB_SWIG_PYTHON_SOURCE_FILE python_kolabformat_wrapper.cpp)
+add_custom_command(OUTPUT ${KOLAB_SWIG_PYTHON_SOURCE_FILE}
+ COMMAND swig -v -c++ -python -o ${KOLAB_SWIG_PYTHON_SOURCE_FILE} kolabformat.i
COMMENT "Generating python bindings"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS kolabformat.i
VERBATIM
)
+SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PYTHON_SOURCE_FILE} PROPERTIES GENERATED 1)
+ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
-SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_SOURCE_FILES} PROPERTIES GENERATED 1)
-ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_SOURCE_FILES})
+set(KOLAB_SWIG_PHP_SOURCE_FILE php_kolabformat_wrapper.cpp)
+add_custom_command(OUTPUT ${KOLAB_SWIG_PHP_SOURCE_FILE}
+ COMMAND swig -v -c++ -php -o ${KOLAB_SWIG_PHP_SOURCE_FILE} kolabformat.i
+ COMMENT "Generating php bindings"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ DEPENDS kolabformat.i
+ VERBATIM
+ )
+SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PHP_SOURCE_FILE} PROPERTIES GENERATED 1)
+ADD_CUSTOM_TARGET(generate_php_bindings ALL DEPENDS ${KOLAB_SWIG_PHP_SOURCE_FILE})
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" )
include_directories( ./ )
-include_directories(/usr/include/python2.7)
-add_library(bindings SHARED ${KOLAB_SWIG_SOURCE_FILES} kolabformat.cpp)
-ADD_DEPENDENCIES(bindings generate_python_bindings)
-SET_TARGET_PROPERTIES(bindings PROPERTIES OUTPUT_NAME "_kolabformat")
-SET_TARGET_PROPERTIES(bindings PROPERTIES PREFIX "")
+#PYTHON
+find_package(PythonLibs)
+include_directories(${PYTHON_INCLUDE_DIRS})
+add_library(pythonbindings SHARED ${KOLAB_SWIG_SOURCE_FILES} ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
+# ADD_DEPENDENCIES(bindings generate_python_bindings)
+SET_TARGET_PROPERTIES(pythonbindings PROPERTIES OUTPUT_NAME "_kolabformat")
+SET_TARGET_PROPERTIES(pythonbindings PROPERTIES PREFIX "")
+
+
+
+#PHP
+#set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} `php-config --includes`" )
+find_package(PHP4)
+include_directories(${PHP4_INCLUDE_PATH})
+add_library(phpbindings SHARED ${KOLAB_SWIG_SOURCE_FILES} ${KOLAB_SWIG_PHP_SOURCE_FILE})
+# ADD_DEPENDENCIES(bindings generate_python_bindings)
+SET_TARGET_PROPERTIES(phpbindings PROPERTIES OUTPUT_NAME "kolabformat")
+SET_TARGET_PROPERTIES(phpbindings PROPERTIES PREFIX "")
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index 6c45778..e020abf 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -4,8 +4,46 @@
#include <kcalcore/event.h>
#include <iostream>
+#include <bindings/kolabformat.hxx>
//#include "note.h"
+namespace Kolab {
+
+// xml_schema::date::operator Date(Date &d, const xml_schema::date &dt) {
+// Date d;
+// d.year = year();
+// return d;
+// }; //conversion operator
+
+Date &operator <<(Date &d, const xml_schema::date &dt)
+{
+ d.year = dt.year();
+ return d;
+}
+
+// Date &operator =(Date &d, const xml_schema::date &dt)
+// {
+// d.year = dt.year();
+// return d;
+// }
+
+//Event & operator<<(const MyClass &rhs);
+Date &operator <<(Date &d, const icalendar_2_0::DateDatetimePropertyType &dtProperty)
+{
+ if (dtProperty.date_time()) {
+ const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(dtProperty.date_time());
+ //datetime.day()
+// (*(d->date_time()))
+ } else if (dtProperty.date()) {
+ const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(dtProperty.date());
+// e.date = date;
+ d.year = date.year();
+// const KDateTime dt(QDateTime(QDate(date.year(), date.month(), date.day()), QTime()));
+// // dt.setTimeSpec(spec);
+// event.setDtStart(dt);
+ }
+ return d;
+}
/*
QString Kolab::serializeNote(const Kolab::Note& note)
{
@@ -18,6 +56,50 @@ std::string serializeEvent()
return "bla";
}
+void readEvent(const std::string &s)
+{
+ std::auto_ptr<icalendar_2_0::VeventType> vevent(icalendar_2_0::vevent(s, xml_schema::flags::dont_validate));
+
+ const icalendar_2_0::BaseComponentType::properties_type& properties = *vevent->properties();
+ const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
+
+ KCalCore::Event event;
+
+ Kolab::Event e;
+
+ for (icalendar_2_0::ArrayOfProperties::baseProperty_const_iterator it(propertyList.begin()); it != propertyList.end(); it++) {
+ if (const icalendar_2_0::DtstartPropType* d = dynamic_cast<const icalendar_2_0::DtstartPropType*> (&(*it))) {
+ std::cout << "Start" << std::endl;
+
+// KDateTime::TimeZone tz;
+// KDateTime::Spec spec;
+ if (d->date_time()) {
+ const icalendar_2_0::DateDatetimePropertyType::date_time_type datetime = *(d->date_time());
+ //datetime.day()
+// (*(d->date_time()))
+ } else if (d->date()) {
+ const icalendar_2_0::DateDatetimePropertyType::date_type &date = *(d->date());
+// e.date = date;
+ e.date << date;
+ const KDateTime dt(QDateTime(QDate(date.year(), date.month(), date.day()), QTime()));
+// dt.setTimeSpec(spec);
+ event.setDtStart(dt);
+ }
+
+ } else if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*it))) {
+ std::cout << "Rrule" << std::endl;
+ std::cout << d->recur().freq() << std::endl;
+ std::cout << d->recur().count() << std::endl;
+ //std::cout << d->recur().byhour() << std::endl;
+ } else {
+ std::cout << "other" << std::endl;
+ const icalendar_2_0::BasePropertyType &baseProperty = (*it);
+ }
+ }
+// const icalendar_2_0::
+}
+
+
void Test::test()
{
std::cout << "test";
@@ -40,3 +122,6 @@ Kolab::readIncidence(const QString &string, KCalCore::Incidence &incidence)
// {
// event.setSummary(string);
// }
+
+}
+
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index fa27675..350d38a 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -3,12 +3,13 @@
#define KOLABFORMAT_H
//#include <QString>
#include <string>
+#include <xsd/cxx/tree/date-time.hxx>
namespace KCalCore {
class Event;
}
-// namespace Kolab {
+namespace Kolab {
//class Note;
@@ -29,11 +30,22 @@ public:
void test();
};
+
+struct Date {
+ int year;
+};
+
+struct Event {
+ Date date;
+};
+
+
std::string serializeEvent();
+void readEvent(const std::string&);
//QString serializeEvent(const KCalCore::Event ¬e);
//void readEvent(const QString &string, KCalCore::Event &);
-// }
+}
#endif // KOLABFORMAT_H
diff --git a/c++/lib/kolabformat.i b/c++/lib/kolabformat.i
index cf7ae03..d14ae8f 100644
--- a/c++/lib/kolabformat.i
+++ b/c++/lib/kolabformat.i
@@ -7,6 +7,7 @@
%include "std_string.i"
/*%apply const std::string& {std::string* foo};*/
+namespace Kolab {
std::string serializeEvent();
@@ -14,5 +15,13 @@ class Test {
public:
void test();
};
+struct Date {
+ int year;
+};
+
+struct Event {
+ Date date;
+};
+}
/*extern void readEvent(const QString &string, KCalCore::Event &); */
diff --git a/c++/tests/CMakeLists.txt b/c++/tests/CMakeLists.txt
index d59dc7c..0794b7e 100644
--- a/c++/tests/CMakeLists.txt
+++ b/c++/tests/CMakeLists.txt
@@ -1,10 +1,10 @@
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
-QT4_WRAP_CPP(kcalconversiontest_MOC kcalconversiontest.h)
+# QT4_WRAP_CPP(kcalconversiontest_MOC kcalconversiontest.h)
#add_test("conversiontest" kcalconversiontest ${kolabproxy_shared_relative_SRCS} ${AKONADI_COLLECTIONATTRIBUTES_SHARED_SOURCES} kcalconversiontest.cpp)
-add_executable(kcalconversiontest kcalconversiontest.cpp ${kcalconversiontest_MOC})
-target_link_libraries(kcalconversiontest ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTTEST_LIBRARY} ${KDEPIMLIBS_KCALCORE_LIBS} kolabxml)
+# add_executable(kcalconversiontest kcalconversiontest.cpp ${kcalconversiontest_MOC})
+# target_link_libraries(kcalconversiontest ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTTEST_LIBRARY} ${KDEPIMLIBS_KCALCORE_LIBS} kolabxml)
#QT4_WRAP_CPP(BINDINGSTEST_MOC bindingstest.cpp)
QT4_AUTOMOC(bindingstest.cpp)
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 1e741ea..5c1157a 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -13,23 +13,23 @@
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
+#include <bindings/contact.hxx>
void BindingsTest::writeNoteTest()
{
xml_schema::date_time datetime(2011, 11, 23, 12, 12, 12);
- KolabXSD::XMLBase::sensitivity_type sensitivity = KolabXSD::Sensitivity::public_;
- KolabXSD::Note::background_color_type bg = KolabXSD::Note::background_color_default_value();
- KolabXSD::Note::foreground_color_type fg = KolabXSD::Note::foreground_color_default_value();
- KolabXSD::Note note("test", "test", datetime, datetime, sensitivity, "", bg, fg);
-
+ KolabXSD_test::XMLBase::sensitivity_type sensitivity = KolabXSD_test::Sensitivity::public_;
+ KolabXSD_test::Note::background_color_type bg = KolabXSD_test::Note::background_color_default_value();
+ KolabXSD_test::Note::foreground_color_type fg = KolabXSD_test::Note::foreground_color_default_value();
+ KolabXSD_test::Note note("test", "test", datetime, datetime, sensitivity, "", bg, fg);
+
xml_schema::namespace_infomap map;
map[""].name = "http://kolab.org";
map[""].schema = "note.xsd";
- KolabXSD::note (std::cout, note, map);
-
-
+ KolabXSD_test::note (std::cout, note, map);
+
/* QFETCH(KCalCore::Recurrence, kcalrecurrence);
KolabXSD::Recurrence ret = Kolab::KCalConversion::fromKCal( &kcalrecurrence );
@@ -43,13 +43,13 @@ void BindingsTest::readNoteTest()
xml_schema::properties props;
// props.no_namespace_schema_location ("../../schemas/note.xsd");
// props.schema_location ("http://kolab.org", "../../schemas/note.xsd"); //Force schema
- std::auto_ptr<KolabXSD::Note> note(KolabXSD::note("testfiles/testnote.xml", xml_schema::flags::keep_dom | xml_schema::flags::dont_validate, props));
+ std::auto_ptr<KolabXSD_test::Note> note(KolabXSD_test::note("testfiles/testnote.xml", xml_schema::flags::keep_dom | xml_schema::flags::dont_validate, props));
xml_schema::namespace_infomap map;
map[""].name = "http://kolab.org";
map[""].schema = "note.xsd";
- KolabXSD::note (std::cout, *note, map);
+ KolabXSD_test::note (std::cout, *note, map);
} catch (const xml_schema::exception& e) {
std::cout << e << endl;
QVERIFY(false);
@@ -63,103 +63,107 @@ void BindingsTest::writeReadNoteTest()
void BindingsTest::writeKolabXCalEvent()
{
- try {
- //Components
- icalendar_2_0::EventTodoComponentType::components_type::valarm_type alarm;
-
- icalendar_2_0::ArrayOfEventTodoContainedComponents component;
- component.valarm().push_back(alarm);
-
- //Properties
-
- //Recurrence
- icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
- recur.count(2);
- recur.byhour().push_back("3");
- icalendar_2_0::RrulePropType rrule(recur);
-
- //Startdate
- xml_schema::date_time dt(2011,8,12,2,12,15);
- icalendar_2_0::DtstartPropType::date_time_type datetime(dt);
- icalendar_2_0::DtstartPropType startdate;
- startdate.date_time(datetime);
- //Startdate timezone
- ::icalendar_2_0::ArrayOfParameters parameters;
- ::icalendar_2_0::TzidParamType tzid("US/Eastern");
- parameters.baseParameter().push_back(tzid);
- startdate.parameters(parameters);
-
-
- //Custom value
- KolabXSD::CustomType custom("cusotomtypeidentifier", "sldjfldfj");
-
- //Assembling event properties
- ::icalendar_2_0::ArrayOfProperties properties;
- properties.baseProperty().push_back(startdate);
- properties.baseProperty().push_back(rrule);
- properties.baseProperty().push_back(custom);
-
- //Assembling the complete event
- icalendar_2_0::VeventType event(component);
- event.properties(properties);
-
- KolabXSD::Event kolabEvent(event);
- xml_schema::namespace_infomap map;
- map["kolab"].name = "http://kolab.org";
- map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
- //map["xcal"].schema = "iCalendar.xsd";
-
- KolabXSD::event (std::cout, kolabEvent, map);
-
- } catch (const xml_schema::exception& e) {
- std::cout << e << endl;
- QVERIFY(false);
- }
+// try {
+// //Components
+// icalendar_2_0::EventTodoComponentType::components_type::valarm_type alarm;
+//
+// icalendar_2_0::ArrayOfEventTodoContainedComponents component;
+// component.valarm().push_back(alarm);
+//
+// //Properties
+//
+// //Recurrence
+// icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
+// recur.count(2);
+// recur.byhour().push_back("3");
+// icalendar_2_0::RrulePropType rrule(recur);
+//
+// //Startdate
+// xml_schema::date_time dt(2011,8,12,2,12,15);
+// icalendar_2_0::DtstartPropType::date_time_type datetime(dt);
+// icalendar_2_0::DtstartPropType startdate;
+// startdate.date_time(datetime);
+// //Startdate timezone
+// ::icalendar_2_0::ArrayOfParameters parameters;
+// ::icalendar_2_0::TzidParamType tzid("US/Eastern");
+// parameters.baseParameter().push_back(tzid);
+// startdate.parameters(parameters);
+//
+//
+// //Custom value
+// KolabXSD::CustomType custom("cusotomtypeidentifier", "sldjfldfj");
+//
+// //Assembling event properties
+// ::icalendar_2_0::ArrayOfProperties properties;
+// properties.baseProperty().push_back(startdate);
+// properties.baseProperty().push_back(rrule);
+// properties.baseProperty().push_back(custom);
+//
+// //Assembling the complete event
+// icalendar_2_0::VeventType event(component);
+// event.properties(properties);
+//
+// KolabXSD::Event kolabEvent(event);
+// xml_schema::namespace_infomap map;
+// map["kolab"].name = "http://kolab.org";
+// map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
+// //map["xcal"].schema = "iCalendar.xsd";
+//
+// KolabXSD::event (std::cout, kolabEvent, map);
+//
+//
+// // icalendar_2_0::VstrictTodoType todo;
+// // icalendar_2_0::RecurType recur(icalendar_2_0::RecurType::freq_type::DAILY);
+// // todo.rrule().;
+//
+// } catch (const xml_schema::exception& e) {
+// std::cout << e << endl;
+// QVERIFY(false);
+// }
}
void BindingsTest::readKolabXCalEvent()
{
- try {
-// xml_schema::properties props;
-// props.no_namespace_schema_location ("../../../schemas/ical/kolabevent.xsd");
-// props.schema_location ("http://kolab.org", "../../../schemas/ical/kolabevent.xsd"); //Force schema
-// std::auto_ptr<KolabXSD::Event> event(KolabXSD::kolabevent("testfiles/testkolabevent.xml", 0, props));
-
- std::auto_ptr<KolabXSD::Event> event(KolabXSD::event("testfiles/testkolabevent.xml", xml_schema::flags::dont_validate));
-
- const icalendar_2_0::BaseComponentType::properties_type& properties = *event->vevent().properties();
- const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
-
- /*for(int i = 0; i < propertyList.size(); i++) {
- const icalendar_2_0::ArrayOfProperties::baseProperty_type prop = propertyList.at(i);
-
- }*/
- std::cout << propertyList.size() << std::endl;
- for (icalendar_2_0::ArrayOfProperties::baseProperty_sequence::const_iterator i (propertyList.begin ()); i != propertyList.end (); ++i) {
- if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*i))) {
- std::cout << "Rrule" << std::endl;
- std::cout << d->recur().freq() << std::endl;
- std::cout << d->recur().count() << std::endl;
- //std::cout << d->recur().byhour() << std::endl;
- } else {
- std::cout << "other" << std::endl;
- const icalendar_2_0::BasePropertyType &baseProperty = (*i);
- }
- }
-
- xml_schema::namespace_infomap map;
- map[""].name = "http://kolab.org";
-// map[""].schema = "kolabevent.xsd";
- map["xcal"].name = "urn:ietf:params:xml:ns:icalendar-2.0";
-// map["xcal"].schema = "iCalendar.xsd";
-
- KolabXSD::event (std::cout, *event, map);
-
- } catch (const xml_schema::exception& e) {
- std::cout << e << std::endl;
- QVERIFY(false);
- }
+// try {
+// // xml_schema::properties props;
+// // props.no_namespace_schema_location ("../../../schemas/ical/kolabevent.xsd");
+// // props.schema_location ("http://kolab.org", "../../../schemas/ical/kolabevent.xsd"); //Force schema
+// // std::auto_ptr<KolabXSD::Event> event(KolabXSD::kolabevent("testfiles/testkolabevent.xml", 0, props));
+//
+// std::auto_ptr<KolabXSD::Event> event(KolabXSD::event("testfiles/testkolabevent.xml", xml_schema::flags::dont_validate));
+//
+// const icalendar_2_0::BaseComponentType::properties_type& properties = *event->vevent().properties();
+// const icalendar_2_0::ArrayOfProperties::baseProperty_sequence &propertyList = properties.baseProperty();
+//
+// /*for(int i = 0; i < propertyList.size(); i++) {
+// const icalendar_2_0::ArrayOfProperties::baseProperty_type prop = propertyList.at(i);
+// }*/
+// std::cout << propertyList.size() << std::endl;
+// for (icalendar_2_0::ArrayOfProperties::baseProperty_sequence::const_iterator i (propertyList.begin ()); i != propertyList.end (); ++i) {
+// if (const icalendar_2_0::RrulePropType* d = dynamic_cast<const icalendar_2_0::RrulePropType*> (&(*i))) {
+// std::cout << "Rrule" << std::endl;
+// std::cout << d->recur().freq() << std::endl;
+// std::cout << d->recur().count() << std::endl;
+// //std::cout << d->recur().byhour() << std::endl;
+// } else {
+// std::cout << "other" << std::endl;
+// const icalendar_2_0::BasePropertyType &baseProperty = (*i);
+// }
+// }
+//
+// xml_schema::namespace_infomap map;
+// map["kolab"].name = "http://kolab.org";
+// // map[""].schema = "kolabevent.xsd";
+// map[""].name = "urn:ietf:params:xml:ns:icalendar-2.0";
+// // map["xcal"].schema = "iCalendar.xsd";
+//
+// KolabXSD::event (std::cout, *event, map);
+//
+// } catch (const xml_schema::exception& e) {
+// std::cout << e << std::endl;
+// QVERIFY(false);
+// }
}
#if 0
@@ -286,6 +290,44 @@ void BindingsTest::xercesException()
doc->release();
}
+void BindingsTest::writeContact()
+{
+ try {
+ KolabXSD::Contact::vcard_type vcard;
+
+ vcard_4_0::fnPropType fn("Fritz Muster");
+ vcard.baseProperty().push_back(fn);
+
+ vcard_4_0::nPropType n;
+ n.given().push_back("john");
+ n.surname().push_back("doe");
+ vcard.baseProperty().push_back(n);
+
+ vcard_4_0::bdayPropType bday;
+ vcard_4_0::bdayPropType::date_type date(1988,12,12);
+ bday.date(date);
+ vcard.baseProperty().push_back(bday);
+
+ KolabXSD::Contact contact(vcard);
+ xml_schema::namespace_infomap map;
+ map["kolab"].name = "http://kolab.org";
+ map[""].name = "urn:ietf:params:xml:ns:vcard-4.0";
+ //map["xcal"].schema = "iCalendar.xsd";
+
+ KolabXSD::contact (std::cout, contact, map);
+
+
+ } catch (const xml_schema::exception& e) {
+ std::cout << e << endl;
+ QVERIFY(false);
+ }
+}
+
+void BindingsTest::readContact()
+{
+
+}
+
QTEST_MAIN( BindingsTest )
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index 4122321..fd93cac 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -18,6 +18,9 @@ class BindingsTest : public QObject
void readNoteTest();
void writeReadNoteTest();
void xercesException();
+
+ void writeContact();
+ void readContact();
};
#endif
\ No newline at end of file
diff --git a/c++/tests/testfiles/testkolabevent.xml b/c++/tests/testfiles/testkolabevent.xml
index 021f289..e991846 100644
--- a/c++/tests/testfiles/testkolabevent.xml
+++ b/c++/tests/testfiles/testkolabevent.xml
@@ -1,29 +1,29 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
-<event xmlns="http://kolab.org" xmlns:xcal="urn:ietf:params:xml:ns:icalendar-2.0">
+<kolab:event xmlns:kolab="http://kolab.org" xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
- <xcal:vevent>
- <xcal:properties>
- <xcal:dtstart>
- <xcal:date>2011-11-10+10:10</xcal:date>
- </xcal:dtstart>
- <xcal:rrule>
- <xcal:recur>
- <xcal:count>2</xcal:count>
- <xcal:byhour>3</xcal:byhour>
- <xcal:freq>DAILY</xcal:freq>
+ <vevent>
+ <properties>
+ <dtstart>
+ <date>2011-11-10+10:10</date>
+ </dtstart>
+ <rrule>
+ <recur>
+ <count>2</count>
+ <byhour>3</byhour>
+ <freq>DAILY</freq>
- </xcal:recur>
- </xcal:rrule>
+ </recur>
+ </rrule>
<x-custom-property>
<unknown>blabla</unknown>
</x-custom-property>
<x-unknown-property>
<unknown>blibla</unknown>
</x-unknown-property>
- </xcal:properties>
- <xcal:components>
- <xcal:valarm/>
- </xcal:components>
- </xcal:vevent>
+ </properties>
+ <components>
+ <valarm/>
+ </components>
+ </vevent>
-</event>
+</kolab:event>
diff --git a/schemas/ical/iCalendar.xsd b/schemas/ical/iCalendar.xsd
index bd937d7..89f9b00 100644
--- a/schemas/ical/iCalendar.xsd
+++ b/schemas/ical/iCalendar.xsd
@@ -48,6 +48,23 @@
<xs:element name="standard" type="xcal:StandardType" substitutionGroup="xcal:baseComponent"/>
<xs:element name="daylight" type="xcal:DaylightType" substitutionGroup="xcal:baseComponent"/>
<xs:element name="valarm" type="xcal:ValarmType"/>
+
+
+
+
+ <xs:element name="vstricttodo" type="xcal:VstrictTodoType" substitutionGroup="xcal:vcalendarContainedComponent"/>
+ <xs:complexType name="VstrictTodoType" mixed="false">
+ <xs:complexContent>
+ <xs:extension base="xcal:VcalendarContainedComponentType">
+ <xs:sequence>
+<!-- <xs:element ref="xcal:rdate" minOccurs="0" maxOccurs="unbounded"/> -->
+ <xs:element name="rrule" type="xcal:RrulePropType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+
<!-- 3.4 iCalendar Stream -->
<xs:complexType name="IcalendarType">
<xs:sequence>
diff --git a/schemas/ical/kolabformat.xsd b/schemas/ical/kolabformat.xsd
index fff27e1..aa27828 100644
--- a/schemas/ical/kolabformat.xsd
+++ b/schemas/ical/kolabformat.xsd
@@ -1,27 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xcal="urn:ietf:params:xml:ns:icalendar-2.0"
+ xmlns:xcard="urn:ietf:params:xml:ns:vcard-4.0"
targetNamespace="http://kolab.org"
xmlns="http://kolab.org"
elementFormDefault="qualified">
<xs:import schemaLocation="iCalendar.xsd" namespace="urn:ietf:params:xml:ns:icalendar-2.0"/>
+ <xs:import schemaLocation="xCard.xsd" namespace="urn:ietf:params:xml:ns:vcard-4.0"/>
+
+
+ <xs:complexType name="KolabBase">
+ <xs:attribute name="version" type="xs:string" fixed="3.0dev1" />
+ </xs:complexType>
- <xs:element name="event" type="Event"/>
-
+<!-- <xs:element ref="xcal:vevent"/> -->
+
<xs:complexType name="Event">
- <xs:sequence>
- <xs:element ref="xcal:vevent" minOccurs="1" maxOccurs="1"/>
- </xs:sequence>
+ <xs:complexContent mixed="false">
+ <xs:extension base="KolabBase">
+ <xs:sequence>
+ <xs:element ref="xcal:vevent" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
</xs:complexType>
<xs:element name="todo" type="Todo"/>
-
<xs:complexType name="Todo">
+ <xs:complexContent mixed="false">
+ <xs:extension base="KolabBase">
+ <xs:sequence>
+ <xs:element ref="xcal:vtodo" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="note" type="Note"/>
+ <xs:complexType name="Note">
+ <xs:complexContent mixed="false">
+ <xs:extension base="KolabBase">
+ <xs:sequence>
+ <xs:element ref="xcal:vjournal" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="contact" type="Contact"/>
+ <xs:complexType name="Contact">
+ <xs:complexContent mixed="false">
+ <xs:extension base="KolabBase">
+ <xs:sequence>
+ <xs:element ref="xcard:vcard" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+<!-- <xs:element name="distlist" type="DistributionList"/>
+
+ <xs:complexType name="DistributionList">
<xs:sequence>
- <xs:element ref="xcal:vtodo" minOccurs="1" maxOccurs="1"/>
+ <xs:element ref="xcard:vcard" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
- </xs:complexType>
+ </xs:complexType>-->
<xs:complexType name="CustomType" >
<xs:complexContent mixed="false">
@@ -35,5 +79,6 @@
</xs:complexType>
<xs:element name="x-kolab-customproperty" type="CustomType" substitutionGroup="xcal:baseProperty" />
+<!-- <xs:element name="x-kolab-customproperty" type="xcardCustomType" substitutionGroup="xcard:baseProperty" /> -->
</xs:schema>
\ No newline at end of file
commit 06f064f656b17234b534d4212d6863078a32c6a7
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Thu Nov 17 12:22:46 2011 +0100
disable wscal extensions and availability-extension so xsdcxx produces compiling code (workaround)
diff --git a/schemas/ical/iCalendar-wscal-extensions.xsd b/schemas/ical/iCalendar-wscal-extensions.xsd
index 4f3c7fe..8f3dcb3 100644
--- a/schemas/ical/iCalendar-wscal-extensions.xsd
+++ b/schemas/ical/iCalendar-wscal-extensions.xsd
@@ -16,6 +16,7 @@
<!--OASIS WS-Calendar extensions to icalendar -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xcal="urn:ietf:params:xml:ns:icalendar-2.0" targetNamespace="urn:ietf:params:xml:ns:icalendar-2.0" elementFormDefault="qualified">
<xs:include schemaLocation="iCalendar-valtypes.xsd"/>
+ <xs:include schemaLocation="iCalendar-availability-extension.xsd"/>
<!-- ===================== Properties ================================= -->
<xs:include schemaLocation="iCalendar-props.xsd"/>
<!-- ===================== Components ================================= -->
diff --git a/schemas/ical/iCalendar.xsd b/schemas/ical/iCalendar.xsd
index def79cb..bd937d7 100644
--- a/schemas/ical/iCalendar.xsd
+++ b/schemas/ical/iCalendar.xsd
@@ -20,8 +20,8 @@
<!-- ===================== Proprietary Extensions ======================= -->
<xs:include schemaLocation="iCalendar-bw-extensions.xsd"/>
<xs:include schemaLocation="iCalendar-ms-extensions.xsd"/>
- <xs:include schemaLocation="iCalendar-availability-extension.xsd"/>
- <xs:include schemaLocation="iCalendar-wscal-extensions.xsd"/>
+<!-- <xs:include schemaLocation="iCalendar-availability-extension.xsd"/> -->
+<!-- <xs:include schemaLocation="iCalendar-wscal-extensions.xsd"/> -->
<!-- =====================================================================
3.4 Calendar Components
===================================================================== -->
commit 8bd9bd3ca300b8db3971beded2453d2d50e73a7a
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Mon Nov 14 23:18:32 2011 +0100
first working SWIG tests
diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index dc1b2a3..350994d 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -57,3 +57,4 @@ include_directories( ./ )
add_library(kolabxml lib/kolabkcalconversion.cpp ${SCHEMA_SOURCEFILES})
target_link_libraries(${kolabxml} xerces-c)
add_subdirectory(tests)
+add_subdirectory(lib)
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
new file mode 100644
index 0000000..342e65a
--- /dev/null
+++ b/c++/lib/CMakeLists.txt
@@ -0,0 +1,31 @@
+
+# add_custom_command(OUTPUT qt_wrap.c
+# COMMAND swig -c++ -python -I$QTPATH/include qt.i
+# COMMENT "Generating qt python bindings"
+# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+# DEPENDS qt.i
+# VERBATIM
+# )
+
+set(KOLAB_SWIG_SOURCE_FILES kolabformat_wrap.cxx)
+add_custom_command(OUTPUT ${KOLAB_SWIG_SOURCE_FILES}
+ COMMAND swig -v -c++ -python kolabformat.i
+ COMMENT "Generating python bindings"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ DEPENDS kolabformat.i
+ VERBATIM
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_SOURCE_FILES} PROPERTIES GENERATED 1)
+
+ADD_CUSTOM_TARGET(generate_python_bindings ALL DEPENDS ${KOLAB_SWIG_SOURCE_FILES})
+
+set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" )
+
+include_directories( ./ )
+include_directories(/usr/include/python2.7)
+
+add_library(bindings SHARED ${KOLAB_SWIG_SOURCE_FILES} kolabformat.cpp)
+ADD_DEPENDENCIES(bindings generate_python_bindings)
+SET_TARGET_PROPERTIES(bindings PROPERTIES OUTPUT_NAME "_kolabformat")
+SET_TARGET_PROPERTIES(bindings PROPERTIES PREFIX "")
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
new file mode 100644
index 0000000..6c45778
--- /dev/null
+++ b/c++/lib/kolabformat.cpp
@@ -0,0 +1,42 @@
+
+
+#include "kolabformat.h"
+
+#include <kcalcore/event.h>
+#include <iostream>
+//#include "note.h"
+
+/*
+QString Kolab::serializeNote(const Kolab::Note& note)
+{
+
+}
+*/
+std::string serializeEvent()
+{
+ std::cout << "ksjdsldfj";
+ return "bla";
+}
+
+void Test::test()
+{
+ std::cout << "test";
+}
+
+
+// QString Kolab::serializeEvent(const KCalCore::Event& event)
+// {
+// return event.summary();
+// }
+
+/*
+Kolab::readIncidence(const QString &string, KCalCore::Incidence &incidence)
+{
+
+}
+*/
+
+// void Kolab::readEvent(const QString &string, KCalCore::Event &event)
+// {
+// event.setSummary(string);
+// }
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
new file mode 100644
index 0000000..fa27675
--- /dev/null
+++ b/c++/lib/kolabformat.h
@@ -0,0 +1,39 @@
+
+#ifndef KOLABFORMAT_H
+#define KOLABFORMAT_H
+//#include <QString>
+#include <string>
+
+namespace KCalCore {
+ class Event;
+}
+
+// namespace Kolab {
+
+//class Note;
+
+/*
+enum TYPE {
+ NoteType,
+ TodoType,
+ EventType,
+ ContactType
+};*/
+
+
+//QString serializeNote(const Note ¬e);
+
+class Test
+{
+public:
+ void test();
+};
+
+std::string serializeEvent();
+
+//QString serializeEvent(const KCalCore::Event ¬e);
+//void readEvent(const QString &string, KCalCore::Event &);
+
+// }
+
+#endif // KOLABFORMAT_H
diff --git a/c++/lib/kolabformat.i b/c++/lib/kolabformat.i
new file mode 100644
index 0000000..cf7ae03
--- /dev/null
+++ b/c++/lib/kolabformat.i
@@ -0,0 +1,18 @@
+/* kolabformat.i */
+ %module kolabformat
+ %{
+ /* Put header files here or function declarations like below */
+ #include "kolabformat.h"
+ %}
+%include "std_string.i"
+
+/*%apply const std::string& {std::string* foo};*/
+
+std::string serializeEvent();
+
+class Test {
+public:
+ void test();
+};
+
+/*extern void readEvent(const QString &string, KCalCore::Event &); */
More information about the commits
mailing list