Result list: improve the spelling suggestions now presented as links which will replace the appropriate word inside the query
This commit is contained in:
parent
cc5ba21d79
commit
f6e50fd9eb
@ -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)),
|
||||
|
||||
@ -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;// ??
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 "…";}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user