00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "opimtodo.h"
00031
00032
00033 #include <opie2/opimstate.h>
00034 #include <opie2/opimrecurrence.h>
00035 #include <opie2/opimmaintainer.h>
00036 #include <opie2/opimnotifymanager.h>
00037 #include <opie2/opimresolver.h>
00038 #include <opie2/odebug.h>
00039
00040 #include <qpe/palmtopuidgen.h>
00041 #include <qpe/palmtoprecord.h>
00042 #include <qpe/categories.h>
00043 #include <qpe/categoryselect.h>
00044 #include <qpe/stringutil.h>
00045
00046
00047 #include <qobject.h>
00048 #include <qshared.h>
00049
00050 namespace Opie
00051 {
00052
00053 struct OPimTodo::OPimTodoData : public QShared
00054 {
00055 OPimTodoData() : QShared()
00056 {
00057 recur = 0;
00058 state = 0;
00059 maintainer = 0;
00060 notifiers = 0;
00061 };
00062 ~OPimTodoData()
00063 {
00064 delete recur;
00065 delete maintainer;
00066 delete notifiers;
00067 delete state;
00068 }
00069
00070 QDate date;
00071 bool isCompleted: 1;
00072 bool hasDate: 1;
00073 int priority;
00074 QString desc;
00075 QString sum;
00076 QMap<QString, QString> extra;
00077 ushort prog;
00078 OPimState *state;
00079 OPimRecurrence *recur;
00080 OPimMaintainer *maintainer;
00081 QDate start;
00082 QDate completed;
00083 OPimNotifyManager *notifiers;
00084 };
00085
00086
00087 OPimTodo::OPimTodo( const OPimTodo &event )
00088 : OPimRecord( event ), data( event.data )
00089 {
00090 data->ref();
00091 }
00092
00093
00094 OPimTodo::~OPimTodo()
00095 {
00096
00097 if ( data->deref() )
00098 {
00099 delete data;
00100 data = 0l;
00101 }
00102 }
00103
00104
00105 OPimTodo::OPimTodo( bool completed, int priority,
00106 const QArray<int> &category,
00107 const QString& summary,
00108 const QString &description,
00109 ushort progress,
00110 bool hasDate, QDate date, int uid )
00111 : OPimRecord( uid )
00112 {
00113 setCategories( category );
00114
00115 data = new OPimTodoData;
00116
00117 data->date = date;
00118 data->isCompleted = completed;
00119 data->hasDate = hasDate;
00120 if ( priority < 1 )
00121 priority = 1;
00122 else if ( priority > 5 )
00123 priority = 5;
00124 data->priority = priority;
00125 data->sum = summary;
00126 data->prog = progress;
00127 data->desc = Qtopia::simplifyMultiLineSpace( description );
00128 }
00129
00130
00131 OPimTodo::OPimTodo( bool completed, int priority,
00132 const QStringList &category,
00133 const QString& summary,
00134 const QString &description,
00135 ushort progress,
00136 bool hasDate, QDate date, int uid )
00137 : OPimRecord( uid )
00138 {
00139 setCategories( idsFromString( category.join( ";" ) ) );
00140
00141 data = new OPimTodoData;
00142
00143 data->date = date;
00144 data->isCompleted = completed;
00145 data->hasDate = hasDate;
00146 if ( priority < 1 )
00147 priority = 1;
00148 else if ( priority > 5 )
00149 priority = 5;
00150 data->priority = priority;
00151 data->sum = summary;
00152 data->prog = progress;
00153 data->desc = Qtopia::simplifyMultiLineSpace( description );
00154 }
00155
00156
00157 bool OPimTodo::match( const QRegExp ®Exp ) const
00158 {
00159 if ( QString::number( data->priority ).find( regExp ) != -1 )
00160 {
00161 setLastHitField( Priority );
00162 return true;
00163 }
00164 else if ( data->hasDate && data->date.toString().find( regExp ) != -1 )
00165 {
00166 setLastHitField( HasDate );
00167 return true;
00168 }
00169 else if ( data->desc.find( regExp ) != -1 )
00170 {
00171 setLastHitField( Description );
00172 return true;
00173 }
00174 else if ( data->sum.find( regExp ) != -1 )
00175 {
00176 setLastHitField( Summary );
00177 return true;
00178 }
00179 return false;
00180 }
00181
00182
00183 bool OPimTodo::isCompleted() const
00184 {
00185 return data->isCompleted;
00186 }
00187
00188
00189 bool OPimTodo::hasDueDate() const
00190 {
00191 return data->hasDate;
00192 }
00193
00206 bool OPimTodo::hasStartDate() const
00207 {
00208 return data->start.isValid();
00209 }
00210
00221 bool OPimTodo::hasCompletedDate() const
00222 {
00223 return data->completed.isValid();
00224 }
00225
00226
00227 int OPimTodo::priority() const
00228 {
00229 return data->priority;
00230 }
00231
00232
00233 QString OPimTodo::summary() const
00234 {
00235 return data->sum;
00236 }
00237
00238
00239 ushort OPimTodo::progress() const
00240 {
00241 return data->prog;
00242 }
00243
00244
00245 QDate OPimTodo::dueDate() const
00246 {
00247 return data->date;
00248 }
00249
00250
00251 QDate OPimTodo::startDate() const
00252 {
00253 return data->start;
00254 }
00255
00256
00257 QDate OPimTodo::completedDate() const
00258 {
00259 return data->completed;
00260 }
00261
00262
00263 QString OPimTodo::description() const
00264 {
00265 return data->desc;
00266 }
00267
00268
00269 bool OPimTodo::hasState() const
00270 {
00271 if ( !data->state ) return false;
00272 return ( data->state->state() != OPimState::Undefined );
00273 }
00274
00275
00276 OPimState OPimTodo::state() const
00277 {
00278 if ( !data->state )
00279 {
00280 OPimState state;
00281 return state;
00282 }
00283
00284 return ( *data->state );
00285 }
00286
00287
00288 bool OPimTodo::hasRecurrence() const
00289 {
00290 if ( !data->recur ) return false;
00291 return data->recur->doesRecur();
00292 }
00293
00294
00295 OPimRecurrence OPimTodo::recurrence() const
00296 {
00297 if ( !data->recur ) return OPimRecurrence();
00298
00299 return ( *data->recur );
00300 }
00301
00302
00303 bool OPimTodo::hasMaintainer() const
00304 {
00305 if ( !data->maintainer ) return false;
00306
00307 return ( data->maintainer->mode() != OPimMaintainer::Undefined );
00308 }
00309
00310
00311 OPimMaintainer OPimTodo::maintainer() const
00312 {
00313 if ( !data->maintainer ) return OPimMaintainer();
00314
00315 return ( *data->maintainer );
00316 }
00317
00318
00319 void OPimTodo::setCompleted( bool completed )
00320 {
00321 changeOrModify();
00322 data->isCompleted = completed;
00323 }
00324
00325
00326 void OPimTodo::setHasDueDate( bool hasDate )
00327 {
00328 changeOrModify();
00329 data->hasDate = hasDate;
00330 }
00331
00332
00333 void OPimTodo::setDescription( const QString &desc )
00334 {
00335 changeOrModify();
00336 data->desc = Qtopia::simplifyMultiLineSpace( desc );
00337 }
00338
00339
00340 void OPimTodo::setSummary( const QString& sum )
00341 {
00342 changeOrModify();
00343 data->sum = sum;
00344 }
00345
00346
00347 void OPimTodo::setPriority( int prio )
00348 {
00349 changeOrModify();
00350 if ( prio < 1 )
00351 prio = 1;
00352 else if ( prio > 5 )
00353 prio = 5;
00354 data->priority = prio;
00355 }
00356
00357
00358 void OPimTodo::setDueDate( const QDate& date )
00359 {
00360 changeOrModify();
00361 data->date = date;
00362 }
00363
00364
00365 void OPimTodo::setStartDate( const QDate& date )
00366 {
00367 changeOrModify();
00368 data->start = date;
00369 }
00370
00371
00372 void OPimTodo::setCompletedDate( const QDate& date )
00373 {
00374 changeOrModify();
00375 data->completed = date;
00376 }
00377
00378
00379 void OPimTodo::setState( const OPimState& state )
00380 {
00381 changeOrModify();
00382 if ( data->state )
00383 ( *data->state ) = state;
00384 else
00385 data->state = new OPimState( state );
00386 }
00387
00388
00389 void OPimTodo::setRecurrence( const OPimRecurrence& rec )
00390 {
00391 changeOrModify();
00392 if ( data->recur )
00393 ( *data->recur ) = rec;
00394 else
00395 data->recur = new OPimRecurrence( rec );
00396 }
00397
00398
00399 void OPimTodo::setMaintainer( const OPimMaintainer& pim )
00400 {
00401 changeOrModify();
00402
00403 if ( data->maintainer )
00404 ( *data->maintainer ) = pim;
00405 else
00406 data->maintainer = new OPimMaintainer( pim );
00407 }
00408
00409
00410 bool OPimTodo::isOverdue( )const
00411 {
00412 if ( data->hasDate && !data->isCompleted )
00413 return QDate::currentDate() > data->date;
00414 return false;
00415 }
00416
00417
00418 void OPimTodo::setProgress( ushort progress )
00419 {
00420 changeOrModify();
00421 data->prog = progress;
00422 }
00423
00424
00425 QString OPimTodo::toShortText() const
00426 {
00427 return summary();
00428 }
00429
00430
00434 QString OPimTodo::toRichText() const
00435 {
00436 QString text;
00437 QStringList catlist;
00438
00439
00440 text += "<b><h3><img src=\"todo/TodoList\"> ";
00441 if ( !summary().isEmpty() )
00442 {
00443 text += Qtopia::escapeString( summary() ).replace( QRegExp( "[\n]" ), "" );
00444 }
00445 text += "</h3></b><br><hr><br>";
00446
00447
00448 if ( !description().isEmpty() )
00449 {
00450 text += "<b>" + QObject::tr( "Description:" ) + "</b><br>";
00451 text += Qtopia::escapeString( description() ).replace( QRegExp( "[\n]" ), "<br>" ) + "<br>";
00452 }
00453
00454
00455 int priorityval = priority();
00456 text += "<b>" + QObject::tr( "Priority:" ) + " </b><img src=\"todo/priority" +
00457 QString::number( priorityval ) + "\"> ";
00458
00459 switch ( priorityval )
00460 {
00461 case 1 : text += QObject::tr( "Very high" );
00462 break;
00463 case 2 : text += QObject::tr( "High" );
00464 break;
00465 case 3 : text += QObject::tr( "Normal" );
00466 break;
00467 case 4 : text += QObject::tr( "Low" );
00468 break;
00469 case 5 : text += QObject::tr( "Very low" );
00470 break;
00471 };
00472 text += "<br>";
00473
00474
00475 text += "<b>" + QObject::tr( "Progress:" ) + " </b>"
00476 + QString::number( progress() ) + " %<br>";
00477
00478
00479 if ( hasDueDate() )
00480 {
00481 QDate dd = dueDate();
00482 int off = QDate::currentDate().daysTo( dd );
00483
00484 text += "<b>" + QObject::tr( "Deadline:" ) + " </b><font color=\"";
00485 if ( off < 0 )
00486 text += "#FF0000";
00487 else if ( off == 0 )
00488 text += "#FFFF00";
00489 else if ( off > 0 )
00490 text += "#00FF00";
00491
00492 text += "\">" + dd.toString() + "</font><br>";
00493 }
00494
00495
00496 text += "<b>" + QObject::tr( "Category:" ) + "</b> ";
00497 text += categoryNames( "Todo List" ).join( ", " );
00498 text += "<br>";
00499
00500 return text;
00501 }
00502
00503
00504 bool OPimTodo::hasNotifiers() const
00505 {
00506 if ( !data->notifiers ) return false;
00507 return !data->notifiers->isEmpty();
00508 }
00509
00510
00511 OPimNotifyManager& OPimTodo::notifiers()
00512 {
00513 if ( !data->notifiers )
00514 data->notifiers = new OPimNotifyManager;
00515 return ( *data->notifiers );
00516 }
00517
00518
00519 const OPimNotifyManager& OPimTodo::notifiers() const
00520 {
00521 if ( !data->notifiers )
00522 data->notifiers = new OPimNotifyManager;
00523
00524 return ( *data->notifiers );
00525 }
00526
00527
00528 bool OPimTodo::operator<( const OPimTodo &toDoEvent ) const
00529 {
00530 if ( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
00531 if ( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
00532 if ( hasDueDate() && toDoEvent.hasDueDate() )
00533 {
00534 if ( dueDate() == toDoEvent.dueDate() )
00535 {
00536 return priority() < toDoEvent.priority();
00537 }
00538 else
00539 {
00540 return dueDate() < toDoEvent.dueDate();
00541 }
00542 }
00543 return false;
00544 }
00545
00546
00547 bool OPimTodo::operator<=( const OPimTodo &toDoEvent ) const
00548 {
00549 if ( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
00550 if ( !hasDueDate() && toDoEvent.hasDueDate() ) return true;
00551 if ( hasDueDate() && toDoEvent.hasDueDate() )
00552 {
00553 if ( dueDate() == toDoEvent.dueDate() )
00554 {
00555 return priority() <= toDoEvent.priority();
00556 }
00557 else
00558 {
00559 return dueDate() <= toDoEvent.dueDate();
00560 }
00561 }
00562 return true;
00563 }
00564
00565
00566 bool OPimTodo::operator>( const OPimTodo &toDoEvent ) const
00567 {
00568 if ( !hasDueDate() && !toDoEvent.hasDueDate() ) return false;
00569 if ( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
00570 if ( hasDueDate() && toDoEvent.hasDueDate() )
00571 {
00572 if ( dueDate() == toDoEvent.dueDate() )
00573 {
00574 return priority() > toDoEvent.priority();
00575 }
00576 else
00577 {
00578 return dueDate() > toDoEvent.dueDate();
00579 }
00580 }
00581 return false;
00582 }
00583
00584
00585 bool OPimTodo::operator>=( const OPimTodo &toDoEvent ) const
00586 {
00587 if ( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
00588 if ( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
00589 if ( hasDueDate() && toDoEvent.hasDueDate() )
00590 {
00591 if ( dueDate() == toDoEvent.dueDate() )
00592 {
00593 return priority() > toDoEvent.priority();
00594 }
00595 else
00596 {
00597 return dueDate() > toDoEvent.dueDate();
00598 }
00599 }
00600 return true;
00601 }
00602
00603
00604 bool OPimTodo::operator==( const OPimTodo &toDoEvent ) const
00605 {
00606 if ( data->priority != toDoEvent.data->priority ) return false;
00607 if ( data->priority != toDoEvent.data->prog ) return false;
00608 if ( data->isCompleted != toDoEvent.data->isCompleted ) return false;
00609 if ( data->hasDate != toDoEvent.data->hasDate ) return false;
00610 if ( data->date != toDoEvent.data->date ) return false;
00611 if ( data->sum != toDoEvent.data->sum ) return false;
00612 if ( data->desc != toDoEvent.data->desc ) return false;
00613 if ( data->maintainer != toDoEvent.data->maintainer )
00614 return false;
00615
00616 return OPimRecord::operator==( toDoEvent );
00617 }
00618
00619
00620 void OPimTodo::deref()
00621 {
00622
00623 if ( data->deref() )
00624 {
00625 delete data;
00626 data = 0;
00627 }
00628 }
00629
00630
00631 OPimTodo &OPimTodo::operator=( const OPimTodo &item )
00632 {
00633 if ( this == &item ) return * this;
00634
00635 OPimRecord::operator=( item );
00636 item.data->ref();
00637 deref();
00638 data = item.data;
00639
00640 return *this;
00641 }
00642
00643
00644 QMap<int, QString> OPimTodo::toMap() const
00645 {
00646 QMap<int, QString> map;
00647
00648 map.insert( Uid, QString::number( uid() ) );
00649 map.insert( Category, idsToString( categories() ) );
00650 map.insert( HasDate, QString::number( data->hasDate ) );
00651 map.insert( Completed, QString::number( data->isCompleted ) );
00652 map.insert( Description, data->desc );
00653 map.insert( Summary, data->sum );
00654 map.insert( Priority, QString::number( data->priority ) );
00655 map.insert( DateDay, QString::number( data->date.day() ) );
00656 map.insert( DateMonth, QString::number( data->date.month() ) );
00657 map.insert( DateYear, QString::number( data->date.year() ) );
00658 map.insert( Progress, QString::number( data->prog ) );
00659
00660
00661
00662
00663
00664
00665 return map;
00666 }
00667
00668
00674 void OPimTodo::changeOrModify()
00675 {
00676 if ( data->count != 1 )
00677 {
00678 data->deref();
00679 OPimTodoData* d2 = new OPimTodoData();
00680 copy( data, d2 );
00681 data = d2;
00682 }
00683 }
00684
00685
00686
00687
00688
00689
00690
00691 void OPimTodo::copy( OPimTodoData* src, OPimTodoData* dest )
00692 {
00693 dest->date = src->date;
00694 dest->isCompleted = src->isCompleted;
00695 dest->hasDate = src->hasDate;
00696 dest->priority = src->priority;
00697 dest->desc = src->desc;
00698 dest->sum = src->sum;
00699 dest->extra = src->extra;
00700 dest->prog = src->prog;
00701
00702 if ( src->state )
00703 dest->state = new OPimState( *src->state );
00704
00705 if ( src->recur )
00706 dest->recur = new OPimRecurrence( *src->recur );
00707
00708 if ( src->maintainer )
00709 dest->maintainer = new OPimMaintainer( *src->maintainer )
00710 ;
00711 dest->start = src->start;
00712 dest->completed = src->completed;
00713
00714 if ( src->notifiers )
00715 dest->notifiers = new OPimNotifyManager( *src->notifiers );
00716 }
00717
00718
00719 QString OPimTodo::type() const
00720 {
00721 return QString::fromLatin1( "OPimTodo" );
00722 }
00723
00724
00725 QString OPimTodo::recordField( int id) const
00726 {
00727 QString res;
00728 Q_UNUSED( id )
00729 #if 0
00730 switch( id ) {
00731 case HasDate:
00732 res = (hasDueDate() ?
00733 QObject::tr( "Has a due-date" )
00734 : QObject::tr( "No due-date" ));
00735 break;
00736 case Completed:
00737 res = ( isCompleted() ?
00738 QObject::tr( "Completed" ) :
00739 QObject::tr( "Not completed" ));
00740 break;
00741 case Description:
00742 res = description();
00743 break;
00744 case Summary:
00745 res = summary();
00746 break;
00747 case Priority:
00748 res = QString::number( priority() );
00749 break;
00750 case DateDay:
00751 res = QString::number( dueDate().day() );
00752 break;
00753 case DateMonth:
00754 res = QString::number( dueDate().month() );
00755 break;
00756 case DateYear:
00757 res = QString::number( dueDate().year() );
00758 break;
00759 case Progress:
00760 res = QString::number( progress() );
00761 break;
00762 case State:
00763 res = QString::number( state().state() );
00764 break;
00765 case Recurrence:
00766 res = ( hasRecurrence() ?
00767 QString::null :
00768 QObject::tr("No reccurrence"));
00769 break;
00770 case Alarms:
00771 break;
00772 case Reminders:
00773 break;
00774 case Maintainer:
00775 break;
00776 case StartDate:
00777 res = ( hasStartDate() ?
00778 QString::null :
00779 QObject::tr( "No start-date" ) );
00780 break;
00781 case CompletedDate:
00782 res = ( hasCompletedDate() ?
00783 QString::null :
00784 QObject::tr( "No completed-date" ) );
00785 break;
00786 case DueDate:
00787 res = ( hasDueDate() ?
00788 QString::null :
00789 QObject::tr( "No due-date" );
00790 break;
00791 default:
00792 res = OPimRecord::recordField( id );
00793 }
00794
00795 #endif
00796 return res;
00797 }
00798
00799
00800 int OPimTodo::rtti() const
00801 {
00802 return OPimResolver::TodoList;
00803 }
00804
00816 OPimTodo* OPimTodo::safeCast( const OPimRecord* rec ) {
00817 return (rec && rec->rtti() == OPimResolver::TodoList ) ?
00818 static_cast<OPimTodo*>( const_cast<OPimRecord*>(rec) ) :
00819 0l;
00820 }
00821
00822 }