Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

otodoaccessxml.cpp

Go to the documentation of this file.
00001 /*
00002                              This file is part of the Opie Project
00003                              Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
00004               =.             Copyright (C) The Opie Team <opie-devel@handhelds.org>
00005             .=l.
00006            .>+-=
00007  _;:,     .>    :=|.         This program is free software; you can
00008 .> <`_,   >  .   <=          redistribute it and/or  modify it under
00009 :`=1 )Y*s>-.--   :           the terms of the GNU Library General Public
00010 .="- .-=="i,     .._         License as published by the Free Software
00011  - .   .-<_>     .<>         Foundation; either version 2 of the License,
00012      ._= =}       :          or (at your option) any later version.
00013     .%`+i>       _;_.
00014     .i_,=:_.      -<s.       This program is distributed in the hope that
00015      +  .  -:.       =       it will be useful,  but WITHOUT ANY WARRANTY;
00016     : ..    .:,     . . .    without even the implied warranty of
00017     =_        +     =;=|`    MERCHANTABILITY or FITNESS FOR A
00018   _.=:.       :    :=>`:     PARTICULAR PURPOSE. See the GNU
00019 ..}^=.=       =       ;      Library General Public License for more
00020 ++=   -.     .`     .:       details.
00021  :     =  ...= . :.=-
00022  -.   .:....=;==+<;          You should have received a copy of the GNU
00023   -_. . .   )=.  =           Library General Public License along with
00024     --        :-=`           this library; see the file COPYING.LIB.
00025                              If not, write to the Free Software Foundation,
00026                              Inc., 59 Temple Place - Suite 330,
00027                              Boston, MA 02111-1307, USA.
00028 */
00029 
00030 /* OPIE */
00031 #include <opie2/opimdateconversion.h>
00032 #include <opie2/opimstate.h>
00033 #include <opie2/opimtimezone.h>
00034 #include <opie2/opimnotifymanager.h>
00035 #include <opie2/opimrecurrence.h>
00036 #include <opie2/otodoaccessxml.h>
00037 #include <opie2/otodoaccess.h>
00038 #include <opie2/odebug.h>
00039 
00040 #include <opie2/private/opimtodosortvector.h>
00041 
00042 #include <qpe/global.h>
00043 #include <qpe/stringutil.h>
00044 #include <qpe/timeconversion.h>
00045 
00046 /* QT */
00047 #include <qfile.h>
00048 #include <qvector.h>
00049 
00050 /* STD */
00051 #include <errno.h>
00052 #include <fcntl.h>
00053 
00054 #include <sys/mman.h>
00055 #include <sys/stat.h>
00056 #include <sys/types.h>
00057 
00058 #include <unistd.h>
00059 
00060 
00061 using namespace Opie;
00062 
00063 namespace {
00064     time_t rp_end;
00065     OPimRecurrence* rec;
00066     OPimRecurrence *recur() {
00067         if (!rec ) rec = new OPimRecurrence;
00068         return rec;
00069     }
00070     int snd;
00071     enum MoreAttributes {
00072         FRType = OPimTodo::CompletedDate + 2,
00073         FRWeekdays,
00074         FRPosition,
00075         FRFreq,
00076         FRHasEndDate,
00077         FREndDate,
00078         FRStart,
00079         FREnd
00080     };
00081     // FROM TT again
00082 char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen)
00083 {
00084     char needleChar;
00085     char haystackChar;
00086     if (!needle || !haystack || !hLen || !nLen)
00087     return 0;
00088 
00089     const char* hsearch = haystack;
00090 
00091     if ((needleChar = *needle++) != 0) {
00092     nLen--; //(to make up for needle++)
00093     do {
00094         do {
00095         if ((haystackChar = *hsearch++) == 0)
00096             return (0);
00097         if (hsearch >= haystack + hLen)
00098             return (0);
00099         } while (haystackChar != needleChar);
00100     } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0);
00101     hsearch--;
00102     }
00103     return ((char *)hsearch);
00104 }
00105 }
00106 
00107 namespace Opie {
00108 
00109 OPimTodoAccessXML::OPimTodoAccessXML( const QString& appName,
00110                                 const QString& fileName )
00111     : OPimTodoAccessBackend(), m_app( appName ),  m_opened( false ), m_changed( false )
00112 {
00113     if (!fileName.isEmpty() )
00114         m_file = fileName;
00115     else
00116         m_file = Global::applicationFileName( "todolist", "todolist.xml" );
00117 }
00118 OPimTodoAccessXML::~OPimTodoAccessXML() {
00119 
00120 }
00121 bool OPimTodoAccessXML::load() {
00122     rec = 0;
00123     m_opened = true;
00124     m_changed = false;
00125     /* initialize dict */
00126     /*
00127      * UPDATE dict if you change anything!!!
00128      */
00129     QAsciiDict<int> dict(26);
00130     dict.setAutoDelete( TRUE );
00131     dict.insert("Categories" ,     new int(OPimTodo::Category)         );
00132     dict.insert("Uid" ,            new int(OPimTodo::Uid)              );
00133     dict.insert("HasDate" ,        new int(OPimTodo::HasDate)          );
00134     dict.insert("Completed" ,      new int(OPimTodo::Completed)        );
00135     dict.insert("Description" ,    new int(OPimTodo::Description)      );
00136     dict.insert("Summary" ,        new int(OPimTodo::Summary)          );
00137     dict.insert("Priority" ,       new int(OPimTodo::Priority)         );
00138     dict.insert("DateDay" ,        new int(OPimTodo::DateDay)          );
00139     dict.insert("DateMonth" ,      new int(OPimTodo::DateMonth)        );
00140     dict.insert("DateYear" ,       new int(OPimTodo::DateYear)         );
00141     dict.insert("Progress" ,       new int(OPimTodo::Progress)         );
00142     dict.insert("CompletedDate",   new int(OPimTodo::CompletedDate)    );
00143     dict.insert("StartDate",       new int(OPimTodo::StartDate)        );
00144     dict.insert("CrossReference",  new int(OPimTodo::CrossReference)   );
00145     dict.insert("State",           new int(OPimTodo::State)            );
00146     dict.insert("Alarms",          new int(OPimTodo::Alarms)           );
00147     dict.insert("Reminders",       new int(OPimTodo::Reminders)        );
00148     dict.insert("Maintainer",      new int(OPimTodo::Maintainer)       );
00149     dict.insert("rtype",           new int(FRType)                  );
00150     dict.insert("rweekdays",       new int(FRWeekdays)              );
00151     dict.insert("rposition",       new int(FRPosition)              );
00152     dict.insert("rfreq",           new int(FRFreq)                  );
00153     dict.insert("start",           new int(FRStart)                 );
00154     dict.insert("rhasenddate",     new int(FRHasEndDate)            );
00155     dict.insert("enddt",           new int(FREndDate)               );
00156 
00157     // here the custom XML parser from TT it's GPL
00158     // but we want to push OpiePIM... to TT.....
00159     // mmap part from zecke :)
00160     int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY );
00161     struct stat attribut;
00162     if ( fd < 0 ) return false;
00163 
00164     if ( fstat(fd, &attribut ) == -1 ) {
00165         ::close( fd );
00166         return false;
00167     }
00168     void* map_addr = ::mmap(NULL,  attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 );
00169     if ( map_addr == ( (caddr_t)-1) ) {
00170         ::close(fd );
00171         return false;
00172     }
00173     /* advise the kernel who we want to read it */
00174     ::madvise( map_addr,  attribut.st_size,  MADV_SEQUENTIAL );
00175     /* we do not the file any more */
00176     ::close( fd );
00177 
00178     char* dt = (char*)map_addr;
00179     int len = attribut.st_size;
00180     int i = 0;
00181     char *point;
00182     const char* collectionString = "<Task ";
00183     int strLen = strlen(collectionString);
00184     while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) {
00185         i = point -dt;
00186         i+= strLen;
00187 
00188         OPimTodo ev;
00189         m_year = m_month = m_day = 0;
00190 
00191         while ( TRUE ) {
00192             while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
00193         ++i;
00194         if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
00195         break;
00196 
00197         // we have another attribute, read it.
00198         int j = i;
00199         while ( j < len && dt[j] != '=' )
00200         ++j;
00201         QCString attr( dt+i, j-i+1);
00202 
00203         i = ++j; // skip =
00204 
00205         // find the start of quotes
00206         while ( i < len && dt[i] != '"' )
00207         ++i;
00208         j = ++i;
00209 
00210         bool haveUtf = FALSE;
00211         bool haveEnt = FALSE;
00212         while ( j < len && dt[j] != '"' ) {
00213         if ( ((unsigned char)dt[j]) > 0x7f )
00214             haveUtf = TRUE;
00215         if ( dt[j] == '&' )
00216             haveEnt = TRUE;
00217         ++j;
00218         }
00219         if ( i == j ) {
00220         // empty value
00221         i = j + 1;
00222         continue;
00223         }
00224 
00225         QCString value( dt+i, j-i+1 );
00226         i = j + 1;
00227 
00228         QString str = (haveUtf ? QString::fromUtf8( value )
00229             : QString::fromLatin1( value ) );
00230         if ( haveEnt )
00231         str = Qtopia::plainString( str );
00232 
00233             /*
00234              * add key + value
00235              */
00236             todo( &dict, ev, attr, str );
00237 
00238         }
00239         /*
00240          * now add it
00241          */
00242         if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
00243             ev.setUid( 1 );
00244             m_changed = true;
00245         }
00246         if ( ev.hasDueDate() ) {
00247             ev.setDueDate( QDate(m_year, m_month, m_day) );
00248         }
00249         if ( rec && rec->doesRecur() ) {
00250             OPimTimeZone utc = OPimTimeZone::utc();
00251             OPimRecurrence recu( *rec ); // call copy c'tor
00252             recu.setEndDate( utc.fromUTCDateTime( rp_end ).date() );
00253             recu.setStart( ev.dueDate() );
00254             ev.setRecurrence( recu );
00255         }
00256         m_events.insert(ev.uid(), ev );
00257         m_year = m_month = m_day = -1;
00258         delete rec;
00259         rec = 0;
00260     }
00261 
00262     munmap(map_addr, attribut.st_size );
00263 
00264     return true;
00265 }
00266 bool OPimTodoAccessXML::reload() {
00267     m_events.clear();
00268     return load();
00269 }
00270 bool OPimTodoAccessXML::save() {
00271     if (!m_opened || !m_changed ) {
00272         return true;
00273     }
00274     QString strNewFile = m_file + ".new";
00275     QFile f( strNewFile );
00276     if (!f.open( IO_WriteOnly|IO_Raw ) )
00277         return false;
00278 
00279     int written;
00280     QString out;
00281     out = "<!DOCTYPE Tasks>\n<Tasks>\n";
00282 
00283     // for all todos
00284     QMap<int, OPimTodo>::Iterator it;
00285     for (it = m_events.begin(); it != m_events.end(); ++it ) {
00286         out+= "<Task " + toString( (*it) ) + " />\n";
00287         QCString cstr = out.utf8();
00288         written = f.writeBlock( cstr.data(),  cstr.length() );
00289 
00290         /* less written then we wanted */
00291         if ( written != (int)cstr.length() ) {
00292             f.close();
00293             QFile::remove( strNewFile );
00294             return false;
00295         }
00296         out = QString::null;
00297     }
00298 
00299     out +=  "</Tasks>";
00300     QCString cstr = out.utf8();
00301     written = f.writeBlock( cstr.data(), cstr.length() );
00302 
00303     if ( written != (int)cstr.length() ) {
00304         f.close();
00305         QFile::remove( strNewFile );
00306         return false;
00307     }
00308     /* flush before renaming */
00309     f.close();
00310 
00311     if( ::rename( strNewFile.latin1(),  m_file.latin1() ) < 0 ) {
00312         QFile::remove( strNewFile );
00313     }
00314 
00315     m_changed = false;
00316     return true;
00317 }
00318 QArray<int> OPimTodoAccessXML::allRecords()const {
00319     QArray<int> ids( m_events.count() );
00320     QMap<int, OPimTodo>::ConstIterator it;
00321     int i = 0;
00322 
00323     for ( it = m_events.begin(); it != m_events.end(); ++it )
00324         ids[i++] = it.key();
00325 
00326 
00327     return ids;
00328 }
00329 
00330 OPimTodo OPimTodoAccessXML::find( int uid )const {
00331     OPimTodo todo;
00332     todo.setUid( 0 ); // isEmpty()
00333     QMap<int, OPimTodo>::ConstIterator it = m_events.find( uid );
00334     if ( it != m_events.end() )
00335         todo = it.data();
00336 
00337     return todo;
00338 }
00339 void OPimTodoAccessXML::clear() {
00340     if (m_opened )
00341         m_changed = true;
00342 
00343     m_events.clear();
00344 }
00345 bool OPimTodoAccessXML::add( const OPimTodo& todo ) {
00346     m_changed = true;
00347     m_events.insert( todo.uid(), todo );
00348 
00349     return true;
00350 }
00351 bool OPimTodoAccessXML::remove( int uid ) {
00352     m_changed = true;
00353     m_events.remove( uid );
00354 
00355     return true;
00356 }
00357 bool OPimTodoAccessXML::replace( const OPimTodo& todo) {
00358     m_changed = true;
00359     m_events.replace( todo.uid(), todo );
00360 
00361     return true;
00362 }
00363 QArray<int> OPimTodoAccessXML::effectiveToDos( const QDate& start,
00364                                             const QDate& end,
00365                                             bool includeNoDates )const {
00366     QArray<int> ids( m_events.count() );
00367     QMap<int, OPimTodo>::ConstIterator it;
00368 
00369     int i = 0;
00370     for ( it = m_events.begin(); it != m_events.end(); ++it ) {
00371         if ( !it.data().hasDueDate() && includeNoDates) {
00372                 ids[i++] = it.key();
00373         }else if ( it.data().dueDate() >= start &&
00374                    it.data().dueDate() <= end ) {
00375             ids[i++] = it.key();
00376         }
00377     }
00378     ids.resize( i );
00379     return ids;
00380 }
00381 QArray<int> OPimTodoAccessXML::overDue()const {
00382     QArray<int> ids( m_events.count() );
00383     int i = 0;
00384 
00385     QMap<int, OPimTodo>::ConstIterator it;
00386     for ( it = m_events.begin(); it != m_events.end(); ++it ) {
00387         if ( it.data().isOverdue() ) {
00388             ids[i] = it.key();
00389             i++;
00390         }
00391     }
00392     ids.resize( i );
00393     return ids;
00394 }
00395 
00396 
00397 /* private */
00398 void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev,
00399                             const QCString& attr, const QString& val) {
00400 
00401     int *find=0;
00402 
00403     find = (*dict)[ attr.data() ];
00404     if (!find ) {
00405         ev.setCustomField( attr, val );
00406         return;
00407     }
00408 
00409     switch( *find ) {
00410     case OPimTodo::Uid:
00411         ev.setUid( val.toInt() );
00412         break;
00413     case OPimTodo::Category:
00414         ev.setCategories( ev.idsFromString( val ) );
00415         break;
00416     case OPimTodo::HasDate:
00417         ev.setHasDueDate( val.toInt() );
00418         break;
00419     case OPimTodo::Completed:
00420         ev.setCompleted( val.toInt() );
00421         break;
00422     case OPimTodo::Description:
00423         ev.setDescription( val );
00424         break;
00425     case OPimTodo::Summary:
00426         ev.setSummary( val );
00427         break;
00428     case OPimTodo::Priority:
00429         ev.setPriority( val.toInt() );
00430         break;
00431     case OPimTodo::DateDay:
00432         m_day = val.toInt();
00433         break;
00434     case OPimTodo::DateMonth:
00435         m_month = val.toInt();
00436         break;
00437     case OPimTodo::DateYear:
00438         m_year = val.toInt();
00439         break;
00440     case OPimTodo::Progress:
00441         ev.setProgress( val.toInt() );
00442         break;
00443     case OPimTodo::CompletedDate:
00444         ev.setCompletedDate( OPimDateConversion::dateFromString( val ) );
00445         break;
00446     case OPimTodo::StartDate:
00447         ev.setStartDate( OPimDateConversion::dateFromString( val ) );
00448         break;
00449     case OPimTodo::State:
00450         ev.setState( val.toInt() );
00451         break;
00452     case OPimTodo::Alarms:{
00453         OPimNotifyManager &manager = ev.notifiers();
00454         QStringList als = QStringList::split(";", val );
00455         for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) {
00456             QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty
00457             OPimAlarm al( alarm[2].toInt(), OPimDateConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() );
00458             manager.add( al );
00459         }
00460     }
00461         break;
00462     case OPimTodo::Reminders:{
00463         OPimNotifyManager &manager = ev.notifiers();
00464         QStringList rems = QStringList::split(";", val );
00465         for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) {
00466             OPimReminder rem( (*it).toInt() );
00467             manager.add( rem );
00468         }
00469     }
00470         break;
00471     case OPimTodo::CrossReference:
00472     {
00473         /*
00474          * A cross refernce looks like
00475          * appname,id;appname,id
00476          * we need to split it up
00477          */
00478         QStringList  refs = QStringList::split(';', val );
00479         QStringList::Iterator strIt;
00480         for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
00481             int pos = (*strIt).find(',');
00482             if ( pos > -1 )
00483                 ; // ev.addRelation( (*strIt).left(pos),  (*strIt).mid(pos+1).toInt() );
00484 
00485         }
00486         break;
00487     }
00488     /* Recurrence stuff below + post processing later */
00489     case FRType:
00490         if ( val == "Daily" )
00491             recur()->setType( OPimRecurrence::Daily );
00492         else if ( val == "Weekly" )
00493             recur()->setType( OPimRecurrence::Weekly);
00494         else if ( val == "MonthlyDay" )
00495             recur()->setType( OPimRecurrence::MonthlyDay );
00496         else if ( val == "MonthlyDate" )
00497             recur()->setType( OPimRecurrence::MonthlyDate );
00498         else if ( val == "Yearly" )
00499             recur()->setType( OPimRecurrence::Yearly );
00500         else
00501             recur()->setType( OPimRecurrence::NoRepeat );
00502         break;
00503     case FRWeekdays:
00504         recur()->setDays( val.toInt() );
00505         break;
00506     case FRPosition:
00507         recur()->setPosition( val.toInt() );
00508         break;
00509     case FRFreq:
00510         recur()->setFrequency( val.toInt() );
00511         break;
00512     case FRHasEndDate:
00513         recur()->setHasEndDate( val.toInt() );
00514         break;
00515     case FREndDate: {
00516         rp_end = (time_t) val.toLong();
00517         break;
00518     }
00519     default:
00520         ev.setCustomField( attr, val );
00521         break;
00522     }
00523 }
00524 
00525 // from PalmtopRecord... GPL ### FIXME
00526 namespace {
00527 QString customToXml(const QMap<QString, QString>& customMap )
00528 {
00529     QString buf(" ");
00530     for ( QMap<QString, QString>::ConstIterator cit = customMap.begin();
00531         cit != customMap.end(); ++cit) {
00532     buf += cit.key();
00533     buf += "=\"";
00534     buf += Qtopia::escapeString(cit.data());
00535     buf += "\" ";
00536     }
00537     return buf;
00538 }
00539 
00540 
00541 }
00542 
00543 QString OPimTodoAccessXML::toString( const OPimTodo& ev )const {
00544     QString str;
00545 
00546     str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
00547     str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
00548     str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
00549     str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
00550 
00551     str += "Categories=\"" + toString( ev.categories() ) + "\" ";
00552     str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
00553     str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
00554 
00555     if ( ev.hasDueDate() ) {
00556         str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
00557         str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
00558         str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
00559     }
00560     str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
00561 
00562 // append the extra options
00563     /* FIXME Qtopia::Record this is currently not
00564      * possible you can set custom fields
00565      * but don' iterate over the list
00566      * I may do #define private protected
00567      * for this case - cough  --zecke
00568      */
00569     /*
00570     QMap<QString, QString> extras = ev.extras();
00571     QMap<QString, QString>::Iterator extIt;
00572     for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
00573         str += extIt.key() + "=\"" +  extIt.data() + "\" ";
00574     */
00575     // cross refernce
00576     if ( ev.hasRecurrence() ) {
00577         str += ev.recurrence().toString();
00578     }
00579     if ( ev.hasStartDate() )
00580         str += "StartDate=\""+ OPimDateConversion::dateToString( ev.startDate() ) +"\" ";
00581     if ( ev.hasCompletedDate() )
00582         str += "CompletedDate=\""+ OPimDateConversion::dateToString( ev.completedDate() ) +"\" ";
00583     if ( ev.hasState() )
00584         str += "State=\""+QString::number( ev.state().state() )+"\" ";
00585 
00586     /*
00587      * save reminders and notifiers!
00588      * DATE_TIME:DURATION:SOUND:NOT_USED_YET;OTHER_DATE_TIME:OTHER_DURATION:SOUND:....
00589      */
00590     if ( ev.hasNotifiers() ) {
00591         OPimNotifyManager manager = ev.notifiers();
00592         OPimNotifyManager::Alarms alarms = manager.alarms();
00593         if (!alarms.isEmpty() ) {
00594             QStringList als;
00595             OPimNotifyManager::Alarms::Iterator it = alarms.begin();
00596             for ( ; it != alarms.end(); ++it ) {
00597                 /* only if time is valid */
00598                 if ( (*it).dateTime().isValid() ) {
00599                     als << OPimDateConversion::dateTimeToString( (*it).dateTime() )
00600                         + ":" + QString::number( (*it).duration() )
00601                         + ":" + QString::number( (*it).sound() )
00602                         + ":";
00603                 }
00604             }
00605             // now write the list
00606             str += "Alarms=\""+als.join(";") +"\" ";
00607         }
00608 
00609         /*
00610          * now the same for reminders but more easy. We just save the uid of the OPimEvent.
00611          */
00612         OPimNotifyManager::Reminders reminders = manager.reminders();
00613         if (!reminders.isEmpty() ) {
00614             OPimNotifyManager::Reminders::Iterator it = reminders.begin();
00615             QStringList records;
00616             for ( ; it != reminders.end(); ++it ) {
00617                 records << QString::number( (*it).recordUid() );
00618             }
00619             str += "Reminders=\""+ records.join(";") +"\" ";
00620         }
00621     }
00622     str += customToXml( ev.toExtraMap() );
00623 
00624 
00625     return str;
00626 }
00627 QString OPimTodoAccessXML::toString( const QArray<int>& ints ) const {
00628     return Qtopia::Record::idsToString( ints );
00629 }
00630 
00631 
00632 QArray<int> OPimTodoAccessXML::sorted( const UIDArray& events, bool asc,
00633                                        int sortOrder,int sortFilter,
00634                                        const QArray<int>& categories )const {
00635     Internal::OPimTodoSortVector vector(events.count(), asc,sortOrder );
00636     int item = 0;
00637 
00638     bool bCat = sortFilter  & OPimTodoAccess::FilterCategory ? true : false;
00639     bool bOnly = sortFilter & OPimTodoAccess::OnlyOverDue ? true : false;
00640     bool comp = sortFilter  & OPimTodoAccess::DoNotShowCompleted ? true : false;
00641     bool catPassed = false;
00642     int cat;
00643 
00644     for ( uint i = 0; i < events.count(); ++i ) {
00645         /* Guard against creating a new item... */
00646         if ( !m_events.contains( events[i] ) )
00647             continue;
00648 
00649         OPimTodo todo = m_events[events[i]];
00650 
00651         /* show category */
00652         /* -1 == unfiled */
00653         catPassed = false;
00654         for ( uint cat_nu = 0; cat_nu < categories.count(); ++cat_nu ) {
00655             cat = categories[cat_nu];
00656             if ( bCat && cat == -1 ) {
00657                 if(!todo.categories().isEmpty() )
00658                     continue;
00659             } else if ( bCat && cat != 0)
00660                 if (!todo.categories().contains( cat ) )
00661                     continue;
00662             catPassed = true;
00663             break;
00664         }
00665 
00666         /*
00667          * If none of the Categories matched
00668          * continue
00669          */
00670         if ( !catPassed )
00671             continue;
00672         if ( !todo.isOverdue() && bOnly )
00673             continue;
00674         if (todo.isCompleted() && comp )
00675             continue;
00676 
00677         vector.insert(item++, todo );
00678     }
00679 
00680     vector.resize( item );
00681     /* sort it now */
00682     vector.sort();
00683     /* now get the uids */
00684     UIDArray array( vector.count() );
00685     for (uint i= 0; i < vector.count(); i++ )
00686         array[i] = vector.uidAt( i );
00687 
00688     return array;
00689 }
00690 
00691 void OPimTodoAccessXML::removeAllCompleted() {
00692     QMap<int, OPimTodo> events = m_events;
00693     for ( QMap<int, OPimTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) {
00694         if ( (*it).isCompleted() )
00695             events.remove( it.key() );
00696     }
00697     m_events = events;
00698 }
00699 
00700 QArray<int> OPimTodoAccessXML::matchRegexp(  const QRegExp &r ) const
00701 {
00702     QArray<int> currentQuery( m_events.count() );
00703     uint arraycounter = 0;
00704 
00705     QMap<int, OPimTodo>::ConstIterator it;
00706     for (it = m_events.begin(); it != m_events.end(); ++it ) {
00707         if ( it.data().match( r ) )
00708             currentQuery[arraycounter++] = it.data().uid();
00709 
00710     }
00711     // Shrink to fit..
00712     currentQuery.resize(arraycounter);
00713 
00714     return currentQuery;
00715 }
00716 
00717 }

Generated on Sat Nov 5 16:16:18 2005 for OPIE by  doxygen 1.4.2