You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
katapult/katapult/common/cachedcatalog.cpp

176 lines
4.6 KiB

/***************************************************************************
* Copyright (C) 2005 by Joe Ferris *
* jferris@optimistictech.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "cachedcatalog.moc"
#include <tqstringlist.h>
#include <tqstring.h>
#include "cachedcatalog.h"
#include "katapultitem.h"
#include "match.h"
#include "status.h"
CachedCatalog::CachedCatalog()
: KatapultCatalog()
{
cache.setAutoDelete(TRUE);
results.setAutoDelete(FALSE);
}
CachedCatalog::~CachedCatalog()
{
}
unsigned int CachedCatalog::minQueryLen() const
{
return 3;
}
void CachedCatalog::queryChanged()
{
int newStatus = 0;
if(query() == "")
{
results.clear();
setBestMatch(Match());
} else {
if(query().length() >= minQueryLen())
{
Match newBestMatch;
if(status() & S_Active)
{
TQPtrListIterator<KatapultItem> it(results);
KatapultItem *item;
while((item = it.current())!=0)
{
++it;
Match match = queryItem(item, query());
if(match.isNull())
results.removeRef(item);
else if(newBestMatch.isNull() || match.rank() > newBestMatch.rank())
newBestMatch = match;
}
} else {
results.clear();
TQPtrListIterator<KatapultItem> it(cache);
KatapultItem *item;
while((item=it.current())!=0)
{
++it;
Match match = queryItem(item, query());
if(!match.isNull()) {
results.append(item);
if(newBestMatch.isNull() || match.rank() > newBestMatch.rank())
newBestMatch = match;
}
}
}
newStatus |= S_Active;
if(results.count() > 0)
{
newStatus |= S_HasResults;
if(results.count() > 1)
newStatus |= S_Multiple;
} else
newStatus |= S_NoResults;
setBestMatch(newBestMatch);
}
}
setStatus(newStatus);
}
Match CachedCatalog::queryItem(const KatapultItem *item, TQString query) const
{
int wordNo = 0;
int _rank = 0;
unsigned int _matched = 0;
TQString text = item->text().lower();
TQStringList queryWords = TQStringList::split(" ", query.lower());
int wordMax = queryWords.count()-1;
TQStringList words = TQStringList::split(" ", text);
TQStringList::Iterator wit = words.begin();
for(TQStringList::Iterator qit = queryWords.begin(); qit != queryWords.end(); ++qit) {
TQString queryWord = *qit;
bool didMatch = FALSE;
for(; wit != words.end(); ++wit) {
TQString word = *wit;
if(word.startsWith(queryWord)) {
if(_matched != 0)
_matched++;
if(wordNo == wordMax) {
_matched += queryWord.length();
} else {
_matched += word.length();
}
didMatch = TRUE;
break;
}
if(wordNo == 0) {
if(_matched != 0)
_matched++;
_matched += word.length();
}
}
if(didMatch == FALSE) {
return Match();
}
wordNo++;
}
if(_matched > text.length())
return Match();
_rank = 100*query.length()/text.length();
if(_rank == 0)
return Match();
else
return Match(item, _rank, _matched);
}
const KatapultItem * CachedCatalog::findExact(TQString text) const
{
text = text.lower();
KatapultItem *item;
TQPtrListIterator<KatapultItem> it(cache);
while((item=it.current())!=0)
{
++it;
if(item->text().lower() == text)
return item;
}
return 0;
}
void CachedCatalog::addItem(KatapultItem *item)
{
if(findExact(item->text())) {
tqDebug("Ignored duplicate item: %s", item->text().ascii());
delete item;
} else
cache.append(item);
}