diff -r 000000000000 -r 4a5361db8937 logsui/logscntfinder/src/logscntfinder.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/logsui/logscntfinder/src/logscntfinder.cpp Tue May 04 12:39:37 2010 +0300 @@ -0,0 +1,796 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "logscntfinder.h" +#include "logspredictivetranslator.h" +#include "logslogger.h" + +const int MaxPredSearchPatternLen = 15; +const QChar ZeroSepar('0'); + + +// ----------------------------------------------------------------------------- +// LogsCntEntry::richText() +// ----------------------------------------------------------------------------- +// +QString LogsCntText::richText( QString startTag, + QString endTag ) const +{ + QString str = text(); + if ( str.length() > 0 && highlights() > 0 ) { + str.insert( highlights() , endTag ); + str.insert( 0, startTag ); + } + + return str; + +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::LogsCntEntry() +// ----------------------------------------------------------------------------- +// +LogsCntEntry::LogsCntEntry( LogsCntEntryHandle& handle, + quint32 cid ) + : mType( EntryTypeHistory ), mCid( cid ), + mCached( true ),mHandle(&handle) +{ + LogsCntText empty; + mFirstName.append( empty ); + mLastName.append( empty ); + mAvatarPath = ""; +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::LogsCntEntry() +// ----------------------------------------------------------------------------- +// +LogsCntEntry::LogsCntEntry( quint32 cid ) + : mType( EntryTypeContact ), mCid( cid ), + mCached( false ),mHandle(0) +{ + LogsCntText empty; + mFirstName.append( empty ); + mLastName.append( empty ); + mAvatarPath = ""; +} + +// ----------------------------------------------------------------------------- +// copy LogsCntEntry::LogsCntEntry() +// ----------------------------------------------------------------------------- +// +LogsCntEntry::LogsCntEntry( const LogsCntEntry& entry ) + : mType(entry.mType), + mCid(entry.mCid), + mFirstName(entry.mFirstName), + mLastName(entry.mLastName), + mCached(entry.mCached), + mHandle(entry.mHandle), + mPhoneNumber(entry.mPhoneNumber), + mAvatarPath(entry.mAvatarPath) +{ +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::~LogsCntEntry() +// ----------------------------------------------------------------------------- +// +LogsCntEntry::~LogsCntEntry() +{ +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::firstName() +// ----------------------------------------------------------------------------- +// +const LogsCntTextList& LogsCntEntry::firstName() const +{ + return mFirstName; +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::lastName() +// ----------------------------------------------------------------------------- +// +const LogsCntTextList& LogsCntEntry::lastName() const +{ + return mLastName; +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::avatarPath() +// ----------------------------------------------------------------------------- +// +const QString& LogsCntEntry::avatarPath() const +{ + return mAvatarPath; +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::phoneNumber() +// ----------------------------------------------------------------------------- +// +const LogsCntText& LogsCntEntry::phoneNumber() const +{ + return mPhoneNumber; +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::speedDial() +// ----------------------------------------------------------------------------- +// +const QString& LogsCntEntry::speedDial() const +{ + return mSpeedDial; +} + + + +// ----------------------------------------------------------------------------- +// LogsCntEntry::contactId() +// ----------------------------------------------------------------------------- +// +quint32 LogsCntEntry::contactId() const +{ + return mCid; +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::handle() +// ----------------------------------------------------------------------------- +// +LogsCntEntryHandle* LogsCntEntry::handle() const +{ + return mHandle; +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::setFirstName() +// ----------------------------------------------------------------------------- +// +void LogsCntEntry::setFirstName( const QString& name ) +{ + mCached=true; + mFirstName.clear(); + doSetText( name, mFirstName ); +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::setLastName() +// ----------------------------------------------------------------------------- +// +void LogsCntEntry::setLastName( const QString& name ) +{ + mCached=true; + mLastName.clear(); + doSetText( name, mLastName ); +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::setAvatarPath() +// ----------------------------------------------------------------------------- +// +void LogsCntEntry::setAvatarPath( const QString& avatarpath ) +{ + mCached=true; + mAvatarPath.clear(); + mAvatarPath = avatarpath; +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::tokens() +// ----------------------------------------------------------------------------- +// +QStringList LogsCntEntry::tokens( const QString& source, + const QChar& separ ) const +{ + QStringList target = source.split( separ, QString::SkipEmptyParts ); + if ( target.length() > 1 && separ == ZeroSepar ) { + QString& first = target[0]; + QString& last = target[target.length()-1]; + padWithZeros( first, source, 0 ); + padWithZeros( last, source, last.length() ); + } + return target; + +} + + +// ----------------------------------------------------------------------------- +// LogsCntEntry::padWithLeadingZeros() +// ----------------------------------------------------------------------------- +// +void LogsCntEntry::padWithZeros( QString& token, + const QString& source, int padIndex ) const +{ + const QChar* content = source.data(); + int index = !padIndex ? 0 : source.length()-1; + + while( index >= 0 && index < source.length() ) { + if ( content[ index ] == ZeroSepar ) { + token.insert( padIndex, ZeroSepar ); + index = !padIndex ? index+1 : index-1; + } else { + index = -1; + } + } +} + + + +// ----------------------------------------------------------------------------- +// LogsCntEntry::doSetText() +// ----------------------------------------------------------------------------- +// +void LogsCntEntry::doSetText( const QString& text, LogsCntTextList& textlist ) +{ + QListIterator iter( tokens( text ) ); + + while( iter.hasNext() ) { + LogsCntText txt; + txt.mText = iter.next(); + txt.mTranslatedText = + LogsPredictiveTranslator::instance()->translate( txt.mText ); + textlist.append( txt ); + } + if ( textlist.count() == 0 ) { + textlist.append( LogsCntText() ); + } +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::setPhoneNumber() +// ----------------------------------------------------------------------------- +// +void LogsCntEntry::setPhoneNumber( const QString& number ) +{ + mCached=true; + mPhoneNumber.mText = number; +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::resetHighlights() +// ----------------------------------------------------------------------------- +// +void LogsCntEntry::resetHighlights( LogsCntTextList& nameArray ) +{ + QMutableListIterator names( nameArray ); + while( names.hasNext() ) { + names.next().mHighlights = 0; + } + +} + + +// ----------------------------------------------------------------------------- +// LogsCntEntry::setHighlights() +// ----------------------------------------------------------------------------- +// +void LogsCntEntry::setHighlights( const QString& pattern ) +{ + resetHighlights( mFirstName ); + resetHighlights( mLastName ); + + mPhoneNumber.mHighlights = + mPhoneNumber.text().startsWith( pattern ) && + mPhoneNumber.text().length() >= pattern.length() ? + pattern.length(): 0; + + doSetHighlights( pattern, mFirstName ); + doSetHighlights( pattern, mLastName ); + +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::doSetHighlights() +// ----------------------------------------------------------------------------- +// +void LogsCntEntry::doSetHighlights( const QString& pattern, + LogsCntTextList& nameArray ) +{ + + LogsPredictiveTranslator* translator = + LogsPredictiveTranslator::instance(); + QMutableListIterator names( nameArray ); + bool hasZeros = pattern.contains( ZeroSepar ); + + //simple + while( names.hasNext() ) { + LogsCntText& nameItem = names.next(); + nameItem.mHighlights = + translator->startsWith( nameItem.mText, pattern, false ); + } + + //complex + QStringList tokenArray = tokens( pattern, ZeroSepar ); + QListIterator patternArray( tokenArray ); + while( hasZeros && patternArray.hasNext() ) { + QString patternItem = patternArray.next(); + names.toFront(); + while( names.hasNext() ) { + LogsCntText& nameItem = names.next(); + int matchSize = translator->startsWith( nameItem.mText, + patternItem, !hasZeros ); + nameItem.mHighlights = matchSize > nameItem.mHighlights ? + matchSize : nameItem.mHighlights; + } + } +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::setSpeedDial() +// ----------------------------------------------------------------------------- +// +void LogsCntEntry::setSpeedDial( const QString& number ) +{ + mSpeedDial = number; +} + + + +// ----------------------------------------------------------------------------- +// LogsCntEntry::match() +// ----------------------------------------------------------------------------- +// +bool LogsCntEntry::match( const QString& pattern ) const +{ + bool match = false; + + //direct match with phone number is enough + match = mPhoneNumber.text().startsWith( pattern ) || + doSimpleMatch( pattern ); + + if ( !match && pattern.contains( ZeroSepar ) ) { + QStringList patternArray = tokens( pattern, ZeroSepar ); + match = doComplexMatch( patternArray ); + } + + return match; +} + +// ----------------------------------------------------------------------------- +// LogsCntEntry::doSimpleMatch() +// ----------------------------------------------------------------------------- +// +bool LogsCntEntry::doSimpleMatch( const QString& pattern ) const +{ + LogsCntTextList nameArray = mFirstName + mLastName; //with empties + QListIterator names( nameArray ); + int matchCount = 0; + + while( names.hasNext() && !matchCount ) { + matchCount = (int)names.next().mTranslatedText.startsWith( pattern ); + } + + return matchCount > 0; +} + + +// ----------------------------------------------------------------------------- +// LogsCntEntry::doComplexMatch() +// ----------------------------------------------------------------------------- +// +bool LogsCntEntry::doComplexMatch( QStringList patternArray ) const +{ + const bool zero = false; + + LogsCntTextList nameArray = mFirstName + mLastName; //with empties + + int targetMatchCount = patternArray.count(); + int namesCount = nameArray.count(); + + //if pattern has more tokens than name(s), it is a missmatch + if ( namesCount < targetMatchCount ) { + return false; + } + + QListIterator names( nameArray ); + QListIterator patterns( patternArray ); + QVector matchVector(targetMatchCount, zero ); + int currentPattern = 0; + int matchCount = 0; + bool match = false; + + while( names.hasNext() && matchCount < targetMatchCount ) { + LogsCntText name = names.next(); + currentPattern = 0; + patterns.toFront(); + match = false; + while ( !name.mText.isEmpty() && + patterns.hasNext() && !match ) { + QString pattern = patterns.next(); + //unique match check + if ( !matchVector.at( currentPattern ) ) { + match = matchVector[ currentPattern ] + = name.mTranslatedText.startsWith( pattern ); + matchCount = match ? matchCount+1 : matchCount; + } + currentPattern++; + } + } + return matchCount >= targetMatchCount; + + } + + + +// ----------------------------------------------------------------------------- +// LogsCntEntry::isCached() +// ----------------------------------------------------------------------------- +// +bool LogsCntEntry::isCached() const +{ + return mCached; +} + + +// ----------------------------------------------------------------------------- +// LogsCntEntry::type() +// ----------------------------------------------------------------------------- +// +LogsCntEntry::EntryType LogsCntEntry::type() const +{ + return mType; +} + +// ----------------------------------------------------------------------------- +// LogsCntFinder::LogsCntFinder() +// ----------------------------------------------------------------------------- +// +LogsCntFinder::LogsCntFinder() + : mCachedCounter(0) +{ + LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::LogsCntFinder()" ) + + // Create manager ourselves, object takes care of deletion when registering + // as parent. + QMap dummyParams; + mContactManager = new QContactManager("symbian", dummyParams, this); + + LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::LogsCntFinder()" ) +} + +// ----------------------------------------------------------------------------- +// LogsCntFinder::LogsCntFinder() +// ----------------------------------------------------------------------------- +// +LogsCntFinder::LogsCntFinder(QContactManager& contactManager) + : mCachedCounter(0) +{ + LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::LogsCntFinder(), cntmgr from client" ) + + mContactManager = &contactManager; + + LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::LogsCntFinder()" ) +} + +// ----------------------------------------------------------------------------- +// LogsCntFinder::~LogsCntFinder() +// ----------------------------------------------------------------------------- +// +LogsCntFinder::~LogsCntFinder() +{ + LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::~LogsCntFinder()" ) + + qDeleteAll( mResults ); + qDeleteAll( mHistoryEvents ); + LogsPredictiveTranslator::deleteInstance(); + + LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::~LogsCntFinder()" ) +} + +// ----------------------------------------------------------------------------- +// LogsCntFinder::isProgressivePattern +// ----------------------------------------------------------------------------- +// +bool LogsCntFinder::isProgressivePattern( const QString& pattern ) const +{ + //"" -> XXX not progressive + //XX -> YY not progressive + //XXX -> YY not progressive + int prevPatternLen = mCurrentPredictivePattern.length(); + return prevPatternLen > 0 && + pattern.length() - prevPatternLen > 0; +} + + +// ----------------------------------------------------------------------------- +// LogsCntFinder::predictiveSearchQuery +// ----------------------------------------------------------------------------- +// +void LogsCntFinder::predictiveSearchQuery( const QString& pattern ) +{ + LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::predictiveSearchQuery()" ) + LOGS_QDEBUG_2( "logs [FINDER] pattern= ", pattern ) + + if ( pattern.length() > MaxPredSearchPatternLen ) { + LOGS_QDEBUG( "logs [FINDER] too long pattern. Exit quietly.") + LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::predictiveSearchQuery()" ) + return; + } + + //in this point mCurrentPredictivePattern is previous + bool patternIsProgressive = isProgressivePattern( pattern ); + bool resultsAreAllCached = resultsCount() > 0 && + mCachedCounter == resultsCount(); + bool nothingToDo = resultsCount() == 0 && + patternIsProgressive; + + LOGS_QDEBUG_2( "logs [FINDER] patternIsProgressive = ", patternIsProgressive ) + LOGS_QDEBUG_2( "logs [FINDER] resultsAreAllCached = ", resultsAreAllCached ) + LOGS_QDEBUG_2( "logs [FINDER] nothingToDo = ", nothingToDo ) + LOGS_QDEBUG_2( "logs [FINDER] cachedCounter = ", mCachedCounter ) + + mCurrentPredictivePattern = pattern; + + if ( mCurrentPredictivePattern.isEmpty() ) { + qDeleteAll( mResults ); + mResults.clear(); + mCachedCounter = 0; + } else if ( ( patternIsProgressive && + resultsAreAllCached ) || + nothingToDo ) { + doPredictiveCacheQuery(); + } else { + mCachedCounter = 0; + LogsCntEntryList recentResults = mResults; + mResults.clear(); + doPredictiveHistoryQuery(); + doPredictiveContactQuery( recentResults ); + qDeleteAll( recentResults ); + } + emit queryReady(); + + LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::predictiveSearchQuery()" ) +} + +// ----------------------------------------------------------------------------- +// LogsCntFinder::doPredictiveHistoryQuery +// ----------------------------------------------------------------------------- +// +void LogsCntFinder::doPredictiveHistoryQuery() +{ + LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::doPredictiveHistoryQuery()" ) + + QListIterator iter(mHistoryEvents); + + while( iter.hasNext() ) { + LogsCntEntry* e = iter.next(); + if ( e->match( mCurrentPredictivePattern ) ) { + LogsCntEntry* entry = new LogsCntEntry( *e ); + addResult( entry ); + } + } + + LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::doPredictiveHistoryQuery()" ) +} + +// ----------------------------------------------------------------------------- +// LogsCntFinder::doPredictiveContactQuery +// ----------------------------------------------------------------------------- +// +void LogsCntFinder::doPredictiveContactQuery( LogsCntEntryList& recentResults ) +{ + LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::doPredictiveContactQuery()" ) + QContactDetailFilter df; + df.setDetailDefinitionName( QContactName::DefinitionName ); + df.setMatchFlags( QContactFilter::MatchKeypadCollation ); + df.setValue( mCurrentPredictivePattern ); + QList cntIds; + LOGS_QDEBUG( "logs [FINDER] about to call contacts manager" ) + + cntIds = mContactManager->contactIds( df ); + LOGS_QDEBUG_2( "logs [FINDER] number of matched contacts =", cntIds.count() ) + int index = 0; + while( index < cntIds.count() ) { + addResult( cntIds.at( index++ ), recentResults ); + } + LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::doPredictiveContactQuery()" ) + +} + +// ----------------------------------------------------------------------------- +// LogsCntFinder::doPredictiveCacheQuery() +// ----------------------------------------------------------------------------- +// +void LogsCntFinder::doPredictiveCacheQuery() +{ + LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::doPredictiveCacheQuery()" ) + QMutableListIterator iter(mResults); + while( iter.hasNext() ) { + LogsCntEntry* entry = iter.next(); + if ( !entry->match( mCurrentPredictivePattern ) ) { + mCachedCounter = + entry->isCached() ? mCachedCounter-1 : mCachedCounter; + iter.remove(); + delete entry; + } else { + entry->setHighlights( mCurrentPredictivePattern ); + } + } + LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::doPredictiveCacheQuery()" ) + +} + +// ----------------------------------------------------------------------------- +// LogsCntFinder::addResult() +// ----------------------------------------------------------------------------- +// +void LogsCntFinder::addResult( quint32 cntId, LogsCntEntryList& recentResults ) +{ + QMutableListIterator iter(recentResults); + bool reused = false; + while( iter.hasNext() && !reused ) { + LogsCntEntry* entry = iter.next(); + if ( entry->contactId() == cntId ) { + LOGS_QDEBUG_4( "logs [FINDER] LogsCntFinder::addResult() - \ +re-using entry. contact id ", cntId, "cached=", entry->isCached() ); + iter.remove(); + addResult( entry ); + reused = true; + } + } + + if ( !reused ) { + LogsCntEntry* entry = new LogsCntEntry( cntId ); + addResult( entry ); + } +} + + +// ----------------------------------------------------------------------------- +// LogsCntFinder::addResult() +// ----------------------------------------------------------------------------- +// +void LogsCntFinder::addResult( LogsCntEntry* entry ) +{ + updateResult( entry ); + mResults.append( entry ); +} + +// ----------------------------------------------------------------------------- +// LogsCntFinder::updateResult() +// ----------------------------------------------------------------------------- +// +void LogsCntFinder::updateResult( LogsCntEntry* entry ) +{ + if ( entry->isCached() ) { + entry->setHighlights( mCurrentPredictivePattern ); + mCachedCounter++; + } +} + + +// ----------------------------------------------------------------------------- +// LogsCntFinder::resultsCount +// ----------------------------------------------------------------------------- +// +int LogsCntFinder::resultsCount() const +{ + return mResults.count(); +} + +// ----------------------------------------------------------------------------- +// LogsCntFinder::resultAt +// ----------------------------------------------------------------------------- +// +const LogsCntEntry& LogsCntFinder::resultAt( int index ) +{ + LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::resultAt()" ) + LOGS_QDEBUG_2( "logs [FINDER] index=", index ) + + LogsCntEntry* entry = mResults.at( index ); + if ( !entry->isCached() ) { + LOGS_QDEBUG_2( "logs [FINDER] caching from DB cid=", entry->contactId() ) + QContact contact = mContactManager->contact( entry->contactId() ); + QContactName contactName = contact.detail( QContactName::DefinitionName ); + entry->setFirstName( contactName.value( QContactName::FieldFirst ) ); + entry->setLastName( contactName.value( QContactName::FieldLast ) ); + QContactPhoneNumber contactPhoneNumber = + contact.detail( QContactPhoneNumber::DefinitionName ); + entry->setPhoneNumber( + contactPhoneNumber.value( QContactPhoneNumber::FieldNumber ) ); + QContactAvatar contactAvatar = contact.detail(); + if (contactAvatar.subType().compare( + QLatin1String(QContactAvatar::SubTypeImage)) == 0 && + !contactAvatar.avatar().isEmpty()) { + entry->setAvatarPath(contactAvatar.avatar()); + } + + updateResult( entry ); + } + LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::resultAt()" ) + return *entry; +} + + +// ----------------------------------------------------------------------------- +// LogsCntFinder::insertEntry +// ----------------------------------------------------------------------------- +// +void LogsCntFinder::insertEntry( int index, LogsCntEntry* entry ) +{ + LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::insertEntry()" ) + LOGS_QDEBUG_4( "logs [FINDER] handle=", entry->handle()," to index ", index ) + + mHistoryEvents.insert( index, entry ); + + LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::insertEntry()" ) +} + +// ----------------------------------------------------------------------------- +// LogsCntFinder::getEntry +// ----------------------------------------------------------------------------- +// +LogsCntEntry* LogsCntFinder::getEntry( const LogsCntEntryHandle& handle ) const +{ + LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::getEntry()" ) + return doGetEntry( mHistoryEvents, handle ); +} + +// ----------------------------------------------------------------------------- +// LogsCntFinder::doGetEntry +// ----------------------------------------------------------------------------- +// +LogsCntEntry* LogsCntFinder::doGetEntry( const LogsCntEntryList& list, + const LogsCntEntryHandle& handle ) const +{ + LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::doGetEntry()" ) + LOGS_QDEBUG_2( "logs [FINDER] handle= ", &handle ) + + LogsCntEntry* entry = 0; + QListIterator iter(list); + + while( iter.hasNext() && !entry ) { + LogsCntEntry* e = iter.next(); + entry = e->handle() == &handle ? e : 0; + } + + LOGS_QDEBUG_2( "logs [FINDER] found=", (entry!=0) ) + LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::doGetEntry()" ) + return entry; +} + +// ----------------------------------------------------------------------------- +// LogsCntFinder::deleteEntry +// ----------------------------------------------------------------------------- +// +void LogsCntFinder::deleteEntry( const LogsCntEntryHandle& handle ) +{ + LOGS_QDEBUG( "logs [FINDER] -> LogsCntFinder::deleteEntry()" ) + LOGS_QDEBUG_2( "logs [FINDER] handle= ", &handle ) + + LogsCntEntry* toRemoveHistoryEv = doGetEntry( mHistoryEvents, handle ); + mHistoryEvents.removeOne( toRemoveHistoryEv ); + delete toRemoveHistoryEv; + + LOGS_QDEBUG( "logs [FINDER] <- LogsCntFinder::deleteEntry()" ) + +} + + + +