logsui/logscntfinder/src/logscntfinder.cpp
changeset 0 4a5361db8937
child 2 7119b73b84d6
equal deleted inserted replaced
-1:000000000000 0:4a5361db8937
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include <QListIterator>
       
    19 
       
    20 #include <qcontactdetailfilter.h>
       
    21 #include <qcontactphonenumber.h>
       
    22 #include <qcontactname.h>
       
    23 #include <qcontactmanager.h>
       
    24 #include <qcontactavatar.h>
       
    25 #include <QVector>
       
    26 
       
    27 #include "logscntfinder.h"
       
    28 #include "logspredictivetranslator.h"
       
    29 #include "logslogger.h"
       
    30 
       
    31 const int MaxPredSearchPatternLen = 15;
       
    32 const QChar ZeroSepar('0');
       
    33 
       
    34 
       
    35 // -----------------------------------------------------------------------------
       
    36 // LogsCntEntry::richText()
       
    37 // -----------------------------------------------------------------------------
       
    38 //
       
    39 QString LogsCntText::richText( QString startTag, 
       
    40                                QString endTag ) const
       
    41 {
       
    42     QString str = text();
       
    43     if ( str.length() > 0 && highlights() > 0 ) {
       
    44         str.insert( highlights() , endTag );
       
    45         str.insert( 0, startTag );
       
    46     }
       
    47 
       
    48     return str;
       
    49     
       
    50 }
       
    51 
       
    52 // -----------------------------------------------------------------------------
       
    53 // LogsCntEntry::LogsCntEntry()
       
    54 // -----------------------------------------------------------------------------
       
    55 //
       
    56 LogsCntEntry::LogsCntEntry( LogsCntEntryHandle& handle, 
       
    57                             quint32 cid )
       
    58     : mType( EntryTypeHistory ), mCid( cid ), 
       
    59       mCached( true ),mHandle(&handle)
       
    60 {
       
    61     LogsCntText empty;
       
    62     mFirstName.append( empty );
       
    63     mLastName.append( empty );
       
    64     mAvatarPath = "";
       
    65 }
       
    66 
       
    67 // -----------------------------------------------------------------------------
       
    68 // LogsCntEntry::LogsCntEntry()
       
    69 // -----------------------------------------------------------------------------
       
    70 //
       
    71 LogsCntEntry::LogsCntEntry( quint32 cid )
       
    72     : mType( EntryTypeContact ), mCid( cid ), 
       
    73       mCached( false ),mHandle(0)
       
    74 {
       
    75     LogsCntText empty;
       
    76     mFirstName.append( empty );
       
    77     mLastName.append( empty );
       
    78     mAvatarPath = "";
       
    79 }
       
    80 
       
    81 // -----------------------------------------------------------------------------
       
    82 // copy LogsCntEntry::LogsCntEntry()
       
    83 // -----------------------------------------------------------------------------
       
    84 //
       
    85 LogsCntEntry::LogsCntEntry( const LogsCntEntry& entry )
       
    86     : mType(entry.mType),
       
    87       mCid(entry.mCid),
       
    88       mFirstName(entry.mFirstName),
       
    89       mLastName(entry.mLastName),
       
    90       mCached(entry.mCached),
       
    91       mHandle(entry.mHandle),
       
    92       mPhoneNumber(entry.mPhoneNumber),
       
    93       mAvatarPath(entry.mAvatarPath)
       
    94 {
       
    95 }
       
    96 
       
    97 // -----------------------------------------------------------------------------
       
    98 // LogsCntEntry::~LogsCntEntry()
       
    99 // -----------------------------------------------------------------------------
       
   100 //
       
   101 LogsCntEntry::~LogsCntEntry()
       
   102 {
       
   103 }
       
   104 
       
   105 // -----------------------------------------------------------------------------
       
   106 // LogsCntEntry::firstName()
       
   107 // -----------------------------------------------------------------------------
       
   108 //
       
   109 const LogsCntTextList& LogsCntEntry::firstName() const 
       
   110 {
       
   111     return mFirstName;
       
   112 }
       
   113 
       
   114 // -----------------------------------------------------------------------------
       
   115 // LogsCntEntry::lastName()
       
   116 // -----------------------------------------------------------------------------
       
   117 //
       
   118 const LogsCntTextList& LogsCntEntry::lastName() const
       
   119 {
       
   120     return mLastName;
       
   121 }
       
   122 
       
   123 // -----------------------------------------------------------------------------
       
   124 // LogsCntEntry::avatarPath()
       
   125 // -----------------------------------------------------------------------------
       
   126 //
       
   127 const QString& LogsCntEntry::avatarPath() const
       
   128 {
       
   129     return mAvatarPath;
       
   130 }
       
   131 
       
   132 // -----------------------------------------------------------------------------
       
   133 // LogsCntEntry::phoneNumber()
       
   134 // -----------------------------------------------------------------------------
       
   135 //
       
   136 const LogsCntText& LogsCntEntry::phoneNumber() const
       
   137 {
       
   138     return mPhoneNumber;
       
   139 }
       
   140 
       
   141 // -----------------------------------------------------------------------------
       
   142 // LogsCntEntry::speedDial()
       
   143 // -----------------------------------------------------------------------------
       
   144 //
       
   145 const QString& LogsCntEntry::speedDial() const
       
   146 {
       
   147     return mSpeedDial;
       
   148 }
       
   149 
       
   150 
       
   151 
       
   152 // -----------------------------------------------------------------------------
       
   153 // LogsCntEntry::contactId()
       
   154 // -----------------------------------------------------------------------------
       
   155 //
       
   156 quint32 LogsCntEntry::contactId() const
       
   157 {
       
   158     return mCid;
       
   159 }
       
   160 
       
   161 // -----------------------------------------------------------------------------
       
   162 // LogsCntEntry::handle()
       
   163 // -----------------------------------------------------------------------------
       
   164 //
       
   165 LogsCntEntryHandle* LogsCntEntry::handle() const
       
   166 {
       
   167     return mHandle;
       
   168 }
       
   169 
       
   170 // -----------------------------------------------------------------------------
       
   171 // LogsCntEntry::setFirstName()
       
   172 // -----------------------------------------------------------------------------
       
   173 //
       
   174 void LogsCntEntry::setFirstName( const QString& name ) 
       
   175 {
       
   176     mCached=true;
       
   177     mFirstName.clear();
       
   178     doSetText( name, mFirstName );
       
   179 }
       
   180 
       
   181 // -----------------------------------------------------------------------------
       
   182 // LogsCntEntry::setLastName()
       
   183 // -----------------------------------------------------------------------------
       
   184 //
       
   185 void LogsCntEntry::setLastName( const QString& name ) 
       
   186 {
       
   187     mCached=true;
       
   188     mLastName.clear();
       
   189     doSetText( name, mLastName );
       
   190 }
       
   191 
       
   192 // -----------------------------------------------------------------------------
       
   193 // LogsCntEntry::setAvatarPath()
       
   194 // -----------------------------------------------------------------------------
       
   195 //
       
   196 void LogsCntEntry::setAvatarPath( const QString& avatarpath ) 
       
   197 {
       
   198     mCached=true;
       
   199     mAvatarPath.clear();
       
   200     mAvatarPath = avatarpath;
       
   201 }
       
   202 
       
   203 // -----------------------------------------------------------------------------
       
   204 // LogsCntEntry::tokens()
       
   205 // -----------------------------------------------------------------------------
       
   206 //
       
   207 QStringList LogsCntEntry::tokens( const QString& source, 
       
   208                                   const QChar& separ ) const
       
   209 {
       
   210     QStringList target = source.split( separ, QString::SkipEmptyParts );
       
   211     if ( target.length() > 1 && separ == ZeroSepar ) {
       
   212         QString& first = target[0];
       
   213         QString& last = target[target.length()-1];
       
   214         padWithZeros( first, source, 0 );
       
   215         padWithZeros( last, source, last.length() );
       
   216     }
       
   217     return target;
       
   218     
       
   219 }
       
   220 
       
   221 
       
   222 // -----------------------------------------------------------------------------
       
   223 // LogsCntEntry::padWithLeadingZeros()
       
   224 // -----------------------------------------------------------------------------
       
   225 //
       
   226 void LogsCntEntry::padWithZeros( QString& token, 
       
   227                                  const QString& source, int padIndex ) const
       
   228 {
       
   229     const QChar* content = source.data();
       
   230     int index = !padIndex ? 0 : source.length()-1;
       
   231             
       
   232     while( index >= 0 && index < source.length() ) {
       
   233         if ( content[ index ] == ZeroSepar ) {
       
   234             token.insert( padIndex, ZeroSepar );
       
   235             index = !padIndex ? index+1 : index-1;
       
   236         } else {
       
   237             index = -1;
       
   238         }
       
   239     }
       
   240 }
       
   241 
       
   242 
       
   243 
       
   244 // -----------------------------------------------------------------------------
       
   245 // LogsCntEntry::doSetText()
       
   246 // -----------------------------------------------------------------------------
       
   247 //
       
   248 void LogsCntEntry::doSetText( const QString& text, LogsCntTextList& textlist ) 
       
   249 {
       
   250     QListIterator<QString> iter( tokens( text ) );
       
   251 
       
   252     while( iter.hasNext() ) {
       
   253         LogsCntText txt;
       
   254         txt.mText = iter.next();
       
   255         txt.mTranslatedText = 
       
   256             LogsPredictiveTranslator::instance()->translate( txt.mText );
       
   257         textlist.append( txt );
       
   258     }
       
   259     if ( textlist.count() == 0 ) {
       
   260         textlist.append( LogsCntText() );
       
   261     }
       
   262 }
       
   263 
       
   264 // -----------------------------------------------------------------------------
       
   265 // LogsCntEntry::setPhoneNumber()
       
   266 // -----------------------------------------------------------------------------
       
   267 //
       
   268 void LogsCntEntry::setPhoneNumber( const QString& number )
       
   269 {
       
   270     mCached=true;
       
   271     mPhoneNumber.mText = number;
       
   272 }
       
   273 
       
   274 // -----------------------------------------------------------------------------
       
   275 // LogsCntEntry::resetHighlights()
       
   276 // -----------------------------------------------------------------------------
       
   277 //
       
   278 void LogsCntEntry::resetHighlights( LogsCntTextList& nameArray )
       
   279 {
       
   280     QMutableListIterator<LogsCntText> names( nameArray ); 
       
   281     while( names.hasNext() ) {
       
   282         names.next().mHighlights = 0;
       
   283     }
       
   284     
       
   285 }
       
   286 
       
   287 
       
   288 // -----------------------------------------------------------------------------
       
   289 // LogsCntEntry::setHighlights()
       
   290 // -----------------------------------------------------------------------------
       
   291 //
       
   292 void LogsCntEntry::setHighlights( const QString& pattern )
       
   293 {
       
   294     resetHighlights( mFirstName );
       
   295     resetHighlights( mLastName );
       
   296     
       
   297     mPhoneNumber.mHighlights = 
       
   298             mPhoneNumber.text().startsWith( pattern ) &&
       
   299             mPhoneNumber.text().length() >= pattern.length() ?
       
   300             pattern.length(): 0;
       
   301     
       
   302     doSetHighlights( pattern, mFirstName );
       
   303     doSetHighlights( pattern, mLastName );
       
   304     
       
   305 }
       
   306 
       
   307 // -----------------------------------------------------------------------------
       
   308 // LogsCntEntry::doSetHighlights()
       
   309 // -----------------------------------------------------------------------------
       
   310 //
       
   311 void LogsCntEntry::doSetHighlights( const QString& pattern, 
       
   312                                     LogsCntTextList& nameArray )
       
   313 {
       
   314     
       
   315     LogsPredictiveTranslator* translator = 
       
   316             LogsPredictiveTranslator::instance();
       
   317     QMutableListIterator<LogsCntText> names( nameArray ); 
       
   318     bool hasZeros = pattern.contains( ZeroSepar );
       
   319     
       
   320     //simple
       
   321     while( names.hasNext() ) {
       
   322         LogsCntText& nameItem = names.next();
       
   323         nameItem.mHighlights = 
       
   324                 translator->startsWith( nameItem.mText, pattern, false );
       
   325     }
       
   326     
       
   327     //complex
       
   328     QStringList tokenArray = tokens( pattern, ZeroSepar );
       
   329     QListIterator<QString> patternArray( tokenArray  );
       
   330     while( hasZeros && patternArray.hasNext() ) {
       
   331         QString patternItem = patternArray.next();
       
   332         names.toFront();
       
   333         while( names.hasNext() ) {
       
   334             LogsCntText& nameItem = names.next();
       
   335             int matchSize = translator->startsWith( nameItem.mText, 
       
   336                                                     patternItem, !hasZeros );
       
   337             nameItem.mHighlights = matchSize > nameItem.mHighlights ?
       
   338                                    matchSize : nameItem.mHighlights; 
       
   339         }
       
   340     }
       
   341 }
       
   342 
       
   343 // -----------------------------------------------------------------------------
       
   344 // LogsCntEntry::setSpeedDial()
       
   345 // -----------------------------------------------------------------------------
       
   346 //
       
   347 void LogsCntEntry::setSpeedDial( const QString& number )
       
   348 {
       
   349     mSpeedDial = number;
       
   350 }
       
   351 
       
   352 
       
   353 
       
   354 // -----------------------------------------------------------------------------
       
   355 // LogsCntEntry::match()
       
   356 // -----------------------------------------------------------------------------
       
   357 //
       
   358 bool LogsCntEntry::match( const QString& pattern ) const
       
   359 {
       
   360     bool match = false;
       
   361     
       
   362     //direct match with phone number is enough
       
   363     match = mPhoneNumber.text().startsWith( pattern ) ||
       
   364             doSimpleMatch( pattern );
       
   365     
       
   366     if ( !match && pattern.contains( ZeroSepar ) ) {
       
   367         QStringList patternArray = tokens( pattern, ZeroSepar );
       
   368         match = doComplexMatch( patternArray );
       
   369     }
       
   370     
       
   371     return match;
       
   372 }
       
   373 
       
   374 // -----------------------------------------------------------------------------
       
   375 // LogsCntEntry::doSimpleMatch()
       
   376 // -----------------------------------------------------------------------------
       
   377 //
       
   378 bool LogsCntEntry::doSimpleMatch( const QString& pattern ) const
       
   379 {
       
   380     LogsCntTextList nameArray = mFirstName + mLastName; //with empties
       
   381     QListIterator<LogsCntText> names( nameArray ); 
       
   382     int matchCount = 0;
       
   383 
       
   384     while( names.hasNext() && !matchCount ) {
       
   385         matchCount = (int)names.next().mTranslatedText.startsWith( pattern );
       
   386     }
       
   387 
       
   388     return matchCount > 0;
       
   389 }
       
   390 
       
   391 
       
   392 // -----------------------------------------------------------------------------
       
   393 // LogsCntEntry::doComplexMatch()
       
   394 // -----------------------------------------------------------------------------
       
   395 //
       
   396 bool LogsCntEntry::doComplexMatch( QStringList patternArray ) const
       
   397 {
       
   398     const bool zero = false;
       
   399 
       
   400     LogsCntTextList nameArray = mFirstName + mLastName; //with empties
       
   401 
       
   402     int targetMatchCount = patternArray.count();
       
   403     int namesCount = nameArray.count();
       
   404 
       
   405     //if pattern has more tokens than name(s), it is a missmatch
       
   406     if ( namesCount < targetMatchCount ) {
       
   407         return false;
       
   408     }
       
   409 
       
   410     QListIterator<LogsCntText> names( nameArray ); 
       
   411     QListIterator<QString> patterns( patternArray );
       
   412     QVector<bool> matchVector(targetMatchCount, zero );
       
   413     int currentPattern = 0;
       
   414     int matchCount = 0;
       
   415     bool match = false;
       
   416     
       
   417     while( names.hasNext() && matchCount < targetMatchCount ) {
       
   418         LogsCntText name = names.next();
       
   419         currentPattern = 0;
       
   420         patterns.toFront();
       
   421         match = false;
       
   422         while ( !name.mText.isEmpty() && 
       
   423                  patterns.hasNext() && !match ) {
       
   424             QString pattern = patterns.next();
       
   425             //unique match check
       
   426             if ( !matchVector.at( currentPattern ) ) {
       
   427                 match = matchVector[ currentPattern ] 
       
   428                       = name.mTranslatedText.startsWith( pattern );
       
   429                 matchCount = match ? matchCount+1 : matchCount;
       
   430             }
       
   431             currentPattern++;
       
   432         }
       
   433     }
       
   434     return matchCount >= targetMatchCount;
       
   435 
       
   436     }
       
   437     
       
   438     
       
   439 
       
   440 // -----------------------------------------------------------------------------
       
   441 // LogsCntEntry::isCached()
       
   442 // -----------------------------------------------------------------------------
       
   443 //
       
   444 bool LogsCntEntry::isCached() const
       
   445 {
       
   446     return mCached;
       
   447 }
       
   448 
       
   449 
       
   450 // -----------------------------------------------------------------------------
       
   451 // LogsCntEntry::type()
       
   452 // -----------------------------------------------------------------------------
       
   453 //
       
   454 LogsCntEntry::EntryType LogsCntEntry::type() const
       
   455 {
       
   456     return mType;
       
   457 }
       
   458 
       
   459 // -----------------------------------------------------------------------------
       
   460 // LogsCntFinder::LogsCntFinder()
       
   461 // -----------------------------------------------------------------------------
       
   462 //
       
   463 LogsCntFinder::LogsCntFinder()
       
   464     : mCachedCounter(0)
       
   465 {
       
   466     LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::LogsCntFinder()" )
       
   467     
       
   468     // Create manager ourselves, object takes care of deletion when registering
       
   469     // as parent.
       
   470     QMap<QString, QString> dummyParams;
       
   471     mContactManager = new QContactManager("symbian", dummyParams, this);
       
   472     
       
   473     LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::LogsCntFinder()" )
       
   474 }
       
   475 
       
   476 // -----------------------------------------------------------------------------
       
   477 // LogsCntFinder::LogsCntFinder()
       
   478 // -----------------------------------------------------------------------------
       
   479 //
       
   480 LogsCntFinder::LogsCntFinder(QContactManager& contactManager)
       
   481     : mCachedCounter(0)
       
   482 {
       
   483     LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::LogsCntFinder(), cntmgr from client" )
       
   484     
       
   485     mContactManager = &contactManager;
       
   486     
       
   487     LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::LogsCntFinder()" )
       
   488 }
       
   489 
       
   490 // -----------------------------------------------------------------------------
       
   491 // LogsCntFinder::~LogsCntFinder()
       
   492 // -----------------------------------------------------------------------------
       
   493 //
       
   494 LogsCntFinder::~LogsCntFinder()
       
   495 {
       
   496     LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::~LogsCntFinder()" )
       
   497 
       
   498     qDeleteAll( mResults );
       
   499     qDeleteAll( mHistoryEvents );
       
   500     LogsPredictiveTranslator::deleteInstance();
       
   501     
       
   502     LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::~LogsCntFinder()" )
       
   503 }
       
   504 
       
   505 // -----------------------------------------------------------------------------
       
   506 // LogsCntFinder::isProgressivePattern
       
   507 // -----------------------------------------------------------------------------
       
   508 //
       
   509 bool LogsCntFinder::isProgressivePattern( const QString& pattern ) const
       
   510 {
       
   511     //"" -> XXX not progressive
       
   512     //XX -> YY not progressive
       
   513     //XXX -> YY not progressive
       
   514     int prevPatternLen = mCurrentPredictivePattern.length();
       
   515     return prevPatternLen > 0 &&  
       
   516            pattern.length() - prevPatternLen > 0;
       
   517 }
       
   518 
       
   519 
       
   520 // -----------------------------------------------------------------------------
       
   521 // LogsCntFinder::predictiveSearchQuery
       
   522 // -----------------------------------------------------------------------------
       
   523 //
       
   524 void LogsCntFinder::predictiveSearchQuery( const QString& pattern )
       
   525 {
       
   526     LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::predictiveSearchQuery()" )
       
   527     LOGS_QDEBUG_2( "logs [FINDER] pattern= ", pattern )
       
   528 
       
   529     if ( pattern.length() > MaxPredSearchPatternLen ) {
       
   530         LOGS_QDEBUG( "logs [FINDER] too long pattern. Exit quietly.")
       
   531         LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::predictiveSearchQuery()" )
       
   532         return;
       
   533     }
       
   534         
       
   535     //in this point mCurrentPredictivePattern is previous
       
   536     bool patternIsProgressive = isProgressivePattern( pattern );
       
   537     bool resultsAreAllCached = resultsCount() > 0 && 
       
   538                                mCachedCounter == resultsCount();
       
   539     bool nothingToDo = resultsCount() == 0 &&
       
   540                        patternIsProgressive;
       
   541                                            
       
   542     LOGS_QDEBUG_2( "logs [FINDER] patternIsProgressive = ", patternIsProgressive )
       
   543     LOGS_QDEBUG_2( "logs [FINDER] resultsAreAllCached = ", resultsAreAllCached )
       
   544     LOGS_QDEBUG_2( "logs [FINDER] nothingToDo = ", nothingToDo )
       
   545     LOGS_QDEBUG_2( "logs [FINDER] cachedCounter = ", mCachedCounter )
       
   546     
       
   547     mCurrentPredictivePattern = pattern;
       
   548     
       
   549     if ( mCurrentPredictivePattern.isEmpty() ) {
       
   550         qDeleteAll( mResults );
       
   551         mResults.clear();
       
   552         mCachedCounter = 0;
       
   553     } else if ( ( patternIsProgressive &&
       
   554                   resultsAreAllCached ) ||
       
   555                 nothingToDo ) {
       
   556         doPredictiveCacheQuery();
       
   557     } else {        
       
   558         mCachedCounter = 0;
       
   559         LogsCntEntryList recentResults = mResults;
       
   560         mResults.clear();
       
   561         doPredictiveHistoryQuery();
       
   562         doPredictiveContactQuery( recentResults );
       
   563         qDeleteAll( recentResults );
       
   564     }
       
   565     emit queryReady();
       
   566  
       
   567     LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::predictiveSearchQuery()" )
       
   568 }
       
   569 
       
   570 // -----------------------------------------------------------------------------
       
   571 // LogsCntFinder::doPredictiveHistoryQuery
       
   572 // -----------------------------------------------------------------------------
       
   573 //
       
   574 void LogsCntFinder::doPredictiveHistoryQuery()
       
   575 {
       
   576     LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::doPredictiveHistoryQuery()" )
       
   577     
       
   578     QListIterator<LogsCntEntry*> iter(mHistoryEvents);
       
   579     
       
   580     while( iter.hasNext() ) {
       
   581         LogsCntEntry* e = iter.next();
       
   582         if ( e->match( mCurrentPredictivePattern ) ) {
       
   583             LogsCntEntry* entry = new LogsCntEntry( *e );
       
   584             addResult( entry );
       
   585         }
       
   586     }
       
   587         
       
   588     LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::doPredictiveHistoryQuery()" )
       
   589 }
       
   590 
       
   591 // -----------------------------------------------------------------------------
       
   592 // LogsCntFinder::doPredictiveContactQuery
       
   593 // -----------------------------------------------------------------------------
       
   594 //
       
   595 void LogsCntFinder::doPredictiveContactQuery( LogsCntEntryList& recentResults )
       
   596 {
       
   597     LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::doPredictiveContactQuery()" )
       
   598     QContactDetailFilter df;
       
   599     df.setDetailDefinitionName( QContactName::DefinitionName );
       
   600     df.setMatchFlags( QContactFilter::MatchKeypadCollation );
       
   601     df.setValue( mCurrentPredictivePattern );
       
   602     QList<QContactLocalId> cntIds;
       
   603     LOGS_QDEBUG( "logs [FINDER] about to call contacts manager" )
       
   604     
       
   605     cntIds = mContactManager->contactIds( df );
       
   606     LOGS_QDEBUG_2( "logs [FINDER] number of matched contacts =", cntIds.count() )
       
   607     int index = 0;
       
   608     while( index < cntIds.count() ) {
       
   609         addResult( cntIds.at( index++ ), recentResults );
       
   610     }
       
   611     LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::doPredictiveContactQuery()" )
       
   612     
       
   613 }
       
   614 
       
   615 // -----------------------------------------------------------------------------
       
   616 // LogsCntFinder::doPredictiveCacheQuery()
       
   617 // -----------------------------------------------------------------------------
       
   618 //
       
   619 void LogsCntFinder::doPredictiveCacheQuery()
       
   620 {
       
   621     LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::doPredictiveCacheQuery()" )
       
   622     QMutableListIterator<LogsCntEntry*> iter(mResults);
       
   623     while( iter.hasNext() ) {
       
   624         LogsCntEntry* entry = iter.next();
       
   625         if ( !entry->match( mCurrentPredictivePattern ) ) {
       
   626             mCachedCounter = 
       
   627                     entry->isCached() ? mCachedCounter-1 : mCachedCounter;
       
   628             iter.remove();
       
   629             delete entry;
       
   630         } else {
       
   631             entry->setHighlights( mCurrentPredictivePattern );
       
   632         }
       
   633     }
       
   634     LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::doPredictiveCacheQuery()" )
       
   635     
       
   636 }
       
   637 
       
   638 // -----------------------------------------------------------------------------
       
   639 // LogsCntFinder::addResult()
       
   640 // -----------------------------------------------------------------------------
       
   641 //
       
   642 void LogsCntFinder::addResult( quint32 cntId, LogsCntEntryList& recentResults )
       
   643 {
       
   644     QMutableListIterator<LogsCntEntry*> iter(recentResults);
       
   645     bool reused = false;
       
   646     while( iter.hasNext() && !reused ) {
       
   647         LogsCntEntry* entry = iter.next();
       
   648         if ( entry->contactId() == cntId ) {
       
   649             LOGS_QDEBUG_4( "logs [FINDER] LogsCntFinder::addResult() - \
       
   650 re-using entry. contact id ", cntId, "cached=", entry->isCached() );
       
   651             iter.remove();
       
   652             addResult( entry );
       
   653             reused = true;
       
   654         }
       
   655     }
       
   656     
       
   657     if ( !reused ) {
       
   658         LogsCntEntry* entry = new LogsCntEntry( cntId );
       
   659         addResult( entry );
       
   660     }
       
   661 }
       
   662 
       
   663 
       
   664 // -----------------------------------------------------------------------------
       
   665 // LogsCntFinder::addResult()
       
   666 // -----------------------------------------------------------------------------
       
   667 //
       
   668 void LogsCntFinder::addResult( LogsCntEntry* entry )
       
   669 {
       
   670     updateResult( entry );
       
   671     mResults.append( entry );
       
   672 }
       
   673 
       
   674 // -----------------------------------------------------------------------------
       
   675 // LogsCntFinder::updateResult()
       
   676 // -----------------------------------------------------------------------------
       
   677 //
       
   678 void LogsCntFinder::updateResult( LogsCntEntry* entry )
       
   679 {
       
   680     if ( entry->isCached() ) {
       
   681         entry->setHighlights( mCurrentPredictivePattern );
       
   682         mCachedCounter++;
       
   683     }
       
   684 }
       
   685 
       
   686 
       
   687 // -----------------------------------------------------------------------------
       
   688 // LogsCntFinder::resultsCount
       
   689 // -----------------------------------------------------------------------------
       
   690 //
       
   691 int LogsCntFinder::resultsCount() const
       
   692 {
       
   693     return mResults.count();
       
   694 }
       
   695 
       
   696 // -----------------------------------------------------------------------------
       
   697 // LogsCntFinder::resultAt
       
   698 // -----------------------------------------------------------------------------
       
   699 //
       
   700 const LogsCntEntry& LogsCntFinder::resultAt( int index )
       
   701 {
       
   702     LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::resultAt()" )
       
   703     LOGS_QDEBUG_2( "logs [FINDER] index=", index )
       
   704     
       
   705     LogsCntEntry* entry = mResults.at( index );
       
   706     if ( !entry->isCached() ) {
       
   707         LOGS_QDEBUG_2( "logs [FINDER] caching from DB cid=", entry->contactId() )
       
   708         QContact contact = mContactManager->contact( entry->contactId() );
       
   709         QContactName contactName = contact.detail( QContactName::DefinitionName );
       
   710         entry->setFirstName( contactName.value( QContactName::FieldFirst ) );
       
   711         entry->setLastName( contactName.value( QContactName::FieldLast ) );
       
   712         QContactPhoneNumber contactPhoneNumber = 
       
   713               contact.detail( QContactPhoneNumber::DefinitionName );
       
   714         entry->setPhoneNumber( 
       
   715               contactPhoneNumber.value( QContactPhoneNumber::FieldNumber ) );
       
   716         QContactAvatar contactAvatar = contact.detail<QContactAvatar>();  
       
   717         if (contactAvatar.subType().compare(
       
   718         QLatin1String(QContactAvatar::SubTypeImage)) == 0 && 
       
   719                !contactAvatar.avatar().isEmpty()) {
       
   720                   entry->setAvatarPath(contactAvatar.avatar());
       
   721               } 
       
   722         
       
   723         updateResult( entry );      
       
   724     }
       
   725     LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::resultAt()" )
       
   726     return *entry;
       
   727 }
       
   728 
       
   729 
       
   730 // -----------------------------------------------------------------------------
       
   731 // LogsCntFinder::insertEntry
       
   732 // -----------------------------------------------------------------------------
       
   733 //
       
   734 void LogsCntFinder::insertEntry( int index, LogsCntEntry* entry )
       
   735 {
       
   736     LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::insertEntry()" )
       
   737     LOGS_QDEBUG_4( "logs [FINDER] handle=", entry->handle()," to index ", index )
       
   738     
       
   739     mHistoryEvents.insert( index, entry );
       
   740     
       
   741     LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::insertEntry()" )
       
   742 }
       
   743 
       
   744 // -----------------------------------------------------------------------------
       
   745 // LogsCntFinder::getEntry
       
   746 // -----------------------------------------------------------------------------
       
   747 //
       
   748 LogsCntEntry* LogsCntFinder::getEntry( const LogsCntEntryHandle& handle ) const
       
   749 {
       
   750     LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::getEntry()" )
       
   751     return doGetEntry( mHistoryEvents, handle );      
       
   752 }
       
   753 
       
   754 // -----------------------------------------------------------------------------
       
   755 // LogsCntFinder::doGetEntry
       
   756 // -----------------------------------------------------------------------------
       
   757 //
       
   758 LogsCntEntry* LogsCntFinder::doGetEntry( const LogsCntEntryList& list, 
       
   759                                          const LogsCntEntryHandle& handle ) const
       
   760 {
       
   761     LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::doGetEntry()" )
       
   762     LOGS_QDEBUG_2( "logs [FINDER] handle= ", &handle )
       
   763     
       
   764     LogsCntEntry* entry = 0;
       
   765     QListIterator<LogsCntEntry*> iter(list);
       
   766     
       
   767     while( iter.hasNext() && !entry ) {
       
   768         LogsCntEntry* e = iter.next();
       
   769         entry = e->handle() == &handle ? e : 0;
       
   770     }
       
   771     
       
   772     LOGS_QDEBUG_2( "logs [FINDER] found=", (entry!=0) )
       
   773     LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::doGetEntry()" )
       
   774     return entry;
       
   775 }
       
   776 
       
   777 // -----------------------------------------------------------------------------
       
   778 // LogsCntFinder::deleteEntry
       
   779 // -----------------------------------------------------------------------------
       
   780 //
       
   781 void LogsCntFinder::deleteEntry( const LogsCntEntryHandle& handle )
       
   782 {
       
   783     LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::deleteEntry()" )
       
   784     LOGS_QDEBUG_2( "logs [FINDER] handle= ", &handle )
       
   785     
       
   786     LogsCntEntry* toRemoveHistoryEv = doGetEntry( mHistoryEvents, handle );
       
   787     mHistoryEvents.removeOne( toRemoveHistoryEv );
       
   788     delete toRemoveHistoryEv;
       
   789     
       
   790     LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::deleteEntry()" )
       
   791     
       
   792 }
       
   793 
       
   794 
       
   795 
       
   796