Result list: improve the spelling suggestions now presented as links which will replace the appropriate word inside the query

This commit is contained in:
Jean-Francois Dockes 2012-02-17 09:01:28 +01:00
parent cc5ba21d79
commit f6e50fd9eb
7 changed files with 64 additions and 18 deletions

View File

@ -306,6 +306,8 @@ void RclMain::init()
this, SLOT(docExpand(Rcl::Doc)));
connect(reslist, SIGNAL(wordSelect(QString)),
sSearch, SLOT(addTerm(QString)));
connect(reslist, SIGNAL(wordReplace(const QString&, const QString&)),
sSearch, SLOT(onWordReplace(const QString&, const QString&)));
connect(reslist, SIGNAL(nextPageAvailable(bool)),
this, SLOT(enableNextPage(bool)));
connect(reslist, SIGNAL(prevPageAvailable(bool)),

View File

@ -76,7 +76,8 @@ public:
virtual string nextUrl();
virtual string prevUrl();
virtual string pageTop();
virtual void suggest(const vector<string>uterms, vector<string>&sugg);
virtual void suggest(const vector<string>uterms,
map<string, vector<string> >& sugg);
virtual string absSep() {return (const char *)(prefs.abssep.toUtf8());}
virtual string iconUrl(RclConfig *, Rcl::Doc& doc);
private:
@ -163,7 +164,8 @@ string QtGuiResListPager::pageTop()
}
void QtGuiResListPager::suggest(const vector<string>uterms, vector<string>&sugg)
void QtGuiResListPager::suggest(const vector<string>uterms,
map<string, vector<string> >& sugg)
{
sugg.clear();
#ifdef RCL_USE_ASPELL
@ -179,6 +181,10 @@ void QtGuiResListPager::suggest(const vector<string>uterms, vector<string>&sugg)
uit != uterms.end(); uit++) {
list<string> asuggs;
string reason;
// If the term is in the index, we don't suggest alternatives.
// Actually, we may want to check the frequencies and propose something
// anyway if a possible variation is much more common (as google does)
if (aspell->check(*rcldb, *uit, reason))
continue;
else if (!reason.empty())
@ -189,7 +195,15 @@ void QtGuiResListPager::suggest(const vector<string>uterms, vector<string>&sugg)
continue;
}
if (!asuggs.empty()) {
sugg.push_back(*asuggs.begin());
sugg[*uit] = vector<string>(asuggs.begin(), asuggs.end());
if (sugg[*uit].size() > 5)
sugg[*uit].resize(5);
// Set up the links as a <href="Sold|new">.
for (vector<string>::iterator it = sugg[*uit].begin();
it != sugg[*uit].end(); it++) {
*it = string("<a href=\"S") + *uit + "|" + *it + "\">" +
*it + "</a>";
}
}
}
#endif
@ -607,11 +621,9 @@ void ResList::mouseDoubleClickEvent(QMouseEvent *event)
void ResList::linkWasClicked(const QUrl &url)
{
QByteArray s = url.toString().toAscii();
const char *ascurl = (const char *)s;
LOGDEB(("ResList::linkWasClicked: [%s]\n", ascurl));
string ascurl = (const char *)url.toString().toAscii();;
LOGDEB(("ResList::linkWasClicked: [%s]\n", ascurl.c_str()));
int i = atoi(ascurl+1) - 1;
int what = ascurl[0];
switch (what) {
case 'H':
@ -620,6 +632,7 @@ void ResList::linkWasClicked(const QUrl &url)
case 'P':
case 'E':
{
int i = atoi(ascurl.c_str()+1) - 1;
Rcl::Doc doc;
if (!getDoc(i, doc)) {
LOGERR(("ResList::linkWasClicked: can't get doc for %d\n", i));
@ -637,8 +650,21 @@ void ResList::linkWasClicked(const QUrl &url)
case 'p':
resultPageBack();
break;
case 'S':
{
QString s = url.toString();
if (!s.isEmpty())
s = s.right(s.size()-1);
int bar = s.indexOf("|");
if (bar != -1 && bar < s.size()-1) {
QString o = s.left(bar);
QString n = s.right(s.size() - (bar+1));
emit wordReplace(o, n);
}
}
break;
default:
LOGERR(("ResList::linkWasClicked: bad link [%s]\n", ascurl));
LOGERR(("ResList::linkWasClicked: bad link [%s]\n", ascurl.c_str()));
break;// ??
}
}

View File

@ -105,6 +105,7 @@ class ResList : public QTextBrowser
void headerClicked();
void docExpand(Rcl::Doc);
void wordSelect(QString);
void wordReplace(const QString&, const QString&);
void linkClicked(const QString&, int); // See emitLinkClicked()
void hasResults(int);

View File

@ -236,6 +236,15 @@ void SSearch::addTerm(QString term)
queryText->setEditText(text);
}
void SSearch::onWordReplace(const QString& o, const QString& n)
{
QString txt = queryText->currentText();
QRegExp exp = QRegExp(QString("\\b") + o + QString("\\b"));
exp.setCaseSensitivity(Qt::CaseInsensitive);
txt.replace(exp, n);
queryText->setEditText(txt);
}
void SSearch::setAnyTermMode()
{
searchTypCMB->setCurrentIndex(SST_ANY);

View File

@ -51,7 +51,7 @@ public slots:
virtual void setSearchString(const QString& text);
virtual void startSimpleSearch();
virtual void addTerm(QString);
virtual void onWordReplace(const QString&, const QString&);
signals:
void startSearch(RefCntr<Rcl::SearchData>);
void clearSearch();

View File

@ -290,17 +290,24 @@ void ResListPager::displayPage(RclConfig *config)
vector<string>uterms;
m_docSource->getUTerms(uterms);
if (!uterms.empty()) {
vector<string> spellings;
map<string, vector<string> > spellings;
suggest(uterms, spellings);
if (!spellings.empty()) {
chunk <<
trans("<p><i>Alternate spellings (accents suppressed): </i>");
for (vector<string>::iterator it = spellings.begin();
it != spellings.end(); it++) {
chunk << *it;
chunk << " ";
}
chunk << "</p>";
trans("<p><i>Alternate spellings (accents suppressed): </i>")
<< "<br /><blockquote>";
for (map<string, vector<string> >::const_iterator it0 =
spellings.begin(); it0 != spellings.end(); it0++) {
chunk << "<b>" << it0->first << "</b> : ";
for (vector<string>::const_iterator it =
it0->second.begin();
it != it0->second.end(); it++) {
chunk << *it << " ";
}
chunk << "<br />";
}
chunk << "</blockquote></p>";
}
}
} else {

View File

@ -111,7 +111,8 @@ public:
virtual string prevUrl();
virtual string pageTop() {return string();}
virtual string iconUrl(RclConfig *, Rcl::Doc& doc);
virtual void suggest(const vector<string>, vector<string>&sugg) {
virtual void suggest(const vector<string>,
map<string, vector<string> >& sugg) {
sugg.clear();
}
virtual string absSep() {return "&hellip;";}