svcore  1.9
TextMatcher.cpp
Go to the documentation of this file.
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 }