00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include <qdatetime.h>
00023
#include <qstring.h>
00024
#include <qptrlist.h>
00025
#include <qregexp.h>
00026
#include <qclipboard.h>
00027
#include <qfile.h>
00028
#include <qtextstream.h>
00029
#include <qxml.h>
00030
00031
#include <kdebug.h>
00032
#include <klocale.h>
00033
00034
#include "calendar.h"
00035
#include "calendarlocal.h"
00036
00037
#include "qtopiaformat.h"
00038
00039
using namespace KCal;
00040
00041
class QtopiaParser :
public QXmlDefaultHandler
00042 {
00043
public:
00044 QtopiaParser(
Calendar *calendar ) : mCalendar( calendar ) {}
00045
00046
bool startElement(
const QString &,
const QString &,
const QString & qName,
00047
const QXmlAttributes &attributes )
00048 {
00049
if ( qName ==
"event" ) {
00050
Event *event =
new Event;
00051
QString uid =
"Qtopia" + attributes.value(
"uid" );
00052 event->
setUid( uid );
00053
00054 event->
setSummary( attributes.value(
"description" ) );
00055 event->
setLocation( attributes.value(
"location" ) );
00056 event->
setDescription( attributes.value(
"note" ) );
00057 event->
setDtStart( toDateTime( attributes.value(
"start" ) ) );
00058 event->
setDtEnd( toDateTime( attributes.value(
"end" ) ) );
00059
00060
if ( attributes.value(
"type" ) ==
"AllDay" ) {
00061 event->
setFloats(
true );
00062 }
else {
00063 event->
setFloats(
false );
00064 }
00065
00066
QString rtype = attributes.value(
"rtype" );
00067
if ( !rtype.isEmpty() ) {
00068
QDate startDate = event->
dtStart().date();
00069
00070
QString freqStr = attributes.value(
"rfreq" );
00071
int freq = freqStr.toInt();
00072
00073
QString hasEndDateStr = attributes.value(
"rhasenddate" );
00074
bool hasEndDate = hasEndDateStr ==
"1";
00075
00076
QString endDateStr = attributes.value(
"enddt" );
00077
QDate endDate = toDateTime( endDateStr ).date();
00078
00079
QString weekDaysStr = attributes.value(
"rweekdays" );
00080
int weekDaysNum = weekDaysStr.toInt();
00081
QBitArray weekDays( 7 );
00082
int i;
00083
for( i = 1; i <= 7; ++i ) {
00084 weekDays.setBit( i - 1, ( 2 << i ) & weekDaysNum );
00085 }
00086
00087
QString posStr = attributes.value(
"rposition" );
00088
int pos = posStr.toInt();
00089
00090
Recurrence *r = event->
recurrence();
00091
00092
if ( rtype ==
"Daily" ) {
00093
if ( hasEndDate ) r->
setDaily( freq, endDate );
00094
else r->
setDaily( freq, -1 );
00095 }
else if ( rtype ==
"Weekly" ) {
00096
if ( hasEndDate ) r->
setWeekly( freq, weekDays, endDate );
00097
else r->
setWeekly( freq, weekDays, -1 );
00098 }
else if ( rtype ==
"MonthlyDate" ) {
00099
if ( hasEndDate )
00100 r->
setMonthly( Recurrence::rMonthlyDay, freq, endDate );
00101
else
00102 r->
setMonthly( Recurrence::rMonthlyDay, freq, -1 );
00103 r->
addMonthlyDay( startDate.day() );
00104 }
else if ( rtype ==
"MonthlyDay" ) {
00105
if ( hasEndDate )
00106 r->
setMonthly( Recurrence::rMonthlyPos, freq, endDate );
00107
else
00108 r->
setMonthly( Recurrence::rMonthlyPos, freq, -1 );
00109
QBitArray days( 7 );
00110 days.fill(
false );
00111 days.setBit( startDate.dayOfWeek() - 1 );
00112 r->
addMonthlyPos( pos, days );
00113 }
else if ( rtype ==
"Yearly" ) {
00114
if ( hasEndDate )
00115 r->
setYearly( Recurrence::rYearlyMonth, freq, endDate );
00116
else
00117 r->
setYearly( Recurrence::rYearlyMonth, freq, -1 );
00118 r->
addYearlyNum( startDate.month() );
00119 }
00120 }
00121
00122
QString categoryList = attributes.value(
"categories" );
00123 event->
setCategories( lookupCategories( categoryList ) );
00124
00125
QString alarmStr = attributes.value(
"alarm" );
00126
if ( !alarmStr.isEmpty() ) {
00127 kdDebug(5800) <<
"Alarm: " << alarmStr << endl;
00128
Alarm *alarm =
new Alarm( event );
00129 alarm->
setType( Alarm::Display );
00130 alarm->
setEnabled(
true );
00131
int alarmOffset = alarmStr.toInt();
00132 alarm->
setStartOffset( alarmOffset * -60 );
00133 event->
addAlarm( alarm );
00134 }
00135
00136 Event *oldEvent = mCalendar->event( uid );
00137
if ( oldEvent ) mCalendar->deleteEvent( oldEvent );
00138
00139 mCalendar->addEvent( event );
00140 }
else if ( qName ==
"Task" ) {
00141
Todo *todo =
new Todo;
00142
00143
QString uid =
"Qtopia" + attributes.value(
"Uid" );
00144 todo->
setUid( uid );
00145
00146
QString description = attributes.value(
"Description" );
00147
int pos = description.find(
'\n' );
00148
if ( pos > 0 ) {
00149
QString summary = description.left( pos );
00150 todo->
setSummary( summary );
00151 todo->
setDescription( description );
00152 }
else {
00153 todo->
setSummary( description );
00154 }
00155
00156
int priority = attributes.value(
"Priority" ).toInt();
00157
if ( priority == 0 ) priority = 3;
00158 todo->
setPriority( priority );
00159
00160
QString categoryList = attributes.value(
"Categories" );
00161 todo->
setCategories( lookupCategories( categoryList ) );
00162
00163
QString completedStr = attributes.value(
"Completed" );
00164
if ( completedStr ==
"1" ) todo->
setCompleted(
true );
00165
00166
QString hasDateStr = attributes.value(
"HasDate" );
00167
if ( hasDateStr ==
"1" ) {
00168
int year = attributes.value(
"DateYear" ).toInt();
00169
int month = attributes.value(
"DateMonth" ).toInt();
00170
int day = attributes.value(
"DateDay" ).toInt();
00171
00172 todo->
setDtDue(
QDateTime(
QDate( year, month, day ) ) );
00173 todo->
setHasDueDate(
true );
00174 }
00175
00176 Todo *oldTodo = mCalendar->todo( uid );
00177
if ( oldTodo ) mCalendar->deleteTodo( oldTodo );
00178
00179 mCalendar->addTodo( todo );
00180 }
else if ( qName ==
"Category" ) {
00181
QString id = attributes.value(
"id" );
00182
QString name = attributes.value(
"name" );
00183 setCategory(
id, name );
00184 }
00185
00186
return true;
00187 }
00188
00189
bool warning (
const QXmlParseException &exception )
00190 {
00191 kdDebug(5800) <<
"WARNING" << endl;
00192 printException( exception );
00193
return true;
00194 }
00195
00196
bool error (
const QXmlParseException &exception )
00197 {
00198 kdDebug(5800) <<
"ERROR" << endl;
00199 printException( exception );
00200
return false;
00201 }
00202
00203
bool fatalError (
const QXmlParseException &exception )
00204 {
00205 kdDebug(5800) <<
"FATALERROR" << endl;
00206 printException( exception );
00207
return false;
00208 }
00209
00210
QString errorString ()
00211 {
00212
return "QtopiaParser: Error!";
00213 }
00214
00215
protected:
00216
void printException(
const QXmlParseException &exception )
00217 {
00218 kdError() <<
"XML Parse Error (line " << exception.lineNumber()
00219 <<
", col " << exception.columnNumber() <<
"): "
00220 << exception.message() <<
"(public ID: '"
00221 << exception.publicId() <<
"' system ID: '"
00222 << exception.systemId() <<
"')" << endl;
00223 }
00224
00225
QDateTime toDateTime(
const QString &value )
00226 {
00227
QDateTime dt;
00228 dt.setTime_t( value.toUInt() );
00229
00230
return dt;
00231 }
00232
00233
QStringList lookupCategories(
const QString &categoryList )
00234 {
00235
QStringList categoryIds = QStringList::split(
";", categoryList );
00236
QStringList categories;
00237 QStringList::ConstIterator it;
00238
for( it = categoryIds.begin(); it != categoryIds.end(); ++it ) {
00239 categories.append( category( *it ) );
00240 }
00241
return categories;
00242 }
00243
00244
private:
00245
Calendar *mCalendar;
00246
00247
static QString category(
const QString &
id )
00248 {
00249
QMap<QString,QString>::ConstIterator it = mCategoriesMap.find(
id );
00250
if ( it == mCategoriesMap.end() )
return id;
00251
else return *it;
00252 }
00253
00254
static void setCategory(
const QString &
id,
const QString &name )
00255 {
00256 mCategoriesMap.insert(
id, name );
00257 }
00258
00259
static QMap<QString,QString> mCategoriesMap;
00260 };
00261
00262
QMap<QString,QString> QtopiaParser::mCategoriesMap;
00263
00264 QtopiaFormat::QtopiaFormat()
00265 {
00266 }
00267
00268 QtopiaFormat::~QtopiaFormat()
00269 {
00270 }
00271
00272 bool QtopiaFormat::load(
Calendar *calendar,
const QString &fileName)
00273 {
00274 kdDebug(5800) <<
"QtopiaFormat::load() " << fileName << endl;
00275
00276
clearException();
00277
00278 QtopiaParser handler( calendar );
00279
QFile xmlFile( fileName );
00280
QXmlInputSource source( xmlFile );
00281
QXmlSimpleReader reader;
00282 reader.setContentHandler( &handler );
00283
return reader.parse( source );
00284 }
00285
00286 bool QtopiaFormat::save(
Calendar *calendar,
const QString &fileName )
00287 {
00288 kdDebug(5800) <<
"QtopiaFormat::save(): " << fileName << endl;
00289
00290
clearException();
00291
00292
QString text =
toString( calendar );
00293
00294
if ( text.isNull() )
return false;
00295
00296
00297
00298
QFile file( fileName );
00299
if (!file.open( IO_WriteOnly ) ) {
00300
setException(
new ErrorFormat(ErrorFormat::SaveError,
00301 i18n(
"Could not open file '%1'").arg(fileName)));
00302
return false;
00303 }
00304
QTextStream ts( &file );
00305 ts << text;
00306 file.close();
00307
00308
return true;
00309 }
00310
00311 bool QtopiaFormat::fromString(
Calendar *,
const QString & )
00312 {
00313 kdDebug(5800) <<
"QtopiaFormat::fromString() not yet implemented." << endl;
00314
return false;
00315 }
00316
00317 QString QtopiaFormat::toString(
Calendar * )
00318 {
00319
return QString::null;
00320 }