astyled + removed some debug/diag statements inserted during kde5 port

This commit is contained in:
Jean-Francois Dockes 2016-04-05 08:45:51 +02:00
parent 2de064796d
commit 5435681d4e
5 changed files with 441 additions and 391 deletions

View File

@ -87,7 +87,8 @@ z
pthread pthread
) )
install(FILES recoll.protocol DESTINATION ${SERVICES_INSTALL_DIR}) install(FILES recoll.protocol recollf.protocol
DESTINATION ${SERVICES_INSTALL_DIR})
install(FILES data/welcome.html data/help.html install(FILES data/welcome.html data/help.html
DESTINATION ${DATA_INSTALL_DIR}/kio_recoll) DESTINATION ${DATA_INSTALL_DIR}/kio_recoll)

View File

@ -19,7 +19,7 @@
* A lot of code in this file was copied from kio_beagle 0.4.0, * A lot of code in this file was copied from kio_beagle 0.4.0,
* which is a GPL program. The authors listed are: * which is a GPL program. The authors listed are:
* Debajyoti Bera <dbera.web@gmail.com> * Debajyoti Bera <dbera.web@gmail.com>
* *
* KDE4 port: * KDE4 port:
* Stephan Binner <binner@kde.org> * Stephan Binner <binner@kde.org>
*/ */
@ -45,50 +45,53 @@ static const QString resultBaseName("recollResult");
// Check if the input URL is of the form that konqueror builds by // Check if the input URL is of the form that konqueror builds by
// appending one of our result file names to the directory name (which // appending one of our result file names to the directory name (which
// is the search string). If it is, extract return the result document // is the search string). If it is, extract and return the result
// number. Possibly restart the search if the search string does not // document number. Possibly restart the search if the search string
// match the current one // does not match the current one
bool RecollProtocol::isRecollResult(const QUrl &url, int *num, QString *q) bool RecollProtocol::isRecollResult(const QUrl& url, int *num, QString *q)
{ {
*num = -1; *num = -1;
qDebug() << "RecollProtocol::isRecollResult: url: " << url; qDebug() << "RecollProtocol::isRecollResult: url: " << url;
// Basic checks // Basic checks
if (!url.host().isEmpty() || url.path().isEmpty() || if (!url.host().isEmpty() || url.path().isEmpty() ||
(url.scheme().compare("recoll") && url.scheme().compare("recollf"))) { (url.scheme().compare("recoll") && url.scheme().compare("recollf"))) {
qDebug() << "RecollProtocol::isRecollResult: no: url.host " << qDebug() << "RecollProtocol::isRecollResult: no: url.host " <<
url.host() << " path " << url.path() << " scheme " << url.scheme(); url.host() << " path " << url.path() << " scheme " << url.scheme();
return false; return false;
} }
QString path = url.path(); QString path = url.path();
qDebug() << "RecollProtocol::isRecollResult: path: " << path; qDebug() << "RecollProtocol::isRecollResult: path: " << path;
// if (!path.startsWith("/")) { if (!path.startsWith("/")) {
// return false; return false;
// } }
// Look for the last '/' and check if it is followed by // Look for the last '/' and check if it is followed by
// resultBaseName (riiiight...) // resultBaseName (riiiight...)
int slashpos = path.lastIndexOf("/"); int slashpos = path.lastIndexOf("/");
if (slashpos == -1 || slashpos == 0 || slashpos == path.length() -1) if (slashpos == -1 || slashpos == 0 || slashpos == path.length() - 1) {
return false; return false;
}
slashpos++; slashpos++;
//qDebug() << "Comparing " << path.mid(slashpos, resultBaseName.length()) << //qDebug() << "Comparing " << path.mid(slashpos, resultBaseName.length()) <<
// "and " << resultBaseName; // "and " << resultBaseName;
if (path.mid(slashpos, resultBaseName.length()).compare(resultBaseName)) if (path.mid(slashpos, resultBaseName.length()).compare(resultBaseName)) {
return false; return false;
}
// Extract the result number // Extract the result number
QString snum = path.mid(slashpos + resultBaseName.length()); QString snum = path.mid(slashpos + resultBaseName.length());
sscanf(snum.toUtf8(), "%d", num); sscanf(snum.toUtf8(), "%d", num);
if (*num == -1) if (*num == -1) {
return false; return false;
}
//qDebug() << "URL analysis ok, num:" << *num; //qDebug() << "URL analysis ok, num:" << *num;
// We do have something that ressembles a recoll result locator. Check if // We do have something that ressembles a recoll result locator. Check if
// this matches the current search, else have to run the requested one // this matches the current search, else have to run the requested one
*q = path.mid(1, slashpos-2); *q = path.mid(1, slashpos - 2);
return true; return true;
} }
@ -96,33 +99,59 @@ bool RecollProtocol::isRecollResult(const QUrl &url, int *num, QString *q)
static const UDSEntry resultToUDSEntry(const Rcl::Doc& doc, int num) static const UDSEntry resultToUDSEntry(const Rcl::Doc& doc, int num)
{ {
UDSEntry entry; UDSEntry entry;
QUrl url(doc.url.c_str());
// qDebug() << doc.url.c_str();
entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, url.fileName()); QUrl url(doc.url.c_str());
char cnum[30];sprintf(cnum, "%04d", num); //qDebug() << doc.url.c_str();
/// Filename - as displayed in directory listings etc.
/// "." has the usual special meaning of "current directory"
/// UDS_NAME must always be set and never be empty, neither contain '/'.
///
/// Note that KIO will append the UDS_NAME to the url of their
/// parent directory, so all kioslaves must use that naming scheme
/// ("url_of_parent/filename" will be the full url of that file).
/// To customize the appearance of files without changing the url
/// of the items, use UDS_DISPLAY_NAME.
//
// Use the result number to designate the file in case we are
// asked to access it
char cnum[30];
sprintf(cnum, "%04d", num);
entry.insert(KIO::UDSEntry::UDS_NAME, resultBaseName + cnum); entry.insert(KIO::UDSEntry::UDS_NAME, resultBaseName + cnum);
if (!doc.mimetype.compare("application/x-fsdirectory") || // Display the real file name
!doc.mimetype.compare("inode/directory")) { entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, url.fileName());
/// A local file path if the ioslave display files sitting on the
/// local filesystem (but in another hierarchy, e.g. settings:/ or
/// remote:/)
entry.insert(KIO::UDSEntry::UDS_LOCAL_PATH, url.path());
/// This file is a shortcut or mount, pointing to an
/// URL in a different hierarchy
/// @since 4.1
// We should probably set this only if the scheme is not 'file' (e.g.
// from the web cache).
entry.insert(KIO::UDSEntry::UDS_TARGET_URL, doc.url.c_str());
if (!doc.mimetype.compare("application/x-fsdirectory") ||
!doc.mimetype.compare("inode/directory")) {
entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, "inode/directory"); entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, "inode/directory");
entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
} else { } else {
entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, doc.mimetype.c_str()); entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, doc.mimetype.c_str());
entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG);
} }
entry.insert(KIO::UDSEntry::UDS_LOCAL_PATH, url.path());
// For local files, supply the usual file stat information // For local files, supply the usual file stat information
struct stat info; struct stat info;
if (lstat(url.path().toUtf8(), &info) >= 0) { if (lstat(url.path().toUtf8(), &info) >= 0) {
entry.insert( KIO::UDSEntry::UDS_SIZE, info.st_size); entry.insert(KIO::UDSEntry::UDS_SIZE, info.st_size);
entry.insert( KIO::UDSEntry::UDS_ACCESS, info.st_mode); entry.insert(KIO::UDSEntry::UDS_ACCESS, info.st_mode);
entry.insert( KIO::UDSEntry::UDS_MODIFICATION_TIME, info.st_mtime); entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, info.st_mtime);
entry.insert( KIO::UDSEntry::UDS_ACCESS_TIME, info.st_atime); entry.insert(KIO::UDSEntry::UDS_ACCESS_TIME, info.st_atime);
entry.insert( KIO::UDSEntry::UDS_CREATION_TIME, info.st_ctime); entry.insert(KIO::UDSEntry::UDS_CREATION_TIME, info.st_ctime);
} }
entry.insert(KIO::UDSEntry::UDS_TARGET_URL, doc.url.c_str());
return entry; return entry;
} }
@ -132,10 +161,10 @@ static const UDSEntry resultToUDSEntry(const Rcl::Doc& doc, int num)
static void createRootEntry(KIO::UDSEntry& entry) static void createRootEntry(KIO::UDSEntry& entry)
{ {
entry.clear(); entry.clear();
entry.insert( KIO::UDSEntry::UDS_NAME, "."); entry.insert(KIO::UDSEntry::UDS_NAME, ".");
entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
entry.insert( KIO::UDSEntry::UDS_ACCESS, 0700); entry.insert(KIO::UDSEntry::UDS_ACCESS, 0700);
entry.insert( KIO::UDSEntry::UDS_MIME_TYPE, "inode/directory"); entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, "inode/directory");
} }
// Points to html query screen // Points to html query screen
@ -154,9 +183,9 @@ static void createGoHomeEntry(KIO::UDSEntry& entry)
// Points to help file // Points to help file
static void createGoHelpEntry(KIO::UDSEntry& entry) static void createGoHelpEntry(KIO::UDSEntry& entry)
{ {
QString location = QString location =
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStandardPaths::locate(QStandardPaths::GenericDataLocation,
"kio_recoll/help.html"); "kio_recoll/help.html");
entry.clear(); entry.clear();
entry.insert(KIO::UDSEntry::UDS_NAME, "help"); entry.insert(KIO::UDSEntry::UDS_NAME, "help");
entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, "Recoll help (click me first)"); entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, "Recoll help (click me first)");
@ -168,6 +197,7 @@ static void createGoHelpEntry(KIO::UDSEntry& entry)
entry.insert(KIO::UDSEntry::UDS_ICON_NAME, "help"); entry.insert(KIO::UDSEntry::UDS_ICON_NAME, "help");
} }
// As far as I can see we only ever get this on '/' so why all the code?
void RecollProtocol::stat(const QUrl& url) void RecollProtocol::stat(const QUrl& url)
{ {
qDebug() << "RecollProtocol::stat:" << url; qDebug() << "RecollProtocol::stat:" << url;
@ -175,19 +205,19 @@ void RecollProtocol::stat(const QUrl& url)
UrlIngester ingest(this, url); UrlIngester ingest(this, url);
KIO::UDSEntry entry; KIO::UDSEntry entry;
entry.insert(KIO::UDSEntry::UDS_TARGET_URL, url.url()); // entry.insert(KIO::UDSEntry::UDS_TARGET_URL, url.url());
entry.insert(KIO::UDSEntry::UDS_URL, url.url()); // entry.insert(KIO::UDSEntry::UDS_URL, url.url());
UrlIngester::RootEntryType rettp; UrlIngester::RootEntryType rettp;
QueryDesc qd; QueryDesc qd;
int num; int num;
if (ingest.isRootEntry(&rettp)) { if (ingest.isRootEntry(&rettp)) {
qDebug() << "RecollProtocol::stat: root entry"; qDebug() << "RecollProtocol::stat: root entry";
switch(rettp) { switch (rettp) {
case UrlIngester::UIRET_ROOT: case UrlIngester::UIRET_ROOT:
qDebug() << "RecollProtocol::stat: root"; qDebug() << "RecollProtocol::stat: root";
createRootEntry(entry); createRootEntry(entry);
break; break;
case UrlIngester::UIRET_HELP: case UrlIngester::UIRET_HELP:
qDebug() << "RecollProtocol::stat: root help"; qDebug() << "RecollProtocol::stat: root help";
createGoHelpEntry(entry); createGoHelpEntry(entry);
break; break;
@ -195,9 +225,9 @@ void RecollProtocol::stat(const QUrl& url)
qDebug() << "RecollProtocol::stat: root search"; qDebug() << "RecollProtocol::stat: root search";
createGoHomeEntry(entry); createGoHomeEntry(entry);
break; break;
default: default:
qDebug() << "RecollProtocol::stat: ??"; qDebug() << "RecollProtocol::stat: ??";
error(ERR_DOES_NOT_EXIST, QString()); error(ERR_DOES_NOT_EXIST, QString());
break; break;
} }
} else if (ingest.isResult(&qd, &num)) { } else if (ingest.isResult(&qd, &num)) {
@ -207,14 +237,14 @@ void RecollProtocol::stat(const QUrl& url)
if (num >= 0 && m_source && m_source->getDoc(num, doc)) { if (num >= 0 && m_source && m_source->getDoc(num, doc)) {
entry = resultToUDSEntry(doc, num); entry = resultToUDSEntry(doc, num);
} else { } else {
error(ERR_DOES_NOT_EXIST, QString()); error(ERR_DOES_NOT_EXIST, QString());
} }
} else { } else {
// hopefully syncSearch() set the error? // hopefully syncSearch() set the error?
} }
} else if (ingest.isQuery(&qd)) { } else if (ingest.isQuery(&qd)) {
qDebug() << "RecollProtocol::stat: isquery"; qDebug() << "RecollProtocol::stat: isquery";
// ie "recoll:/some string" or "recoll:/some string/" // ie "recoll:/some string" or "recoll:/some string/"
// //
// We have a problem here. We'd like to let the user enter // We have a problem here. We'd like to let the user enter
// either form and get an html or a dir contents result, // either form and get an html or a dir contents result,
@ -224,20 +254,15 @@ void RecollProtocol::stat(const QUrl& url)
// //
// Another approach would be to use different protocol names // Another approach would be to use different protocol names
// to avoid any possibility of mixups // to avoid any possibility of mixups
if (true || m_alwaysdir || ingest.alwaysDir() || ingest.endSlashQuery()) { if (m_alwaysdir || ingest.alwaysDir() || ingest.endSlashQuery()) {
qDebug() << "RecollProtocol::stat: Directory type:"; qDebug() << "RecollProtocol::stat: Directory type:";
// Need to check no / in there // Need to check no / in there
#if 0 entry.insert(KIO::UDSEntry::UDS_NAME, qd.query);
entry.insert(KIO::UDSEntry::UDS_NAME, "dockes bla"/*qd.query*/); entry.insert(KIO::UDSEntry::UDS_ACCESS, 0700);
entry.insert(KIO::UDSEntry::UDS_URL, "recoll:other query");
entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, qd.query);
entry.insert(KIO::UDSEntry::UDS_ACCESS, 0777);
entry.insert(KIO::UDSEntry::UDS_SIZE, 20480);
entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, time(0)); entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, time(0));
entry.insert(KIO::UDSEntry::UDS_CREATION_TIME, time(0)); entry.insert(KIO::UDSEntry::UDS_CREATION_TIME, time(0));
entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, "inode/directory"); entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, "inode/directory");
#endif
} }
} else { } else {
qDebug() << "RecollProtocol::stat: none of the above ??"; qDebug() << "RecollProtocol::stat: none of the above ??";
@ -255,24 +280,23 @@ void RecollProtocol::listDir(const QUrl& url)
QueryDesc qd; QueryDesc qd;
if (ingest.isRootEntry(&rettp)) { if (ingest.isRootEntry(&rettp)) {
switch(rettp) { switch (rettp) {
case UrlIngester::UIRET_ROOT: case UrlIngester::UIRET_ROOT: {
{ qDebug() << "RecollProtocol::listDir:list /";
qDebug() << "RecollProtocol::listDir:list /"; UDSEntryList entries;
UDSEntryList entries; KIO::UDSEntry entry;
KIO::UDSEntry entry; createRootEntry(entry);
createRootEntry(entry); entries.append(entry);
entries.append(entry); createGoHomeEntry(entry);
createGoHomeEntry(entry); entries.append(entry);
entries.append(entry); createGoHelpEntry(entry);
createGoHelpEntry(entry); entries.append(entry);
entries.append(entry); listEntries(entries);
listEntries(entries); finished();
finished(); }
} return;
return;
default: default:
error(ERR_CANNOT_ENTER_DIRECTORY, QString()); error(ERR_CANNOT_ENTER_DIRECTORY, QString());
return; return;
} }
} else if (ingest.isQuery(&qd)) { } else if (ingest.isQuery(&qd)) {
@ -297,10 +321,12 @@ void RecollProtocol::listDir(const QUrl& url)
static int maxentries = -1; static int maxentries = -1;
if (maxentries == -1) { if (maxentries == -1) {
if (o_rclconfig) if (o_rclconfig) {
o_rclconfig->getConfParam("kio_max_direntries", &maxentries); o_rclconfig->getConfParam("kio_max_direntries", &maxentries);
if (maxentries == -1) }
if (maxentries == -1) {
maxentries = 10000; maxentries = 10000;
}
} }
static const int pagesize = 200; static const int pagesize = 200;
int pagebase = 0; int pagebase = 0;
@ -309,7 +335,7 @@ void RecollProtocol::listDir(const QUrl& url)
int pagelen = m_source->getSeqSlice(pagebase, pagesize, page); int pagelen = m_source->getSeqSlice(pagebase, pagesize, page);
UDSEntry entry; UDSEntry entry;
if (pagelen < 0) { if (pagelen < 0) {
error(ERR_SLAVE_DEFINED, u8s2qs("Internal error")); error(ERR_SLAVE_DEFINED, u8s2qs("Internal error"));
break; break;
} }
UDSEntryList entries; UDSEntryList entries;

View File

@ -18,7 +18,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <string> #include <string>
@ -45,8 +45,9 @@ using namespace KIO;
bool RecollKioPager::append(const string& data) bool RecollKioPager::append(const string& data)
{ {
if (!m_parent) if (!m_parent) {
return false; return false;
}
m_parent->data(QByteArray(data.c_str())); m_parent->data(QByteArray(data.c_str()));
return true; return true;
} }
@ -54,21 +55,23 @@ bool RecollKioPager::append(const string& data)
string RecollProtocol::makeQueryUrl(int page, bool isdet) string RecollProtocol::makeQueryUrl(int page, bool isdet)
{ {
ostringstream str; ostringstream str;
str << "recoll://search/query?q=" << str << "recoll://search/query?q=" <<
url_encode((const char*)m_query.query.toUtf8()) << url_encode((const char*)m_query.query.toUtf8()) <<
"&qtp=" << (const char*)m_query.opt.toUtf8(); "&qtp=" << (const char*)m_query.opt.toUtf8();
if (page >= 0) if (page >= 0) {
str << "&p=" << page; str << "&p=" << page;
if (isdet) }
str << "&det=1"; if (isdet) {
str << "&det=1";
}
return str.str(); return str.str();
} }
string RecollKioPager::detailsLink() string RecollKioPager::detailsLink()
{ {
string chunk = string("<a href=\"") + string chunk = string("<a href=\"") +
m_parent->makeQueryUrl(m_parent->m_pager.pageNumber(), true) + "\">" m_parent->makeQueryUrl(m_parent->m_pager.pageNumber(), true) + "\">"
+ "(show query)" + "</a>"; + "(show query)" + "</a>";
return chunk; return chunk;
} }
@ -78,24 +81,24 @@ const string& RecollKioPager::parFormat()
// Need to escape the % inside the query url // Need to escape the % inside the query url
string qurl = m_parent->makeQueryUrl(-1, false), escurl; string qurl = m_parent->makeQueryUrl(-1, false), escurl;
for (string::size_type pos = 0; pos < qurl.length(); pos++) { for (string::size_type pos = 0; pos < qurl.length(); pos++) {
switch(qurl.at(pos)) { switch (qurl.at(pos)) {
case '%': case '%':
escurl += "%%"; escurl += "%%";
break; break;
default: default:
escurl += qurl.at(pos); escurl += qurl.at(pos);
} }
} }
ostringstream str; ostringstream str;
str << str <<
"<a href=\"%U\"><img src=\"%I\" align=\"left\"></a>" "<a href=\"%U\"><img src=\"%I\" align=\"left\"></a>"
"%R %S " "%R %S "
"<a href=\"" << escurl << "&cmd=pv&dn=%N\">Preview</a>&nbsp;&nbsp;" << "<a href=\"" << escurl << "&cmd=pv&dn=%N\">Preview</a>&nbsp;&nbsp;" <<
"<a href=\"%U\">Open</a> " << "<a href=\"%U\">Open</a> " <<
"<b>%T</b><br>" "<b>%T</b><br>"
"%M&nbsp;%D&nbsp;&nbsp; <i>%U</i>&nbsp;&nbsp;%i<br>" "%M&nbsp;%D&nbsp;&nbsp; <i>%U</i>&nbsp;&nbsp;%i<br>"
"%A %K"; "%A %K";
return parformat = str.str(); return parformat = str.str();
} }
@ -107,30 +110,32 @@ string RecollKioPager::pageTop()
return pt; return pt;
// Would be nice to have but doesnt work because the query may be executed // Would be nice to have but doesnt work because the query may be executed
// by another kio instance which has no idea of the current page o // by another kio instance which has no idea of the current page o
#if 0 #if 0
" &nbsp;&nbsp;&nbsp;<a href=\"recoll:///" + " &nbsp;&nbsp;&nbsp;<a href=\"recoll:///" +
url_encode(string(m_parent->m_query.query.toUtf8())) + url_encode(string(m_parent->m_query.query.toUtf8())) +
"/\">Directory view</a> (you may need to reload the page)" "/\">Directory view</a> (you may need to reload the page)"
#endif #endif
} }
string RecollKioPager::nextUrl() string RecollKioPager::nextUrl()
{ {
int pagenum = pageNumber(); int pagenum = pageNumber();
if (pagenum < 0) if (pagenum < 0) {
pagenum = 0; pagenum = 0;
else } else {
pagenum++; pagenum++;
}
return m_parent->makeQueryUrl(pagenum); return m_parent->makeQueryUrl(pagenum);
} }
string RecollKioPager::prevUrl() string RecollKioPager::prevUrl()
{ {
int pagenum = pageNumber(); int pagenum = pageNumber();
if (pagenum <= 0) if (pagenum <= 0) {
pagenum = 0; pagenum = 0;
else } else {
pagenum--; pagenum--;
}
return m_parent->makeQueryUrl(pagenum); return m_parent->makeQueryUrl(pagenum);
} }
@ -140,19 +145,19 @@ void RecollProtocol::searchPage()
{ {
mimeType("text/html"); mimeType("text/html");
if (welcomedata.empty()) { if (welcomedata.empty()) {
QString location = QString location =
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStandardPaths::locate(QStandardPaths::GenericDataLocation,
"kio_recoll/welcome.html"); "kio_recoll/welcome.html");
string reason; string reason;
if (location.isEmpty() || if (location.isEmpty() ||
!file_to_string((const char *)location.toUtf8(), !file_to_string((const char *)location.toUtf8(),
welcomedata, &reason)) { welcomedata, &reason)) {
welcomedata = "<html><head><title>Recoll Error</title></head>" welcomedata = "<html><head><title>Recoll Error</title></head>"
"<body><p>Could not locate Recoll welcome.html file: "; "<body><p>Could not locate Recoll welcome.html file: ";
welcomedata += reason; welcomedata += reason;
welcomedata += "</p></body></html>"; welcomedata += "</p></body></html>";
} }
} }
string catgq; string catgq;
#if 0 #if 0
@ -162,14 +167,14 @@ void RecollProtocol::searchPage()
// language, but not too useful in this case, so scrap it for now. // language, but not too useful in this case, so scrap it for now.
list<string> cats; list<string> cats;
if (o_rclconfig->getMimeCategories(cats) && !cats.empty()) { if (o_rclconfig->getMimeCategories(cats) && !cats.empty()) {
catgq = "<p>Filter on types: " catgq = "<p>Filter on types: "
"<input type=\"radio\" name=\"ct\" value=\"All\" checked>All"; "<input type=\"radio\" name=\"ct\" value=\"All\" checked>All";
for (list<string>::iterator it = cats.begin(); it != cats.end();it++) { for (list<string>::iterator it = cats.begin(); it != cats.end(); it++) {
catgq += "\n<input type=\"radio\" name=\"ct\" value=\"" + catgq += "\n<input type=\"radio\" name=\"ct\" value=\"" +
*it + "\">" + *it ; *it + "\">" + *it ;
} }
} }
#endif #endif
string tmp; string tmp;
map<char, string> subs; map<char, string> subs;
@ -188,47 +193,44 @@ void RecollProtocol::queryDetails()
os << "<html><head>" << endl; os << "<html><head>" << endl;
os << "<meta http-equiv=\"Content-Type\" content=\"text/html;" os << "<meta http-equiv=\"Content-Type\" content=\"text/html;"
"charset=utf-8\">" << endl; "charset=utf-8\">" << endl;
os << "<title>" << "Recoll query details" << "</title>\n" << endl; os << "<title>" << "Recoll query details" << "</title>\n" << endl;
os << "</head>" << endl; os << "</head>" << endl;
os << "<body><h3>Query details:</h3>" << endl; os << "<body><h3>Query details:</h3>" << endl;
os << "<p>" << m_pager.queryDescription().c_str() <<"</p>"<< endl; os << "<p>" << m_pager.queryDescription().c_str() << "</p>" << endl;
os << "<p><a href=\"" << makeQueryUrl(m_pager.pageNumber()).c_str() << os << "<p><a href=\"" << makeQueryUrl(m_pager.pageNumber()).c_str() <<
"\">Return to results</a>" << endl; "\">Return to results</a>" << endl;
os << "</body></html>" << endl; os << "</body></html>" << endl;
data(array); data(array);
} }
class PlainToRichKio : public PlainToRich { class PlainToRichKio : public PlainToRich {
public: public:
PlainToRichKio(const string& nm) PlainToRichKio(const string& nm)
: m_name(nm) : m_name(nm) {
{ }
}
virtual string header() { virtual string header() {
if (m_inputhtml) { if (m_inputhtml) {
return cstr_null; return cstr_null;
} else { } else {
return string("<html><head>" return string("<html><head>"
"<META http-equiv=\"Content-Type\"" "<META http-equiv=\"Content-Type\""
"content=\"text/html;charset=UTF-8\"><title>"). "content=\"text/html;charset=UTF-8\"><title>").
append(m_name). append(m_name).
append("</title></head><body><pre>"); append("</title></head><body><pre>");
} }
} }
virtual string startMatch(unsigned int) virtual string startMatch(unsigned int) {
{ return string("<font color=\"blue\">");
return string("<font color=\"blue\">");
} }
virtual string endMatch() virtual string endMatch() {
{ return string("</font>");
return string("</font>");
} }
const string &m_name; const string& m_name;
}; };
void RecollProtocol::showPreview(const Rcl::Doc& idoc) void RecollProtocol::showPreview(const Rcl::Doc& idoc)
@ -237,13 +239,13 @@ void RecollProtocol::showPreview(const Rcl::Doc& idoc)
Rcl::Doc fdoc; Rcl::Doc fdoc;
string ipath = idoc.ipath; string ipath = idoc.ipath;
if (!interner.internfile(fdoc, ipath)) { if (!interner.internfile(fdoc, ipath)) {
error(KIO::ERR_SLAVE_DEFINED, error(KIO::ERR_SLAVE_DEFINED,
u8s2qs("Cannot convert file to internal format")); u8s2qs("Cannot convert file to internal format"));
return; return;
} }
if (!interner.get_html().empty()) { if (!interner.get_html().empty()) {
fdoc.text = interner.get_html(); fdoc.text = interner.get_html();
fdoc.mimetype = "text/html"; fdoc.mimetype = "text/html";
} }
mimeType("text/html"); mimeType("text/html");
@ -253,15 +255,16 @@ void RecollProtocol::showPreview(const Rcl::Doc& idoc)
ptr.set_inputhtml(!fdoc.mimetype.compare("text/html")); ptr.set_inputhtml(!fdoc.mimetype.compare("text/html"));
list<string> otextlist; list<string> otextlist;
HighlightData hdata; HighlightData hdata;
if (m_source) if (m_source) {
m_source->getTerms(hdata); m_source->getTerms(hdata);
}
ptr.plaintorich(fdoc.text, otextlist, hdata); ptr.plaintorich(fdoc.text, otextlist, hdata);
QByteArray array; QByteArray array;
QTextStream os(&array, QIODevice::WriteOnly); QTextStream os(&array, QIODevice::WriteOnly);
for (list<string>::iterator it = otextlist.begin(); for (list<string>::iterator it = otextlist.begin();
it != otextlist.end(); it++) { it != otextlist.end(); it++) {
os << (*it).c_str(); os << (*it).c_str();
} }
os << "</body></html>" << endl; os << "</body></html>" << endl;
data(array); data(array);
@ -270,30 +273,33 @@ void RecollProtocol::showPreview(const Rcl::Doc& idoc)
void RecollProtocol::htmlDoSearch(const QueryDesc& qd) void RecollProtocol::htmlDoSearch(const QueryDesc& qd)
{ {
qDebug() << "q" << qd.query << "option" << qd.opt << "page" << qd.page << qDebug() << "q" << qd.query << "option" << qd.opt << "page" << qd.page <<
"isdet" << qd.isDetReq << endl; "isdet" << qd.isDetReq << endl;
mimeType("text/html"); mimeType("text/html");
if (!syncSearch(qd)) if (!syncSearch(qd)) {
return; return;
}
// syncSearch/doSearch do the setDocSource when needed // syncSearch/doSearch do the setDocSource when needed
if (m_pager.pageNumber() < 0) { if (m_pager.pageNumber() < 0) {
m_pager.resultPageNext(); m_pager.resultPageNext();
} }
if (qd.isDetReq) { if (qd.isDetReq) {
queryDetails(); queryDetails();
return; return;
} }
// Check / adjust page number // Check / adjust page number
if (qd.page > m_pager.pageNumber()) { if (qd.page > m_pager.pageNumber()) {
int npages = qd.page - m_pager.pageNumber(); int npages = qd.page - m_pager.pageNumber();
for (int i = 0; i < npages; i++) for (int i = 0; i < npages; i++) {
m_pager.resultPageNext(); m_pager.resultPageNext();
}
} else if (qd.page < m_pager.pageNumber()) { } else if (qd.page < m_pager.pageNumber()) {
int npages = m_pager.pageNumber() - qd.page; int npages = m_pager.pageNumber() - qd.page;
for (int i = 0; i < npages; i++) for (int i = 0; i < npages; i++) {
m_pager.resultPageBack(); m_pager.resultPageBack();
}
} }
// Display // Display
m_pager.displayPage(o_rclconfig); m_pager.displayPage(o_rclconfig);

View File

@ -18,7 +18,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include <string> #include <string>
@ -47,44 +47,41 @@ using namespace std;
RclConfig *RecollProtocol::o_rclconfig; RclConfig *RecollProtocol::o_rclconfig;
RecollProtocol::RecollProtocol(const QByteArray &pool, const QByteArray &app) RecollProtocol::RecollProtocol(const QByteArray& pool, const QByteArray& app)
: SlaveBase("recoll", pool, app), m_initok(false), m_rcldb(0), : SlaveBase("recoll", pool, app), m_initok(false), m_rcldb(0),
m_alwaysdir(false) m_alwaysdir(false)
{ {
qDebug() << "RecollProtocol::RecollProtocol()"; qDebug() << "RecollProtocol::RecollProtocol()";
int fd = ::creat("/tmp/recolldebug", 0666);
::write(fd, "Hello\n", strlen("Hello\n"));
::close(fd);
if (o_rclconfig == 0) { if (o_rclconfig == 0) {
o_rclconfig = recollinit(0, 0, m_reason); o_rclconfig = recollinit(0, 0, m_reason);
if (!o_rclconfig || !o_rclconfig->ok()) { if (!o_rclconfig || !o_rclconfig->ok()) {
m_reason = string("Configuration problem: ") + m_reason; m_reason = string("Configuration problem: ") + m_reason;
return; return;
} }
} }
if (o_rclconfig->getDbDir().empty()) { if (o_rclconfig->getDbDir().empty()) {
// Note: this will have to be replaced by a call to a // Note: this will have to be replaced by a call to a
// configuration building dialog for initial configuration? Or // configuration building dialog for initial configuration? Or
// do we assume that the QT GUO is always used for this ? // do we assume that the QT GUO is always used for this ?
m_reason = "No db directory in configuration ??"; m_reason = "No db directory in configuration ??";
return; return;
} }
rwSettings(false); rwSettings(false);
m_rcldb = new Rcl::Db(o_rclconfig); m_rcldb = new Rcl::Db(o_rclconfig);
if (!m_rcldb) { if (!m_rcldb) {
m_reason = "Could not build database object. (out of memory ?)"; m_reason = "Could not build database object. (out of memory ?)";
return; return;
} }
// Decide if we allow switching between html and file manager // Decide if we allow switching between html and file manager
// presentation by using an end slash or not. Can also be done dynamically // presentation by using an end slash or not. Can also be done dynamically
// by switching proto names. // by switching proto names.
const char *cp = getenv("RECOLL_KIO_ALWAYS_DIR"); const char *cp = getenv("RECOLL_KIO_ALWAYS_DIR");
if (cp) { if (cp) {
m_alwaysdir = stringToBool(cp); m_alwaysdir = stringToBool(cp);
} else { } else {
o_rclconfig->getConfParam("kio_always_dir", &m_alwaysdir); o_rclconfig->getConfParam("kio_always_dir", &m_alwaysdir);
} }
cp = getenv("RECOLL_KIO_STEMLANG"); cp = getenv("RECOLL_KIO_STEMLANG");
@ -102,25 +99,25 @@ RecollProtocol::RecollProtocol(const QByteArray &pool, const QByteArray &app)
// Doesn't seem needed in the kio context. // Doesn't seem needed in the kio context.
RecollProtocol::~RecollProtocol() RecollProtocol::~RecollProtocol()
{ {
qDebug() << "RecollProtocol::~RecollProtocol()"; qDebug() << "RecollProtocol::~RecollProtocol()";
delete m_rcldb; delete m_rcldb;
} }
bool RecollProtocol::maybeOpenDb(string &reason) bool RecollProtocol::maybeOpenDb(string& reason)
{ {
if (!m_rcldb) { if (!m_rcldb) {
reason = "Internal error: initialization error"; reason = "Internal error: initialization error";
return false; return false;
} }
if (!m_rcldb->isopen() && !m_rcldb->open(Rcl::Db::DbRO)) { if (!m_rcldb->isopen() && !m_rcldb->open(Rcl::Db::DbRO)) {
reason = "Could not open database in " + o_rclconfig->getDbDir(); reason = "Could not open database in " + o_rclconfig->getDbDir();
return false; return false;
} }
return true; return true;
} }
// This is never called afaik // This is never called afaik
void RecollProtocol::mimetype(const QUrl &url) void RecollProtocol::mimetype(const QUrl& url)
{ {
qDebug() << "RecollProtocol::mimetype: url: " << url; qDebug() << "RecollProtocol::mimetype: url: " << url;
mimeType("text/html"); mimeType("text/html");
@ -135,93 +132,94 @@ UrlIngester::UrlIngester(RecollProtocol *p, const QUrl& url)
m_alwaysdir = !url.scheme().compare("recollf"); m_alwaysdir = !url.scheme().compare("recollf");
QString path = url.path(); QString path = url.path();
if (url.host().isEmpty()) { if (url.host().isEmpty()) {
if (path.isEmpty() || !path.compare("/")) { if (path.isEmpty() || !path.compare("/")) {
m_type = UIMT_ROOTENTRY; m_type = UIMT_ROOTENTRY;
m_retType = UIRET_ROOT; m_retType = UIRET_ROOT;
return; return;
} else if (!path.compare("/help.html")) { } else if (!path.compare("/help.html")) {
m_type = UIMT_ROOTENTRY; m_type = UIMT_ROOTENTRY;
m_retType = UIRET_HELP; m_retType = UIRET_HELP;
return; return;
} else if (!path.compare("/search.html")) { } else if (!path.compare("/search.html")) {
m_type = UIMT_ROOTENTRY; m_type = UIMT_ROOTENTRY;
m_retType = UIRET_SEARCH; m_retType = UIRET_SEARCH;
QUrlQuery q(url); QUrlQuery q(url);
// Retrieve the query value for preloading the form // Retrieve the query value for preloading the form
m_query.query = q.queryItemValue("q"); m_query.query = q.queryItemValue("q");
return; return;
} else if (m_parent->isRecollResult(url, &m_resnum, &m_query.query)) { } else if (m_parent->isRecollResult(url, &m_resnum, &m_query.query)) {
m_type = UIMT_QUERYRESULT; m_type = UIMT_QUERYRESULT;
m_query.opt = "l"; m_query.opt = "l";
m_query.page = 0; m_query.page = 0;
} else { } else {
// Have to think this is some search string // Have to think this is some search string
m_type = UIMT_QUERY; m_type = UIMT_QUERY;
m_query.query = url.path(); m_query.query = url.path();
m_query.opt = "l"; m_query.opt = "l";
m_query.page = 0; m_query.page = 0;
} }
} else { } else {
// Non empty host, url must be something like : // Non empty host, url must be something like :
// //search/query?q=query&param=value... // //search/query?q=query&param=value...
qDebug() << "UrlIngester::UrlIngester: host " << qDebug() << "UrlIngester::UrlIngester: host " <<
url.host() << " path " << url.path(); url.host() << " path " << url.path();
if (url.host().compare("search") || url.path().compare("/query")) { if (url.host().compare("search") || url.path().compare("/query")) {
return; return;
} }
m_type = UIMT_QUERY; m_type = UIMT_QUERY;
// Decode the forms' arguments // Decode the forms' arguments
// Retrieve the query value for preloading the form // Retrieve the query value for preloading the form
QUrlQuery q(url); QUrlQuery q(url);
m_query.query = q.queryItemValue("q"); m_query.query = q.queryItemValue("q");
m_query.opt = q.queryItemValue("qtp"); m_query.opt = q.queryItemValue("qtp");
if (m_query.opt.isEmpty()) { if (m_query.opt.isEmpty()) {
m_query.opt = "l"; m_query.opt = "l";
} }
QString p = q.queryItemValue("p"); QString p = q.queryItemValue("p");
if (p.isEmpty()) { if (p.isEmpty()) {
m_query.page = 0; m_query.page = 0;
} else { } else {
sscanf(p.toUtf8(), "%d", &m_query.page); sscanf(p.toUtf8(), "%d", &m_query.page);
} }
p = q.queryItemValue("det"); p = q.queryItemValue("det");
m_query.isDetReq = !p.isEmpty(); m_query.isDetReq = !p.isEmpty();
p = q.queryItemValue("cmd"); p = q.queryItemValue("cmd");
if (!p.isEmpty() && !p.compare("pv")) { if (!p.isEmpty() && !p.compare("pv")) {
p = q.queryItemValue("dn"); p = q.queryItemValue("dn");
if (!p.isEmpty()) { if (!p.isEmpty()) {
// Preview and no docnum ?? // Preview and no docnum ??
m_resnum = atoi((const char *)p.toUtf8()); m_resnum = atoi((const char *)p.toUtf8());
// Result in page is 1+ // Result in page is 1+
m_resnum--; m_resnum--;
m_type = UIMT_PREVIEW; m_type = UIMT_PREVIEW;
} }
} }
}
if (m_query.query.startsWith("/")) {
m_query.query.remove(0, 1);
} }
if (m_query.query.startsWith("/"))
m_query.query.remove(0,1);
if (m_query.query.endsWith("/")) { if (m_query.query.endsWith("/")) {
qDebug() << "UrlIngester::UrlIngester: query Ends with /"; qDebug() << "UrlIngester::UrlIngester: query Ends with /";
m_slashend = true; m_slashend = true;
m_query.query.chop(1); m_query.query.chop(1);
} else { } else {
m_slashend = false; m_slashend = false;
} }
return; return;
} }
bool RecollProtocol::syncSearch(const QueryDesc &qd) bool RecollProtocol::syncSearch(const QueryDesc& qd)
{ {
qDebug() << "RecollProtocol::syncSearch"; qDebug() << "RecollProtocol::syncSearch";
if (!m_initok || !maybeOpenDb(m_reason)) { if (!m_initok || !maybeOpenDb(m_reason)) {
string reason = "RecollProtocol::listDir: Init error:" + m_reason; string reason = "RecollProtocol::listDir: Init error:" + m_reason;
error(KIO::ERR_SLAVE_DEFINED, u8s2qs(reason)); error(KIO::ERR_SLAVE_DEFINED, u8s2qs(reason));
return false; return false;
} }
if (qd.sameQuery(m_query)) { if (qd.sameQuery(m_query)) {
return true; return true;
} }
// doSearch() calls error() if appropriate. // doSearch() calls error() if appropriate.
return doSearch(qd); return doSearch(qd);
@ -235,9 +233,9 @@ void RecollProtocol::get(const QUrl& url)
qDebug() << "RecollProtocol::get: " << url; qDebug() << "RecollProtocol::get: " << url;
if (!m_initok || !maybeOpenDb(m_reason)) { if (!m_initok || !maybeOpenDb(m_reason)) {
string reason = "Recoll: init error: " + m_reason; string reason = "Recoll: init error: " + m_reason;
error(KIO::ERR_SLAVE_DEFINED, u8s2qs(reason)); error(KIO::ERR_SLAVE_DEFINED, u8s2qs(reason));
return; return;
} }
UrlIngester ingest(this, url); UrlIngester ingest(this, url);
@ -245,66 +243,66 @@ void RecollProtocol::get(const QUrl& url)
QueryDesc qd; QueryDesc qd;
int resnum; int resnum;
if (ingest.isRootEntry(&rettp)) { if (ingest.isRootEntry(&rettp)) {
switch(rettp) { switch (rettp) {
case UrlIngester::UIRET_HELP: case UrlIngester::UIRET_HELP: {
{ QString location =
QString location = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kio_recoll/help.html");
"kio_recoll/help.html"); redirection(QUrl::fromLocalFile(location));
redirection(QUrl::fromLocalFile(location)); }
} goto out;
goto out; default:
default: searchPage();
searchPage(); goto out;
goto out; }
}
} else if (ingest.isResult(&qd, &resnum)) { } else if (ingest.isResult(&qd, &resnum)) {
// Url matched one generated by konqueror/Dolphin out of a // Url matched one generated by konqueror/Dolphin out of a
// search directory listing: ie: // search directory listing: ie:
// recoll:/some search string/recollResultxx // recoll:/some search string/recollResultxx
// //
// This happens when the user drags/drop the result to another // This happens when the user drags/drop the result to another
// app, or with the "open-with" right-click. Does not happen // app, or with the "open-with" right-click. Does not happen
// if the entry itself is clicked (the UDS_URL is apparently // if the entry itself is clicked (the UDS_URL is apparently
// used in this case // used in this case
// //
// Redirect to the result document URL // Redirect to the result document URL
if (!syncSearch(qd)) { if (!syncSearch(qd)) {
return; return;
} }
Rcl::Doc doc; Rcl::Doc doc;
if (resnum >= 0 && m_source && m_source->getDoc(resnum, doc)) { if (resnum >= 0 && m_source && m_source->getDoc(resnum, doc)) {
mimeType(doc.mimetype.c_str()); mimeType(doc.mimetype.c_str());
redirection(QUrl::fromLocalFile((const char *)(doc.url.c_str()+7))); redirection(QUrl::fromLocalFile((const char *)(doc.url.c_str() + 7)));
goto out; goto out;
} }
} else if (ingest.isPreview(&qd, &resnum)) { } else if (ingest.isPreview(&qd, &resnum)) {
if (!syncSearch(qd)) { if (!syncSearch(qd)) {
return; return;
} }
Rcl::Doc doc; Rcl::Doc doc;
if (resnum >= 0 && m_source && m_source->getDoc(resnum, doc)) { if (resnum >= 0 && m_source && m_source->getDoc(resnum, doc)) {
showPreview(doc); showPreview(doc);
goto out; goto out;
} }
} else if (ingest.isQuery(&qd)) { } else if (ingest.isQuery(&qd)) {
#if 0 #if 0
// Do we need this ? // Do we need this ?
if (host.isEmpty()) { if (host.isEmpty()) {
char cpage[20];sprintf(cpage, "%d", page); char cpage[20];
QString nurl = QString::fromAscii("recoll://search/query?q=") + sprintf(cpage, "%d", page);
query + "&qtp=" + opt + "&p=" + cpage; QString nurl = QString::fromAscii("recoll://search/query?q=") +
redirection(QUrl(nurl)); query + "&qtp=" + opt + "&p=" + cpage;
goto out; redirection(QUrl(nurl));
} goto out;
}
#endif #endif
// htmlDoSearch does the search syncing (needs to know about changes). // htmlDoSearch does the search syncing (needs to know about changes).
htmlDoSearch(qd); htmlDoSearch(qd);
goto out; goto out;
} }
error(KIO::ERR_SLAVE_DEFINED, u8s2qs("Unrecognized URL or internal error")); error(KIO::ERR_SLAVE_DEFINED, u8s2qs("Unrecognized URL or internal error"));
out: out:
finished(); finished();
} }
@ -318,39 +316,40 @@ bool RecollProtocol::doSearch(const QueryDesc& qd)
string qs = (const char *)qd.query.toUtf8(); string qs = (const char *)qd.query.toUtf8();
Rcl::SearchData *sd = 0; Rcl::SearchData *sd = 0;
if (opt != 'l') { if (opt != 'l') {
Rcl::SearchDataClause *clp = 0; Rcl::SearchDataClause *clp = 0;
if (opt == 'f') { if (opt == 'f') {
clp = new Rcl::SearchDataClauseFilename(qs); clp = new Rcl::SearchDataClauseFilename(qs);
} else { } else {
clp = new Rcl::SearchDataClauseSimple(opt == 'o' ? Rcl::SCLT_OR : clp = new Rcl::SearchDataClauseSimple(opt == 'o' ? Rcl::SCLT_OR :
Rcl::SCLT_AND, qs); Rcl::SCLT_AND, qs);
} }
sd = new Rcl::SearchData(Rcl::SCLT_OR, m_stemlang); sd = new Rcl::SearchData(Rcl::SCLT_OR, m_stemlang);
if (sd && clp) if (sd && clp) {
sd->addClause(clp); sd->addClause(clp);
}
} else { } else {
sd = wasaStringToRcl(o_rclconfig, m_stemlang, qs, m_reason); sd = wasaStringToRcl(o_rclconfig, m_stemlang, qs, m_reason);
} }
if (!sd) { if (!sd) {
m_reason = "Internal Error: cant build search"; m_reason = "Internal Error: cant build search";
error(KIO::ERR_SLAVE_DEFINED, u8s2qs(m_reason)); error(KIO::ERR_SLAVE_DEFINED, u8s2qs(m_reason));
return false; return false;
} }
STD_SHARED_PTR<Rcl::SearchData> sdata(sd); STD_SHARED_PTR<Rcl::SearchData> sdata(sd);
STD_SHARED_PTR<Rcl::Query>query(new Rcl::Query(m_rcldb)); STD_SHARED_PTR<Rcl::Query>query(new Rcl::Query(m_rcldb));
query->setCollapseDuplicates(prefs.collapseDuplicates); query->setCollapseDuplicates(prefs.collapseDuplicates);
if (!query->setQuery(sdata)) { if (!query->setQuery(sdata)) {
m_reason = "Query execute failed. Invalid query or syntax error?"; m_reason = "Query execute failed. Invalid query or syntax error?";
error(KIO::ERR_SLAVE_DEFINED, u8s2qs(m_reason)); error(KIO::ERR_SLAVE_DEFINED, u8s2qs(m_reason));
return false; return false;
} }
DocSequenceDb *src = DocSequenceDb *src =
new DocSequenceDb(STD_SHARED_PTR<Rcl::Query>(query), "Query results", sdata); new DocSequenceDb(STD_SHARED_PTR<Rcl::Query>(query), "Query results", sdata);
if (src == 0) { if (src == 0) {
error(KIO::ERR_SLAVE_DEFINED, u8s2qs("Can't build result sequence")); error(KIO::ERR_SLAVE_DEFINED, u8s2qs("Can't build result sequence"));
return false; return false;
} }
m_source = STD_SHARED_PTR<DocSequence>(src); m_source = STD_SHARED_PTR<DocSequence>(src);
// Reset pager in all cases. Costs nothing, stays at page -1 initially // Reset pager in all cases. Costs nothing, stays at page -1 initially
@ -365,8 +364,8 @@ int kdemain(int argc, char **argv)
qDebug() << "*** starting kio_recoll "; qDebug() << "*** starting kio_recoll ";
if (argc != 4) { if (argc != 4) {
qDebug() << "Usage: kio_recoll proto dom-socket1 dom-socket2\n"; qDebug() << "Usage: kio_recoll proto dom-socket1 dom-socket2\n";
exit(-1); exit(-1);
} }
RecollProtocol slave(argv[2], argv[3]); RecollProtocol slave(argv[2], argv[3]);

View File

@ -36,13 +36,16 @@ class RecollProtocol;
class RecollKioPager : public ResListPager { class RecollKioPager : public ResListPager {
public: public:
RecollKioPager() : m_parent(0) {} RecollKioPager() : m_parent(0) {}
void setParent(RecollProtocol *proto) {m_parent = proto;} void setParent(RecollProtocol *proto) {
m_parent = proto;
}
virtual bool append(const std::string& data); virtual bool append(const std::string& data);
virtual bool append(const std::string& data, int, const Rcl::Doc&) virtual bool append(const std::string& data, int, const Rcl::Doc&) {
{return append(data);} return append(data);
}
virtual std::string detailsLink(); virtual std::string detailsLink();
virtual const std::string &parFormat(); virtual const std::string& parFormat();
virtual std::string nextUrl(); virtual std::string nextUrl();
virtual std::string prevUrl(); virtual std::string prevUrl();
virtual std::string pageTop(); virtual std::string pageTop();
@ -59,7 +62,7 @@ public:
int page; int page;
bool isDetReq; bool isDetReq;
bool sameQuery(const QueryDesc& o) const { bool sameQuery(const QueryDesc& o) const {
return !opt.compare(o.opt) && !query.compare(o.query); return !opt.compare(o.opt) && !query.compare(o.query);
} }
}; };
@ -70,29 +73,41 @@ public:
UrlIngester(RecollProtocol *p, const QUrl& url); UrlIngester(RecollProtocol *p, const QUrl& url);
enum RootEntryType {UIRET_NONE, UIRET_ROOT, UIRET_HELP, UIRET_SEARCH}; enum RootEntryType {UIRET_NONE, UIRET_ROOT, UIRET_HELP, UIRET_SEARCH};
bool isRootEntry(RootEntryType *tp) { bool isRootEntry(RootEntryType *tp) {
if (m_type != UIMT_ROOTENTRY) return false; if (m_type != UIMT_ROOTENTRY) {
*tp = m_retType; return false;
return true; }
*tp = m_retType;
return true;
} }
bool isQuery(QueryDesc *q) { bool isQuery(QueryDesc *q) {
if (m_type != UIMT_QUERY) return false; if (m_type != UIMT_QUERY) {
*q = m_query; return false;
return true; }
*q = m_query;
return true;
} }
bool isResult(QueryDesc *q, int *num) { bool isResult(QueryDesc *q, int *num) {
if (m_type != UIMT_QUERYRESULT) return false; if (m_type != UIMT_QUERYRESULT) {
*q = m_query; return false;
*num = m_resnum; }
return true; *q = m_query;
*num = m_resnum;
return true;
} }
bool isPreview(QueryDesc *q, int *num) { bool isPreview(QueryDesc *q, int *num) {
if (m_type != UIMT_PREVIEW) return false; if (m_type != UIMT_PREVIEW) {
*q = m_query; return false;
*num = m_resnum; }
return true; *q = m_query;
*num = m_resnum;
return true;
}
bool endSlashQuery() {
return m_slashend;
}
bool alwaysDir() {
return m_alwaysdir;
} }
bool endSlashQuery() {return m_slashend;}
bool alwaysDir() {return m_alwaysdir;}
private: private:
RecollProtocol *m_parent; RecollProtocol *m_parent;
@ -102,7 +117,8 @@ private:
RootEntryType m_retType; RootEntryType m_retType;
int m_resnum; int m_resnum;
enum MyType {UIMT_NONE, UIMT_ROOTENTRY, UIMT_QUERY, UIMT_QUERYRESULT, enum MyType {UIMT_NONE, UIMT_ROOTENTRY, UIMT_QUERY, UIMT_QUERYRESULT,
UIMT_PREVIEW}; UIMT_PREVIEW
};
MyType m_type; MyType m_type;
}; };
@ -112,7 +128,7 @@ private:
* Things are made a little complicated because KIO slaves can't hope * Things are made a little complicated because KIO slaves can't hope
* that their internal state will remain consistent with their user * that their internal state will remain consistent with their user
* application state: slaves die, are restarted, reused, at random * application state: slaves die, are restarted, reused, at random
* between requests. * between requests.
* In our case, this means that any request has to be processed * In our case, this means that any request has to be processed
* without reference to the last operation performed. Ie, if the * without reference to the last operation performed. Ie, if the
* search parameters are not those from the last request, the search * search parameters are not those from the last request, the search
@ -129,17 +145,17 @@ private:
* functionality, and one based on a directory listing model, which * functionality, and one based on a directory listing model, which
* will always be more limited, but may be useful in some cases to * will always be more limited, but may be useful in some cases to
* allow easy copying of files etc. Which one is in use is decided by * allow easy copying of files etc. Which one is in use is decided by
* the form of the URL. * the form of the URL.
*/ */
class RecollProtocol : public KIO::SlaveBase { class RecollProtocol : public KIO::SlaveBase {
public: public:
RecollProtocol(const QByteArray &pool, const QByteArray &app ); RecollProtocol(const QByteArray& pool, const QByteArray& app);
virtual ~RecollProtocol(); virtual ~RecollProtocol();
virtual void mimetype(const QUrl& url); virtual void mimetype(const QUrl& url);
virtual void get(const QUrl& url); virtual void get(const QUrl& url);
// The directory mode is not available with KDE 4.0, I could find // The directory mode is not available with KDE 4.0, I could find
// no way to avoid crashing kdirmodel // no way to avoid crashing kdirmodel
virtual void stat(const QUrl & url); virtual void stat(const QUrl& url);
virtual void listDir(const QUrl& url); virtual void listDir(const QUrl& url);
static RclConfig *o_rclconfig; static RclConfig *o_rclconfig;
@ -147,9 +163,9 @@ class RecollProtocol : public KIO::SlaveBase {
friend class RecollKioPager; friend class RecollKioPager;
friend class UrlIngester; friend class UrlIngester;
private: private:
bool maybeOpenDb(std::string& reason); bool maybeOpenDb(std::string& reason);
bool URLToQuery(const QUrl &url, QString& q, QString& opt, int *page=0); bool URLToQuery(const QUrl& url, QString& q, QString& opt, int *page = 0);
bool doSearch(const QueryDesc& qd); bool doSearch(const QueryDesc& qd);
void searchPage(); void searchPage();
@ -158,14 +174,14 @@ class RecollProtocol : public KIO::SlaveBase {
bool syncSearch(const QueryDesc& qd); bool syncSearch(const QueryDesc& qd);
void htmlDoSearch(const QueryDesc& qd); void htmlDoSearch(const QueryDesc& qd);
void showPreview(const Rcl::Doc& doc); void showPreview(const Rcl::Doc& doc);
bool isRecollResult(const QUrl &url, int *num, QString* q); bool isRecollResult(const QUrl& url, int *num, QString* q);
bool m_initok; bool m_initok;
Rcl::Db *m_rcldb; Rcl::Db *m_rcldb;
std::string m_reason; std::string m_reason;
bool m_alwaysdir; bool m_alwaysdir;
// english by default else env[RECOLL_KIO_STEMLANG] // english by default else env[RECOLL_KIO_STEMLANG]
std::string m_stemlang; std::string m_stemlang;
// Search state: because of how the KIO slaves are used / reused, // 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 // we can't be sure that the next request will be for the same
@ -180,12 +196,14 @@ class RecollProtocol : public KIO::SlaveBase {
QueryDesc m_query; QueryDesc m_query;
}; };
extern "C" { __attribute__ ((visibility("default"))) int extern "C" {
kdemain(int argc, char **argv);} __attribute__((visibility("default"))) int
kdemain(int argc, char **argv);
}
inline QString u8s2qs(const string& s) inline QString u8s2qs(const string& s)
{ {
return QString::fromUtf8(s.c_str()); return QString::fromUtf8(s.c_str());
} }