summaryrefslogtreecommitdiffabout
path: root/libkcal/sharpformat.cpp
Unidiff
Diffstat (limited to 'libkcal/sharpformat.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/sharpformat.cpp1007
1 files changed, 1007 insertions, 0 deletions
diff --git a/libkcal/sharpformat.cpp b/libkcal/sharpformat.cpp
new file mode 100644
index 0000000..f83f72e
--- a/dev/null
+++ b/libkcal/sharpformat.cpp
@@ -0,0 +1,1007 @@
1/*
2 This file is part of libkcal.
3
4 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20*/
21
22#include <qdatetime.h>
23#include <qstring.h>
24#include <qapplication.h>
25#include <qptrlist.h>
26#include <qregexp.h>
27#include <qmessagebox.h>
28#include <qclipboard.h>
29#include <qfile.h>
30#include <qtextstream.h>
31#include <qtextcodec.h>
32#include <qxml.h>
33#include <qlabel.h>
34
35#include <kdebug.h>
36#include <klocale.h>
37#include <kglobal.h>
38
39#include "calendar.h"
40#include "alarm.h"
41#include "recurrence.h"
42#include "calendarlocal.h"
43
44#include "sharpformat.h"
45
46using namespace KCal;
47
48//CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY
49// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
50
51//ARSD silentalarm = 0
52// 11 RTYP 225 no /0 dialy/ 1 weekly/ 3 month by date/ 2 month by day(pos)/ yearly
53// 12 RFRQ
54// 13 RPOS pos = 4. monday in month
55// 14 RDYS days: 1 mon/ 2 tue .. 64 sun
56// 15 REND 0 = no end/ 1 = end
57// 16 REDT rec end dt
58//ALSD
59//ALED
60//MDAY
61
62class SharpParser : public QObject
63{
64 public:
65 SharpParser( Calendar *calendar ) : mCalendar( calendar ) {
66 oldCategories = 0;
67 }
68
69 bool startElement( Calendar *existingCalendar, const QStringList & attList, QString qName )
70 {
71 int i = 1;
72 bool skip = true;
73 int max = attList.count() -2;
74 while ( i < max ) {
75 if ( !attList[i].isEmpty() ) {
76 skip = false;
77 break;
78 }
79 ++i ;
80 }
81 if ( skip )
82 return false;
83 ulong cSum = SharpFormat::getCsum(attList );
84
85 if ( qName == "Event" ) {
86 Event *event;
87 event = existingCalendar->event( attList[0].toInt() );
88 if ( event )
89 event = (Event*)event->clone();
90 else
91 event = new Event;
92 event->setZaurusId( attList[0].toInt() );
93 event->setZaurusUid( cSum );
94 event->setZaurusStat( -2 );
95
96 event->setSummary( attList[2] );
97 event->setLocation( attList[3] );
98 event->setDescription( attList[4] );
99 if ( attList[7] == "1" ) {
100 event->setDtStart( QDateTime(fromString( attList[17]+"000000", false ).date(),QTime(0,0,0 ) ));
101 event->setDtEnd( QDateTime(fromString( attList[18]+"000000", false ).date(),QTime(0,0,0 )));
102 event->setFloats( true );
103 } else {
104 event->setFloats( false );
105 event->setDtStart( fromString( attList[5] ) );
106 event->setDtEnd( fromString( attList[6] ));
107 }
108
109 QString rtype = attList[11];
110 if ( rtype != "255" ) {
111 // qDebug("recurs ");
112 QDate startDate = event->dtStart().date();
113
114 QString freqStr = attList[12];
115 int freq = freqStr.toInt();
116
117 QString hasEndDateStr = attList[15] ;
118 bool hasEndDate = hasEndDateStr == "1";
119
120 QString endDateStr = attList[16];
121 QDate endDate = fromString( endDateStr ).date();
122
123 QString weekDaysStr = attList[14];
124 uint weekDaysNum = weekDaysStr.toInt();
125
126 QBitArray weekDays( 7 );
127 int i;
128 int bb = 1;
129 for( i = 1; i <= 7; ++i ) {
130 weekDays.setBit( i - 1, ( bb & weekDaysNum ));
131 bb = 2 << (i-1);
132 //qDebug(" %d bit %d ",i-1,weekDays.at(i-1) );
133 }
134 // qDebug("next ");
135 QString posStr = attList[13];
136 int pos = posStr.toInt();
137 Recurrence *r = event->recurrence();
138
139 if ( rtype == "0" ) {
140 if ( hasEndDate ) r->setDaily( freq, endDate );
141 else r->setDaily( freq, -1 );
142 } else if ( rtype == "1" ) {
143 if ( hasEndDate ) r->setWeekly( freq, weekDays, endDate );
144 else r->setWeekly( freq, weekDays, -1 );
145 } else if ( rtype == "3" ) {
146 if ( hasEndDate )
147 r->setMonthly( Recurrence::rMonthlyDay, freq, endDate );
148 else
149 r->setMonthly( Recurrence::rMonthlyDay, freq, -1 );
150 r->addMonthlyDay( startDate.day() );
151 } else if ( rtype == "2" ) {
152 if ( hasEndDate )
153 r->setMonthly( Recurrence::rMonthlyPos, freq, endDate );
154 else
155 r->setMonthly( Recurrence::rMonthlyPos, freq, -1 );
156 QBitArray days( 7 );
157 days.fill( false );
158 days.setBit( startDate.dayOfWeek() - 1 );
159 r->addMonthlyPos( pos, days );
160 } else if ( rtype == "4" ) {
161 if ( hasEndDate )
162 r->setYearly( Recurrence::rYearlyMonth, freq, endDate );
163 else
164 r->setYearly( Recurrence::rYearlyMonth, freq, -1 );
165 r->addYearlyNum( startDate.month() );
166 }
167 }
168
169 QString categoryList = attList[1] ;
170 event->setCategories( lookupCategories( categoryList ) );
171
172 // strange 0 semms to mean: alarm enabled
173 if ( attList[8] == "0" ) {
174 Alarm *alarm;
175 if ( event->alarms().count() > 0 )
176 alarm = event->alarms().first();
177 else {
178 alarm = new Alarm( event );
179 event->addAlarm( alarm );
180 }
181 alarm->setType( Alarm::Audio );
182 alarm->setEnabled( true );
183 int alarmOffset = attList[9].toInt();
184 alarm->setStartOffset( alarmOffset * -60 );
185 }
186
187 mCalendar->addEvent( event);
188 } else if ( qName == "Todo" ) {
189 Todo *todo;
190
191 todo = existingCalendar->todo( attList[0].toInt() );
192 if (todo )
193 todo = (Todo*)todo->clone();
194 else
195 todo = new Todo;
196
197//CARDID,CATEGORY,ETDY,LTDY,FNDY,MARK,PRTY,TITL,MEM1
198// 0 1 2 3 4 5 6 7 8
199//1,,,,,1,4,Loch zumachen,""
200//3,Privat,20040317T000000,20040318T000000,20040319T000000,0,5,Call bbb,"notes123 bbb gggg ""bb "" "
201//2,"Familie,Freunde,Holiday",20040318T000000,20040324T000000,20040317T000000,1,2,tod2,notes
202
203 todo->setZaurusId( attList[0].toInt() );
204 todo->setZaurusUid( cSum );
205 todo->setZaurusStat( -2 );
206
207 todo->setSummary( attList[7] );
208 todo->setDescription( attList[8]);
209
210 int priority = attList[6].toInt();
211 if ( priority == 0 ) priority = 3;
212 todo->setPriority( priority );
213
214 QString categoryList = attList[1];
215 todo->setCategories( lookupCategories( categoryList ) );
216
217
218
219 QString hasDateStr = attList[3]; // due
220 if ( !hasDateStr.isEmpty() ) {
221 if ( hasDateStr.right(6) == "000000" ) {
222 todo->setDtDue( QDateTime(fromString( hasDateStr, false ).date(), QTime(0,0,0 )) );
223 todo->setFloats( true );
224 }
225 else {
226 todo->setDtDue( fromString( hasDateStr ) );
227 todo->setFloats( false );
228 }
229
230 todo->setHasDueDate( true );
231 }
232 hasDateStr = attList[2];//start
233 if ( !hasDateStr.isEmpty() ) {
234
235 todo->setDtStart( fromString( hasDateStr ) );
236 todo->setHasStartDate( true);
237 } else
238 todo->setHasStartDate( false );
239 hasDateStr = attList[4];//completed
240 if ( !hasDateStr.isEmpty() ) {
241 todo->setCompleted(fromString( hasDateStr ) );
242 }
243 QString completedStr = attList[5];
244 if ( completedStr == "0" )
245 todo->setCompleted( true );
246 else
247 todo->setCompleted( false );
248 mCalendar->addTodo( todo );
249
250 } else if ( qName == "Category" ) {
251 /*
252 QString id = attributes.value( "id" );
253 QString name = attributes.value( "name" );
254 setCategory( id, name );
255 */
256 }
257 //qDebug("end ");
258 return true;
259 }
260
261
262 void setCategoriesList ( QStringList * c )
263 {
264 oldCategories = c;
265 }
266
267 QDateTime fromString ( QString s, bool useTz = true ) {
268 QDateTime dt;
269 int y,m,t,h,min,sec;
270 y = s.mid(0,4).toInt();
271 m = s.mid(4,2).toInt();
272 t = s.mid(6,2).toInt();
273 h = s.mid(9,2).toInt();
274 min = s.mid(11,2).toInt();
275 sec = s.mid(13,2).toInt();
276 dt = QDateTime(QDate(y,m,t), QTime(h,min,sec));
277 int offset = KGlobal::locale()->localTimeOffset( dt );
278 if ( useTz )
279 dt = dt.addSecs ( offset*60);
280 return dt;
281
282 }
283 protected:
284 QDateTime toDateTime( const QString &value )
285 {
286 QDateTime dt;
287 dt.setTime_t( value.toUInt() );
288
289 return dt;
290 }
291
292 QStringList lookupCategories( const QString &categoryList )
293 {
294 QStringList categoryIds = QStringList::split( ";", categoryList );
295 QStringList categories;
296 QStringList::ConstIterator it;
297 for( it = categoryIds.begin(); it != categoryIds.end(); ++it ) {
298 QString cate = category( *it );
299 if ( oldCategories ) {
300 if ( ! oldCategories->contains( cate ) )
301 oldCategories->append( cate );
302 }
303 categories.append(cate );
304 }
305 return categories;
306 }
307
308 private:
309 Calendar *mCalendar;
310 QStringList * oldCategories;
311 static QString category( const QString &id )
312 {
313 QMap<QString,QString>::ConstIterator it = mCategoriesMap.find( id );
314 if ( it == mCategoriesMap.end() ) return id;
315 else return *it;
316 }
317
318 static void setCategory( const QString &id, const QString &name )
319 {
320 mCategoriesMap.insert( id, name );
321 }
322
323 static QMap<QString,QString> mCategoriesMap;
324};
325
326QMap<QString,QString> SharpParser::mCategoriesMap;
327
328SharpFormat::SharpFormat()
329{
330 mCategories = 0;
331}
332
333SharpFormat::~SharpFormat()
334{
335}
336ulong SharpFormat::getCsum( const QStringList & attList)
337{
338 int max = attList.count() -1;
339 ulong cSum = 0;
340 int j,k,i;
341 int add;
342 for ( i = 1; i < max ; ++i ) {
343 QString s = attList[i];
344 if ( ! s.isEmpty() ){
345 j = s.length();
346 for ( k = 0; k < j; ++k ) {
347 int mul = k +1;
348 add = s[k].unicode ();
349 if ( k < 16 )
350 mul = mul * mul;
351 add = add * mul *i*i*i;
352 cSum += add;
353 }
354 }
355 }
356 return cSum;
357
358}
359#include <stdlib.h>
360#define DEBUGMODE false
361bool SharpFormat::load( Calendar *calendar, Calendar *existngCal )
362{
363
364
365 bool debug = DEBUGMODE;
366 //debug = true;
367 QString text;
368 QString codec = "utf8";
369 QLabel status ( i18n("Reading events ..."), 0 );
370
371 int w = status.sizeHint().width()+20 ;
372 if ( w < 200 ) w = 200;
373 int h = status.sizeHint().height()+20 ;
374 int dw = QApplication::desktop()->width();
375 int dh = QApplication::desktop()->height();
376 status.setCaption(i18n("Reading DTM Data") );
377 status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
378 status.show();
379 status.raise();
380 qApp->processEvents();
381 QString fileName;
382 if ( ! debug ) {
383 fileName = "/tmp/kopitempout";
384 QString command ="db2file datebook -r -c "+ codec + " > " + fileName;
385 system ( command.latin1() );
386 } else {
387 fileName = "/tmp/events.txt";
388
389 }
390 QFile file( fileName );
391 if (!file.open( IO_ReadOnly ) ) {
392 return false;
393
394 }
395 QTextStream ts( &file );
396 ts.setCodec( QTextCodec::codecForName("utf8") );
397 text = ts.read();
398 file.close();
399 status.setText( i18n("Processing events ...") );
400 status.raise();
401 qApp->processEvents();
402 fromString2Cal( calendar, existngCal, text, "Event" );
403 status.setText( i18n("Reading todos ...") );
404 qApp->processEvents();
405 if ( ! debug ) {
406 fileName = "/tmp/kopitempout";
407 QString command = "db2file todo -r -c " + codec+ " > " + fileName;
408 system ( command.latin1() );
409 } else {
410 fileName = "/tmp/todo.txt";
411 }
412 file.setName( fileName );
413 if (!file.open( IO_ReadOnly ) ) {
414 return false;
415
416 }
417 ts.setDevice( &file );
418 text = ts.read();
419 file.close();
420
421 status.setText( i18n("Processing todos ...") );
422 status.raise();
423 qApp->processEvents();
424 fromString2Cal( calendar, existngCal, text, "Todo" );
425 return true;
426}
427int SharpFormat::getNumFromRecord( QString answer, Incidence* inc )
428{
429 int retval = -1;
430 QStringList templist;
431 QString tempString;
432 int start = 0;
433 int len = answer.length();
434 int end = answer.find ("\n",start)+1;
435 bool ok = true;
436 start = end;
437 int ccc = 0;
438 while ( start > 0 ) {
439 templist.clear();
440 ok = true;
441 int loopCount = 0;
442 while ( ok ) {
443 ++loopCount;
444 if ( loopCount > 25 ) {
445 qDebug("KO: Error in while loop");
446 ok = false;
447 start = 0;
448 break;
449 }
450 if ( ok )
451 tempString = getPart( answer, ok, start );
452 if ( start >= len || start == 0 ) {
453 start = 0;
454 ok = false;
455 }
456 if ( tempString.right(1) =="\n" )
457 tempString = tempString.left( tempString.length()-1);
458
459 templist.append( tempString );
460 }
461 ++ccc;
462 if ( ccc == 2 && loopCount < 25 ) {
463 start = 0;
464 bool ok;
465 int newnum = templist[0].toInt( &ok );
466 if ( ok && newnum > 0) {
467 retval = newnum;
468 inc->setZaurusId( newnum );
469 inc->setZaurusUid( getCsum( templist ) );
470 inc->setZaurusStat( -4 );
471 }
472 }
473 }
474 //qDebug("getNumFromRecord returning : %d ", retval);
475 return retval;
476}
477bool SharpFormat::save( Calendar *calendar)
478{
479
480 QLabel status ( i18n("Processing/adding events ..."), 0 );
481 int w = status.sizeHint().width()+20 ;
482 if ( w < 200 ) w = 200;
483 int h = status.sizeHint().height()+20 ;
484 int dw = QApplication::desktop()->width();
485 int dh = QApplication::desktop()->height();
486 status.setCaption(i18n("Writing DTM Data") );
487 status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
488 status.show();
489 status.raise();
490 qApp->processEvents();
491 bool debug = DEBUGMODE;
492 QString codec = "utf8";
493 QString answer;
494 QString ePrefix = "CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY\n";
495 QString tPrefix = "CARDID,CATEGORY,ETDY,LTDY,FNDY,MARK,PRTY,TITL,MEM1\n";
496 QString command;
497 QPtrList<Event> er = calendar->rawEvents();
498 Event* ev = er.first();
499 QString fileName = "/tmp/kopitempout";
500 int i = 0;
501 QString changeString = ePrefix;
502 QString deleteString = ePrefix;
503 bool deleteEnt = false;
504 bool changeEnt = false;
505 QString message = i18n("Processing event # ");
506 int procCount = 0;
507 while ( ev ) {
508 //qDebug("i %d ", ++i);
509 if ( ev->zaurusStat() != -2 ) {
510 status.setText ( message + QString::number ( ++procCount ) );
511 qApp->processEvents();
512 QString eString = getEventString( ev );
513 if ( ev->zaurusStat() == -3 ) { // delete
514 // deleting empty strings does not work.
515 // we write first and x and then delete the record with the x
516 eString = eString.replace( QRegExp(",\"\""),",\"x\"" );
517 changeString += eString + "\n";
518 deleteString += eString + "\n";
519 deleteEnt = true;
520 changeEnt = true;
521 }
522 else if ( ev->zaurusId() == -1 ) { // add new
523 command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName;
524 system ( command.utf8() );
525 QFile file( fileName );
526 if (!file.open( IO_ReadOnly ) ) {
527 return false;
528
529 }
530 QTextStream ts( &file );
531 ts.setCodec( QTextCodec::codecForName("utf8") );
532 answer = ts.read();
533 file.close();
534 //qDebug("answer \n%s ", answer.latin1());
535 getNumFromRecord( answer, ev ) ;
536
537 }
538 else { // change existing
539 //qDebug("canging %d %d",ev->zaurusStat() ,ev->zaurusId() );
540 //command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName;
541 changeString += eString + "\n";
542 changeEnt = true;
543
544 }
545 }
546 ev = er.next();
547 }
548 status.setText ( i18n("Changing events ...") );
549 qApp->processEvents();
550 //qDebug("changing... ");
551 if ( changeEnt ) {
552 QFile file( fileName );
553 if (!file.open( IO_WriteOnly ) ) {
554 return false;
555
556 }
557 QTextStream ts( &file );
558 ts.setCodec( QTextCodec::codecForName("utf8") );
559 ts << changeString ;
560 file.close();
561 command = "db2file datebook -w -g -c " + codec+ " < "+ fileName;
562 system ( command.latin1() );
563 //qDebug("command %s file :\n%s ", command.latin1(), changeString.latin1());
564
565 }
566 status.setText ( i18n("Deleting events ...") );
567 qApp->processEvents();
568 //qDebug("deleting... ");
569 if ( deleteEnt ) {
570 QFile file( fileName );
571 if (!file.open( IO_WriteOnly ) ) {
572 return false;
573
574 }
575 QTextStream ts( &file );
576 ts.setCodec( QTextCodec::codecForName("utf8") );
577 ts << deleteString;
578 file.close();
579 command = "db2file datebook -d -c " + codec+ " < "+ fileName;
580 system ( command.latin1() );
581 // qDebug("command %s file :\n%s ", command.latin1(), deleteString.latin1());
582 }
583
584
585 changeString = tPrefix;
586 deleteString = tPrefix;
587 status.setText ( i18n("Processing todos ...") );
588 qApp->processEvents();
589 QPtrList<Todo> tl = calendar->rawTodos();
590 Todo* to = tl.first();
591 i = 0;
592 message = i18n("Processing todo # ");
593 procCount = 0;
594 while ( to ) {
595 if ( to->zaurusStat() != -2 ) {
596 status.setText ( message + QString::number ( ++procCount ) );
597 qApp->processEvents();
598 QString eString = getTodoString( to );
599 if ( to->zaurusStat() == -3 ) { // delete
600 // deleting empty strings does not work.
601 // we write first and x and then delete the record with the x
602 eString = eString.replace( QRegExp(",\"\""),",\"x\"" );
603 changeString += eString + "\n";
604 deleteString += eString + "\n";
605 deleteEnt = true;
606 changeEnt = true;
607 }
608 else if ( to->zaurusId() == -1 ) { // add new
609 command = "(echo \"" + tPrefix + eString + "\" ) | db2file todo -w -g -c " + codec+ " > "+ fileName;
610 system ( command.utf8() );
611 QFile file( fileName );
612 if (!file.open( IO_ReadOnly ) ) {
613 return false;
614
615 }
616 QTextStream ts( &file );
617 ts.setCodec( QTextCodec::codecForName("utf8") );
618 answer = ts.read();
619 file.close();
620 //qDebug("answer \n%s ", answer.latin1());
621 getNumFromRecord( answer, to ) ;
622
623 }
624 else { // change existing
625 //qDebug("canging %d %d",to->zaurusStat() ,to->zaurusId() );
626 //command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName;
627 changeString += eString + "\n";
628 changeEnt = true;
629
630 }
631 }
632
633 to = tl.next();
634 }
635 status.setText ( i18n("Changing todos ...") );
636 qApp->processEvents();
637 //qDebug("changing... ");
638 if ( changeEnt ) {
639 QFile file( fileName );
640 if (!file.open( IO_WriteOnly ) ) {
641 return false;
642
643 }
644 QTextStream ts( &file );
645 ts.setCodec( QTextCodec::codecForName("utf8") );
646 ts << changeString ;
647 file.close();
648 command = "db2file todo -w -g -c " + codec+ " < "+ fileName;
649 system ( command.latin1() );
650 //qDebug("command %s file :\n%s ", command.latin1(), changeString.latin1());
651
652 }
653 status.setText ( i18n("Deleting todos ...") );
654 qApp->processEvents();
655 //qDebug("deleting... ");
656 if ( deleteEnt ) {
657 QFile file( fileName );
658 if (!file.open( IO_WriteOnly ) ) {
659 return false;
660
661 }
662 QTextStream ts( &file );
663 ts.setCodec( QTextCodec::codecForName("utf8") );
664 ts << deleteString;
665 file.close();
666 command = "db2file todo -d -c " + codec+ " < "+ fileName;
667 system ( command.latin1() );
668 // qDebug("command %s file :\n%s ", command.latin1(), deleteString.latin1());
669 }
670
671 return true;
672}
673QString SharpFormat::dtToString( const QDateTime& dti, bool useTZ )
674{
675 QString datestr;
676 QString timestr;
677 int offset = KGlobal::locale()->localTimeOffset( dti );
678 QDateTime dt;
679 if (useTZ)
680 dt = dti.addSecs ( -(offset*60));
681 else
682 dt = dti;
683 if(dt.date().isValid()){
684 const QDate& date = dt.date();
685 datestr.sprintf("%04d%02d%02d",
686 date.year(), date.month(), date.day());
687 }
688 if(dt.time().isValid()){
689 const QTime& time = dt.time();
690 timestr.sprintf("T%02d%02d%02d",
691 time.hour(), time.minute(), time.second());
692 }
693 return datestr + timestr;
694}
695QString SharpFormat::getEventString( Event* event )
696{
697 QStringList list;
698 list.append( QString::number(event->zaurusId() ) );
699 list.append( event->categories().join(",") );
700 if ( !event->summary().isEmpty() )
701 list.append( event->summary() );
702 else
703 list.append("" );
704 if ( !event->location().isEmpty() )
705 list.append( event->location() );
706 else
707 list.append("" );
708 if ( !event->description().isEmpty() )
709 list.append( event->description() );
710 else
711 list.append( "" );
712 if ( event->doesFloat () ) {
713 list.append( dtToString( QDateTime(event->dtStart().date(), QTime(0,0,0)), false ));
714 list.append( dtToString( QDateTime(event->dtEnd().date(),QTime(23,59,59)), false )); //6
715 list.append( "1" );
716
717 }
718 else {
719 list.append( dtToString( event->dtStart()) );
720 list.append( dtToString( event->dtEnd()) ); //6
721 list.append( "0" );
722 }
723 bool noAlarm = true;
724 if ( event->alarms().count() > 0 ) {
725 Alarm * al = event->alarms().first();
726 if ( al->enabled() ) {
727 noAlarm = false;
728 list.append( "0" ); // yes, 0 == alarm
729 list.append( QString::number( al->startOffset().asSeconds()/(-60) ) );
730 if ( al->type() == Alarm::Audio )
731 list.append( "1" ); // type audio
732 else
733 list.append( "0" ); // type silent
734 }
735 }
736 if ( noAlarm ) {
737 list.append( "1" ); // yes, 1 == no alarm
738 list.append( "0" ); // no alarm offset
739 list.append( "1" ); // type
740 }
741 // next is: 11
742 // next is: 11-16 are recurrence
743 Recurrence* rec = event->recurrence();
744
745 bool writeEndDate = false;
746 switch ( rec->doesRecur() )
747 {
748 case Recurrence::rDaily: // 0
749 list.append( "0" );
750 list.append( QString::number( rec->frequency() ));//12
751 list.append( "0" );
752 list.append( "0" );
753 writeEndDate = true;
754 break;
755 case Recurrence::rWeekly:// 1
756 list.append( "1" );
757 list.append( QString::number( rec->frequency()) );//12
758 list.append( "0" );
759 {
760 int days = 0;
761 QBitArray weekDays = rec->days();
762 int i;
763 for( i = 1; i <= 7; ++i ) {
764 if ( weekDays[i-1] ) {
765 days += 1 << (i-1);
766 }
767 }
768 list.append( QString::number( days ) );
769 }
770 //pending weekdays
771 writeEndDate = true;
772
773 break;
774 case Recurrence::rMonthlyPos:// 2
775 list.append( "2" );
776 list.append( QString::number( rec->frequency()) );//12
777
778 writeEndDate = true;
779 {
780 int count = 1;
781 QPtrList<Recurrence::rMonthPos> rmp;
782 rmp = rec->monthPositions();
783 if ( rmp.first()->negative )
784 count = 5 - rmp.first()->rPos - 1;
785 else
786 count = rmp.first()->rPos - 1;
787 list.append( QString::number( count ) );
788
789 }
790
791 list.append( "0" );
792 break;
793 case Recurrence::rMonthlyDay:// 3
794 list.append( "3" );
795 list.append( QString::number( rec->frequency()) );//12
796 list.append( "0" );
797 list.append( "0" );
798 writeEndDate = true;
799 break;
800 case Recurrence::rYearlyMonth://4
801 list.append( "4" );
802 list.append( QString::number( rec->frequency()) );//12
803 list.append( "0" );
804 list.append( "0" );
805 writeEndDate = true;
806 break;
807
808 default:
809 list.append( "255" );
810 list.append( QString() );
811 list.append( "0" );
812 list.append( QString() );
813 list.append( "0" );
814 list.append( "20991231T000000" );
815 break;
816 }
817 if ( writeEndDate ) {
818
819 if ( rec->endDate().isValid() ) { // 15 + 16
820 list.append( "1" );
821 list.append( dtToString( rec->endDate()) );
822 } else {
823 list.append( "0" );
824 list.append( "20991231T000000" );
825 }
826
827 }
828 if ( event->doesFloat () ) {
829 list.append( dtToString( event->dtStart(), false ).left( 8 ));
830 list.append( dtToString( event->dtEnd(), false ).left( 8 )); //6
831
832 }
833 else {
834 list.append( QString() );
835 list.append( QString() );
836
837 }
838 if (event->dtStart().date() == event->dtEnd().date() )
839 list.append( "0" );
840 else
841 list.append( "1" );
842
843
844 for(QStringList::Iterator it=list.begin();
845 it!=list.end(); ++it){
846 QString& s = (*it);
847 s.replace(QRegExp("\""), "\"\"");
848 if(s.contains(QRegExp("[,\"\r\n]")) || s.stripWhiteSpace() != s){
849 s.prepend('\"');
850 s.append('\"');
851 } else if(s.isEmpty() && !s.isNull()){
852 s = "\"\"";
853 }
854 }
855 return list.join(",");
856
857
858}
859QString SharpFormat::getTodoString( Todo* todo )
860{
861 QStringList list;
862 list.append( QString::number( todo->zaurusId() ) );
863 list.append( todo->categories().join(",") );
864
865 if ( todo->hasStartDate() ) {
866 list.append( dtToString( todo->dtStart()) );
867 } else
868 list.append( QString() );
869
870 if ( todo->hasDueDate() ) {
871 QTime tim;
872 if ( todo->doesFloat()) {
873 list.append( dtToString( QDateTime(todo->dtDue().date(),QTime( 0,0,0 )), false)) ;
874 } else {
875 list.append( dtToString(todo->dtDue() ) );
876 }
877 } else
878 list.append( QString() );
879
880 if ( todo->isCompleted() ) {
881 list.append( dtToString( todo->completed()) );
882 list.append( "0" ); // yes 0 == completed
883 } else {
884 list.append( dtToString( todo->completed()) );
885 list.append( "1" );
886 }
887 list.append( QString::number( todo->priority() ));
888 if( ! todo->summary().isEmpty() )
889 list.append( todo->summary() );
890 else
891 list.append( "" );
892 if (! todo->description().isEmpty() )
893 list.append( todo->description() );
894 else
895 list.append( "" );
896 for(QStringList::Iterator it=list.begin();
897 it!=list.end(); ++it){
898 QString& s = (*it);
899 s.replace(QRegExp("\""), "\"\"");
900 if(s.contains(QRegExp("[,\"\r\n]")) || s.stripWhiteSpace() != s){
901 s.prepend('\"');
902 s.append('\"');
903 } else if(s.isEmpty() && !s.isNull()){
904 s = "\"\"";
905 }
906 }
907 return list.join(",");
908}
909QString SharpFormat::getPart( const QString & text, bool &ok, int &start )
910{
911 //qDebug("start %d ", start);
912
913 QString retval ="";
914 if ( text.at(start) == '"' ) {
915 if ( text.mid( start,2) == "\"\"" && !( text.mid( start+2,1) == "\"")) {
916 start = start +2;
917 if ( text.mid( start,1) == "," ) {
918 start += 1;
919 }
920 retval = "";
921 if ( text.mid( start,1) == "\n" ) {
922 start += 1;
923 ok = false;
924 }
925 return retval;
926 }
927 int hk = start+1;
928 hk = text.find ('"',hk);
929 while ( text.at(hk+1) == '"' )
930 hk = text.find ('"',hk+2);
931 retval = text.mid( start+1, hk-start-1);
932 start = hk+1;
933 retval.replace( QRegExp("\"\""), "\"");
934 if ( text.mid( start,1) == "," ) {
935 start += 1;
936 }
937 if ( text.mid( start,1) == "\n" ) {
938 start += 1;
939 ok = false;
940 }
941 //qDebug("retval***%s*** ",retval.latin1() );
942 return retval;
943
944 } else {
945 int nl = text.find ("\n",start);
946 int kom = text.find (',',start);
947 if ( kom < nl ) {
948 // qDebug("kom < nl %d ", kom);
949 retval = text.mid(start, kom-start);
950 start = kom+1;
951 return retval;
952 } else {
953 if ( nl == kom ) {
954 // qDebug(" nl == kom ");
955 start = 0;
956 ok = false;
957 return "0";
958 }
959 // qDebug(" nl < kom ", nl);
960 retval = text.mid( start, nl-start);
961 ok = false;
962 start = nl+1;
963 return retval;
964 }
965 }
966}
967bool SharpFormat::fromString( Calendar *calendar, const QString & text)
968{
969 return false;
970}
971bool SharpFormat::fromString2Cal( Calendar *calendar,Calendar *existingCalendar, const QString & text, const QString & type)
972{
973 // qDebug("test %s ", text.latin1());
974 QStringList templist;
975 QString tempString;
976 int start = 0;
977 int len = text.length();
978 int end = text.find ("\n",start)+1;
979 bool ok = true;
980 start = end;
981 SharpParser handler( calendar );
982 handler.setCategoriesList( mCategories );
983 while ( start > 0 ) {
984 templist.clear();
985 ok = true;
986 while ( ok ) {
987 tempString = getPart( text, ok, start );
988 if ( start >= len || start == 0 ) {
989 start = 0;
990 ok = false;
991 }
992 if ( tempString.right(1) =="\n" )
993 tempString = tempString.left( tempString.length()-1);
994 //if ( ok )
995 templist.append( tempString );
996 //qDebug("%d ---%s---", templist.count(),tempString.latin1() );
997 }
998 handler.startElement( existingCalendar, templist, type );
999 }
1000
1001 return false;
1002}
1003
1004QString SharpFormat::toString( Calendar * )
1005{
1006 return QString::null;
1007}