summaryrefslogtreecommitdiffabout
path: root/libkcal
Unidiff
Diffstat (limited to 'libkcal') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/event.cpp46
-rw-r--r--libkcal/event.h2
-rw-r--r--libkcal/phoneformat.cpp104
-rw-r--r--libkcal/phoneformat.h2
-rw-r--r--libkcal/todo.cpp58
-rw-r--r--libkcal/todo.h1
-rw-r--r--libkcal/vcalformat.cpp141
7 files changed, 227 insertions, 127 deletions
diff --git a/libkcal/event.cpp b/libkcal/event.cpp
index dfa265b..7256f05 100644
--- a/libkcal/event.cpp
+++ b/libkcal/event.cpp
@@ -47,24 +47,70 @@ Incidence *Event::clone()
47 return new Event(*this); 47 return new Event(*this);
48} 48}
49 49
50bool KCal::operator==( const Event& e1, const Event& e2 ) 50bool KCal::operator==( const Event& e1, const Event& e2 )
51{ 51{
52 return operator==( (const Incidence&)e1, (const Incidence&)e2 ) && 52 return operator==( (const Incidence&)e1, (const Incidence&)e2 ) &&
53 e1.dtEnd() == e2.dtEnd() && 53 e1.dtEnd() == e2.dtEnd() &&
54 e1.hasEndDate() == e2.hasEndDate() && 54 e1.hasEndDate() == e2.hasEndDate() &&
55 e1.transparency() == e2.transparency(); 55 e1.transparency() == e2.transparency();
56} 56}
57 57
58 58
59bool Event::contains ( Event* from )
60{
61
62 if ( !from->summary().isEmpty() )
63 if ( !summary().startsWith( from->summary() ))
64 return false;
65 if ( from->dtStart().isValid() )
66 if (dtStart() != from->dtStart() )
67 return false;
68 if ( from->dtEnd().isValid() )
69 if ( dtEnd() != from->dtEnd() )
70 return false;
71 if ( !from->location().isEmpty() )
72 if ( !location().startsWith( from->location() ) )
73 return false;
74 if ( !from->description().isEmpty() )
75 if ( !description().startsWith( from->description() ))
76 return false;
77 if ( from->alarms().count() ) {
78 Alarm *a = from->alarms().first();
79 if ( a->enabled() ){
80 if ( !alarms().count() )
81 return false;
82 Alarm *b = alarms().first();
83 if( ! b->enabled() )
84 return false;
85 if ( ! (a->offset() == b->offset() ))
86 return false;
87 }
88 }
89 QStringList cat = categories();
90 QStringList catFrom = from->categories();
91 QString nCat;
92 int iii;
93 for ( iii = 0; iii < catFrom.count();++iii ) {
94 nCat = catFrom[iii];
95 if ( !nCat.isEmpty() )
96 if ( !cat.contains( nCat )) {
97 return false;
98 }
99 }
100 if ( from->doesRecur() )
101 if ( from->doesRecur() != doesRecur() && ! (from->doesRecur()== Recurrence::rYearlyMonth && doesRecur()== Recurrence::rYearlyDay) )
102 return false;
103 return true;
104}
59 105
60void Event::setDtEnd(const QDateTime &dtEnd) 106void Event::setDtEnd(const QDateTime &dtEnd)
61{ 107{
62 if (mReadOnly) return; 108 if (mReadOnly) return;
63 109
64 mDtEnd = getEvenTime( dtEnd ); 110 mDtEnd = getEvenTime( dtEnd );
65 111
66 setHasEndDate(true); 112 setHasEndDate(true);
67 setHasDuration(false); 113 setHasDuration(false);
68 114
69 updated(); 115 updated();
70} 116}
diff --git a/libkcal/event.h b/libkcal/event.h
index 2a8bd95..3bc8adc 100644
--- a/libkcal/event.h
+++ b/libkcal/event.h
@@ -62,24 +62,26 @@ class Event : public Incidence
62 bool hasEndDate() const; 62 bool hasEndDate() const;
63 63
64 /** Return true if the event spans multiple days, otherwise return false. */ 64 /** Return true if the event spans multiple days, otherwise return false. */
65 bool isMultiDay() const; 65 bool isMultiDay() const;
66 66
67 /** set the event's time transparency level. */ 67 /** set the event's time transparency level. */
68 void setTransparency(Transparency transparency); 68 void setTransparency(Transparency transparency);
69 /** get the event's time transparency level. */ 69 /** get the event's time transparency level. */
70 Transparency transparency() const; 70 Transparency transparency() const;
71 71
72 void setDuration(int seconds); 72 void setDuration(int seconds);
73 73
74 bool contains ( Event*);
75
74 private: 76 private:
75 bool accept(Visitor &v) { return v.visit(this); } 77 bool accept(Visitor &v) { return v.visit(this); }
76 78
77 QDateTime mDtEnd; 79 QDateTime mDtEnd;
78 bool mHasEndDate; 80 bool mHasEndDate;
79 Transparency mTransparency; 81 Transparency mTransparency;
80}; 82};
81 83
82bool operator==( const Event&, const Event& ); 84bool operator==( const Event&, const Event& );
83 85
84 86
85} 87}
diff --git a/libkcal/phoneformat.cpp b/libkcal/phoneformat.cpp
index 281434e..101db57 100644
--- a/libkcal/phoneformat.cpp
+++ b/libkcal/phoneformat.cpp
@@ -303,68 +303,75 @@ bool PhoneFormat::load( Calendar *calendar, Calendar *existingCal)
303 vfload.setLocalTime ( true ); 303 vfload.setLocalTime ( true );
304 qDebug("loading file ..."); 304 qDebug("loading file ...");
305 305
306 if ( ! vfload.load( calendar, fileName ) ) 306 if ( ! vfload.load( calendar, fileName ) )
307 return false; 307 return false;
308 QPtrList<Event> er = calendar->rawEvents(); 308 QPtrList<Event> er = calendar->rawEvents();
309 Event* ev = er.first(); 309 Event* ev = er.first();
310 qDebug("reading events... "); 310 qDebug("reading events... ");
311 while ( ev ) { 311 while ( ev ) {
312 QStringList cat = ev->categories(); 312 QStringList cat = ev->categories();
313 if ( cat.contains( "MeetingDEF" )) { 313 if ( cat.contains( "MeetingDEF" )) {
314 ev->setCategories( QStringList() ); 314 ev->setCategories( QStringList() );
315 } else
316 if ( cat.contains( "Birthday" )) {
317 ev->setFloats( true );
318 QDate da = ev->dtStart().date();
319 ev->setDtStart( QDateTime( da) );
320 ev->setDtEnd( QDateTime( da.addDays(1)) );
321
315 } 322 }
323 uint cSum;
324 cSum = PhoneFormat::getCsumEvent( ev );
316 int id = ev->pilotId(); 325 int id = ev->pilotId();
317 Event *event; 326 Event *event;
318 event = existingCal->event( mProfileName ,QString::number( id ) ); 327 event = existingCal->event( mProfileName ,QString::number( id ) );
319 if ( event ) { 328 if ( event ) {
320 event = (Event*)event->clone(); 329 event = (Event*)event->clone();
321 copyEvent( event, ev ); 330 copyEvent( event, ev );
322 calendar->deleteEvent( ev ); 331 calendar->deleteEvent( ev );
323 calendar->addEvent( event); 332 calendar->addEvent( event);
324 } 333 }
325 else 334 else
326 event = ev; 335 event = ev;
327 uint cSum;
328 cSum = PhoneFormat::getCsumEvent( event );
329 event->setCsum( mProfileName, QString::number( cSum )); 336 event->setCsum( mProfileName, QString::number( cSum ));
330 event->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL ); 337 event->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL );
331 event->setID( mProfileName,QString::number( id ) ); 338 event->setID( mProfileName,QString::number( id ) );
332 ev = er.next(); 339 ev = er.next();
333 } 340 }
334 { 341 {
335 qDebug("reading todos... "); 342 qDebug("reading todos... ");
336 QPtrList<Todo> tr = calendar->rawTodos(); 343 QPtrList<Todo> tr = calendar->rawTodos();
337 Todo* ev = tr.first(); 344 Todo* ev = tr.first();
338 while ( ev ) { 345 while ( ev ) {
339 346
340 QStringList cat = ev->categories(); 347 QStringList cat = ev->categories();
341 if ( cat.contains( "MeetingDEF" )) { 348 if ( cat.contains( "MeetingDEF" )) {
342 ev->setCategories( QStringList() ); 349 ev->setCategories( QStringList() );
343 } 350 }
344 int id = ev->pilotId(); 351 int id = ev->pilotId();
352 uint cSum;
353 cSum = PhoneFormat::getCsumTodo( ev );
345 Todo *event; 354 Todo *event;
346 event = existingCal->todo( mProfileName ,QString::number( id ) ); 355 event = existingCal->todo( mProfileName ,QString::number( id ) );
347 if ( event ) { 356 if ( event ) {
348 //qDebug("copy todo %s ", event->summary().latin1()); 357 //qDebug("copy todo %s ", event->summary().latin1());
349 358
350 event = (Todo*)event->clone(); 359 event = (Todo*)event->clone();
351 copyTodo( event, ev ); 360 copyTodo( event, ev );
352 calendar->deleteTodo( ev ); 361 calendar->deleteTodo( ev );
353 calendar->addTodo( event); 362 calendar->addTodo( event);
354 } 363 }
355 else 364 else
356 event = ev; 365 event = ev;
357 uint cSum;
358 cSum = PhoneFormat::getCsumTodo( event );
359 event->setCsum( mProfileName, QString::number( cSum )); 366 event->setCsum( mProfileName, QString::number( cSum ));
360 event->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL ); 367 event->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL );
361 event->setID( mProfileName,QString::number( id ) ); 368 event->setID( mProfileName,QString::number( id ) );
362 ev = tr.next(); 369 ev = tr.next();
363 } 370 }
364 } 371 }
365 return true; 372 return true;
366} 373}
367void PhoneFormat::copyEvent( Event* to, Event* from ) 374void PhoneFormat::copyEvent( Event* to, Event* from )
368{ 375{
369 if ( from->dtStart().isValid() ) 376 if ( from->dtStart().isValid() )
370 to->setDtStart( from->dtStart() ); 377 to->setDtStart( from->dtStart() );
@@ -373,70 +380,69 @@ void PhoneFormat::copyEvent( Event* to, Event* from )
373 if ( !from->location().isEmpty() ) 380 if ( !from->location().isEmpty() )
374 to->setLocation( from->location() ); 381 to->setLocation( from->location() );
375 if ( !from->description().isEmpty() ) 382 if ( !from->description().isEmpty() )
376 to->setDescription( from->description() ); 383 to->setDescription( from->description() );
377 if ( !from->summary().isEmpty() ) 384 if ( !from->summary().isEmpty() )
378 to->setSummary( from->summary() ); 385 to->setSummary( from->summary() );
379 386
380 if ( from->alarms().count() ) { 387 if ( from->alarms().count() ) {
381 to->clearAlarms(); 388 to->clearAlarms();
382 Alarm *a = from->alarms().first(); 389 Alarm *a = from->alarms().first();
383 Alarm *b = to->newAlarm( ); 390 Alarm *b = to->newAlarm( );
384 b->setEnabled( a->enabled() ); 391 b->setEnabled( a->enabled() );
385 if ( a->hasStartOffset() ) { 392 b->setStartOffset(Duration( a->offset() ) );
386 b->setStartOffset( a->startOffset() );
387 }
388 if ( a->hasTime() )
389 b->setTime( a->time() );
390 393
391 } 394 }
392 QStringList cat = to->categories(); 395 QStringList cat = to->categories();
393 QStringList catFrom = from->categories(); 396 QStringList catFrom = from->categories();
394 QString nCat; 397 QString nCat;
395 int iii; 398 int iii;
396 for ( iii = 0; iii < catFrom.count();++iii ) { 399 for ( iii = 0; iii < catFrom.count();++iii ) {
397 nCat = catFrom[iii]; 400 nCat = catFrom[iii];
398 if ( !nCat.isEmpty() ) 401 if ( !nCat.isEmpty() )
399 if ( !cat.contains( nCat )) { 402 if ( !cat.contains( nCat )) {
400 cat << nCat; 403 cat << nCat;
401 } 404 }
402 } 405 }
403 to->setCategories( cat ); 406 to->setCategories( cat );
404 Recurrence * r = new Recurrence( *from->recurrence(),to); 407 if ( from->doesRecur() ) {
405 to->setRecurrence( r ) ; 408 Recurrence * r = new Recurrence( *from->recurrence(),to);
409 to->setRecurrence( r ) ;
410 }
406 411
407 412
408} 413}
409void PhoneFormat::copyTodo( Todo* to, Todo* from ) 414void PhoneFormat::copyTodo( Todo* to, Todo* from )
410{ 415{
411 if ( from->dtStart().isValid() ) 416 if ( from->hasStartDate() ) {
417 to->setHasStartDate( true );
412 to->setDtStart( from->dtStart() ); 418 to->setDtStart( from->dtStart() );
413 if ( from->dtDue().isValid() ) 419 }
420 if ( from->hasDueDate() ){
421 to->setHasDueDate( true );
414 to->setDtDue( from->dtDue() ); 422 to->setDtDue( from->dtDue() );
423 }
415 if ( !from->location().isEmpty() ) 424 if ( !from->location().isEmpty() )
416 to->setLocation( from->location() ); 425 to->setLocation( from->location() );
417 if ( !from->description().isEmpty() ) 426 if ( !from->description().isEmpty() )
418 to->setDescription( from->description() ); 427 to->setDescription( from->description() );
419 if ( !from->summary().isEmpty() ) 428 if ( !from->summary().isEmpty() )
420 to->setSummary( from->summary() ); 429 to->setSummary( from->summary() );
421 430
422 if ( from->alarms().count() ) { 431 if ( from->alarms().count() ) {
423 to->clearAlarms(); 432 to->clearAlarms();
424 Alarm *a = from->alarms().first(); 433 Alarm *a = from->alarms().first();
425 Alarm *b = to->newAlarm( ); 434 Alarm *b = to->newAlarm( );
426 b->setEnabled( a->enabled() ); 435 b->setEnabled( a->enabled() );
427 if ( a->hasStartOffset() ) 436 b->setStartOffset(Duration( a->offset() ) );
428 b->setStartOffset( a->startOffset() );
429 if ( a->hasTime() )
430 b->setTime( a->time() );
431 } 437 }
432 438
433 QStringList cat = to->categories(); 439 QStringList cat = to->categories();
434 QStringList catFrom = from->categories(); 440 QStringList catFrom = from->categories();
435 QString nCat; 441 QString nCat;
436 int iii; 442 int iii;
437 for ( iii = 0; iii < catFrom.count();++iii ) { 443 for ( iii = 0; iii < catFrom.count();++iii ) {
438 nCat = catFrom[iii]; 444 nCat = catFrom[iii];
439 if ( !nCat.isEmpty() ) 445 if ( !nCat.isEmpty() )
440 if ( !cat.contains( nCat )) { 446 if ( !cat.contains( nCat )) {
441 cat << nCat; 447 cat << nCat;
442 } 448 }
@@ -452,69 +458,52 @@ void PhoneFormat::copyTodo( Todo* to, Todo* from )
452 to->setPercentComplete(from->percentComplete()); 458 to->setPercentComplete(from->percentComplete());
453 } 459 }
454 if( to->priority() == 2 && from->priority() == 1 ) 460 if( to->priority() == 2 && from->priority() == 1 )
455 ; //skip 461 ; //skip
456 else if (to->priority() == 4 && from->priority() == 5 ) 462 else if (to->priority() == 4 && from->priority() == 5 )
457 ; 463 ;
458 else 464 else
459 to->setPriority(from->priority()); 465 to->setPriority(from->priority());
460 466
461} 467}
462#include <qcstring.h> 468#include <qcstring.h>
463 469
464void PhoneFormat::afterSave( Incidence* inc) 470void PhoneFormat::afterSave( Incidence* inc,const QString& id ,const QString& csum)
465{ 471{
466 uint csum; 472 inc->setID( mProfileName, id );
467 inc->removeID( mProfileName ); 473 inc->setCsum( mProfileName, csum);
468 if ( inc->type() == "Event")
469 csum = PhoneFormat::getCsumEvent( (Event*) inc );
470 else
471 csum = PhoneFormat::getCsumTodo( (Todo*) inc );
472 inc->setCsum( mProfileName, QString::number( csum ));
473
474 inc->setTempSyncStat( SYNC_TEMPSTATE_NEW_ID ); 474 inc->setTempSyncStat( SYNC_TEMPSTATE_NEW_ID );
475 475
476} 476}
477 477
478bool PhoneFormat::writeToPhone( Calendar * calendar) 478bool PhoneFormat::writeToPhone( Calendar * calendar)
479{ 479{
480#ifdef _WIN32_ 480#ifdef _WIN32_
481 QString fileName = locateLocal("tmp", "tempfile.vcs"); 481 QString fileName = locateLocal("tmp", "phonefile.vcs");
482#else 482#else
483 QString fileName = "/tmp/kdepimtemp.vcs"; 483 QString fileName = "/tmp/phonefile.vcs";
484#endif 484#endif
485 485
486 VCalFormat vfsave; 486 VCalFormat vfsave;
487 vfsave.setLocalTime ( true ); 487 vfsave.setLocalTime ( true );
488 QString id = calendar->timeZoneId(); 488 QString id = calendar->timeZoneId();
489 calendar->setLocalTime(); 489 calendar->setLocalTime();
490 if ( ! vfsave.save( calendar, fileName ) ) 490 if ( ! vfsave.save( calendar, fileName ) )
491 return false; 491 return false;
492 calendar->setTimeZoneId( id ); 492 calendar->setTimeZoneId( id );
493 return PhoneAccess::writeToPhone( fileName ); 493 return PhoneAccess::writeToPhone( fileName );
494} 494}
495bool PhoneFormat::save( Calendar *calendar) 495bool PhoneFormat::save( Calendar *calendar)
496{ 496{
497 QLabel status ( i18n(" Opening device ..."), 0 ); 497
498 int w = status.sizeHint().width()+20 ;
499 if ( w < 200 ) w = 230;
500 int h = status.sizeHint().height()+20 ;
501 int dw = QApplication::desktop()->width();
502 int dh = QApplication::desktop()->height();
503 status.setCaption(i18n("Writing to phone...") );
504 status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
505 status.show();
506 status.raise();
507 qApp->processEvents();
508 QString message;
509 498
510 // 1 remove events which should be deleted 499 // 1 remove events which should be deleted
511 QPtrList<Event> er = calendar->rawEvents(); 500 QPtrList<Event> er = calendar->rawEvents();
512 Event* ev = er.first(); 501 Event* ev = er.first();
513 while ( ev ) { 502 while ( ev ) {
514 if ( ev->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { 503 if ( ev->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) {
515 calendar->deleteEvent( ev ); 504 calendar->deleteEvent( ev );
516 } else { 505 } else {
517 506
518 } 507 }
519 ev = er.next(); 508 ev = er.next();
520 } 509 }
@@ -525,95 +514,92 @@ bool PhoneFormat::save( Calendar *calendar)
525 if ( to->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { 514 if ( to->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) {
526 calendar->deleteTodo( to ); 515 calendar->deleteTodo( to );
527 } else { 516 } else {
528 if ( to->isCompleted()) { 517 if ( to->isCompleted()) {
529 calendar->deleteTodo( to ); 518 calendar->deleteTodo( to );
530 } 519 }
531 } 520 }
532 to = tl.next(); 521 to = tl.next();
533 } 522 }
534 // 3 save file 523 // 3 save file
535 if ( !writeToPhone( calendar ) ) 524 if ( !writeToPhone( calendar ) )
536 return false; 525 return false;
537 526 QLabel status ( i18n(" Opening device ..."), 0 );
527 int w = status.sizeHint().width()+20 ;
528 if ( w < 200 ) w = 230;
529 int h = status.sizeHint().height()+20 ;
530 int dw = QApplication::desktop()->width();
531 int dh = QApplication::desktop()->height();
532 status.setCaption(i18n("Writing to phone...") );
533 status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
534 QString message;
535 status.show();
536 status.raise();
537 qApp->processEvents();
538 // 5 reread data 538 // 5 reread data
539 message = i18n(" Rereading all data ... "); 539 message = i18n(" Rereading all data ... ");
540 status.setText ( message ); 540 status.setText ( message );
541 qApp->processEvents(); 541 qApp->processEvents();
542 CalendarLocal* calendarTemp = new CalendarLocal(); 542 CalendarLocal* calendarTemp = new CalendarLocal();
543 calendarTemp->setTimeZoneId( calendar->timeZoneId()); 543 calendarTemp->setTimeZoneId( calendar->timeZoneId());
544 if ( ! load( calendarTemp,calendar) ){ 544 if ( ! load( calendarTemp,calendar) ){
545 qDebug("error reloading calendar "); 545 qDebug("error reloading calendar ");
546 delete calendarTemp; 546 delete calendarTemp;
547 return false; 547 return false;
548 } 548 }
549 // 6 compare data 549 // 6 compare data
550 550
551//algo 6 compare event 551//algo 6 compare event
552 er = calendar->rawEvents(); 552 er = calendar->rawEvents();
553 ev = er.first(); 553 ev = er.first();
554 message = i18n(" Comparing event # "); 554 message = i18n(" Comparing event # ");
555 QPtrList<Event> er1 = calendarTemp->rawEvents(); 555 QPtrList<Event> er1 = calendarTemp->rawEvents();
556 Event* ev1; 556 Event* ev1;
557 int procCount = 0; 557 int procCount = 0;
558 while ( ev ) { 558 while ( ev ) {
559 //qDebug("event new ID %s",ev->summary().latin1()); 559 //qDebug("event new ID %s",ev->summary().latin1());
560 status.setText ( message + QString::number ( ++procCount ) ); 560 status.setText ( message + QString::number ( ++procCount ) );
561 qApp->processEvents(); 561 qApp->processEvents();
562 uint csum;
563 csum = PhoneFormat::getCsumEvent( ev );
564 QString cSum = QString::number( csum );
565 //ev->setCsum( mProfileName, cSum );
566 //qDebug("Event cSum %s ", cSum.latin1());
567 ev1 = er1.first(); 562 ev1 = er1.first();
568 while ( ev1 ) { 563 while ( ev1 ) {
569 if ( ev1->getCsum( mProfileName ) == cSum ) { 564 if ( ev->contains( ev1 ) ) {
565 afterSave( ev ,ev1->getID(mProfileName),ev1->getCsum(mProfileName));
570 er1.remove( ev1 ); 566 er1.remove( ev1 );
571 afterSave( ev );
572 ev->setID(mProfileName, ev1->getID(mProfileName) );
573 //qDebug("Event found on phone for %s ", ev->summary().latin1());
574
575 break; 567 break;
576 } 568 }
577 ev1 = er1.next(); 569 ev1 = er1.next();
578 } 570 }
579 if ( ! ev1 ) { 571 if ( ! ev1 ) {
580 // ev->removeID(mProfileName); 572 // ev->removeID(mProfileName);
581 qDebug("ERROR: No event found on phone for %s ", ev->summary().latin1()); 573 qDebug("ERROR: No event found on phone for %s ", ev->summary().latin1());
582 } 574 }
583 575
584 576
585 ev = er.next(); 577 ev = er.next();
586 } 578 }
587 //algo 6 compare todo 579 //algo 6 compare todo
588 tl = calendar->rawTodos(); 580 tl = calendar->rawTodos();
589 to = tl.first(); 581 to = tl.first();
590 procCount = 0; 582 procCount = 0;
591 QPtrList<Todo> tl1 = calendarTemp->rawTodos(); 583 QPtrList<Todo> tl1 = calendarTemp->rawTodos();
592 Todo* to1 ; 584 Todo* to1 ;
593 message = i18n(" Comparing todo # "); 585 message = i18n(" Comparing todo # ");
594 while ( to ) { 586 while ( to ) {
595 status.setText ( message + QString::number ( ++procCount ) ); 587 status.setText ( message + QString::number ( ++procCount ) );
596 qApp->processEvents(); 588 qApp->processEvents();
597 uint csum;
598 csum = PhoneFormat::getCsumTodo( to );
599 QString cSum = QString::number( csum );
600 //to->setCsum( mProfileName, cSum );
601 //qDebug("Todo cSum %s ", cSum.latin1());
602 Todo* to1 = tl1.first(); 589 Todo* to1 = tl1.first();
603 while ( to1 ) { 590 while ( to1 ) {
604 if ( to1->getCsum( mProfileName ) == cSum ) { 591 if ( to->contains( to1 ) ) {
592 afterSave( to ,to1->getID(mProfileName),to1->getCsum(mProfileName));
605 tl1.remove( to1 ); 593 tl1.remove( to1 );
606 afterSave( to );
607 to->setID(mProfileName, to1->getID(mProfileName) );
608 break; 594 break;
609 } 595 }
610 to1 = tl1.next(); 596 to1 = tl1.next();
611 } 597 }
612 if ( ! to1 ) { 598 if ( ! to1 ) {
613 //to->removeID(mProfileName); 599 //to->removeID(mProfileName);
614 qDebug("ERROR: No todo found on phone for %s ", to->summary().latin1()); 600 qDebug("ERROR: No todo found on phone for %s ", to->summary().latin1());
615 } 601 }
616 602
617 to = tl.next(); 603 to = tl.next();
618 } 604 }
619 delete calendarTemp; 605 delete calendarTemp;
diff --git a/libkcal/phoneformat.h b/libkcal/phoneformat.h
index 001fd81..d11f68b 100644
--- a/libkcal/phoneformat.h
+++ b/libkcal/phoneformat.h
@@ -45,18 +45,18 @@ class PhoneFormat : public QObject {
45 bool save( Calendar * ); 45 bool save( Calendar * );
46 bool fromString( Calendar *, const QString & ); 46 bool fromString( Calendar *, const QString & );
47 QString toString( Calendar * ); 47 QString toString( Calendar * );
48 static ulong getCsum( const QStringList & ); 48 static ulong getCsum( const QStringList & );
49 static ulong getCsumTodo( Todo* to ); 49 static ulong getCsumTodo( Todo* to );
50 static ulong getCsumEvent( Event* ev ); 50 static ulong getCsumEvent( Event* ev );
51 static bool writeToPhone( Calendar * ); 51 static bool writeToPhone( Calendar * );
52 private: 52 private:
53 void copyEvent( Event* to, Event* from ); 53 void copyEvent( Event* to, Event* from );
54 void copyTodo( Todo* to, Todo* from ); 54 void copyTodo( Todo* to, Todo* from );
55 //int initDevice(GSM_StateMachine *s); 55 //int initDevice(GSM_StateMachine *s);
56 QString mProfileName; 56 QString mProfileName;
57 void afterSave( Incidence* ); 57 void afterSave( Incidence* ,const QString&,const QString&);
58}; 58};
59 59
60} 60}
61 61
62#endif 62#endif
diff --git a/libkcal/todo.cpp b/libkcal/todo.cpp
index 0c1e3e4..3d2de61 100644
--- a/libkcal/todo.cpp
+++ b/libkcal/todo.cpp
@@ -47,25 +47,83 @@ Todo::Todo(const Todo &t) : Incidence(t)
47} 47}
48 48
49Todo::~Todo() 49Todo::~Todo()
50{ 50{
51 51
52} 52}
53 53
54Incidence *Todo::clone() 54Incidence *Todo::clone()
55{ 55{
56 return new Todo(*this); 56 return new Todo(*this);
57} 57}
58 58
59bool Todo::contains ( Todo* from )
60{
59 61
62 if ( !from->summary().isEmpty() )
63 if ( !summary().startsWith( from->summary() ))
64 return false;
65 if ( from->hasStartDate() ) {
66 if ( !hasStartDate() )
67 return false;
68 if ( from->dtStart() != dtStart())
69 return false;
70 }
71 if ( from->hasDueDate() ){
72 if ( !hasDueDate() )
73 return false;
74 if ( from->dtDue() != dtDue())
75 return false;
76 }
77 if ( !from->location().isEmpty() )
78 if ( !location().startsWith( from->location() ) )
79 return false;
80 if ( !from->description().isEmpty() )
81 if ( !description().startsWith( from->description() ))
82 return false;
83 if ( from->alarms().count() ) {
84 Alarm *a = from->alarms().first();
85 if ( a->enabled() ){
86 if ( !alarms().count() )
87 return false;
88 Alarm *b = alarms().first();
89 if( ! b->enabled() )
90 return false;
91 if ( ! (a->offset() == b->offset() ))
92 return false;
93 }
94 }
95
96 QStringList cat = categories();
97 QStringList catFrom = from->categories();
98 QString nCat;
99 int iii;
100 for ( iii = 0; iii < catFrom.count();++iii ) {
101 nCat = catFrom[iii];
102 if ( !nCat.isEmpty() )
103 if ( !cat.contains( nCat )) {
104 return false;
105 }
106 }
107 if ( from->isCompleted() ) {
108 if ( !isCompleted() )
109 return false;
110 }
111 if( priority() != from->priority() )
112 return false;
113
114
115 return true;
116
117}
60bool KCal::operator==( const Todo& t1, const Todo& t2 ) 118bool KCal::operator==( const Todo& t1, const Todo& t2 )
61{ 119{
62 120
63 bool ret = operator==( (const Incidence&)t1, (const Incidence&)t2 ); 121 bool ret = operator==( (const Incidence&)t1, (const Incidence&)t2 );
64 if ( ! ret ) 122 if ( ! ret )
65 return false; 123 return false;
66 if ( t1.hasDueDate() == t2.hasDueDate() ) { 124 if ( t1.hasDueDate() == t2.hasDueDate() ) {
67 if ( t1.hasDueDate() ) { 125 if ( t1.hasDueDate() ) {
68 if ( t1.doesFloat() == t2.doesFloat() ) { 126 if ( t1.doesFloat() == t2.doesFloat() ) {
69 if ( t1.doesFloat() ) { 127 if ( t1.doesFloat() ) {
70 if ( t1.dtDue().date() != t2.dtDue().date() ) 128 if ( t1.dtDue().date() != t2.dtDue().date() )
71 return false; 129 return false;
diff --git a/libkcal/todo.h b/libkcal/todo.h
index 9aa92f8..0f22c59 100644
--- a/libkcal/todo.h
+++ b/libkcal/todo.h
@@ -90,24 +90,25 @@ class Todo : public Incidence
90 range from 0 to 100. 90 range from 0 to 100.
91 */ 91 */
92 void setPercentComplete(int); 92 void setPercentComplete(int);
93 93
94 /** return date and time when todo was completed */ 94 /** return date and time when todo was completed */
95 QDateTime completed() const; 95 QDateTime completed() const;
96 QString completedStr() const; 96 QString completedStr() const;
97 /** set date and time of completion */ 97 /** set date and time of completion */
98 void setCompleted(const QDateTime &completed); 98 void setCompleted(const QDateTime &completed);
99 99
100 /** Return true, if todo has a date associated with completion */ 100 /** Return true, if todo has a date associated with completion */
101 bool hasCompletedDate() const; 101 bool hasCompletedDate() const;
102 bool contains ( Todo*);
102 103
103 private: 104 private:
104 bool accept(Visitor &v) { return v.visit(this); } 105 bool accept(Visitor &v) { return v.visit(this); }
105 106
106 QDateTime mDtDue; // due date of todo 107 QDateTime mDtDue; // due date of todo
107 108
108 bool mHasDueDate; // if todo has associated due date 109 bool mHasDueDate; // if todo has associated due date
109 110
110// int mStatus; // confirmed/delegated/tentative/etc 111// int mStatus; // confirmed/delegated/tentative/etc
111 112
112 QDateTime mCompleted; 113 QDateTime mCompleted;
113 bool mHasCompletedDate; 114 bool mHasCompletedDate;
diff --git a/libkcal/vcalformat.cpp b/libkcal/vcalformat.cpp
index a6ae1bc..df93209 100644
--- a/libkcal/vcalformat.cpp
+++ b/libkcal/vcalformat.cpp
@@ -53,25 +53,26 @@ VCalFormat::VCalFormat()
53VCalFormat::~VCalFormat() 53VCalFormat::~VCalFormat()
54{ 54{
55} 55}
56 56
57void VCalFormat::setLocalTime ( bool b ) 57void VCalFormat::setLocalTime ( bool b )
58{ 58{
59 useLocalTime = b; 59 useLocalTime = b;
60} 60}
61bool VCalFormat::load(Calendar *calendar, const QString &fileName) 61bool VCalFormat::load(Calendar *calendar, const QString &fileName)
62{ 62{
63 mCalendar = calendar; 63 mCalendar = calendar;
64 clearException(); 64 clearException();
65 useLocalTime = mCalendar->isLocalTime(); 65 if ( ! useLocalTime )
66 useLocalTime = mCalendar->isLocalTime();
66 VObject *vcal = 0; 67 VObject *vcal = 0;
67 68
68 // this is not necessarily only 1 vcal. Could be many vcals, or include 69 // this is not necessarily only 1 vcal. Could be many vcals, or include
69 // a vcard... 70 // a vcard...
70 vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data())); 71 vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data()));
71 72
72 if (!vcal) { 73 if (!vcal) {
73 setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); 74 setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
74 return FALSE; 75 return FALSE;
75 } 76 }
76 77
77 // any other top-level calendar stuff should be added/initialized here 78 // any other top-level calendar stuff should be added/initialized here
@@ -81,25 +82,26 @@ bool VCalFormat::load(Calendar *calendar, const QString &fileName)
81 82
82 // clean up from vcal API stuff 83 // clean up from vcal API stuff
83 cleanVObjects(vcal); 84 cleanVObjects(vcal);
84 cleanStrTbl(); 85 cleanStrTbl();
85 86
86 return true; 87 return true;
87} 88}
88 89
89 90
90bool VCalFormat::save(Calendar *calendar, const QString &fileName) 91bool VCalFormat::save(Calendar *calendar, const QString &fileName)
91{ 92{
92 mCalendar = calendar; 93 mCalendar = calendar;
93 useLocalTime = mCalendar->isLocalTime(); 94 if ( ! useLocalTime )
95 useLocalTime = mCalendar->isLocalTime();
94 96
95 QString tmpStr; 97 QString tmpStr;
96 VObject *vcal, *vo; 98 VObject *vcal, *vo;
97 99
98 100
99 vcal = newVObject(VCCalProp); 101 vcal = newVObject(VCCalProp);
100 102
101 // addPropValue(vcal,VCLocationProp, "0.0"); 103 // addPropValue(vcal,VCLocationProp, "0.0");
102 addPropValue(vcal,VCProdIdProp, productId()); 104 addPropValue(vcal,VCProdIdProp, productId());
103 tmpStr = mCalendar->getTimeZoneStr(); 105 tmpStr = mCalendar->getTimeZoneStr();
104 //qDebug("mCalendar->getTimeZoneStr() %s",tmpStr.latin1() ); 106 //qDebug("mCalendar->getTimeZoneStr() %s",tmpStr.latin1() );
105 addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit()); 107 addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit());
@@ -1163,90 +1165,94 @@ Event* VCalFormat::VEventToEvent(VObject *vevent)
1163 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rEndDate); 1165 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rEndDate);
1164 } else { 1166 } else {
1165 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1167 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1166 if (rDuration == 0) 1168 if (rDuration == 0)
1167 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, -1); 1169 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, -1);
1168 else 1170 else
1169 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rDuration); 1171 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rDuration);
1170 } 1172 }
1171 } 1173 }
1172 1174
1173 /*********************** YEARLY-BY-MONTH *******************************/ 1175 /*********************** YEARLY-BY-MONTH *******************************/
1174 else if (tmpStr.left(2) == "YM") { 1176 else if (tmpStr.left(2) == "YM") {
1175 int index = tmpStr.find(' '); 1177 // we have to set this such that recurrence accepts addYearlyNum(tmpDay);
1176 int last = tmpStr.findRev(' ') + 1; 1178 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, 1, -1);
1177 int rFreq = tmpStr.mid(2, (index-1)).toInt(); 1179 int index = tmpStr.find(' ');
1178 index += 1; 1180 int last = tmpStr.findRev(' ') + 1;
1179 short tmpMonth; 1181 int rFreq = tmpStr.mid(2, (index-1)).toInt();
1180 if( index == last ) { 1182 index += 1;
1181 // e.g. YM1 #0 1183 short tmpMonth;
1182 tmpMonth = anEvent->dtStart().date().month(); 1184 if( index == last ) {
1183 anEvent->recurrence()->addYearlyNum(tmpMonth); 1185 // e.g. YM1 #0
1184 } 1186 tmpMonth = anEvent->dtStart().date().month();
1185 else { 1187 anEvent->recurrence()->addYearlyNum(tmpMonth);
1186 // e.g. YM1 3 #0 1188 }
1187 while (index < last) { 1189 else {
1188 int index2 = tmpStr.find(' ', index); 1190 // e.g. YM1 3 #0
1189 tmpMonth = tmpStr.mid(index, (index2-index)).toShort(); 1191 while (index < last) {
1190 index = index2+1; 1192 int index2 = tmpStr.find(' ', index);
1191 anEvent->recurrence()->addYearlyNum(tmpMonth); 1193 tmpMonth = tmpStr.mid(index, (index2-index)).toShort();
1192 } // while != # 1194 index = index2+1;
1193 } 1195 anEvent->recurrence()->addYearlyNum(tmpMonth);
1194 index = last; if (tmpStr.mid(index,1) == "#") index++; 1196 } // while != #
1195 if (tmpStr.find('T', index) != -1) { 1197 }
1196 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1198 index = last; if (tmpStr.mid(index,1) == "#") index++;
1197 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rEndDate); 1199 if (tmpStr.find('T', index) != -1) {
1198 } else { 1200 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1199 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1201 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rEndDate);
1200 if (rDuration == 0) 1202 } else {
1201 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, -1); 1203 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1202 else 1204 if (rDuration == 0)
1203 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rDuration); 1205 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, -1);
1204 } 1206 else
1207 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rDuration);
1208 }
1205 } 1209 }
1206 1210
1207 /*********************** YEARLY-BY-DAY *********************************/ 1211 /*********************** YEARLY-BY-DAY *********************************/
1208 else if (tmpStr.left(2) == "YD") { 1212 else if (tmpStr.left(2) == "YD") {
1209 int index = tmpStr.find(' '); 1213 // we have to set this such that recurrence accepts addYearlyNum(tmpDay);
1210 int last = tmpStr.findRev(' ') + 1; 1214 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, 1, -1);
1211 int rFreq = tmpStr.mid(2, (index-1)).toInt(); 1215 int index = tmpStr.find(' ');
1212 index += 1; 1216 int last = tmpStr.findRev(' ') + 1;
1213 short tmpDay; 1217 int rFreq = tmpStr.mid(2, (index-1)).toInt();
1214 if( index == last ) { 1218 index += 1;
1215 // e.g. YD1 #0 1219 short tmpDay;
1216 tmpDay = anEvent->dtStart().date().dayOfYear(); 1220 if( index == last ) {
1217 anEvent->recurrence()->addYearlyNum(tmpDay); 1221 // e.g. YD1 #0
1218 } 1222 tmpDay = anEvent->dtStart().date().dayOfYear();
1219 else { 1223 anEvent->recurrence()->addYearlyNum(tmpDay);
1220 // e.g. YD1 123 #0 1224 }
1221 while (index < last) { 1225 else {
1222 int index2 = tmpStr.find(' ', index); 1226 // e.g. YD1 123 #0
1223 tmpDay = tmpStr.mid(index, (index2-index)).toShort(); 1227 while (index < last) {
1224 index = index2+1; 1228 int index2 = tmpStr.find(' ', index);
1225 anEvent->recurrence()->addYearlyNum(tmpDay); 1229 tmpDay = tmpStr.mid(index, (index2-index)).toShort();
1226 } // while != # 1230 index = index2+1;
1227 } 1231 anEvent->recurrence()->addYearlyNum(tmpDay);
1228 index = last; if (tmpStr.mid(index,1) == "#") index++; 1232 } // while != #
1229 if (tmpStr.find('T', index) != -1) { 1233 }
1230 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1234 index = last; if (tmpStr.mid(index,1) == "#") index++;
1231 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rEndDate); 1235 if (tmpStr.find('T', index) != -1) {
1232 } else { 1236 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1233 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1237 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rEndDate);
1234 if (rDuration == 0) 1238 } else {
1235 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, -1); 1239 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1236 else 1240 if (rDuration == 0)
1237 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rDuration); 1241 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, -1);
1238 } 1242 else
1243 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rDuration);
1244 }
1239 } else { 1245 } else {
1240 kdDebug(5800) << "we don't understand this type of recurrence!" << endl; 1246 kdDebug(5800) << "we don't understand this type of recurrence!" << endl;
1241 } // if 1247 } // if
1242 } // repeats 1248 } // repeats
1243 1249
1244 1250
1245 // recurrence exceptions 1251 // recurrence exceptions
1246 if ((vo = isAPropertyOf(vevent, VCExpDateProp)) != 0) { 1252 if ((vo = isAPropertyOf(vevent, VCExpDateProp)) != 0) {
1247 s = fakeCString(vObjectUStringZValue(vo)); 1253 s = fakeCString(vObjectUStringZValue(vo));
1248 QStringList exDates = QStringList::split(",",s); 1254 QStringList exDates = QStringList::split(",",s);
1249 QStringList::ConstIterator it; 1255 QStringList::ConstIterator it;
1250 for(it = exDates.begin(); it != exDates.end(); ++it ) { 1256 for(it = exDates.begin(); it != exDates.end(); ++it ) {
1251 anEvent->addExDate(ISOToQDate(*it)); 1257 anEvent->addExDate(ISOToQDate(*it));
1252 } 1258 }
@@ -1527,30 +1533,31 @@ void VCalFormat::populate(VObject *vcal)
1527 1533
1528 // warn the user we might have trouble reading this unknown version. 1534 // warn the user we might have trouble reading this unknown version.
1529 if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) { 1535 if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) {
1530 char *s = fakeCString(vObjectUStringZValue(curVO)); 1536 char *s = fakeCString(vObjectUStringZValue(curVO));
1531 if (strcmp(_VCAL_VERSION, s) != 0) 1537 if (strcmp(_VCAL_VERSION, s) != 0)
1532 kdDebug() << "This vCalendar file has version " << s 1538 kdDebug() << "This vCalendar file has version " << s
1533 << "We only support " << _VCAL_VERSION << endl; 1539 << "We only support " << _VCAL_VERSION << endl;
1534 deleteStr(s); 1540 deleteStr(s);
1535 } 1541 }
1536 1542
1537 // set the time zone 1543 // set the time zone
1538 if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) { 1544 if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) {
1539 char *s = fakeCString(vObjectUStringZValue(curVO)); 1545 if ( vObjectUStringZValue(curVO) != 0 ) {
1540 mCalendar->setTimeZone(s); 1546 char *s = fakeCString(vObjectUStringZValue(curVO));
1541 deleteStr(s); 1547 mCalendar->setTimeZone(s);
1548 deleteStr(s);
1549 }
1542 } 1550 }
1543 1551
1544
1545 // Store all events with a relatedTo property in a list for post-processing 1552 // Store all events with a relatedTo property in a list for post-processing
1546 mEventsRelate.clear(); 1553 mEventsRelate.clear();
1547 mTodosRelate.clear(); 1554 mTodosRelate.clear();
1548 1555
1549 initPropIterator(&i, vcal); 1556 initPropIterator(&i, vcal);
1550 1557
1551 // go through all the vobjects in the vcal 1558 // go through all the vobjects in the vcal
1552 while (moreIteration(&i)) { 1559 while (moreIteration(&i)) {
1553 curVO = nextVObject(&i); 1560 curVO = nextVObject(&i);
1554 1561
1555 /************************************************************************/ 1562 /************************************************************************/
1556 1563