00001 #include <errno.h>
00002 #include <fcntl.h>
00003
00004 #include <sys/mman.h>
00005 #include <sys/stat.h>
00006 #include <sys/types.h>
00007
00008 #include <unistd.h>
00009
00010
00011 #include <qfile.h>
00012 #include <qvector.h>
00013
00014 #include <qpe/global.h>
00015 #include <qpe/stringutil.h>
00016 #include <qpe/timeconversion.h>
00017
00018 #include "oconversion.h"
00019 #include "opimstate.h"
00020 #include "otimezone.h"
00021 #include "opimnotifymanager.h"
00022 #include "orecur.h"
00023 #include "otodoaccessxml.h"
00024
00025 namespace {
00026 time_t rp_end;
00027 ORecur* rec;
00028 ORecur *recur() {
00029 if (!rec ) rec = new ORecur;
00030 return rec;
00031 }
00032 int snd;
00033 enum MoreAttributes {
00034 FRType = OTodo::CompletedDate + 2,
00035 FRWeekdays,
00036 FRPosition,
00037 FRFreq,
00038 FRHasEndDate,
00039 FREndDate,
00040 FRStart,
00041 FREnd
00042 };
00043
00044 char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen)
00045 {
00046 char needleChar;
00047 char haystackChar;
00048 if (!needle || !haystack || !hLen || !nLen)
00049 return 0;
00050
00051 const char* hsearch = haystack;
00052
00053 if ((needleChar = *needle++) != 0) {
00054 nLen--;
00055 do {
00056 do {
00057 if ((haystackChar = *hsearch++) == 0)
00058 return (0);
00059 if (hsearch >= haystack + hLen)
00060 return (0);
00061 } while (haystackChar != needleChar);
00062 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0);
00063 hsearch--;
00064 }
00065 return ((char *)hsearch);
00066 }
00067 }
00068
00069
00070 OTodoAccessXML::OTodoAccessXML( const QString& appName,
00071 const QString& fileName )
00072 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false )
00073 {
00074 if (!fileName.isEmpty() )
00075 m_file = fileName;
00076 else
00077 m_file = Global::applicationFileName( "todolist", "todolist.xml" );
00078 }
00079 OTodoAccessXML::~OTodoAccessXML() {
00080
00081 }
00082 bool OTodoAccessXML::load() {
00083 rec = 0;
00084 m_opened = true;
00085 m_changed = false;
00086
00087
00088
00089
00090 QAsciiDict<int> dict(26);
00091 dict.setAutoDelete( TRUE );
00092 dict.insert("Categories" , new int(OTodo::Category) );
00093 dict.insert("Uid" , new int(OTodo::Uid) );
00094 dict.insert("HasDate" , new int(OTodo::HasDate) );
00095 dict.insert("Completed" , new int(OTodo::Completed) );
00096 dict.insert("Description" , new int(OTodo::Description) );
00097 dict.insert("Summary" , new int(OTodo::Summary) );
00098 dict.insert("Priority" , new int(OTodo::Priority) );
00099 dict.insert("DateDay" , new int(OTodo::DateDay) );
00100 dict.insert("DateMonth" , new int(OTodo::DateMonth) );
00101 dict.insert("DateYear" , new int(OTodo::DateYear) );
00102 dict.insert("Progress" , new int(OTodo::Progress) );
00103 dict.insert("CompletedDate", new int(OTodo::CompletedDate) );
00104 dict.insert("StartDate", new int(OTodo::StartDate) );
00105 dict.insert("CrossReference", new int(OTodo::CrossReference) );
00106 dict.insert("State", new int(OTodo::State) );
00107 dict.insert("Alarms", new int(OTodo::Alarms) );
00108 dict.insert("Reminders", new int(OTodo::Reminders) );
00109 dict.insert("Notifiers", new int(OTodo::Notifiers) );
00110 dict.insert("Maintainer", new int(OTodo::Maintainer) );
00111 dict.insert("rtype", new int(FRType) );
00112 dict.insert("rweekdays", new int(FRWeekdays) );
00113 dict.insert("rposition", new int(FRPosition) );
00114 dict.insert("rfreq", new int(FRFreq) );
00115 dict.insert("start", new int(FRStart) );
00116 dict.insert("rhasenddate", new int(FRHasEndDate) );
00117 dict.insert("enddt", new int(FREndDate) );
00118
00119
00120
00121
00122 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY );
00123 struct stat attribut;
00124 if ( fd < 0 ) return false;
00125
00126 if ( fstat(fd, &attribut ) == -1 ) {
00127 ::close( fd );
00128 return false;
00129 }
00130 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 );
00131 if ( map_addr == ( (caddr_t)-1) ) {
00132 ::close(fd );
00133 return false;
00134 }
00135
00136 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL );
00137
00138 ::close( fd );
00139
00140 char* dt = (char*)map_addr;
00141 int len = attribut.st_size;
00142 int i = 0;
00143 char *point;
00144 const char* collectionString = "<Task ";
00145 int strLen = strlen(collectionString);
00146 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) {
00147 i = point -dt;
00148 i+= strLen;
00149 qWarning("Found a start at %d %d", i, (point-dt) );
00150
00151 OTodo ev;
00152 m_year = m_month = m_day = 0;
00153
00154 while ( TRUE ) {
00155 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
00156 ++i;
00157 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
00158 break;
00159
00160
00161 int j = i;
00162 while ( j < len && dt[j] != '=' )
00163 ++j;
00164 QCString attr( dt+i, j-i+1);
00165
00166 i = ++j;
00167
00168
00169 while ( i < len && dt[i] != '"' )
00170 ++i;
00171 j = ++i;
00172
00173 bool haveUtf = FALSE;
00174 bool haveEnt = FALSE;
00175 while ( j < len && dt[j] != '"' ) {
00176 if ( ((unsigned char)dt[j]) > 0x7f )
00177 haveUtf = TRUE;
00178 if ( dt[j] == '&' )
00179 haveEnt = TRUE;
00180 ++j;
00181 }
00182 if ( i == j ) {
00183
00184 i = j + 1;
00185 continue;
00186 }
00187
00188 QCString value( dt+i, j-i+1 );
00189 i = j + 1;
00190
00191 QString str = (haveUtf ? QString::fromUtf8( value )
00192 : QString::fromLatin1( value ) );
00193 if ( haveEnt )
00194 str = Qtopia::plainString( str );
00195
00196
00197
00198
00199 todo( &dict, ev, attr, str );
00200
00201 }
00202
00203
00204
00205 qWarning("End at %d", i );
00206 if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
00207 ev.setUid( 1 );
00208 m_changed = true;
00209 }
00210 if ( ev.hasDueDate() ) {
00211 ev.setDueDate( QDate(m_year, m_month, m_day) );
00212 }
00213 if ( rec && rec->doesRecur() ) {
00214 OTimeZone utc = OTimeZone::utc();
00215 ORecur recu( *rec );
00216 recu.setEndDate( utc.fromUTCDateTime( rp_end ).date() );
00217 recu.setStart( ev.dueDate() );
00218 ev.setRecurrence( recu );
00219 }
00220 m_events.insert(ev.uid(), ev );
00221 m_year = m_month = m_day = -1;
00222 delete rec;
00223 rec = 0;
00224 }
00225
00226 munmap(map_addr, attribut.st_size );
00227
00228 qWarning("counts %d records loaded!", m_events.count() );
00229 return true;
00230 }
00231 bool OTodoAccessXML::reload() {
00232 m_events.clear();
00233 return load();
00234 }
00235 bool OTodoAccessXML::save() {
00236
00237 if (!m_opened || !m_changed ) {
00238
00239 return true;
00240 }
00241 QString strNewFile = m_file + ".new";
00242 QFile f( strNewFile );
00243 if (!f.open( IO_WriteOnly|IO_Raw ) )
00244 return false;
00245
00246 int written;
00247 QString out;
00248 out = "<!DOCTYPE Tasks>\n<Tasks>\n";
00249
00250
00251 QMap<int, OTodo>::Iterator it;
00252 for (it = m_events.begin(); it != m_events.end(); ++it ) {
00253 out+= "<Task " + toString( (*it) ) + " />\n";
00254 QCString cstr = out.utf8();
00255 written = f.writeBlock( cstr.data(), cstr.length() );
00256
00257
00258 if ( written != (int)cstr.length() ) {
00259 f.close();
00260 QFile::remove( strNewFile );
00261 return false;
00262 }
00263 out = QString::null;
00264 }
00265
00266 out += "</Tasks>";
00267 QCString cstr = out.utf8();
00268 written = f.writeBlock( cstr.data(), cstr.length() );
00269
00270 if ( written != (int)cstr.length() ) {
00271 f.close();
00272 QFile::remove( strNewFile );
00273 return false;
00274 }
00275
00276 f.close();
00277
00278 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) {
00279
00280 QFile::remove( strNewFile );
00281 }
00282
00283 m_changed = false;
00284 return true;
00285 }
00286 QArray<int> OTodoAccessXML::allRecords()const {
00287 QArray<int> ids( m_events.count() );
00288 QMap<int, OTodo>::ConstIterator it;
00289 int i = 0;
00290
00291 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
00292 ids[i] = it.key();
00293 i++;
00294 }
00295 return ids;
00296 }
00297 QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int, const QDateTime& ) {
00298 QArray<int> ids(0);
00299 return ids;
00300 }
00301 OTodo OTodoAccessXML::find( int uid )const {
00302 OTodo todo;
00303 todo.setUid( 0 );
00304 QMap<int, OTodo>::ConstIterator it = m_events.find( uid );
00305 if ( it != m_events.end() )
00306 todo = it.data();
00307
00308 return todo;
00309 }
00310 void OTodoAccessXML::clear() {
00311 if (m_opened )
00312 m_changed = true;
00313
00314 m_events.clear();
00315 }
00316 bool OTodoAccessXML::add( const OTodo& todo ) {
00317
00318 m_changed = true;
00319 m_events.insert( todo.uid(), todo );
00320
00321 return true;
00322 }
00323 bool OTodoAccessXML::remove( int uid ) {
00324 m_changed = true;
00325 m_events.remove( uid );
00326
00327 return true;
00328 }
00329 bool OTodoAccessXML::replace( const OTodo& todo) {
00330 m_changed = true;
00331 m_events.replace( todo.uid(), todo );
00332
00333 return true;
00334 }
00335 QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start,
00336 const QDate& end,
00337 bool includeNoDates ) {
00338 QArray<int> ids( m_events.count() );
00339 QMap<int, OTodo>::Iterator it;
00340
00341 int i = 0;
00342 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
00343 if ( !it.data().hasDueDate() ) {
00344 if ( includeNoDates ) {
00345 ids[i] = it.key();
00346 i++;
00347 }
00348 }else if ( it.data().dueDate() >= start &&
00349 it.data().dueDate() <= end ) {
00350 ids[i] = it.key();
00351 i++;
00352 }
00353 }
00354 ids.resize( i );
00355 return ids;
00356 }
00357 QArray<int> OTodoAccessXML::overDue() {
00358 QArray<int> ids( m_events.count() );
00359 int i = 0;
00360
00361 QMap<int, OTodo>::Iterator it;
00362 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
00363 if ( it.data().isOverdue() ) {
00364 ids[i] = it.key();
00365 i++;
00366 }
00367 }
00368 ids.resize( i );
00369 return ids;
00370 }
00371
00372
00373
00374 void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev,
00375 const QCString& attr, const QString& val) {
00376
00377
00378 int *find=0;
00379
00380 find = (*dict)[ attr.data() ];
00381 if (!find ) {
00382
00383 ev.setCustomField( attr, val );
00384 return;
00385 }
00386
00387 switch( *find ) {
00388 case OTodo::Uid:
00389 ev.setUid( val.toInt() );
00390 break;
00391 case OTodo::Category:
00392 ev.setCategories( ev.idsFromString( val ) );
00393 break;
00394 case OTodo::HasDate:
00395 ev.setHasDueDate( val.toInt() );
00396 break;
00397 case OTodo::Completed:
00398 ev.setCompleted( val.toInt() );
00399 break;
00400 case OTodo::Description:
00401 ev.setDescription( val );
00402 break;
00403 case OTodo::Summary:
00404 ev.setSummary( val );
00405 break;
00406 case OTodo::Priority:
00407 ev.setPriority( val.toInt() );
00408 break;
00409 case OTodo::DateDay:
00410 m_day = val.toInt();
00411 break;
00412 case OTodo::DateMonth:
00413 m_month = val.toInt();
00414 break;
00415 case OTodo::DateYear:
00416 m_year = val.toInt();
00417 break;
00418 case OTodo::Progress:
00419 ev.setProgress( val.toInt() );
00420 break;
00421 case OTodo::CompletedDate:
00422 ev.setCompletedDate( OConversion::dateFromString( val ) );
00423 break;
00424 case OTodo::StartDate:
00425 ev.setStartDate( OConversion::dateFromString( val ) );
00426 break;
00427 case OTodo::State:
00428 ev.setState( val.toInt() );
00429 break;
00430 case OTodo::Alarms:{
00431 OPimNotifyManager &manager = ev.notifiers();
00432 QStringList als = QStringList::split(";", val );
00433 for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) {
00434 QStringList alarm = QStringList::split(":", (*it), TRUE );
00435 qWarning("alarm: %s", alarm.join("___").latin1() );
00436 qWarning("alarm[0]: %s %s", alarm[0].latin1(), OConversion::dateTimeFromString( alarm[0] ).toString().latin1() );
00437 OPimAlarm al( alarm[2].toInt(), OConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() );
00438 manager.add( al );
00439 }
00440 }
00441 break;
00442 case OTodo::Reminders:{
00443 OPimNotifyManager &manager = ev.notifiers();
00444 QStringList rems = QStringList::split(";", val );
00445 for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) {
00446 OPimReminder rem( (*it).toInt() );
00447 manager.add( rem );
00448 }
00449 }
00450 break;
00451 case OTodo::CrossReference:
00452 {
00453
00454
00455
00456
00457
00458 QStringList refs = QStringList::split(';', val );
00459 QStringList::Iterator strIt;
00460 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
00461 int pos = (*strIt).find(',');
00462 if ( pos > -1 )
00463 ;
00464
00465 }
00466 break;
00467 }
00468
00469 case FRType:
00470 if ( val == "Daily" )
00471 recur()->setType( ORecur::Daily );
00472 else if ( val == "Weekly" )
00473 recur()->setType( ORecur::Weekly);
00474 else if ( val == "MonthlyDay" )
00475 recur()->setType( ORecur::MonthlyDay );
00476 else if ( val == "MonthlyDate" )
00477 recur()->setType( ORecur::MonthlyDate );
00478 else if ( val == "Yearly" )
00479 recur()->setType( ORecur::Yearly );
00480 else
00481 recur()->setType( ORecur::NoRepeat );
00482 break;
00483 case FRWeekdays:
00484 recur()->setDays( val.toInt() );
00485 break;
00486 case FRPosition:
00487 recur()->setPosition( val.toInt() );
00488 break;
00489 case FRFreq:
00490 recur()->setFrequency( val.toInt() );
00491 break;
00492 case FRHasEndDate:
00493 recur()->setHasEndDate( val.toInt() );
00494 break;
00495 case FREndDate: {
00496 rp_end = (time_t) val.toLong();
00497 break;
00498 }
00499 default:
00500 ev.setCustomField( attr, val );
00501 break;
00502 }
00503 }
00504
00505
00506 namespace {
00507 QString customToXml(const QMap<QString, QString>& customMap )
00508 {
00509
00510 QString buf(" ");
00511 for ( QMap<QString, QString>::ConstIterator cit = customMap.begin();
00512 cit != customMap.end(); ++cit) {
00513
00514 buf += cit.key();
00515 buf += "=\"";
00516 buf += Qtopia::escapeString(cit.data());
00517 buf += "\" ";
00518 }
00519 return buf;
00520 }
00521
00522
00523 }
00524
00525 QString OTodoAccessXML::toString( const OTodo& ev )const {
00526 QString str;
00527
00528 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
00529 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
00530 str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
00531 str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
00532
00533 str += "Categories=\"" + toString( ev.categories() ) + "\" ";
00534 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
00535 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
00536
00537 if ( ev.hasDueDate() ) {
00538 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
00539 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
00540 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
00541 }
00542
00543 str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 if ( ev.hasRecurrence() ) {
00560 str += ev.recurrence().toString();
00561 }
00562 if ( ev.hasStartDate() )
00563 str += "StartDate=\""+ OConversion::dateToString( ev.startDate() ) +"\" ";
00564 if ( ev.hasCompletedDate() )
00565 str += "CompletedDate=\""+ OConversion::dateToString( ev.completedDate() ) +"\" ";
00566 if ( ev.hasState() )
00567 str += "State=\""+QString::number( ev.state().state() )+"\" ";
00568
00569
00570
00571
00572
00573 if ( ev.hasNotifiers() ) {
00574 OPimNotifyManager manager = ev.notifiers();
00575 OPimNotifyManager::Alarms alarms = manager.alarms();
00576 if (!alarms.isEmpty() ) {
00577 QStringList als;
00578 OPimNotifyManager::Alarms::Iterator it = alarms.begin();
00579 for ( ; it != alarms.end(); ++it ) {
00580
00581 if ( (*it).dateTime().isValid() ) {
00582 als << OConversion::dateTimeToString( (*it).dateTime() )
00583 + ":" + QString::number( (*it).duration() )
00584 + ":" + QString::number( (*it).sound() )
00585 + ":";
00586 }
00587 }
00588
00589 qWarning("als: %s", als.join("____________").latin1() );
00590 str += "Alarms=\""+als.join(";") +"\" ";
00591 }
00592
00593
00594
00595
00596 OPimNotifyManager::Reminders reminders = manager.reminders();
00597 if (!reminders.isEmpty() ) {
00598 OPimNotifyManager::Reminders::Iterator it = reminders.begin();
00599 QStringList records;
00600 for ( ; it != reminders.end(); ++it ) {
00601 records << QString::number( (*it).recordUid() );
00602 }
00603 str += "Reminders=\""+ records.join(";") +"\" ";
00604 }
00605 }
00606 str += customToXml( ev.toExtraMap() );
00607
00608
00609 return str;
00610 }
00611 QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
00612 return Qtopia::Record::idsToString( ints );
00613 }
00614
00615
00616
00617
00618
00619
00620 struct OTodoXMLContainer {
00621 OTodo todo;
00622 };
00623
00624 namespace {
00625 inline QString string( const OTodo& todo) {
00626 return todo.summary().isEmpty() ?
00627 todo.description().left(20 ) :
00628 todo.summary();
00629 }
00630 inline int completed( const OTodo& todo1, const OTodo& todo2) {
00631 int ret = 0;
00632 if ( todo1.isCompleted() ) ret++;
00633 if ( todo2.isCompleted() ) ret--;
00634 return ret;
00635 }
00636 inline int priority( const OTodo& t1, const OTodo& t2) {
00637 return ( t1.priority() - t2.priority() );
00638 }
00639 inline int description( const OTodo& t1, const OTodo& t2) {
00640 return QString::compare( string(t1), string(t2) );
00641 }
00642 inline int deadline( const OTodo& t1, const OTodo& t2) {
00643 int ret = 0;
00644 if ( t1.hasDueDate() &&
00645 t2.hasDueDate() )
00646 ret = t2.dueDate().daysTo( t1.dueDate() );
00647 else if ( t1.hasDueDate() )
00648 ret = -1;
00649 else if ( t2.hasDueDate() )
00650 ret = 1;
00651 else
00652 ret = 0;
00653
00654 return ret;
00655 }
00656
00657 };
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675 class OTodoXMLVector : public QVector<OTodoXMLContainer> {
00676 public:
00677 OTodoXMLVector(int size, bool asc, int sort)
00678 : QVector<OTodoXMLContainer>( size )
00679 {
00680 setAutoDelete( true );
00681 m_asc = asc;
00682 m_sort = sort;
00683 }
00684
00685 QString string( const OTodo& todo) {
00686 return todo.summary().isEmpty() ?
00687 todo.description().left(20 ) :
00688 todo.summary();
00689 }
00694 int compareItems( Item d1, Item d2 ) {
00695 bool seComp, sePrio, seDesc, seDeadline;
00696 seComp = sePrio = seDeadline = seDesc = false;
00697 int ret =0;
00698 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1;
00699 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2;
00700
00701
00702 if ( con1->todo.uid() == con2->todo.uid() )
00703 return 0;
00704
00705 switch ( m_sort ) {
00706
00707 case 0: {
00708 ret = completed( con1->todo, con2->todo );
00709 seComp = TRUE;
00710 break;
00711 }
00712
00713 case 1: {
00714 ret = priority( con1->todo, con2->todo );
00715 sePrio = TRUE;
00716 break;
00717 }
00718
00719 case 2: {
00720 ret = description( con1->todo, con2->todo );
00721 seDesc = TRUE;
00722 break;
00723 }
00724
00725 case 3: {
00726 ret = deadline( con1->todo, con2->todo );
00727 seDeadline = TRUE;
00728 break;
00729 }
00730 default:
00731 ret = 0;
00732 break;
00733 };
00734
00735
00736
00737
00738
00739
00740 if (!m_asc)
00741 ret = ret * -1;
00742
00743 if ( ret )
00744 return ret;
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755 if (!seComp ) {
00756 if ( (ret = completed( con1->todo, con2->todo ) ) ) {
00757 if (!m_asc ) ret *= -1;
00758 return ret;
00759 }
00760 }
00761 if (!sePrio ) {
00762 if ( (ret = priority( con1->todo, con2->todo ) ) ) {
00763 if (!m_asc ) ret *= -1;
00764 return ret;
00765 }
00766 }
00767 if (!seDesc ) {
00768 if ( (ret = description(con1->todo, con2->todo ) ) ) {
00769 if (!m_asc) ret *= -1;
00770 return ret;
00771 }
00772 }
00773 if (!seDeadline) {
00774 if ( (ret = deadline( con1->todo, con2->todo ) ) ) {
00775 if (!m_asc) ret *= -1;
00776 return ret;
00777 }
00778 }
00779
00780 return 0;
00781 }
00782 private:
00783 bool m_asc;
00784 int m_sort;
00785
00786 };
00787
00788 QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder,
00789 int sortFilter, int cat ) {
00790 OTodoXMLVector vector(m_events.count(), asc,sortOrder );
00791 QMap<int, OTodo>::Iterator it;
00792 int item = 0;
00793
00794 bool bCat = sortFilter & 1 ? true : false;
00795 bool bOnly = sortFilter & 2 ? true : false;
00796 bool comp = sortFilter & 4 ? true : false;
00797 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
00798
00799
00800
00801 if ( bCat && cat == -1 ) {
00802 if(!(*it).categories().isEmpty() )
00803 continue;
00804 }else if ( bCat && cat != 0)
00805 if (!(*it).categories().contains( cat ) ) {
00806 continue;
00807 }
00808
00809
00810
00811
00812
00813
00814 if ( !(*it).isOverdue() && bOnly ) {
00815 continue;
00816 }
00817
00818 if ((*it).isCompleted() && comp ) {
00819 continue;
00820 }
00821
00822
00823 OTodoXMLContainer* con = new OTodoXMLContainer();
00824 con->todo = (*it);
00825 vector.insert(item, con );
00826 item++;
00827 }
00828 vector.resize( item );
00829
00830 vector.sort();
00831
00832 QArray<int> array( vector.count() );
00833 for (uint i= 0; i < vector.count(); i++ ) {
00834 array[i] = ( vector.at(i) )->todo.uid();
00835 }
00836 return array;
00837 };
00838 void OTodoAccessXML::removeAllCompleted() {
00839 QMap<int, OTodo> events = m_events;
00840 for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) {
00841 if ( (*it).isCompleted() )
00842 events.remove( it.key() );
00843 }
00844 m_events = events;
00845 }
00846 QBitArray OTodoAccessXML::supports()const {
00847 static QBitArray ar = sup();
00848 return ar;
00849 }
00850 QBitArray OTodoAccessXML::sup() {
00851 QBitArray ar( OTodo::CompletedDate +1 );
00852 ar.fill( true );
00853 ar[OTodo::CrossReference] = false;
00854 ar[OTodo::State ] = false;
00855 ar[OTodo::Reminders] = false;
00856 ar[OTodo::Notifiers] = false;
00857 ar[OTodo::Maintainer] = false;
00858
00859 return ar;
00860 }
00861 QArray<int> OTodoAccessXML::matchRegexp( const QRegExp &r ) const
00862 {
00863 QArray<int> m_currentQuery( m_events.count() );
00864 uint arraycounter = 0;
00865
00866 QMap<int, OTodo>::ConstIterator it;
00867 for (it = m_events.begin(); it != m_events.end(); ++it ) {
00868 if ( it.data().match( r ) )
00869 m_currentQuery[arraycounter++] = it.data().uid();
00870
00871 }
00872
00873 m_currentQuery.resize(arraycounter);
00874
00875 return m_currentQuery;
00876 }