diff --git a/src/kde/kioslave/recoll/CMakeLists.txt b/src/kde/kioslave/recoll/CMakeLists.txt
index ce9698dc..cdba9852 100644
--- a/src/kde/kioslave/recoll/CMakeLists.txt
+++ b/src/kde/kioslave/recoll/CMakeLists.txt
@@ -95,7 +95,7 @@ target_link_libraries(kio_recoll xapian ${EXTRA_LIBS} ${KDE4_KIO_LIBS})
install(TARGETS kio_recoll DESTINATION ${PLUGIN_INSTALL_DIR})
IF ("${KDE_VERSION_MAJOR}.${KDE_VERSION_MINOR}" GREATER 4.0)
- install(FILES recoll.protocol DESTINATION ${SERVICES_INSTALL_DIR})
+ install(FILES recoll.protocol recollf.protocol DESTINATION ${SERVICES_INSTALL_DIR})
ELSE ("${KDE_VERSION_MAJOR}.${KDE_VERSION_MINOR}" GREATER 4.0)
install(FILES recollnolist.protocol DESTINATION ${SERVICES_INSTALL_DIR}
RENAME recoll.protocol)
diff --git a/src/kde/kioslave/recoll/data/help.html b/src/kde/kioslave/recoll/data/help.html
index 9cf799a8..d6619ade 100644
--- a/src/kde/kioslave/recoll/data/help.html
+++ b/src/kde/kioslave/recoll/data/help.html
@@ -4,7 +4,7 @@
Recoll Kio Slave
- Recoll search
+ Recoll search
Recoll kio slave
Use this module to perform Recoll searches from any program with
diff --git a/src/kde/kioslave/recoll/dirif.cpp b/src/kde/kioslave/recoll/dirif.cpp
index 987f3f34..ed6c8ed7 100644
--- a/src/kde/kioslave/recoll/dirif.cpp
+++ b/src/kde/kioslave/recoll/dirif.cpp
@@ -1,5 +1,5 @@
#ifndef lint
-static char rcsid[] = "@(#$Id: dirif.cpp,v 1.8 2008-12-03 10:02:20 dockes Exp $ (C) 2008 J.F.Dockes";
+static char rcsid[] = "@(#$Id: dirif.cpp,v 1.9 2008-12-03 17:04:20 dockes Exp $ (C) 2008 J.F.Dockes";
#endif
/*
* This program is free software; you can redistribute it and/or modify
@@ -53,14 +53,14 @@ static const QString resultBaseName("recollResult");
// is the search string). If it is, extract return the result document
// number. Possibly restart the search if the search string does not
// match the current one
-bool RecollProtocol::isRecollResult(const KUrl &url, int *num)
+bool RecollProtocol::isRecollResult(const KUrl &url, int *num, QString *q)
{
*num = -1;
- kDebug() << "url" << url << "m_srchStr" << m_srchStr;
+ kDebug() << "url" << url;
// Basic checks
if (!url.host().isEmpty() || url.path().isEmpty() ||
- url.protocol().compare("recoll"))
+ (url.protocol().compare("recoll") && url.protocol().compare("recollf")))
return false;
QString path = url.path();
if (!path.startsWith("/"))
@@ -87,13 +87,7 @@ bool RecollProtocol::isRecollResult(const KUrl &url, int *num)
// We do have something that ressembles a recoll result locator. Check if
// this matches the current search, else have to run the requested one
- QString searchstring = path.mid(1, slashpos-2);
- kDebug() << "Comparing search strings" << m_srchStr << "and" << searchstring;
- if (searchstring.compare(m_srchStr)) {
- if (!doSearch(searchstring))
- return false;
- }
-
+ *q = path.mid(1, slashpos-2);
return true;
}
@@ -106,7 +100,7 @@ static const UDSEntry resultToUDSEntry(const Rcl::Doc& doc, int num)
kDebug() << doc.url.c_str();
entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, url.fileName());
- char cnum[30];sprintf(cnum, "%d", num);
+ char cnum[30];sprintf(cnum, "%04d", num);
entry.insert(KIO::UDSEntry::UDS_NAME, resultBaseName + cnum);
if (!doc.mimetype.compare("application/x-fsdirectory")) {
@@ -150,7 +144,7 @@ static void createGoHomeEntry(KIO::UDSEntry& entry)
entry.insert(KIO::UDSEntry::UDS_NAME, "search");
entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, "Recoll search (click me)");
entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG);
- entry.insert(KIO::UDSEntry::UDS_TARGET_URL, "recoll:///welcome");
+ entry.insert(KIO::UDSEntry::UDS_TARGET_URL, "recoll:///search.html");
entry.insert(KIO::UDSEntry::UDS_ACCESS, 0500);
entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, "text/html");
entry.insert(KIO::UDSEntry::UDS_ICON_NAME, "recoll");
@@ -175,28 +169,40 @@ static void createGoHelpEntry(KIO::UDSEntry& entry)
void RecollProtocol::stat(const KUrl & url)
{
kDebug() << url << endl ;
- int num = -1;
- QString path = url.path();
- QString host = url.host();
+
+ UrlIngester ingest(this, url);
+
KIO::UDSEntry entry;
- if (!host.isEmpty()) {
- // Do nothing probably coming from the html form, if we return a
- // directory here, we crash konqueror
- kDebug() << "HOST NOT EMPTY:" << host;
- } else if (!path.compare("/")) {
- createRootEntry(entry);
- } else if (!path.compare("/help")) {
- createGoHelpEntry(entry);
- } else if (!path.compare("/search")) {
- createGoHomeEntry(entry);
- // } else if (!path.compare("/welcome")) {
- } else if (isRecollResult(url, &num)) {
- // Let's stat said result.
- Rcl::Doc doc;
- if (num >= 0 && !m_source.isNull() && m_source->getDoc(num, doc)) {
- entry = resultToUDSEntry(doc, num);
+ UrlIngester::RootEntryType rettp;
+ QueryDesc qd;
+ int num;
+ if (ingest.isRootEntry(&rettp)) {
+ switch(rettp) {
+ case UrlIngester::UIRET_ROOT:
+ createRootEntry(entry);
+ break;
+ case UrlIngester::UIRET_HELP:
+ createGoHelpEntry(entry);
+ break;
+ case UrlIngester::UIRET_SEARCH:
+ createGoHomeEntry(entry);
+ break;
+ default:
+ error(ERR_DOES_NOT_EXIST, "");
+ break;
}
- } else {
+ } else if (ingest.isResult(&qd, &num)) {
+ if (syncSearch(qd)) {
+ Rcl::Doc doc;
+ if (num >= 0 && !m_source.isNull() && m_source->getDoc(num, doc)) {
+ entry = resultToUDSEntry(doc, num);
+ } else {
+ error(ERR_DOES_NOT_EXIST, "");
+ }
+ } else {
+ // hopefully syncSearch() set the error?
+ }
+ } else if (ingest.isQuery(&qd)) {
// ie "recoll:/some string" or "recoll:/some string/"
//
// We have a problem here. We'd like to let the user enter
@@ -207,13 +213,11 @@ void RecollProtocol::stat(const KUrl & url)
//
// Another approach would be to use different protocol names
// to avoid any possibility of mixups
- if (path.endsWith("/")) {
- QString q, opt;
- URLToQuery(url, q, opt);
- entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
- entry.insert( KIO::UDSEntry::UDS_ACCESS, 0700);
- entry.insert( KIO::UDSEntry::UDS_MIME_TYPE, "inode/directory");
- entry.insert(KIO::UDSEntry::UDS_NAME, q);
+ if (m_alwaysdir || ingest.alwaysDir() || ingest.endSlashQuery()) {
+ entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
+ entry.insert(KIO::UDSEntry::UDS_ACCESS, 0700);
+ entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, "inode/directory");
+ entry.insert(KIO::UDSEntry::UDS_NAME, qd.query);
}
}
@@ -226,50 +230,48 @@ void RecollProtocol::listDir(const KUrl& url)
{
kDebug() << url << endl;
- // It seems that when the request is from konqueror
- // autocompletion it comes with a / at the end, which offers
- // an opportunity to not perform it.
- if (url.path() != "/" && url.path().endsWith("/")) {
- kDebug() << "EndsWith /" << endl;
- error(ERR_SLAVE_DEFINED, "Autocompletion search aborted");
- return;
- }
+ UrlIngester ingest(this, url);
+ UrlIngester::RootEntryType rettp;
+ QueryDesc qd;
- if (!m_initok || !maybeOpenDb(m_reason)) {
- string reason = "RecollProtocol::listDir: Init error:" + m_reason;
- error(KIO::ERR_SLAVE_DEFINED, reason.c_str());
- return;
- }
-
- if (url.path().isEmpty() || url.path() == "/") {
- kDebug() << "list /" << endl;
-
- UDSEntryList entries;
- KIO::UDSEntry entry;
-
- // entry for '/'
- createRootEntry(entry);
- entries.append(entry);
-
- createGoHomeEntry(entry);
- entries.append(entry);
- createGoHelpEntry(entry);
- entries.append(entry);
-
- listEntries(entries);
- finished();
- return;
- }
-
-
- QString query, opt;
- URLToQuery(url, query, opt);
- kDebug() << "Query: " << query;
- if (!query.isEmpty()) {
- if (!doSearch(query, opt))
+ if (ingest.isRootEntry(&rettp)) {
+ switch(rettp) {
+ case UrlIngester::UIRET_ROOT:
+ {
+ kDebug() << "list /" << endl;
+ UDSEntryList entries;
+ KIO::UDSEntry entry;
+ createRootEntry(entry);
+ entries.append(entry);
+ createGoHomeEntry(entry);
+ entries.append(entry);
+ createGoHelpEntry(entry);
+ entries.append(entry);
+ listEntries(entries);
+ finished();
+ }
return;
+ default:
+ error(ERR_CANNOT_ENTER_DIRECTORY, "");
+ finished();
+ return;
+ }
+ } else if (ingest.isQuery(&qd)) {
+ // At this point, it seems that when the request is from
+ // konqueror autocompletion it comes with a / at the end,
+ // which offers an opportunity to not perform it.
+ if (ingest.endSlashQuery()) {
+ kDebug() << "Ends With /" << endl;
+ error(ERR_SLAVE_DEFINED, "Autocompletion search aborted");
+ return;
+ }
+ if (!syncSearch(qd)) {
+ return;
+ }
+ // Fallthrough to actually listing the directory
} else {
- finished();
+ kDebug() << "Cant grok input url";
+ error(ERR_CANNOT_ENTER_DIRECTORY, "");
return;
}
@@ -290,7 +292,9 @@ void RecollProtocol::listDir(const KUrl& url)
listEntries(entries);
finished();
}
+
#else // <--- KDE 4.1+
+
#include
#include "kio_recoll.h"
bool RecollProtocol::isRecollResult(const KUrl &, int *)
diff --git a/src/kde/kioslave/recoll/htmlif.cpp b/src/kde/kioslave/recoll/htmlif.cpp
index 6f3f9d5f..2305f65a 100644
--- a/src/kde/kioslave/recoll/htmlif.cpp
+++ b/src/kde/kioslave/recoll/htmlif.cpp
@@ -1,5 +1,5 @@
#ifndef lint
-static char rcsid[] = "@(#$Id: htmlif.cpp,v 1.5 2008-12-02 13:14:01 dockes Exp $ (C) 2005 J.F.Dockes";
+static char rcsid[] = "@(#$Id: htmlif.cpp,v 1.6 2008-12-03 17:04:20 dockes Exp $ (C) 2005 J.F.Dockes";
#endif
/*
* This program is free software; you can redistribute it and/or modify
@@ -53,10 +53,24 @@ bool RecollKioPager::append(const string& data)
return true;
}
+string RecollProtocol::makeQueryUrl(int page, bool isdet)
+{
+ char buf[100];
+ sprintf(buf, "recoll://search/query?q=%s&qtp=%s&p=%d",
+ (const char*)m_query.query.toUtf8(),
+ (const char*)m_query.opt.toUtf8(),
+ page);
+ string ret(buf);
+ if (isdet)
+ ret += "&det=1";
+ return ret;
+}
+
string RecollKioPager::detailsLink()
{
- string chunk = "";
- chunk += tr("(show query)") + "";
+ string chunk = string("makeQueryUrl(m_parent->m_pager.pageNumber(), true) + "\">"
+ + "(show query)" + "";
return chunk;
}
@@ -73,16 +87,7 @@ const string& RecollKioPager::parFormat()
string RecollKioPager::pageTop()
{
- return "New Search
";
-}
-
-string RecollProtocol::makeQueryUrl(int page)
-{
- char buf[100];
- sprintf(buf, "recoll://search/query?q=%s&qtp=%s&p=%d",
- (const char*)m_srchStr.toUtf8(), (const char*)m_opt.toUtf8(),
- page);
- return string(buf);
+ return "New Search
";
}
string RecollKioPager::nextUrl()
@@ -107,7 +112,7 @@ string RecollKioPager::prevUrl()
static string welcomedata;
-void RecollProtocol::welcomePage()
+void RecollProtocol::searchPage()
{
kDebug();
mimeType("text/html");
@@ -171,32 +176,35 @@ void RecollProtocol::queryDetails()
data(array);
}
-void RecollProtocol::htmlDoSearch(const QString& q, const QString &opt, int page)
+void RecollProtocol::htmlDoSearch(const QueryDesc& qd)
{
- kDebug() << "q" << q << "opt" << opt << "page" << page;
- if (m_source.isNull())
- kDebug() << "Null source";
- // Check if same search or need to start new
- if (q.compare(m_srchStr) || opt.compare(m_opt)) {
- if (!doSearch(q, opt))
- return;
+ kDebug() << "q" << qd.query << "opt" << qd.opt << "page" << qd.page <<
+ "isdet" << qd.isDetReq;
+
+ mimeType("text/html");
+
+ bool samesearch;
+ if (!syncSearch(qd, &samesearch))
+ return;
+ if (!samesearch) {
m_pager.setDocSource(m_source);
- // goto page 0
m_pager.resultPageNext();
}
+ if (qd.isDetReq) {
+ queryDetails();
+ return;
+ }
// Check / adjust page number
- if (page > m_pager.pageNumber()) {
- int npages = page - m_pager.pageNumber();
+ if (qd.page > m_pager.pageNumber()) {
+ int npages = qd.page - m_pager.pageNumber();
for (int i = 0; i < npages; i++)
m_pager.resultPageNext();
- } else if (page < m_pager.pageNumber()) {
- int npages = m_pager.pageNumber() - page;
+ } else if (qd.page < m_pager.pageNumber()) {
+ int npages = m_pager.pageNumber() - qd.page;
for (int i = 0; i < npages; i++)
m_pager.resultPageBack();
}
// Display
- mimeType("text/html");
m_pager.displayPage();
- kDebug() << "done";
}
diff --git a/src/kde/kioslave/recoll/kio_recoll.cpp b/src/kde/kioslave/recoll/kio_recoll.cpp
index f3d4ef42..60228237 100644
--- a/src/kde/kioslave/recoll/kio_recoll.cpp
+++ b/src/kde/kioslave/recoll/kio_recoll.cpp
@@ -1,5 +1,5 @@
#ifndef lint
-static char rcsid[] = "@(#$Id: kio_recoll.cpp,v 1.20 2008-12-01 18:42:52 dockes Exp $ (C) 2005 J.F.Dockes";
+static char rcsid[] = "@(#$Id: kio_recoll.cpp,v 1.21 2008-12-03 17:04:20 dockes Exp $ (C) 2005 J.F.Dockes";
#endif
/*
* This program is free software; you can redistribute it and/or modify
@@ -58,7 +58,8 @@ RclConfig *RclConfig::getMainConfig()
}
RecollProtocol::RecollProtocol(const QByteArray &pool, const QByteArray &app)
- : SlaveBase("recoll", pool, app), m_initok(false), m_rcldb(0), m_opt("l")
+ : SlaveBase("recoll", pool, app), m_initok(false), m_rcldb(0),
+ m_alwaysdir(false)
{
kDebug() << endl;
if (o_rclconfig == 0) {
@@ -81,6 +82,17 @@ RecollProtocol::RecollProtocol(const QByteArray &pool, const QByteArray &app)
m_reason = "Could not build database object. (out of memory ?)";
return;
}
+
+ // Decide if we allow switching between html and file manager
+ // presentation by using an end slash or not. Can also be done dynamically
+ // by switching proto names.
+ const char *cp = getenv("RECOLL_KIO_ALWAYS_DIR");
+ if (cp) {
+ m_alwaysdir = stringToBool(cp);
+ } else {
+ o_rclconfig->getConfParam("kio_always_dir", &m_alwaysdir);
+ }
+
m_pager.setParent(this);
m_initok = true;
return;
@@ -113,46 +125,99 @@ bool RecollProtocol::maybeOpenDb(string &reason)
void RecollProtocol::mimetype(const KUrl &url)
{
kDebug() << url << endl;
+ ///////////////////////////////REMOVEME REMOVEME REMOVEME when sure !/////
+ abort();
+ ////////////////////////////////////////////////////////////////////////
mimeType("text/html");
finished();
}
-bool RecollProtocol::URLToQuery(const KUrl &url, QString& q, QString& opt,
- int *page)
+UrlIngester::UrlIngester(RecollProtocol *p, const KUrl& url)
+ : m_parent(p), m_slashend(false), m_alwaysdir(false),
+ m_retType(UIRET_NONE), m_resnum(0), m_type(UIMT_NONE)
{
- // "recoll:/some query/" or "recoll:/some query"
+ kDebug() << "Url" << url;
+ m_alwaysdir = !url.protocol().compare("recollf");
+ QString path = url.path();
if (url.host().isEmpty()) {
- q = url.path();
- opt = "l";
- if (page)
- *page = 0;
- } else {
- // Decode the forms' arguments
- q = url.queryItem("q");
- opt = url.queryItem("qtp");
- if (opt.isEmpty()) {
- opt = "l";
- }
- if (page) {
- QString p = url.queryItem("p");
- if (p.isEmpty()) {
- *page = 0;
- } else {
- sscanf(p.toAscii(), "%d", page);
- }
+ if (path.isEmpty() || !path.compare("/")) {
+ m_type = UIMT_ROOTENTRY;
+ m_retType = UIRET_ROOT;
+ return;
+ } else if (!path.compare("/help.html")) {
+ m_type = UIMT_ROOTENTRY;
+ m_retType = UIRET_HELP;
+ return;
+ } else if (!path.compare("/search.html")) {
+ m_type = UIMT_ROOTENTRY;
+ m_retType = UIRET_SEARCH;
+ return;
+ } else if (m_parent->isRecollResult(url, &m_resnum, &m_query.query)) {
+ m_type = UIMT_QUERYRESULT;
+ m_query.opt = "l";
+ m_query.page = 0;
+ } else {
+ // Have to think this is some search string
+ m_type = UIMT_QUERY;
+ m_query.query = url.path();
+ m_query.opt = "l";
+ m_query.page = 0;
}
+ } else {
+ if (url.host().compare("search")) {
+ return;
+ }
+ m_type = UIMT_QUERY;
+ // Decode the forms' arguments
+ m_query.query = url.queryItem("q");
+
+ m_query.opt = url.queryItem("qtp");
+ if (m_query.opt.isEmpty()) {
+ m_query.opt = "l";
+ }
+ QString p = url.queryItem("p");
+ if (p.isEmpty()) {
+ m_query.page = 0;
+ } else {
+ sscanf(p.toAscii(), "%d", &m_query.page);
+ }
+ p = url.queryItem("det");
+ m_query.isDetReq = !p.isEmpty();
}
- if (q.startsWith("/"))
- q.remove(0,1);
- if (q.endsWith("/"))
- q.chop(1);
- return true;
+ if (m_query.query.startsWith("/"))
+ m_query.query.remove(0,1);
+ if (m_query.query.endsWith("/")) {
+ m_slashend = true;
+ m_query.query.chop(1);
+ } else {
+ m_slashend = false;
+ }
+ return;
+}
+
+bool RecollProtocol::syncSearch(const QueryDesc &qd, bool *same)
+{
+ kDebug();
+ if (!m_initok || !maybeOpenDb(m_reason)) {
+ string reason = "RecollProtocol::listDir: Init error:" + m_reason;
+ error(KIO::ERR_SLAVE_DEFINED, reason.c_str());
+ return false;
+ }
+ if (qd.sameQuery(m_query)) {
+ if (same)
+ *same = true;
+ return true;
+ }
+ if (same)
+ *same = false;
+ // doSearch() calls error() if appropriate.
+ return doSearch(qd);
}
// This is used by the html interface, but also by the directory one
// when doing file copies for exemple. This is the central dispatcher
// for requests, it has to know a little about both models.
-void RecollProtocol::get(const KUrl & url)
+void RecollProtocol::get(const KUrl& url)
{
kDebug() << url << endl;
@@ -162,56 +227,65 @@ void RecollProtocol::get(const KUrl & url)
return;
}
- QString host = url.host();
- QString path = url.path();
-
- int docnum = -1;
- if (host.isEmpty() &&
- (path.isEmpty() || !path.compare("/")||!path.compare("/welcome"))) {
- // recoll:/ : print the html form page
- welcomePage();
- goto out;
- } else if (host.isEmpty() && isRecollResult(url, &docnum)) {
+ UrlIngester ingest(this, url);
+ UrlIngester::RootEntryType rettp;
+ QueryDesc qd;
+ int resnum;
+ if (ingest.isRootEntry(&rettp)) {
+ switch(rettp) {
+ case UrlIngester::UIRET_HELP:
+ {
+ QString location =
+ KStandardDirs::locate("data", "kio_recoll/help.html");
+ redirection(location);
+ }
+ goto out;
+ default:
+ searchPage();
+ goto out;
+ }
+ } else if (ingest.isResult(&qd, &resnum)) {
// Matched an url generated by konqueror out of a directory listing:
// ie: recoll:/some search string/recollResultxx
// Redirect to the result document URL
+ if (!syncSearch(qd)) {
+ return;
+ }
Rcl::Doc doc;
- if (docnum >= 0 && !m_source.isNull() && m_source->getDoc(docnum, doc)) {
+ if (resnum >= 0 && !m_source.isNull() && m_source->getDoc(resnum, doc)) {
mimeType(doc.mimetype.c_str());
redirection(KUrl::fromLocalFile((const char *)(doc.url.c_str()+7)));
goto out;
}
- } else if (host.isEmpty() ||
- (!host.compare("search") && !path.compare("/query"))) {
- // Either "recoll://search/query?query args"
- // Or "recoll:[/]some search string"
- // HTML style query, maybe initial or request for other page
- QString query, opt;
- int page;
- URLToQuery(url, query, opt, &page);
- if (!query.isEmpty()) {
- htmlDoSearch(query, opt, page);
+ } else if (ingest.isQuery(&qd)) {
+#if 0
+// Do we need this ?
+ if (host.isEmpty()) {
+ char cpage[20];sprintf(cpage, "%d", page);
+ QString nurl = QString::fromAscii("recoll://search/query?q=") +
+ query + "&qtp=" + opt + "&p=" + cpage;
+ redirection(KUrl(nurl));
goto out;
}
- } else if (!host.compare("command")) {
- if (path.indexOf("/QueryDetails") == 0) {
- queryDetails();
- goto out;
- }
+#endif
+ // htmlDoSearch does the search syncing (needs to know about changes).
+ htmlDoSearch(qd);
+ goto out;
}
- error(KIO::ERR_SLAVE_DEFINED, "Unrecognized URL");
+
+ error(KIO::ERR_SLAVE_DEFINED, "Unrecognized URL or internal error");
out:
finished();
}
-// Execute Recoll search, and set the docsource etc.
-bool RecollProtocol::doSearch(const QString& q, const QString &qopt)
+// Execute Recoll search, and set the docsource
+bool RecollProtocol::doSearch(const QueryDesc& qd)
{
- kDebug() << "query" << q << "opt" << qopt;
- m_srchStr = q;
- m_opt = qopt;
- char opt = qopt.isEmpty() ? 'l' : qopt.toUtf8().at(0);
- string qs = (const char *)q.toUtf8();
+ kDebug() << "query" << qd.query << "opt" << qd.opt;
+ m_query = qd;
+
+ char opt = qd.opt.isEmpty() ? 'l' : qd.opt.toUtf8().at(0);
+ string qs = (const char *)qd.query.toUtf8();
Rcl::SearchData *sd = 0;
if (opt != 'l') {
Rcl::SearchDataClause *clp = 0;
@@ -238,7 +312,6 @@ bool RecollProtocol::doSearch(const QString& q, const QString &qopt)
if (!sd) {
m_reason = "Internal Error: cant build search";
error(KIO::ERR_SLAVE_DEFINED, m_reason.c_str());
- finished();
return false;
}
@@ -248,7 +321,6 @@ bool RecollProtocol::doSearch(const QString& q, const QString &qopt)
if (!query->setQuery(sdata)) {
m_reason = "Query execute failed. Invalid query or syntax error?";
error(KIO::ERR_SLAVE_DEFINED, m_reason.c_str());
- finished();
return false;
}
@@ -256,7 +328,6 @@ bool RecollProtocol::doSearch(const QString& q, const QString &qopt)
new DocSequenceDb(RefCntr(query), "Query results", sdata);
if (src == 0) {
error(KIO::ERR_SLAVE_DEFINED, "Can't build result sequence");
- finished();
return false;
}
m_source = RefCntr(src);
diff --git a/src/kde/kioslave/recoll/kio_recoll.h b/src/kde/kioslave/recoll/kio_recoll.h
index e490497d..19f300ff 100644
--- a/src/kde/kioslave/recoll/kio_recoll.h
+++ b/src/kde/kioslave/recoll/kio_recoll.h
@@ -1,5 +1,5 @@
#ifndef _RECOLL_H
-/* @(#$Id: kio_recoll.h,v 1.11 2008-12-01 18:42:52 dockes Exp $ (C) 2005 J.F.Dockes */
+/* @(#$Id: kio_recoll.h,v 1.12 2008-12-03 17:04:20 dockes Exp $ (C) 2005 J.F.Dockes */
#define _RECOLL_H
/*
* This program is free software; you can redistribute it and/or modify
@@ -54,6 +54,54 @@ private:
RecollProtocol *m_parent;
};
+class QueryDesc {
+public:
+ QueryDesc() : opt("l"), page(0), isDetReq(false) {}
+ QString query;
+ QString opt;
+ int page;
+ bool isDetReq;
+ bool sameQuery(const QueryDesc& o) const {
+ return !opt.compare(o.opt) && !query.compare(o.query);
+ }
+};
+
+// Our virtual tree is a bit complicated. We need a class to analyse an URL
+// and tell what we should do with it
+class UrlIngester {
+public:
+ UrlIngester(RecollProtocol *p, const KUrl& url);
+ enum RootEntryType {UIRET_NONE, UIRET_ROOT, UIRET_HELP, UIRET_SEARCH};
+ bool isRootEntry(RootEntryType *tp) {
+ if (m_type != UIMT_ROOTENTRY) return false;
+ *tp = m_retType;
+ return true;
+ }
+ bool isQuery(QueryDesc *q) {
+ if (m_type != UIMT_QUERY) return false;
+ *q = m_query;
+ return true;
+ }
+ bool isResult(QueryDesc *q, int *num) {
+ if (m_type != UIMT_QUERYRESULT) return false;
+ *q = m_query;
+ *num = m_resnum;
+ return true;
+ }
+ bool endSlashQuery() {return m_slashend;}
+ bool alwaysDir() {return m_alwaysdir;}
+private:
+ RecollProtocol *m_parent;
+ QueryDesc m_query;
+ bool m_slashend;
+ bool m_alwaysdir;
+ RootEntryType m_retType;
+ int m_resnum;
+ enum MyType {UIMT_NONE, UIMT_ROOTENTRY, UIMT_QUERY, UIMT_QUERYRESULT};
+ MyType m_type;
+};
+
+
/**
* A KIO slave to execute and display Recoll searches.
*
@@ -95,23 +143,25 @@ class RecollProtocol : public KIO::SlaveBase {
static RclConfig *o_rclconfig;
friend class RecollKioPager;
+ friend class UrlIngester;
private:
bool maybeOpenDb(string& reason);
bool URLToQuery(const KUrl &url, QString& q, QString& opt, int *page=0);
- bool doSearch(const QString& q, const QString& opt = "l");
+ bool doSearch(const QueryDesc& qd);
- void welcomePage();
+ void searchPage();
void queryDetails();
- string makeQueryUrl(int page);
- void htmlDoSearch(const QString& q, const QString& opt, int page);
+ string makeQueryUrl(int page, bool isdet = false);
+ bool syncSearch(const QueryDesc& qd, bool *same = 0);
+ void htmlDoSearch(const QueryDesc& qd);
- bool isRecollResult(const KUrl &url, int *num);
+ bool isRecollResult(const KUrl &url, int *num, QString* q);
bool m_initok;
Rcl::Db *m_rcldb;
string m_reason;
-
+ bool m_alwaysdir;
// Search state: because of how the KIO slaves are used / reused,
// we can't be sure that the next request will be for the same
// search, and we need to check and restart one if the data
@@ -121,8 +171,8 @@ class RecollProtocol : public KIO::SlaveBase {
// cache of recent searches kept open.
RecollKioPager m_pager;
RefCntr m_source;
- QString m_srchStr;
- QString m_opt;
+ // Note: page here is not used, current page always comes from m_pager.
+ QueryDesc m_query;
};
extern "C" {int kdemain(int, char**);}
diff --git a/src/kde/kioslave/recoll/notes.txt b/src/kde/kioslave/recoll/notes.txt
index 676d3400..00e81e8c 100644
Binary files a/src/kde/kioslave/recoll/notes.txt and b/src/kde/kioslave/recoll/notes.txt differ