svcore
1.9
|
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 00002 00003 /* 00004 Sonic Visualiser 00005 An audio file viewer and annotation editor. 00006 Centre for Digital Music, Queen Mary, University of London. 00007 This file copyright 2008 QMUL. 00008 00009 This program is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU General Public License as 00011 published by the Free Software Foundation; either version 2 of the 00012 License, or (at your option) any later version. See the file 00013 COPYING included with this distribution for more information. 00014 */ 00015 00016 #include "TextMatcher.h" 00017 00018 TextMatcher::TextMatcher() 00019 { 00020 } 00021 00022 TextMatcher::~TextMatcher() 00023 { 00024 } 00025 00026 void 00027 TextMatcher::test(Match &match, QStringList keywords, QString text, 00028 QString textType, int score) 00029 { 00030 /* 00031 if (text.toLower() == keyword.toLower()) { 00032 match.score += score * 1.5; 00033 match.fragments << tr("%1: <b>%2</b>").arg(textType).arg(text); 00034 return; 00035 } 00036 */ 00037 int len = text.length(); 00038 int prevEnd = 0; 00039 QString fragment; 00040 00041 while (1) { 00042 00043 bool first = (prevEnd == 0); 00044 00045 int idx = -1; 00046 QString keyword; 00047 00048 for (int ki = 0; ki < keywords.size(); ++ki) { 00049 int midx = text.indexOf(keywords[ki], prevEnd, Qt::CaseInsensitive); 00050 if (midx >= 0 && midx < len) { 00051 if (midx < idx || idx == -1) { 00052 idx = midx; 00053 keyword = keywords[ki]; 00054 } 00055 } 00056 } 00057 00058 if (idx < 0 || idx >= len) break; 00059 00060 int klen = keyword.length(); 00061 00062 if (first) { 00063 match.score += score; 00064 } else { 00065 match.score += score / 4; 00066 } 00067 00068 int start = idx; 00069 int end = start + klen; 00070 00071 if (start == 0) match.score += 1; 00072 if (end == len) match.score += 1; 00073 00074 if (start > prevEnd + 14) { 00075 QString s = text.right((len - start) + 10); 00076 s = XmlExportable::encodeEntities(s.left(10)) + "<b>" + 00077 XmlExportable::encodeEntities(s.left(klen + 10).right(klen)) 00078 + "</b>"; 00079 fragment += QString("...%1").arg(s); 00080 } else { 00081 QString s = text.right(len - prevEnd); 00082 s = XmlExportable::encodeEntities(s.left(start - prevEnd)) + "<b>" + 00083 XmlExportable::encodeEntities(s.left(end - prevEnd).right(klen)) 00084 + "</b>"; 00085 fragment += s; 00086 } 00087 00088 prevEnd = end; 00089 } 00090 00091 if (prevEnd > 0 && prevEnd < len) { 00092 int n = len - prevEnd; 00093 fragment += 00094 XmlExportable::encodeEntities(text.right(n).left(n < 8 ? n : 8)); 00095 } 00096 00097 if (fragment != "") { 00098 match.fragments[textType] = fragment; 00099 } 00100 } 00101 00102 bool 00103 TextMatcher::Match::operator<(const Match &m) const 00104 { 00105 if (score != m.score) { 00106 return score < m.score; 00107 } 00108 if (key != m.key) { 00109 return key < m.key; 00110 } 00111 if (fragments.size() != m.fragments.size()) { 00112 return fragments.size() < m.fragments.size(); 00113 } 00114 00115 for (FragmentMap::const_iterator 00116 i = fragments.begin(), 00117 j = m.fragments.begin(); 00118 i != fragments.end(); ++i, ++j) { 00119 if (i->first != j->first) return i->first < j->first; 00120 if (i->second != j->second) return i->second < j->second; 00121 } 00122 00123 return false; 00124 }