comparison base/TextMatcher.cpp @ 457:ef14acd6d102

* Add beginnings of capability to search plugins that are not yet installed -- lots more work to do here, though
author Chris Cannam
date Tue, 14 Oct 2008 16:36:35 +0000
parents
children 48e9f538e6e9
comparison
equal deleted inserted replaced
456:64e64e304a12 457:ef14acd6d102
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Sonic Visualiser
5 An audio file viewer and annotation editor.
6 Centre for Digital Music, Queen Mary, University of London.
7 This file copyright 2008 QMUL.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version. See the file
13 COPYING included with this distribution for more information.
14 */
15
16 #include "TextMatcher.h"
17
18 TextMatcher::TextMatcher()
19 {
20 }
21
22 TextMatcher::~TextMatcher()
23 {
24 }
25
26 void
27 TextMatcher::test(Match &match, QStringList keywords, QString text,
28 QString textType, int score)
29 {
30 /*
31 if (text.toLower() == keyword.toLower()) {
32 match.score += score * 1.5;
33 match.fragments << tr("%1: <b>%2</b>").arg(textType).arg(text);
34 return;
35 }
36 */
37 int len = text.length();
38 int prevEnd = 0;
39 QString fragment;
40
41 while (1) {
42
43 bool first = (prevEnd == 0);
44
45 int idx = -1;
46 QString keyword;
47
48 for (int ki = 0; ki < keywords.size(); ++ki) {
49 int midx = text.indexOf(keywords[ki], prevEnd, Qt::CaseInsensitive);
50 if (midx >= 0 && midx < len) {
51 if (midx < idx || idx == -1) {
52 idx = midx;
53 keyword = keywords[ki];
54 }
55 }
56 }
57
58 if (idx < 0 || idx >= len) break;
59
60 int klen = keyword.length();
61
62 if (first) {
63 match.score += score;
64 } else {
65 match.score += score / 4;
66 }
67
68 int start = idx;
69 int end = start + klen;
70
71 if (start == 0) match.score += 1;
72 if (end == len) match.score += 1;
73
74 if (start > prevEnd + 14) {
75 QString s = text.right((len - start) + 10);
76 s = XmlExportable::encodeEntities(s.left(10)) + "<b>" +
77 XmlExportable::encodeEntities(s.left(klen + 10).right(klen))
78 + "</b>";
79 fragment += QString("...%1").arg(s);
80 } else {
81 QString s = text.right(len - prevEnd);
82 s = XmlExportable::encodeEntities(s.left(start - prevEnd)) + "<b>" +
83 XmlExportable::encodeEntities(s.left(end - prevEnd).right(klen))
84 + "</b>";
85 fragment += s;
86 }
87
88 prevEnd = end;
89 }
90
91 if (prevEnd > 0 && prevEnd < len) {
92 int n = len - prevEnd;
93 fragment +=
94 XmlExportable::encodeEntities(text.right(n).left(n < 8 ? n : 8));
95 }
96
97 if (fragment != "") {
98 match.fragments[textType] = fragment;
99 }
100 }
101
102 bool
103 TextMatcher::Match::operator<(const Match &m) const
104 {
105 if (score != m.score) {
106 return score < m.score;
107 }
108 if (key != m.key) {
109 return key < m.key;
110 }
111 if (fragments.size() != m.fragments.size()) {
112 return fragments.size() < m.fragments.size();
113 }
114
115 for (FragmentMap::const_iterator
116 i = fragments.begin(),
117 j = m.fragments.begin();
118 i != fragments.end(); ++i, ++j) {
119 if (i->first != j->first) return i->first < j->first;
120 if (i->second != j->second) return i->second < j->second;
121 }
122
123 return false;
124 }