/* This file is part of libkcal. Copyright (c) 2003 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include "calendar.h" #include "calendarlocal.h" #include "qtopiaformat.h" using namespace KCal; class QtopiaParser : public QXmlDefaultHandler { public: QtopiaParser( Calendar *calendar ) : mCalendar( calendar ) { oldCategories = 0; } bool startElement( const QString &, const QString &, const QString & qName, const QXmlAttributes &attributes ) { if ( qName == "event" ) { Event *event = new Event; QString uid = "Qtopia" + attributes.value( "uid" ); // event->setUid( uid ); event->setSummary( attributes.value( "description" ) ); event->setLocation( attributes.value( "location" ) ); event->setDescription( attributes.value( "note" ) ); event->setDtStart( toDateTime( attributes.value( "start" ) ) ); event->setDtEnd( toDateTime( attributes.value( "end" ) ) ); if ( attributes.value( "type" ) == "AllDay" ) { event->setFloats( true ); } else { event->setFloats( false ); } QString rtype = attributes.value( "rtype" ); if ( !rtype.isEmpty() ) { QDate startDate = event->dtStart().date(); QString freqStr = attributes.value( "rfreq" ); int freq = freqStr.toInt(); QString hasEndDateStr = attributes.value( "rhasenddate" ); bool hasEndDate = hasEndDateStr == "1"; QString endDateStr = attributes.value( "enddt" ); QDate endDate = toDateTime( endDateStr ).date(); QString weekDaysStr = attributes.value( "rweekdays" ); int weekDaysNum = weekDaysStr.toInt(); if ( weekDaysNum == 0 ) weekDaysNum = (1 << (event->dtStart().date().dayOfWeek()-1)); QBitArray weekDays( 7 ); weekDays.fill( false ); int i; for( i = 0; i < 7; ++i ) { weekDays.setBit( i , ( 1 << i ) & weekDaysNum ); qDebug("%d %d %d ",i, weekDaysNum, weekDays.at(i) ); } QString posStr = attributes.value( "rposition" ); int pos = posStr.toInt(); Recurrence *r = event->recurrence(); if ( rtype == "Daily" ) { if ( hasEndDate ) r->setDaily( freq, endDate ); else r->setDaily( freq, -1 ); } else if ( rtype == "Weekly" ) { // fix needed here // rweekdays not set in XML file if ( hasEndDate ) r->setWeekly( freq, weekDays, endDate ); else r->setWeekly( freq, weekDays, -1 ); } else if ( rtype == "MonthlyDate" ) { if ( hasEndDate ) r->setMonthly( Recurrence::rMonthlyDay, freq, endDate ); else r->setMonthly( Recurrence::rMonthlyDay, freq, -1 ); r->addMonthlyDay( startDate.day() ); } else if ( rtype == "MonthlyDay" ) { if ( hasEndDate ) r->setMonthly( Recurrence::rMonthlyPos, freq, endDate ); else r->setMonthly( Recurrence::rMonthlyPos, freq, -1 ); QBitArray days( 7 ); days.fill( false ); days.setBit( startDate.dayOfWeek() - 1 ); r->addMonthlyPos( pos, days ); } else if ( rtype == "Yearly" ) { if ( hasEndDate ) r->setYearly( Recurrence::rYearlyMonth, freq, endDate ); else r->setYearly( Recurrence::rYearlyMonth, freq, -1 ); r->addYearlyNum( startDate.month() ); } } QString categoryList = attributes.value( "categories" ); event->setCategories( lookupCategories( categoryList ) ); QString alarmStr = attributes.value( "alarm" ); if ( !alarmStr.isEmpty() ) { Alarm *alarm = new Alarm( event ); alarm->setType( Alarm::Display ); alarm->setEnabled( true ); int alarmOffset = alarmStr.toInt(); alarm->setStartOffset( alarmOffset * -60 ); event->addAlarm( alarm ); } // the following may not be //Event *oldEvent = mCalendar->event( uid ); //if ( oldEvent ) mCalendar->deleteEvent( oldEvent ); mCalendar->addEventNoDup( event ); } else if ( qName == "Task" ) { Todo *todo = new Todo; QString uid = "Qtopia" + attributes.value( "Uid" ); //todo->setUid( uid ); QString description = attributes.value( "Description" ); int pos = description.find( '\n' ); if ( pos > 0 ) { QString summary = description.left( pos ); todo->setSummary( summary ); todo->setDescription( description ); } else { todo->setSummary( description ); } int priority = attributes.value( "Priority" ).toInt(); if ( priority == 0 ) priority = 3; todo->setPriority( priority ); QString categoryList = attributes.value( "Categories" ); todo->setCategories( lookupCategories( categoryList ) ); QString completedStr = attributes.value( "Completed" ); if ( completedStr == "1" ) todo->setCompleted( true ); QString hasDateStr = attributes.value( "HasDate" ); if ( hasDateStr == "1" ) { int year = attributes.value( "DateYear" ).toInt(); int month = attributes.value( "DateMonth" ).toInt(); int day = attributes.value( "DateDay" ).toInt(); todo->setDtDue( QDateTime( QDate( year, month, day ) ) ); todo->setHasDueDate( true ); } // Todo *oldTodo = mCalendar->todo( uid ); //if ( oldTodo ) mCalendar->deleteTodo( oldTodo ); mCalendar->addTodoNoDup( todo ); } else if ( qName == "Category" ) { QString id = attributes.value( "id" ); QString name = attributes.value( "name" ); setCategory( id, name ); } return true; } bool warning ( const QXmlParseException &exception ) { printException( exception ); return true; } bool error ( const QXmlParseException &exception ) { printException( exception ); return false; } bool fatalError ( const QXmlParseException &exception ) { printException( exception ); return false; } QString errorString () { return "QtopiaParser: Error!"; } void setCategoriesList ( QStringList * c ) { oldCategories = c; } protected: void printException( const QXmlParseException &exception ) { kdError() << "XML Parse Error (line " << exception.lineNumber() << ", col " << exception.columnNumber() << "): " << exception.message() << "(public ID: '" << exception.publicId() << "' system ID: '" << exception.systemId() << "')" << endl; } QDateTime toDateTime( const QString &value ) { QDateTime dt; dt.setTime_t( value.toUInt() ); return dt; } QStringList lookupCategories( const QString &categoryList ) { QStringList categoryIds = QStringList::split( ";", categoryList ); QStringList categories; QStringList::ConstIterator it; for( it = categoryIds.begin(); it != categoryIds.end(); ++it ) { QString cate = category( *it ); if ( oldCategories ) { if ( ! oldCategories->contains( cate ) ) oldCategories->append( cate ); } categories.append(cate ); } return categories; } private: Calendar *mCalendar; QStringList * oldCategories; static QString category( const QString &id ) { QMap::ConstIterator it = mCategoriesMap.find( id ); if ( it == mCategoriesMap.end() ) return id; else return *it; } static void setCategory( const QString &id, const QString &name ) { mCategoriesMap.insert( id, name ); } static QMap mCategoriesMap; }; QMap QtopiaParser::mCategoriesMap; QtopiaFormat::QtopiaFormat() { mCategories = 0; } QtopiaFormat::~QtopiaFormat() { } #include bool QtopiaFormat::load( Calendar *calendar, const QString &fileName ) { clearException(); // qDebug("load QtopiaFormat: %s ",fileName.latin1() ); QtopiaParser handler( calendar ); handler.setCategoriesList( mCategories ); QFile xmlFile( fileName ); QXmlInputSource source( xmlFile ); QXmlSimpleReader reader; reader.setContentHandler( &handler ); return reader.parse( source ); } bool QtopiaFormat::save( Calendar *calendar, const QString &fileName ) { clearException(); QString text = toString( calendar ); if ( text.isNull() ) return false; // TODO: write backup file QFile file( fileName ); if (!file.open( QIODevice::WriteOnly ) ) { setException(new ErrorFormat(ErrorFormat::SaveError, i18n("Could not open file '%1'").arg(fileName))); return false; } Q3TextStream ts( &file ); ts << text; file.close(); return true; } bool QtopiaFormat::fromString( Calendar *, const QString & ) { return false; } QString QtopiaFormat::toString( Calendar * ) { return QString::null; }