summaryrefslogtreecommitdiffstats
path: root/katapult/common/cachedcatalog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'katapult/common/cachedcatalog.cpp')
-rw-r--r--katapult/common/cachedcatalog.cpp175
1 files changed, 175 insertions, 0 deletions
diff --git a/katapult/common/cachedcatalog.cpp b/katapult/common/cachedcatalog.cpp
new file mode 100644
index 0000000..bf34b87
--- /dev/null
+++ b/katapult/common/cachedcatalog.cpp
@@ -0,0 +1,175 @@
+/***************************************************************************
+ * 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 <qstringlist.h>
+#include <qstring.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)
+ {
+ QPtrListIterator<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();
+
+ QPtrListIterator<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, QString query) const
+{
+ int wordNo = 0;
+ int _rank = 0;
+ unsigned int _matched = 0;
+ QString text = item->text().lower();
+ QStringList queryWords = QStringList::split(" ", query.lower());
+ int wordMax = queryWords.count()-1;
+ QStringList words = QStringList::split(" ", text);
+ QStringList::Iterator wit = words.begin();
+ for(QStringList::Iterator qit = queryWords.begin(); qit != queryWords.end(); ++qit) {
+ QString queryWord = *qit;
+ bool didMatch = FALSE;
+ for(; wit != words.end(); ++wit) {
+ QString 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(QString text) const
+{
+ text = text.lower();
+ KatapultItem *item;
+ QPtrListIterator<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())) {
+ qDebug("Ignored duplicate item: %s", item->text().ascii());
+ delete item;
+ } else
+ cache.append(item);
+}