00001
00002 #include <qobject.h>
00003 #include <qshared.h>
00004
00005
00006
00007 #include <qpe/palmtopuidgen.h>
00008 #include <qpe/palmtoprecord.h>
00009 #include <qpe/categories.h>
00010 #include <qpe/categoryselect.h>
00011 #include <qpe/stringutil.h>
00012
00013
00014 #include "opimstate.h"
00015 #include "orecur.h"
00016 #include "opimmaintainer.h"
00017 #include "opimnotifymanager.h"
00018 #include "opimresolver.h"
00019
00020 #include "otodo.h"
00021
00022
00023 struct OTodo::OTodoData : public QShared {
00024 OTodoData() : QShared() {
00025 recur = 0;
00026 state = 0;
00027 maintainer = 0;
00028 notifiers = 0;
00029 };
00030 ~OTodoData() {
00031 delete recur;
00032 delete maintainer;
00033 delete notifiers;
00034 }
00035
00036 QDate date;
00037 bool isCompleted:1;
00038 bool hasDate:1;
00039 int priority;
00040 QString desc;
00041 QString sum;
00042 QMap<QString, QString> extra;
00043 ushort prog;
00044 OPimState *state;
00045 ORecur *recur;
00046 OPimMaintainer *maintainer;
00047 QDate start;
00048 QDate completed;
00049 OPimNotifyManager *notifiers;
00050 };
00051
00052 OTodo::OTodo(const OTodo &event )
00053 : OPimRecord( event ), data( event.data )
00054 {
00055 data->ref();
00056
00057 }
00058 OTodo::~OTodo() {
00059
00060
00061 if ( data->deref() ) {
00062
00063 delete data;
00064 data = 0l;
00065 }
00066 }
00067 OTodo::OTodo(bool completed, int priority,
00068 const QArray<int> &category,
00069 const QString& summary,
00070 const QString &description,
00071 ushort progress,
00072 bool hasDate, QDate date, int uid )
00073 : OPimRecord( uid )
00074 {
00075
00076 setCategories( category );
00077
00078 data = new OTodoData;
00079
00080 data->date = date;
00081 data->isCompleted = completed;
00082 data->hasDate = hasDate;
00083 data->priority = priority;
00084 data->sum = summary;
00085 data->prog = progress;
00086 data->desc = Qtopia::simplifyMultiLineSpace(description );
00087 }
00088 OTodo::OTodo(bool completed, int priority,
00089 const QStringList &category,
00090 const QString& summary,
00091 const QString &description,
00092 ushort progress,
00093 bool hasDate, QDate date, int uid )
00094 : OPimRecord( uid )
00095 {
00096
00097 setCategories( idsFromString( category.join(";") ) );
00098
00099 data = new OTodoData;
00100
00101 data->date = date;
00102 data->isCompleted = completed;
00103 data->hasDate = hasDate;
00104 data->priority = priority;
00105 data->sum = summary;
00106 data->prog = progress;
00107 data->desc = Qtopia::simplifyMultiLineSpace(description );
00108 }
00109 bool OTodo::match( const QRegExp ®Exp )const
00110 {
00111 if( QString::number( data->priority ).find( regExp ) != -1 ){
00112 setLastHitField( Priority );
00113 return true;
00114 }else if( data->hasDate && data->date.toString().find( regExp) != -1 ){
00115 setLastHitField( HasDate );
00116 return true;
00117 }else if(data->desc.find( regExp ) != -1 ){
00118 setLastHitField( Description );
00119 return true;
00120 }else if(data->sum.find( regExp ) != -1 ) {
00121 setLastHitField( Summary );
00122 return true;
00123 }
00124 return false;
00125 }
00126 bool OTodo::isCompleted() const
00127 {
00128 return data->isCompleted;
00129 }
00130 bool OTodo::hasDueDate() const
00131 {
00132 return data->hasDate;
00133 }
00134 bool OTodo::hasStartDate()const {
00135 return data->start.isValid();
00136 }
00137 bool OTodo::hasCompletedDate()const {
00138 return data->completed.isValid();
00139 }
00140 int OTodo::priority()const
00141 {
00142 return data->priority;
00143 }
00144 QString OTodo::summary() const
00145 {
00146 return data->sum;
00147 }
00148 ushort OTodo::progress() const
00149 {
00150 return data->prog;
00151 }
00152 QDate OTodo::dueDate()const
00153 {
00154 return data->date;
00155 }
00156 QDate OTodo::startDate()const {
00157 return data->start;
00158 }
00159 QDate OTodo::completedDate()const {
00160 return data->completed;
00161 }
00162 QString OTodo::description()const
00163 {
00164 return data->desc;
00165 }
00166 bool OTodo::hasState() const{
00167 if (!data->state ) return false;
00168 return ( data->state->state() != OPimState::Undefined );
00169 }
00170 OPimState OTodo::state()const {
00171 if (!data->state ) {
00172 OPimState state;
00173 return state;
00174 }
00175
00176 return (*data->state);
00177 }
00178 bool OTodo::hasRecurrence()const {
00179 if (!data->recur) return false;
00180 return data->recur->doesRecur();
00181 }
00182 ORecur OTodo::recurrence()const {
00183 if (!data->recur) return ORecur();
00184
00185 return (*data->recur);
00186 }
00187 bool OTodo::hasMaintainer()const {
00188 if (!data->maintainer) return false;
00189
00190 return (data->maintainer->mode() != OPimMaintainer::Undefined );
00191 }
00192 OPimMaintainer OTodo::maintainer()const {
00193 if (!data->maintainer) return OPimMaintainer();
00194
00195 return (*data->maintainer);
00196 }
00197 void OTodo::setCompleted( bool completed )
00198 {
00199 changeOrModify();
00200 data->isCompleted = completed;
00201 }
00202 void OTodo::setHasDueDate( bool hasDate )
00203 {
00204 changeOrModify();
00205 data->hasDate = hasDate;
00206 }
00207 void OTodo::setDescription(const QString &desc )
00208 {
00209
00210 changeOrModify();
00211 data->desc = Qtopia::simplifyMultiLineSpace(desc );
00212 }
00213 void OTodo::setSummary( const QString& sum )
00214 {
00215 changeOrModify();
00216 data->sum = sum;
00217 }
00218 void OTodo::setPriority(int prio )
00219 {
00220 changeOrModify();
00221 data->priority = prio;
00222 }
00223 void OTodo::setDueDate( const QDate& date )
00224 {
00225 changeOrModify();
00226 data->date = date;
00227 }
00228 void OTodo::setStartDate( const QDate& date ) {
00229 changeOrModify();
00230 data->start = date;
00231 }
00232 void OTodo::setCompletedDate( const QDate& date ) {
00233 changeOrModify();
00234 data->completed = date;
00235 }
00236 void OTodo::setState( const OPimState& state ) {
00237 changeOrModify();
00238 if (data->state )
00239 (*data->state) = state;
00240 else
00241 data->state = new OPimState( state );
00242 }
00243 void OTodo::setRecurrence( const ORecur& rec) {
00244 changeOrModify();
00245 if (data->recur )
00246 (*data->recur) = rec;
00247 else
00248 data->recur = new ORecur( rec );
00249 }
00250 void OTodo::setMaintainer( const OPimMaintainer& pim ) {
00251 changeOrModify();
00252
00253 if (data->maintainer )
00254 (*data->maintainer) = pim;
00255 else
00256 data->maintainer = new OPimMaintainer( pim );
00257 }
00258 bool OTodo::isOverdue( )
00259 {
00260 if( data->hasDate && !data->isCompleted)
00261 return QDate::currentDate() > data->date;
00262 return false;
00263 }
00264 void OTodo::setProgress(ushort progress )
00265 {
00266 changeOrModify();
00267 data->prog = progress;
00268 }
00269 QString OTodo::toShortText() const {
00270 return summary();
00271 }
00275 QString OTodo::toRichText() const
00276 {
00277 QString text;
00278 QStringList catlist;
00279
00280
00281 text += "<b><h3><img src=\"todo/TodoList\"> ";
00282 if ( !summary().isEmpty() ) {
00283 text += Qtopia::escapeString(summary() ).replace(QRegExp( "[\n]"), "" );
00284 }
00285 text += "</h3></b><br><hr><br>";
00286
00287
00288 if( !description().isEmpty() ){
00289 text += "<b>" + QObject::tr( "Description:" ) + "</b><br>";
00290 text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "<br>" ) + "<br>";
00291 }
00292
00293
00294 int priorityval = priority();
00295 text += "<b>" + QObject::tr( "Priority:") +" </b><img src=\"todo/priority" +
00296 QString::number( priorityval ) + "\"> ";
00297
00298 switch ( priorityval )
00299 {
00300 case 1 : text += QObject::tr( "Very high" );
00301 break;
00302 case 2 : text += QObject::tr( "High" );
00303 break;
00304 case 3 : text += QObject::tr( "Normal" );
00305 break;
00306 case 4 : text += QObject::tr( "Low" );
00307 break;
00308 case 5 : text += QObject::tr( "Very low" );
00309 break;
00310 };
00311 text += "<br>";
00312
00313
00314 text += "<b>" + QObject::tr( "Progress:") + " </b>"
00315 + QString::number( progress() ) + " %<br>";
00316
00317
00318 if (hasDueDate() ){
00319 QDate dd = dueDate();
00320 int off = QDate::currentDate().daysTo( dd );
00321
00322 text += "<b>" + QObject::tr( "Deadline:" ) + " </b><font color=\"";
00323 if ( off < 0 )
00324 text += "#FF0000";
00325 else if ( off == 0 )
00326 text += "#FFFF00";
00327 else if ( off > 0 )
00328 text += "#00FF00";
00329
00330 text += "\">" + dd.toString() + "</font><br>";
00331 }
00332
00333
00334 text += "<b>" + QObject::tr( "Category:") + "</b> ";
00335 text += categoryNames( "Todo List" ).join(", ");
00336 text += "<br>";
00337
00338 return text;
00339 }
00340 bool OTodo::hasNotifiers()const {
00341 if (!data->notifiers) return false;
00342 return !data->notifiers->isEmpty();
00343 }
00344 OPimNotifyManager& OTodo::notifiers() {
00345 if (!data->notifiers )
00346 data->notifiers = new OPimNotifyManager;
00347 return (*data->notifiers);
00348 }
00349 const OPimNotifyManager& OTodo::notifiers()const{
00350 if (!data->notifiers )
00351 data->notifiers = new OPimNotifyManager;
00352
00353 return (*data->notifiers);
00354 }
00355
00356 bool OTodo::operator<( const OTodo &toDoEvent )const{
00357 if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
00358 if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
00359 if( hasDueDate() && toDoEvent.hasDueDate() ){
00360 if( dueDate() == toDoEvent.dueDate() ){
00361 return priority() < toDoEvent.priority();
00362 }else{
00363 return dueDate() < toDoEvent.dueDate();
00364 }
00365 }
00366 return false;
00367 }
00368 bool OTodo::operator<=(const OTodo &toDoEvent )const
00369 {
00370 if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
00371 if( !hasDueDate() && toDoEvent.hasDueDate() ) return true;
00372 if( hasDueDate() && toDoEvent.hasDueDate() ){
00373 if( dueDate() == toDoEvent.dueDate() ){
00374 return priority() <= toDoEvent.priority();
00375 }else{
00376 return dueDate() <= toDoEvent.dueDate();
00377 }
00378 }
00379 return true;
00380 }
00381 bool OTodo::operator>(const OTodo &toDoEvent )const
00382 {
00383 if( !hasDueDate() && !toDoEvent.hasDueDate() ) return false;
00384 if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
00385 if( hasDueDate() && toDoEvent.hasDueDate() ){
00386 if( dueDate() == toDoEvent.dueDate() ){
00387 return priority() > toDoEvent.priority();
00388 }else{
00389 return dueDate() > toDoEvent.dueDate();
00390 }
00391 }
00392 return false;
00393 }
00394 bool OTodo::operator>=(const OTodo &toDoEvent )const
00395 {
00396 if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
00397 if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
00398 if( hasDueDate() && toDoEvent.hasDueDate() ){
00399 if( dueDate() == toDoEvent.dueDate() ){
00400 return priority() > toDoEvent.priority();
00401 }else{
00402 return dueDate() > toDoEvent.dueDate();
00403 }
00404 }
00405 return true;
00406 }
00407 bool OTodo::operator==(const OTodo &toDoEvent )const
00408 {
00409 if ( data->priority != toDoEvent.data->priority ) return false;
00410 if ( data->priority != toDoEvent.data->prog ) return false;
00411 if ( data->isCompleted != toDoEvent.data->isCompleted ) return false;
00412 if ( data->hasDate != toDoEvent.data->hasDate ) return false;
00413 if ( data->date != toDoEvent.data->date ) return false;
00414 if ( data->sum != toDoEvent.data->sum ) return false;
00415 if ( data->desc != toDoEvent.data->desc ) return false;
00416 if ( data->maintainer != toDoEvent.data->maintainer )
00417 return false;
00418
00419 return OPimRecord::operator==( toDoEvent );
00420 }
00421 void OTodo::deref() {
00422
00423
00424 if ( data->deref() ) {
00425
00426 delete data;
00427 data= 0;
00428 }
00429 }
00430 OTodo &OTodo::operator=(const OTodo &item )
00431 {
00432 if ( this == &item ) return *this;
00433
00434 OPimRecord::operator=( item );
00435
00436 item.data->ref();
00437 deref();
00438 data = item.data;
00439
00440 return *this;
00441 }
00442
00443 QMap<int, QString> OTodo::toMap() const {
00444 QMap<int, QString> map;
00445
00446 map.insert( Uid, QString::number( uid() ) );
00447 map.insert( Category, idsToString( categories() ) );
00448 map.insert( HasDate, QString::number( data->hasDate ) );
00449 map.insert( Completed, QString::number( data->isCompleted ) );
00450 map.insert( Description, data->desc );
00451 map.insert( Summary, data->sum );
00452 map.insert( Priority, QString::number( data->priority ) );
00453 map.insert( DateDay, QString::number( data->date.day() ) );
00454 map.insert( DateMonth, QString::number( data->date.month() ) );
00455 map.insert( DateYear, QString::number( data->date.year() ) );
00456 map.insert( Progress, QString::number( data->prog ) );
00457
00458
00459
00460
00461
00462
00463 return map;
00464 }
00465
00471 void OTodo::changeOrModify() {
00472 if ( data->count != 1 ) {
00473 qWarning("changeOrModify");
00474 data->deref();
00475 OTodoData* d2 = new OTodoData();
00476 copy(data, d2 );
00477 data = d2;
00478 }
00479 }
00480
00481
00482
00483
00484
00485 void OTodo::copy( OTodoData* src, OTodoData* dest ) {
00486 dest->date = src->date;
00487 dest->isCompleted = src->isCompleted;
00488 dest->hasDate = src->hasDate;
00489 dest->priority = src->priority;
00490 dest->desc = src->desc;
00491 dest->sum = src->sum;
00492 dest->extra = src->extra;
00493 dest->prog = src->prog;
00494
00495 if (src->state )
00496 dest->state = new OPimState( *src->state );
00497
00498 if (src->recur )
00499 dest->recur = new ORecur( *src->recur );
00500
00501 if (src->maintainer )
00502 dest->maintainer = new OPimMaintainer( *src->maintainer )
00503 ;
00504 dest->start = src->start;
00505 dest->completed = src->completed;
00506
00507 if (src->notifiers )
00508 dest->notifiers = new OPimNotifyManager( *src->notifiers );
00509 }
00510 QString OTodo::type() const {
00511 return QString::fromLatin1("OTodo");
00512 }
00513 QString OTodo::recordField(int )const {
00514 return QString::null;
00515 }
00516
00517 int OTodo::rtti(){
00518 return OPimResolver::TodoList;
00519 }