Chris@457: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@457: Chris@457: /* Chris@457: Sonic Visualiser Chris@457: An audio file viewer and annotation editor. Chris@457: Centre for Digital Music, Queen Mary, University of London. Chris@457: This file copyright 2008 QMUL. Chris@457: Chris@457: This program is free software; you can redistribute it and/or Chris@457: modify it under the terms of the GNU General Public License as Chris@457: published by the Free Software Foundation; either version 2 of the Chris@457: License, or (at your option) any later version. See the file Chris@457: COPYING included with this distribution for more information. Chris@457: */ Chris@457: Chris@457: #include "TextMatcher.h" Chris@457: Chris@457: TextMatcher::TextMatcher() Chris@457: { Chris@457: } Chris@457: Chris@457: TextMatcher::~TextMatcher() Chris@457: { Chris@457: } Chris@457: Chris@457: void Chris@457: TextMatcher::test(Match &match, QStringList keywords, QString text, Chris@457: QString textType, int score) Chris@457: { Chris@457: /* Chris@457: if (text.toLower() == keyword.toLower()) { Chris@457: match.score += score * 1.5; Chris@457: match.fragments << tr("%1: %2").arg(textType).arg(text); Chris@457: return; Chris@457: } Chris@457: */ Chris@457: int len = text.length(); Chris@457: int prevEnd = 0; Chris@457: QString fragment; Chris@457: Chris@457: while (1) { Chris@457: Chris@457: bool first = (prevEnd == 0); Chris@457: Chris@457: int idx = -1; Chris@457: QString keyword; Chris@457: Chris@457: for (int ki = 0; ki < keywords.size(); ++ki) { Chris@457: int midx = text.indexOf(keywords[ki], prevEnd, Qt::CaseInsensitive); Chris@457: if (midx >= 0 && midx < len) { Chris@457: if (midx < idx || idx == -1) { Chris@457: idx = midx; Chris@457: keyword = keywords[ki]; Chris@457: } Chris@457: } Chris@457: } Chris@457: Chris@457: if (idx < 0 || idx >= len) break; Chris@457: Chris@457: int klen = keyword.length(); Chris@457: Chris@457: if (first) { Chris@457: match.score += score; Chris@457: } else { Chris@457: match.score += score / 4; Chris@457: } Chris@457: Chris@457: int start = idx; Chris@457: int end = start + klen; Chris@457: Chris@457: if (start == 0) match.score += 1; Chris@457: if (end == len) match.score += 1; Chris@457: Chris@457: if (start > prevEnd + 14) { Chris@457: QString s = text.right((len - start) + 10); Chris@457: s = XmlExportable::encodeEntities(s.left(10)) + "" + Chris@457: XmlExportable::encodeEntities(s.left(klen + 10).right(klen)) Chris@457: + ""; Chris@457: fragment += QString("...%1").arg(s); Chris@457: } else { Chris@457: QString s = text.right(len - prevEnd); Chris@457: s = XmlExportable::encodeEntities(s.left(start - prevEnd)) + "" + Chris@457: XmlExportable::encodeEntities(s.left(end - prevEnd).right(klen)) Chris@457: + ""; Chris@457: fragment += s; Chris@457: } Chris@457: Chris@457: prevEnd = end; Chris@457: } Chris@457: Chris@457: if (prevEnd > 0 && prevEnd < len) { Chris@457: int n = len - prevEnd; Chris@457: fragment += Chris@457: XmlExportable::encodeEntities(text.right(n).left(n < 8 ? n : 8)); Chris@457: } Chris@457: Chris@457: if (fragment != "") { Chris@457: match.fragments[textType] = fragment; Chris@457: } Chris@457: } Chris@457: Chris@457: bool Chris@457: TextMatcher::Match::operator<(const Match &m) const Chris@457: { Chris@457: if (score != m.score) { Chris@457: return score < m.score; Chris@457: } Chris@457: if (key != m.key) { Chris@457: return key < m.key; Chris@457: } Chris@457: if (fragments.size() != m.fragments.size()) { Chris@457: return fragments.size() < m.fragments.size(); Chris@457: } Chris@457: Chris@457: for (FragmentMap::const_iterator Chris@457: i = fragments.begin(), Chris@457: j = m.fragments.begin(); Chris@457: i != fragments.end(); ++i, ++j) { Chris@457: if (i->first != j->first) return i->first < j->first; Chris@457: if (i->second != j->second) return i->second < j->second; Chris@457: } Chris@457: Chris@457: return false; Chris@457: }