compacted res list + completions in ssearch + additional or field
This commit is contained in:
parent
ae2bbf6485
commit
48f415a25c
@ -63,45 +63,6 @@
|
|||||||
<property name="margin">
|
<property name="margin">
|
||||||
<number>8</number>
|
<number>8</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QLabel" row="2" column="0">
|
|
||||||
<property name="name">
|
|
||||||
<cstring>orWordsTL</cstring>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Any of these words</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QLineEdit" row="2" column="1">
|
|
||||||
<property name="name">
|
|
||||||
<cstring>orWordsLE</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QLabel" row="4" column="0">
|
|
||||||
<property name="name">
|
|
||||||
<cstring>textLabel1_2</cstring>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>File name matching</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QLineEdit" row="4" column="1">
|
|
||||||
<property name="name">
|
|
||||||
<cstring>fileNameLE</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QLabel" row="3" column="0">
|
|
||||||
<property name="name">
|
|
||||||
<cstring>noWordsTL</cstring>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>None of these words</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QLineEdit" row="3" column="1">
|
|
||||||
<property name="name">
|
|
||||||
<cstring>noWordsLE</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QLabel" row="0" column="0">
|
<widget class="QLabel" row="0" column="0">
|
||||||
<property name="name">
|
<property name="name">
|
||||||
<cstring>andWordsTL</cstring>
|
<cstring>andWordsTL</cstring>
|
||||||
@ -128,6 +89,58 @@
|
|||||||
<cstring>phraseLE</cstring>
|
<cstring>phraseLE</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QLabel" row="2" column="0">
|
||||||
|
<property name="name">
|
||||||
|
<cstring>orWordsTL</cstring>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Any of these words</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLineEdit" row="2" column="1">
|
||||||
|
<property name="name">
|
||||||
|
<cstring>orWordsLE</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" row="3" column="0">
|
||||||
|
<property name="name">
|
||||||
|
<cstring>orWords1TL</cstring>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Any of these words</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLineEdit" row="3" column="1">
|
||||||
|
<property name="name">
|
||||||
|
<cstring>orWords1LE</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" row="4" column="0">
|
||||||
|
<property name="name">
|
||||||
|
<cstring>noWordsTL</cstring>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>None of these words</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLineEdit" row="4" column="1">
|
||||||
|
<property name="name">
|
||||||
|
<cstring>noWordsLE</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" row="5" column="0">
|
||||||
|
<property name="name">
|
||||||
|
<cstring>textLabel1_2</cstring>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>File name matching</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLineEdit" row="5" column="1">
|
||||||
|
<property name="name">
|
||||||
|
<cstring>fileNameLE</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</grid>
|
</grid>
|
||||||
</widget>
|
</widget>
|
||||||
</hbox>
|
</hbox>
|
||||||
@ -483,6 +496,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
<includes>
|
<includes>
|
||||||
<include location="local" impldecl="in declaration">recoll.h</include>
|
<include location="local" impldecl="in declaration">recoll.h</include>
|
||||||
|
<include location="local" impldecl="in declaration">searchdata.h</include>
|
||||||
<include location="local" impldecl="in implementation">advsearch.ui.h</include>
|
<include location="local" impldecl="in implementation">advsearch.ui.h</include>
|
||||||
</includes>
|
</includes>
|
||||||
<signals>
|
<signals>
|
||||||
|
|||||||
@ -40,6 +40,7 @@ using std::string;
|
|||||||
#include "recoll.h"
|
#include "recoll.h"
|
||||||
#include "rclconfig.h"
|
#include "rclconfig.h"
|
||||||
#include "debuglog.h"
|
#include "debuglog.h"
|
||||||
|
#include "searchdata.h"
|
||||||
|
|
||||||
extern RclConfig *rclconfig;
|
extern RclConfig *rclconfig;
|
||||||
|
|
||||||
@ -132,11 +133,13 @@ void advsearch::searchPB_clicked()
|
|||||||
mydata.allwords = string((const char*)(andWordsLE->text().utf8()));
|
mydata.allwords = string((const char*)(andWordsLE->text().utf8()));
|
||||||
mydata.phrase = string((const char*)(phraseLE->text().utf8()));
|
mydata.phrase = string((const char*)(phraseLE->text().utf8()));
|
||||||
mydata.orwords = string((const char*)(orWordsLE->text().utf8()));
|
mydata.orwords = string((const char*)(orWordsLE->text().utf8()));
|
||||||
|
mydata.orwords1 = string((const char*)(orWords1LE->text().utf8()));
|
||||||
mydata.nowords = string((const char*)(noWordsLE->text().utf8()));
|
mydata.nowords = string((const char*)(noWordsLE->text().utf8()));
|
||||||
mydata.filename = string((const char*)(fileNameLE->text().utf8()));
|
mydata.filename = string((const char*)(fileNameLE->text().utf8()));
|
||||||
|
|
||||||
if (mydata.allwords.empty() && mydata.phrase.empty() &&
|
if (mydata.allwords.empty() && mydata.phrase.empty() &&
|
||||||
mydata.orwords.empty() && mydata.filename.empty()) {
|
mydata.orwords.empty() && mydata.orwords1.empty() &&
|
||||||
|
mydata.filename.empty()) {
|
||||||
if (mydata.nowords.empty())
|
if (mydata.nowords.empty())
|
||||||
return;
|
return;
|
||||||
QMessageBox::warning(0, "Recoll",
|
QMessageBox::warning(0, "Recoll",
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char rcsid[] = "@(#$Id: main.cpp,v 1.41 2006-04-15 17:15:01 dockes Exp $ (C) 2005 J.F.Dockes";
|
static char rcsid[] = "@(#$Id: main.cpp,v 1.42 2006-04-19 08:26:08 dockes Exp $ (C) 2005 J.F.Dockes";
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -40,9 +40,6 @@ static char rcsid[] = "@(#$Id: main.cpp,v 1.41 2006-04-15 17:15:01 dockes Exp $
|
|||||||
#include <qcombobox.h>
|
#include <qcombobox.h>
|
||||||
|
|
||||||
#include "rcldb.h"
|
#include "rcldb.h"
|
||||||
#ifndef NO_NAMESPACES
|
|
||||||
using Rcl::AdvSearchData;
|
|
||||||
#endif /* NO_NAMESPACES */
|
|
||||||
#include "rclconfig.h"
|
#include "rclconfig.h"
|
||||||
#include "pathut.h"
|
#include "pathut.h"
|
||||||
#include "recoll.h"
|
#include "recoll.h"
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
#include "sort.h"
|
#include "sort.h"
|
||||||
#include "uiprefs.h"
|
#include "uiprefs.h"
|
||||||
#include "rcldb.h"
|
#include "rcldb.h"
|
||||||
|
#include "searchdata.h"
|
||||||
|
|
||||||
#include "recollmain.h"
|
#include "recollmain.h"
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char rcsid[] = "@(#$Id: rclreslist.cpp,v 1.11 2006-04-18 08:53:28 dockes Exp $ (C) 2005 J.F.Dockes";
|
static char rcsid[] = "@(#$Id: rclreslist.cpp,v 1.12 2006-04-19 08:26:08 dockes Exp $ (C) 2005 J.F.Dockes";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -283,8 +283,7 @@ void RclResList::showResultPage()
|
|||||||
time_t mtime = doc.dmtime.empty() ?
|
time_t mtime = doc.dmtime.empty() ?
|
||||||
atol(doc.fmtime.c_str()) : atol(doc.dmtime.c_str());
|
atol(doc.fmtime.c_str()) : atol(doc.dmtime.c_str());
|
||||||
struct tm *tm = localtime(&mtime);
|
struct tm *tm = localtime(&mtime);
|
||||||
strftime(datebuf, 99,
|
strftime(datebuf, 99, " %Y-%m-%d %H:%M:%S", tm);
|
||||||
"<i>Modified:</i> %Y-%m-%d %H:%M:%S", tm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size information. We print both doc and file if they differ a lot
|
// Size information. We print both doc and file if they differ a lot
|
||||||
@ -301,6 +300,7 @@ void RclResList::showResultPage()
|
|||||||
} else if (fsize >= 0) {
|
} else if (fsize >= 0) {
|
||||||
sizebuf = displayableBytes(fsize);
|
sizebuf = displayableBytes(fsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Abstract
|
// Abstract
|
||||||
string abst = escapeHtml(doc.abstract);
|
string abst = escapeHtml(doc.abstract);
|
||||||
LOGDEB1(("Abstract: {%s}\n", abst.c_str()));
|
LOGDEB1(("Abstract: {%s}\n", abst.c_str()));
|
||||||
@ -311,12 +311,9 @@ void RclResList::showResultPage()
|
|||||||
result += string("<p><b>") + sh + "</p>\n<p>";
|
result += string("<p><b>") + sh + "</p>\n<p>";
|
||||||
else
|
else
|
||||||
result += "<p>";
|
result += "<p>";
|
||||||
result += string(perbuf) + sizebuf + "<b>" + doc.title + "</b><br>";
|
|
||||||
result += doc.mimetype + " ";
|
|
||||||
result += string(datebuf) + " ";
|
|
||||||
|
|
||||||
|
// Percent relevant + size + preview/edit links + title
|
||||||
// Set up the preview and edit links
|
result += string(perbuf) + sizebuf;
|
||||||
char vlbuf[100];
|
char vlbuf[100];
|
||||||
if (canIntern(doc.mimetype, rclconfig)) {
|
if (canIntern(doc.mimetype, rclconfig)) {
|
||||||
sprintf(vlbuf, "\"P%d\"", m_winfirst+i);
|
sprintf(vlbuf, "\"P%d\"", m_winfirst+i);
|
||||||
@ -327,12 +324,17 @@ void RclResList::showResultPage()
|
|||||||
sprintf(vlbuf, "E%d", m_winfirst+i);
|
sprintf(vlbuf, "E%d", m_winfirst+i);
|
||||||
result += string("<a href=") + vlbuf + ">" + "Edit" + "</a>";
|
result += string("<a href=") + vlbuf + ">" + "Edit" + "</a>";
|
||||||
}
|
}
|
||||||
result += string("<br>");
|
result += " <b>" + doc.title + "</b><br>";
|
||||||
|
|
||||||
|
// Mime type, date modified, url
|
||||||
|
result += doc.mimetype + " ";
|
||||||
|
result += string(datebuf) + " ";
|
||||||
if (!img_name.empty()) {
|
if (!img_name.empty()) {
|
||||||
result += "<img source=\"" + img_name + "\" align=\"left\">";
|
result += "<img source=\"" + img_name + "\" align=\"left\">";
|
||||||
}
|
}
|
||||||
result += "<i>" + url + +"</i><br>";
|
result += "<i>" + url + +"</i><br>";
|
||||||
|
|
||||||
|
// Text: abstract and keywords
|
||||||
if (!abst.empty())
|
if (!abst.empty())
|
||||||
result += abst + "<br>";
|
result += abst + "<br>";
|
||||||
if (!doc.keywords.empty())
|
if (!doc.keywords.empty())
|
||||||
|
|||||||
@ -132,6 +132,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
<includes>
|
<includes>
|
||||||
<include location="local" impldecl="in declaration">recoll.h</include>
|
<include location="local" impldecl="in declaration">recoll.h</include>
|
||||||
|
<include location="local" impldecl="in declaration">searchdata.h</include>
|
||||||
<include location="local" impldecl="in implementation">ssearchb.ui.h</include>
|
<include location="local" impldecl="in implementation">ssearchb.ui.h</include>
|
||||||
</includes>
|
</includes>
|
||||||
<signals>
|
<signals>
|
||||||
@ -144,6 +145,8 @@
|
|||||||
</slots>
|
</slots>
|
||||||
<functions>
|
<functions>
|
||||||
<function>init()</function>
|
<function>init()</function>
|
||||||
|
<function>completion()</function>
|
||||||
|
<function returnType="bool">event( QEvent * evt )</function>
|
||||||
</functions>
|
</functions>
|
||||||
<layoutdefaults spacing="6" margin="0"/>
|
<layoutdefaults spacing="6" margin="0"/>
|
||||||
</UI>
|
</UI>
|
||||||
|
|||||||
@ -25,9 +25,12 @@
|
|||||||
** These will automatically be called by the form's constructor and
|
** These will automatically be called by the form's constructor and
|
||||||
** destructor.
|
** destructor.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
#include <qapplication.h>
|
||||||
|
#include <qinputdialog.h>
|
||||||
|
|
||||||
#include "debuglog.h"
|
#include "debuglog.h"
|
||||||
#include "guiutils.h"
|
#include "guiutils.h"
|
||||||
|
#include "searchdata.h"
|
||||||
|
|
||||||
void SSearchBase::init()
|
void SSearchBase::init()
|
||||||
{
|
{
|
||||||
@ -72,3 +75,72 @@ void SSearchBase::startSimpleSearch()
|
|||||||
|
|
||||||
emit startSearch(sdata);
|
emit startSearch(sdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Complete last word in input by querying db for all possible terms.
|
||||||
|
void SSearchBase::completion()
|
||||||
|
{
|
||||||
|
if (!rcldb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Extract last word in text
|
||||||
|
string txt = (const char *)queryText->text().utf8();
|
||||||
|
string::size_type cs = txt.find_last_of(" ");
|
||||||
|
if (cs == string::npos)
|
||||||
|
cs = 0;
|
||||||
|
else
|
||||||
|
cs++;
|
||||||
|
if (txt.size() == 0 || cs == txt.size()) {
|
||||||
|
QApplication::beep();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
string s = txt.substr(cs);
|
||||||
|
LOGDEB(("Completing: [%s]\n", s.c_str()));
|
||||||
|
|
||||||
|
// Query database
|
||||||
|
const int max = 100;
|
||||||
|
list<string> strs = rcldb->completions(s, prefs.queryStemLang.ascii(),max);
|
||||||
|
if (strs.size() == 0 || strs.size() == (unsigned int)max) {
|
||||||
|
QApplication::beep();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If list from db is single word, insert it, else ask user to select
|
||||||
|
QString res;
|
||||||
|
bool ok = false;
|
||||||
|
if (strs.size() == 1) {
|
||||||
|
res = QString::fromUtf8(strs.begin()->c_str());
|
||||||
|
ok = true;
|
||||||
|
} else {
|
||||||
|
QStringList lst;
|
||||||
|
for (list<string>::iterator it=strs.begin(); it != strs.end(); it++)
|
||||||
|
lst.push_back(QString::fromUtf8(it->c_str()));
|
||||||
|
res = QInputDialog::getItem(tr("Completions"),
|
||||||
|
tr("Select an item:"), lst, 0,
|
||||||
|
FALSE, &ok, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert result
|
||||||
|
if (ok) {
|
||||||
|
txt.erase(cs);
|
||||||
|
txt.append(res.utf8());
|
||||||
|
queryText->setText(QString::fromUtf8(txt.c_str()));
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle CTRL-TAB to mean completion
|
||||||
|
bool SSearchBase::event( QEvent *evt )
|
||||||
|
{
|
||||||
|
if ( evt->type() == QEvent::KeyPress ) {
|
||||||
|
QKeyEvent *ke = (QKeyEvent *)evt;
|
||||||
|
if ( ke->key() == Key_Tab && (ke->state() & Qt::ControlButton)) {
|
||||||
|
// special tab handling here
|
||||||
|
completion();
|
||||||
|
ke->accept();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QWidget::event( evt );
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char rcsid[] = "@(#$Id: rcldb.cpp,v 1.68 2006-04-13 09:50:02 dockes Exp $ (C) 2004 J.F.Dockes";
|
static char rcsid[] = "@(#$Id: rcldb.cpp,v 1.69 2006-04-19 08:26:08 dockes Exp $ (C) 2004 J.F.Dockes";
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -43,6 +43,7 @@ using namespace std;
|
|||||||
#include "smallut.h"
|
#include "smallut.h"
|
||||||
#include "pathhash.h"
|
#include "pathhash.h"
|
||||||
#include "utf8iter.h"
|
#include "utf8iter.h"
|
||||||
|
#include "searchdata.h"
|
||||||
|
|
||||||
#include "xapian.h"
|
#include "xapian.h"
|
||||||
|
|
||||||
@ -120,7 +121,7 @@ class Native {
|
|||||||
string url;
|
string url;
|
||||||
parms.get(string("url"), url);
|
parms.get(string("url"), url);
|
||||||
url = url.substr(7);
|
url = url.substr(7);
|
||||||
if (url.find(rdb->m_asdata.topdir) == 0)
|
if (url.find(rdb->m_filterTopDir) == 0)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -853,27 +854,6 @@ static void stringToXapianQueries(const string &iq,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare query out of simple query string
|
|
||||||
bool Db::setQuery(const std::string &iqstring, QueryOpts opts,
|
|
||||||
const string& stemlang)
|
|
||||||
{
|
|
||||||
LOGDEB(("Db::setQuery: q: [%s], opts 0x%x, stemlang %s\n",
|
|
||||||
iqstring.c_str(), (unsigned int)opts, stemlang.c_str()));
|
|
||||||
if (!m_ndb)
|
|
||||||
return false;
|
|
||||||
m_asdata.erase();
|
|
||||||
m_dbindices.clear();
|
|
||||||
list<Xapian::Query> pqueries;
|
|
||||||
stringToXapianQueries(iqstring, stemlang, m_ndb, pqueries, opts);
|
|
||||||
m_ndb->query = Xapian::Query(Xapian::Query::OP_OR, pqueries.begin(),
|
|
||||||
pqueries.end());
|
|
||||||
delete m_ndb->enquire;
|
|
||||||
m_ndb->enquire = new Xapian::Enquire(m_ndb->db);
|
|
||||||
m_ndb->enquire->set_query(m_ndb->query);
|
|
||||||
m_ndb->mset = Xapian::MSet();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare query out of "advanced search" data
|
// Prepare query out of "advanced search" data
|
||||||
bool Db::setQuery(AdvSearchData &sdata, QueryOpts opts,
|
bool Db::setQuery(AdvSearchData &sdata, QueryOpts opts,
|
||||||
const string& stemlang)
|
const string& stemlang)
|
||||||
@ -882,7 +862,9 @@ bool Db::setQuery(AdvSearchData &sdata, QueryOpts opts,
|
|||||||
LOGDEB((" allwords: %s\n", sdata.allwords.c_str()));
|
LOGDEB((" allwords: %s\n", sdata.allwords.c_str()));
|
||||||
LOGDEB((" phrase: %s\n", sdata.phrase.c_str()));
|
LOGDEB((" phrase: %s\n", sdata.phrase.c_str()));
|
||||||
LOGDEB((" orwords: %s\n", sdata.orwords.c_str()));
|
LOGDEB((" orwords: %s\n", sdata.orwords.c_str()));
|
||||||
|
LOGDEB((" orwords1: %s\n", sdata.orwords1.c_str()));
|
||||||
LOGDEB((" nowords: %s\n", sdata.nowords.c_str()));
|
LOGDEB((" nowords: %s\n", sdata.nowords.c_str()));
|
||||||
|
LOGDEB((" filename: %s\n", sdata.filename.c_str()));
|
||||||
|
|
||||||
string ft;
|
string ft;
|
||||||
for (list<string>::iterator it = sdata.filetypes.begin();
|
for (list<string>::iterator it = sdata.filetypes.begin();
|
||||||
@ -892,7 +874,7 @@ bool Db::setQuery(AdvSearchData &sdata, QueryOpts opts,
|
|||||||
if (!sdata.topdir.empty())
|
if (!sdata.topdir.empty())
|
||||||
LOGDEB((" restricted to: %s\n", sdata.topdir.c_str()));
|
LOGDEB((" restricted to: %s\n", sdata.topdir.c_str()));
|
||||||
|
|
||||||
m_asdata = sdata;
|
m_filterTopDir = sdata.topdir;
|
||||||
m_dbindices.clear();
|
m_dbindices.clear();
|
||||||
|
|
||||||
if (!m_ndb)
|
if (!m_ndb)
|
||||||
@ -965,7 +947,19 @@ bool Db::setQuery(AdvSearchData &sdata, QueryOpts opts,
|
|||||||
Xapian::Query(Xapian::Query::OP_OR, pqueries.begin(),
|
Xapian::Query(Xapian::Query::OP_OR, pqueries.begin(),
|
||||||
pqueries.end());
|
pqueries.end());
|
||||||
xq = xq.empty() ? nq :
|
xq = xq.empty() ? nq :
|
||||||
Xapian::Query(Xapian::Query::OP_AND_MAYBE, xq, nq);
|
Xapian::Query(Xapian::Query::OP_AND, xq, nq);
|
||||||
|
pqueries.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sdata.orwords1.empty()) {
|
||||||
|
stringToXapianQueries(sdata.orwords1, stemlang, m_ndb, pqueries, opts);
|
||||||
|
if (!pqueries.empty()) {
|
||||||
|
Xapian::Query nq =
|
||||||
|
Xapian::Query(Xapian::Query::OP_OR, pqueries.begin(),
|
||||||
|
pqueries.end());
|
||||||
|
xq = xq.empty() ? nq :
|
||||||
|
Xapian::Query(Xapian::Query::OP_AND, xq, nq);
|
||||||
pqueries.clear();
|
pqueries.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1028,6 +1022,42 @@ bool Db::setQuery(AdvSearchData &sdata, QueryOpts opts,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list<string> Db::completions(const string &root, const string &lang, int max)
|
||||||
|
{
|
||||||
|
Xapian::Database db;
|
||||||
|
list<string> res;
|
||||||
|
if (!m_ndb || !m_ndb->m_isopen)
|
||||||
|
return res;
|
||||||
|
string droot;
|
||||||
|
dumb_string(root, droot);
|
||||||
|
db = m_ndb->m_iswritable ? m_ndb->wdb: m_ndb->db;
|
||||||
|
Xapian::TermIterator it = db.allterms_begin();
|
||||||
|
it.skip_to(droot.c_str());
|
||||||
|
for (int n = 0;it != db.allterms_end(); it++) {
|
||||||
|
if ((*it).find(droot) != 0)
|
||||||
|
break;
|
||||||
|
if (lang.empty()) {
|
||||||
|
res.push_back(*it);
|
||||||
|
++n;
|
||||||
|
} else {
|
||||||
|
list<string> stemexps =
|
||||||
|
StemDb::stemExpand(m_ndb->m_basedir, lang, *it);
|
||||||
|
unsigned int cnt =
|
||||||
|
(int)stemexps.size() > max - n ? max - n : stemexps.size();
|
||||||
|
list<string>::iterator sit = stemexps.begin();
|
||||||
|
while (cnt--) {
|
||||||
|
res.push_back(*sit++);
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n >= max)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
res.sort();
|
||||||
|
res.unique();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
bool Db::getQueryTerms(list<string>& terms)
|
bool Db::getQueryTerms(list<string>& terms)
|
||||||
{
|
{
|
||||||
if (!m_ndb)
|
if (!m_ndb)
|
||||||
@ -1118,7 +1148,7 @@ bool Db::getDoc(int exti, Doc &doc, int *percent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For now the only post-query filter is on dir subtree
|
// For now the only post-query filter is on dir subtree
|
||||||
bool postqfilter = !m_asdata.topdir.empty();
|
bool postqfilter = !m_filterTopDir.empty();
|
||||||
LOGDEB1(("Topdir %s postqflt %d\n", m_asdata.topdir.c_str(), postqfilter));
|
LOGDEB1(("Topdir %s postqflt %d\n", m_asdata.topdir.c_str(), postqfilter));
|
||||||
|
|
||||||
int xapi;
|
int xapi;
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
#ifndef _DB_H_INCLUDED_
|
#ifndef _DB_H_INCLUDED_
|
||||||
#define _DB_H_INCLUDED_
|
#define _DB_H_INCLUDED_
|
||||||
/* @(#$Id: rcldb.h,v 1.32 2006-04-12 10:41:39 dockes Exp $ (C) 2004 J.F.Dockes */
|
/* @(#$Id: rcldb.h,v 1.33 2006-04-19 08:26:08 dockes Exp $ (C) 2004 J.F.Dockes */
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -99,32 +99,7 @@ class Doc {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
class AdvSearchData;
|
||||||
* Holder for the advanced query data
|
|
||||||
*/
|
|
||||||
class AdvSearchData {
|
|
||||||
public:
|
|
||||||
string allwords;
|
|
||||||
string phrase;
|
|
||||||
string orwords;
|
|
||||||
string nowords;
|
|
||||||
string filename;
|
|
||||||
list<string> filetypes; // restrict to types. Empty if inactive
|
|
||||||
string topdir; // restrict to subtree. Empty if inactive
|
|
||||||
string description; // Printable expanded version of the complete query
|
|
||||||
// returned after setQuery.
|
|
||||||
void erase() {
|
|
||||||
allwords.erase();
|
|
||||||
phrase.erase();
|
|
||||||
orwords.erase();
|
|
||||||
nowords.erase();
|
|
||||||
filetypes.clear();
|
|
||||||
topdir.erase();
|
|
||||||
filename.erase();
|
|
||||||
description.erase();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Native;
|
class Native;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -155,12 +130,14 @@ class Db {
|
|||||||
// Query-related functions
|
// Query-related functions
|
||||||
|
|
||||||
// Parse query string and initialize query
|
// Parse query string and initialize query
|
||||||
bool setQuery(const string &q, QueryOpts opts = QO_NONE,
|
|
||||||
const string& stemlang = "english");
|
|
||||||
bool setQuery(AdvSearchData &q, QueryOpts opts = QO_NONE,
|
bool setQuery(AdvSearchData &q, QueryOpts opts = QO_NONE,
|
||||||
const string& stemlang = "english");
|
const string& stemlang = "english");
|
||||||
bool getQueryTerms(list<string>& terms);
|
bool getQueryTerms(list<string>& terms);
|
||||||
|
|
||||||
|
// Return a list of database terms that begin with the input string
|
||||||
|
// Stem expansion is performed if lang is not empty
|
||||||
|
list<string> completions(const string &s, const string &lang, int max=20);
|
||||||
|
|
||||||
/// Add extra database for querying
|
/// Add extra database for querying
|
||||||
bool addQueryDb(const string &dir);
|
bool addQueryDb(const string &dir);
|
||||||
/// Remove extra database. if dir == "", remove all.
|
/// Remove extra database. if dir == "", remove all.
|
||||||
@ -188,7 +165,7 @@ class Db {
|
|||||||
string getDbDir();
|
string getDbDir();
|
||||||
private:
|
private:
|
||||||
|
|
||||||
AdvSearchData m_asdata;
|
string m_filterTopDir; // Current query filter on subtree top directory
|
||||||
vector<int> m_dbindices; // In case there is a postq filter: sequence of
|
vector<int> m_dbindices; // In case there is a postq filter: sequence of
|
||||||
// db indices that match
|
// db indices that match
|
||||||
|
|
||||||
|
|||||||
36
src/rcldb/searchdata.h
Normal file
36
src/rcldb/searchdata.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef _SEARCHDATA_H_INCLUDED_
|
||||||
|
#define _SEARCHDATA_H_INCLUDED_
|
||||||
|
/* @(#$Id: searchdata.h,v 1.1 2006-04-19 08:26:08 dockes Exp $ (C) 2004 J.F.Dockes */
|
||||||
|
|
||||||
|
namespace Rcl {
|
||||||
|
/**
|
||||||
|
* Holder for query data
|
||||||
|
*/
|
||||||
|
class AdvSearchData {
|
||||||
|
public:
|
||||||
|
string allwords;
|
||||||
|
string phrase;
|
||||||
|
string orwords;
|
||||||
|
string orwords1; // Have two instances of orwords for and'ing them
|
||||||
|
string nowords;
|
||||||
|
string filename;
|
||||||
|
list<string> filetypes; // restrict to types. Empty if inactive
|
||||||
|
string topdir; // restrict to subtree. Empty if inactive
|
||||||
|
string description; // Printable expanded version of the complete query
|
||||||
|
// returned after setQuery.
|
||||||
|
void erase() {
|
||||||
|
allwords.erase();
|
||||||
|
phrase.erase();
|
||||||
|
orwords.erase();
|
||||||
|
orwords1.erase();
|
||||||
|
nowords.erase();
|
||||||
|
filetypes.clear();
|
||||||
|
topdir.erase();
|
||||||
|
filename.erase();
|
||||||
|
description.erase();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _SEARCHDATA_H_INCLUDED_ */
|
||||||
Loading…
x
Reference in New Issue
Block a user