From e106918cfca5899614af0e189c1c1368be8eefe3 Mon Sep 17 00:00:00 2001 From: dockes Date: Mon, 1 Dec 2008 15:36:52 +0000 Subject: [PATCH] seems to work by re-rerunning search whenever it changes. Still had one crash, needs cleanup --- src/kde/kioslave/recoll/CMakeLists.txt | 2 +- src/kde/kioslave/recoll/cleancmakestuff.sh | 6 +- src/kde/kioslave/recoll/data/help.html | 62 +++++++++ src/kde/kioslave/recoll/data/welcome.html | 17 ++- src/kde/kioslave/recoll/dirif.cpp | 147 ++++++++++++++++----- src/kde/kioslave/recoll/htmlif.cpp | 52 +++++--- src/kde/kioslave/recoll/kio_recoll.cpp | 90 +++++++------ src/kde/kioslave/recoll/kio_recoll.h | 25 +++- src/kde/kioslave/recoll/notes.txt | 20 +++ 9 files changed, 320 insertions(+), 101 deletions(-) create mode 100644 src/kde/kioslave/recoll/data/help.html diff --git a/src/kde/kioslave/recoll/CMakeLists.txt b/src/kde/kioslave/recoll/CMakeLists.txt index 20753667..4c5ca150 100644 --- a/src/kde/kioslave/recoll/CMakeLists.txt +++ b/src/kde/kioslave/recoll/CMakeLists.txt @@ -123,5 +123,5 @@ ELSE ("${KDE_VERSION_MAJOR}.${KDE_VERSION_MINOR}" GREATER 4.0) RENAME recoll.protocol) ENDIF ("${KDE_VERSION_MAJOR}.${KDE_VERSION_MINOR}" GREATER 4.0) -install(FILES data/welcome.html +install(FILES data/welcome.html data/help.html DESTINATION ${DATA_INSTALL_DIR}/kio_recoll) diff --git a/src/kde/kioslave/recoll/cleancmakestuff.sh b/src/kde/kioslave/recoll/cleancmakestuff.sh index 180d2eee..fd97efee 100644 --- a/src/kde/kioslave/recoll/cleancmakestuff.sh +++ b/src/kde/kioslave/recoll/cleancmakestuff.sh @@ -1,2 +1,6 @@ #!/bin/sh -rm -rf CMakeCache.txt CMakeFiles cmake_install.cmake CMakeTmp cmake_uninstall.cmake CPackConfig.cmake CPackSourceConfig.cmake DartTestfile.txt install_manifest.txt kio_recoll_automoc.cpp kio_recoll_automoc.cpp.files kio_recoll.la kio_recoll.so lib Makefile +rm -rf CMakeCache.txt CMakeFiles CTestTestfile.cmake \ + cmake_install.cmake CMakeTmp cmake_uninstall.cmake \ + CPackConfig.cmake CPackSourceConfig.cmake DartTestfile.txt \ + install_manifest.txt kio_recoll_automoc.cpp \ + kio_recoll_automoc.cpp.files kio_recoll.la kio_recoll.so lib Makefile diff --git a/src/kde/kioslave/recoll/data/help.html b/src/kde/kioslave/recoll/data/help.html new file mode 100644 index 00000000..c953740b --- /dev/null +++ b/src/kde/kioslave/recoll/data/help.html @@ -0,0 +1,62 @@ + + + + Recoll Kio Slave + + + +

Recoll kio slave

+ +

Use this module to perform Recoll searches from any program with + a KIO interface (sort of...). kio_recoll is primarily + designed and tested with konqueror, and you will + undoubtedly get even more surprising effects with other tools.

+ +

The module can work in two different modes, depending on the form + of the URLS that it is given:

+
  • Html interface: this is what you get into when you just type + recoll: or recoll:/ in the address bar, and then click the initial + icon.
  • +
  • File/Directory interface: which you enter when you pass + an URL ending with a '/'
  • + +

    Please note that this module is still in its infancy and that it + is still more a toy than anything else. The semantics of the + KIO slaves interface is still a bit unstable between KDE releases, + you will certainly get surprising effects from time to time.

    + +

    HTML interface

    + +

    This works more or less like the Recoll QT GUI, much + simplified. The + + Recoll manual describes the queries that can be + performed.

    +

    Most pages in the interface should quite self-explanatory.

    + +

    File interface

    + +

    kio_recoll enters this mode when it receives an URL ending with + a '/', ie:

    +
    recoll:///xapian recoll ext:.html/
    + +

    The path part of the URI is taken as a Recoll query + language string and executed. The results are displayed as + directory entries.

    + +

    This works fine with normal documents, very badly with message + inside folders, which Konqueror has no way to access.

    + +

    As there is no provision to page directory listings, the number + of results returned is limited to a fixed value, 100 by default, + which you can change by setting the kio_max_direntries in your + Recoll configuration file (usually ~/.recoll). + + More information about Recoll configuration.

    + +

    This interface is very limited, but allows performing multiple + selection, copies, and other file operations on the results, which + may be useful in some cases (or not :))

    + + + diff --git a/src/kde/kioslave/recoll/data/welcome.html b/src/kde/kioslave/recoll/data/welcome.html index b13ff2b7..7bae851b 100644 --- a/src/kde/kioslave/recoll/data/welcome.html +++ b/src/kde/kioslave/recoll/data/welcome.html @@ -7,14 +7,19 @@

    Recoll search

    -

    +

    + Query type:
    - Query language
    - All terms
    - Any term
    + Query language
    + All terms
    + Any term
    + File name
    - Enter search string: -

    + + Enter search string: + +
    +

    diff --git a/src/kde/kioslave/recoll/dirif.cpp b/src/kde/kioslave/recoll/dirif.cpp index 2d9c3170..4f0f144f 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.3 2008-11-28 09:14:42 dockes Exp $ (C) 2008 J.F.Dockes"; +static char rcsid[] = "@(#$Id: dirif.cpp,v 1.4 2008-12-01 15:36:52 dockes Exp $ (C) 2008 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -28,6 +28,7 @@ static char rcsid[] = "@(#$Id: dirif.cpp,v 1.3 2008-11-28 09:14:42 dockes Exp $ */ #include + #if KDE_IS_VERSION(4,1,0) // Couldn't get listDir() to work with kde 4.0, konqueror keeps // crashing because of kdirmodel, couldn't find a workaround (not @@ -37,39 +38,71 @@ static char rcsid[] = "@(#$Id: dirif.cpp,v 1.3 2008-11-28 09:14:42 dockes Exp $ #include #include +#include #include #include "kio_recoll.h" +#include "pathut.h" + using namespace KIO; -void RecollProtocol::stat(const KUrl & url) -{ - kDebug() << url << endl ; +static const QString resultBaseName("recollResult"); +// +bool RecollProtocol::isRecollResult(const KUrl &url, int *num) +{ + *num = -1; + kDebug() << "url" << url << "m_srchStr" << m_srchStr; + // Does the url look like a recoll search result ?? + if (!url.host().isEmpty() || url.path().isEmpty() || + url.protocol().compare("recoll")) + return false; QString path = url.path(); - KIO::UDSEntry entry; - if (!path.compare("/")) - entry.insert(KIO::UDSEntry::UDS_NAME, "/welcome"); - else - entry.insert(KIO::UDSEntry::UDS_NAME, url.path()); - entry.insert(KIO::UDSEntry::UDS_TARGET_URL, url.url()); - entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG); - statEntry(entry); - finished(); + if (!path.startsWith("/")) + return false; + // Look for the last '/' and check if it is followed by + // resultBaseName (riiiight...) + int slashpos = path.lastIndexOf("/"); + if (slashpos == -1 || slashpos == 0 || slashpos == path.length() -1) + return false; + slashpos++; + kDebug() << "Comparing " << path.mid(slashpos, resultBaseName.length()) << + "and " << resultBaseName; + if (path.mid(slashpos, resultBaseName.length()).compare(resultBaseName)) + return false; + + QString snum = path.mid(slashpos + resultBaseName.length()); + sscanf(snum.toAscii(), "%d", num); + if (*num == -1) + return false; + + kDebug() << "URL analysis ok, num:" << *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)) { + kDebug() << "Starting new search"; + if (!doSearch(searchstring)) + return false; + } + + return true; } - - -const UDSEntry resultToUDSEntry(Rcl::Doc doc) +static const UDSEntry resultToUDSEntry(const Rcl::Doc& doc, int num) { - UDSEntry entry; KUrl url(doc.url.c_str()); kDebug() << doc.url.c_str(); - entry.insert(KIO::UDSEntry::UDS_NAME, url.fileName()); + entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, url.fileName()); + char cnum[30];sprintf(cnum, "%d", num); + entry.insert(KIO::UDSEntry::UDS_NAME, resultBaseName + cnum); + if (!doc.mimetype.compare("application/x-fsdirectory")) { entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, "inode/directory"); entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); @@ -87,17 +120,16 @@ const UDSEntry resultToUDSEntry(Rcl::Doc doc) entry.insert( KIO::UDSEntry::UDS_ACCESS_TIME, info.st_atime); entry.insert( KIO::UDSEntry::UDS_CREATION_TIME, info.st_ctime); } - + kDebug() << "entry URL: " << doc.url.c_str(); entry.insert(KIO::UDSEntry::UDS_TARGET_URL, doc.url.c_str()); - // entry.insert(KIO::UDSEntry::UDS_URL, "recoll://search/query/1"); + return entry; } // From kio_beagle -void RecollProtocol::createRootEntry(KIO::UDSEntry& entry) +static void createRootEntry(KIO::UDSEntry& entry) { - // home directory entry.clear(); entry.insert( KIO::UDSEntry::UDS_NAME, "."); entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); @@ -105,11 +137,12 @@ void RecollProtocol::createRootEntry(KIO::UDSEntry& entry) entry.insert( KIO::UDSEntry::UDS_MIME_TYPE, "inode/directory"); } -void RecollProtocol::createGoHomeEntry(KIO::UDSEntry& entry) +// Points to html query screen +static void createGoHomeEntry(KIO::UDSEntry& entry) { - // status file entry.clear(); - entry.insert(KIO::UDSEntry::UDS_NAME, "Recoll home (click me)"); + 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_ACCESS, 0500); @@ -117,6 +150,49 @@ void RecollProtocol::createGoHomeEntry(KIO::UDSEntry& entry) entry.insert(KIO::UDSEntry::UDS_ICON_NAME, "recoll"); } +// Points to help file +static void createGoHelpEntry(KIO::UDSEntry& entry) +{ + QString location = + KStandardDirs::locate("data", "kio_recoll/help.html"); + entry.clear(); + entry.insert(KIO::UDSEntry::UDS_NAME, "help"); + entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, "Recoll help (click me first)"); + entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG); + entry.insert(KIO::UDSEntry::UDS_TARGET_URL, QString("file://") + + location); + entry.insert(KIO::UDSEntry::UDS_ACCESS, 0500); + entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, "text/html"); + entry.insert(KIO::UDSEntry::UDS_ICON_NAME, "help"); +} + +void RecollProtocol::stat(const KUrl & url) +{ + kDebug() << url << endl ; + int num = -1; + QString path = url.path(); + KIO::UDSEntry entry; + if (!path.compare("/")) { + createRootEntry(entry); + } else if (!path.compare("/help")) { + createGoHelpEntry(entry); + } else if (!path.compare("/search")) { + createGoHomeEntry(entry); + } else if (isRecollResult(url, &num)) { + // If this url starts with the current search url appended with a + // result name appended, let's stat said result. + Rcl::Doc doc; + if (num >= 0 && !m_source.isNull() && m_source->getDoc(num, doc)) { + entry = resultToUDSEntry(doc, num); + } + } else { + // ?? + } + + entry.insert(KIO::UDSEntry::UDS_TARGET_URL, url.url()); + statEntry(entry); + finished(); +} void RecollProtocol::listDir(const KUrl& url) { @@ -136,6 +212,7 @@ void RecollProtocol::listDir(const KUrl& url) error(KIO::ERR_SLAVE_DEFINED, reason.c_str()); return; } + if (url.path().isEmpty() || url.path() == "/") { kDebug() << "list /" << endl; @@ -144,12 +221,11 @@ void RecollProtocol::listDir(const KUrl& url) // entry for '/' createRootEntry(entry); - // listEntry(entry, false); entries.append(entry); - // entry for 'Information' createGoHomeEntry(entry); - // listEntry(entry, false); + entries.append(entry); + createGoHelpEntry(entry); entries.append(entry); listEntries(entries); @@ -157,23 +233,32 @@ void RecollProtocol::listDir(const KUrl& url) return; } + QString query, opt; URLToQuery(url, query, opt); kDebug() << "Query: " << query; if (!query.isEmpty()) { - if (!doSearch(query, opt.toUtf8().at(0))) + if (!doSearch(query, opt)) return; } else { finished(); return; } + static int numentries = -1; + if (numentries == -1) { + if (o_rclconfig) + o_rclconfig->getConfParam("kio_max_direntries", &numentries); + if (numentries == -1) + numentries = 100; + } + vector page; - int pagelen = m_source->getSeqSlice(0, 100, page); + int pagelen = m_source->getSeqSlice(0, numentries, page); kDebug() << "Got " << pagelen << " results."; UDSEntryList entries; for (int i = 0; i < pagelen; i++) { - entries.append(resultToUDSEntry(page[i].doc)); + entries.append(resultToUDSEntry(page[i].doc, i)); } listEntries(entries); finished(); diff --git a/src/kde/kioslave/recoll/htmlif.cpp b/src/kde/kioslave/recoll/htmlif.cpp index f12a408e..66e59971 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.2 2008-11-27 17:48:43 dockes Exp $ (C) 2005 J.F.Dockes"; +static char rcsid[] = "@(#$Id: htmlif.cpp,v 1.3 2008-12-01 15:36:52 dockes Exp $ (C) 2005 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -75,6 +75,15 @@ 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); +} + string RecollKioPager::nextUrl() { int pagenum = pageNumber(); @@ -82,10 +91,9 @@ string RecollKioPager::nextUrl() pagenum = 0; else pagenum++; - char buf[100]; - sprintf(buf, "recoll://command/Page%d", pagenum); - return buf; + return m_parent->makeQueryUrl(pagenum); } + string RecollKioPager::prevUrl() { int pagenum = pageNumber(); @@ -93,9 +101,7 @@ string RecollKioPager::prevUrl() pagenum = 0; else pagenum--; - char buf[100]; - sprintf(buf, "recoll://command/Page%d", pagenum); - return buf; + return m_parent->makeQueryUrl(pagenum); } static string welcomedata; @@ -139,21 +145,37 @@ void RecollProtocol::queryDetails() os << "" << endl; os << "

    Query details:

    " << endl; os << "

    " << m_pager.queryDescription().c_str() <<"

    "<< endl; - os << "

    Return to results" << endl; + os << "

    Return to results" << endl; os << "" << endl; data(array); kDebug() << "done" << endl; } -void RecollProtocol::htmlDoSearch(const QString& q, char opt) +void RecollProtocol::htmlDoSearch(const QString& q, const QString &opt, int page) { - kDebug() << "htmlDoSearch" << endl; - if (!doSearch(q, opt)) - return; + kDebug(); + // Check if same search or need to start new + if (q.compare(m_srchStr) || opt.compare(m_opt)) { + if (!doSearch(q, opt)) + return; + m_pager.setDocSource(m_source); + // goto page 0 + m_pager.resultPageNext(); + } + + // Check / adjust page number + if (page > m_pager.pageNumber()) { + int npages = 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; + for (int i = 0; i < npages; i++) + m_pager.resultPageBack(); + } + // Display mimeType("text/html"); - m_pager.setDocSource(m_source); - m_pager.resultPageNext(); m_pager.displayPage(); kDebug() << "done" << endl; } diff --git a/src/kde/kioslave/recoll/kio_recoll.cpp b/src/kde/kioslave/recoll/kio_recoll.cpp index 36ae31b9..64aa58ac 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.18 2008-11-28 09:14:42 dockes Exp $ (C) 2005 J.F.Dockes"; +static char rcsid[] = "@(#$Id: kio_recoll.cpp,v 1.19 2008-12-01 15:36:52 dockes Exp $ (C) 2005 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -66,7 +66,7 @@ RclConfig *RclConfig::getMainConfig() } 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_opt("l") { kDebug() << endl; if (o_rclconfig == 0) { @@ -123,11 +123,14 @@ void RecollProtocol::mimetype(const KUrl &url) finished(); } -bool RecollProtocol::URLToQuery(const KUrl &url, QString& q, QString& opt) +bool RecollProtocol::URLToQuery(const KUrl &url, QString& q, QString& opt, + int *page) { if (url.host().isEmpty()) { q = url.path(); opt = "l"; + if (page) + *page = 0; } else { // Decode the forms' arguments q = url.queryItem("q"); @@ -135,6 +138,14 @@ bool RecollProtocol::URLToQuery(const KUrl &url, QString& q, QString& opt) if (opt.isEmpty()) { opt = "l"; } + if (page) { + QString p = url.queryItem("p"); + if (p.isEmpty()) { + page = 0; + } else { + sscanf(p.toAscii(), "%d", page); + } + } } if (q.startsWith("/")) q.remove(0,1); @@ -146,7 +157,7 @@ void RecollProtocol::get(const KUrl & url) kDebug() << url << endl; if (!m_initok || !maybeOpenDb(m_reason)) { - string reason = "RecollProtocol::get:Init error: " + m_reason; + string reason = "Recoll: init error: " + m_reason; error(KIO::ERR_SLAVE_DEFINED, reason.c_str()); return; } @@ -154,56 +165,53 @@ void RecollProtocol::get(const KUrl & url) QString host = url.host(); QString path = url.path(); - kDebug() << "host:" << host << " path:" << path; - + int docnum = -1; if (host.isEmpty() && (path.isEmpty() || !path.compare("/")||!path.compare("/welcome"))) { - // recoll:/ + // recoll:/ : print the html form page welcomePage(); goto out; - } else if ((!host.compare("search") && !path.compare("/query")) - || host.isEmpty()) { + } else if (host.isEmpty() && isRecollResult(url, &docnum)) { + // Matched an url generated by konqueror out of a directory listing: + // ie: recoll:/some search string/recollResultxx + // Redirect to the result document URL + Rcl::Doc doc; + if (docnum >= 0 && !m_source.isNull() && m_source->getDoc(docnum, 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" + // Or "recoll:[/]some search string" + // HTML style query, maybe initial or request for other page QString query, opt; - URLToQuery(url, query, opt); + int page; + URLToQuery(url, query, opt, &page); if (!query.isEmpty()) { - htmlDoSearch(query, opt.toUtf8().at(0)); + htmlDoSearch(query, opt, page); goto out; } } else if (!host.compare("command")) { - if (!path.isEmpty()) { - if (path.indexOf("/Page") == 0) { - int newpage = 0; - sscanf(path.toUtf8(), "/Page%d", &newpage); - if (newpage > m_pager.pageNumber()) { - int npages = newpage - m_pager.pageNumber(); - for (int i = 0; i < npages; i++) - m_pager.resultPageNext(); - } else if (newpage < m_pager.pageNumber()) { - int npages = m_pager.pageNumber() - newpage; - for (int i = 0; i < npages; i++) - m_pager.resultPageBack(); - } - mimeType("text/html"); - m_pager.displayPage(); - goto out; - } else if (path.indexOf("/QueryDetails") == 0) { - queryDetails(); - goto out; - } - } + if (path.indexOf("/QueryDetails") == 0) { + queryDetails(); + goto out; + } } - kDebug() << "Unrecognized URL" << endl; - outputError("unrecognized URL"); + kDebug() << "Unrecognized URL: " << url << endl; + error(KIO::ERR_SLAVE_DEFINED, "Unrecognized URL"); out: finished(); kDebug() << "done" << endl; } -bool RecollProtocol::doSearch(const QString& q, char opt) +bool RecollProtocol::doSearch(const QString& q, const QString &qopt) { - kDebug() << q << endl; + 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(); Rcl::SearchData *sd = 0; if (opt != 'l') { @@ -232,7 +240,7 @@ bool RecollProtocol::doSearch(const QString& q, char opt) if (!sd) { kDebug() << "Could not build search data from user string"; m_reason = "Internal Error: cant build search"; - error(-1, m_reason.c_str()); + error(KIO::ERR_SLAVE_DEFINED, m_reason.c_str()); finished(); return false; } @@ -242,8 +250,8 @@ bool RecollProtocol::doSearch(const QString& q, char opt) kDebug() << "Executing query"; RefCntrquery(new Rcl::Query(m_rcldb)); if (!query->setQuery(sdata)) { - m_reason = "Internal Error: query execute failed"; - error(-1, m_reason.c_str()); + m_reason = "Query execute failed. Invalid query or syntax error?"; + error(KIO::ERR_SLAVE_DEFINED, m_reason.c_str()); finished(); kDebug() << "setQuery failed, returning"; return false; @@ -254,7 +262,7 @@ bool RecollProtocol::doSearch(const QString& q, char opt) new DocSequenceDb(RefCntr(query), "Query results", sdata); if (src == 0) { kDebug() << "Cant' build result sequence"; - error(-1, "Can't build result sequence"); + error(KIO::ERR_SLAVE_DEFINED, "Can't build result sequence"); finished(); return false; } diff --git a/src/kde/kioslave/recoll/kio_recoll.h b/src/kde/kioslave/recoll/kio_recoll.h index 6a8c19ad..c8dcf80f 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.9 2008-11-28 09:14:42 dockes Exp $ (C) 2005 J.F.Dockes */ +/* @(#$Id: kio_recoll.h,v 1.10 2008-12-01 15:36:52 dockes Exp $ (C) 2005 J.F.Dockes */ #define _RECOLL_H /* * This program is free software; you can redistribute it and/or modify @@ -70,23 +70,36 @@ class RecollProtocol : public KIO::SlaveBase { static RclConfig *o_rclconfig; + friend class RecollKioPager; private: bool maybeOpenDb(string &reason); void outputError(const QString& errmsg); - bool doSearch(const QString& q, char opt = 'l'); + bool doSearch(const QString& q, const QString& opt = "l"); void welcomePage(); void queryDetails(); - void htmlDoSearch(const QString& q, char opt); - bool URLToQuery(const KUrl &url, QString& q, QString& opt); - void createRootEntry(KIO::UDSEntry& entry); - void createGoHomeEntry(KIO::UDSEntry& entry); + void htmlDoSearch(const QString& q, const QString& opt, int page); + bool URLToQuery(const KUrl &url, QString& q, QString& opt, int *page=0); + bool isRecollResult(const KUrl &url, int *num); + string makeQueryUrl(int page); bool m_initok; Rcl::Db *m_rcldb; std::string m_reason; + + // All details about the current 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 changes. This is very wasteful of + // course but hopefully won't happen too much in actual use. One + // possible workaround for some scenarios (one slave several + // konqueror windows) would be to have a small cache of recent + // searches kept open. RecollKioPager m_pager; RefCntr m_source; + QString m_srchStr; + QString m_opt; }; + extern "C" {int kdemain(int, char**);} #endif // _RECOLL_H diff --git a/src/kde/kioslave/recoll/notes.txt b/src/kde/kioslave/recoll/notes.txt index d3a5cf24..7ce295a6 100644 --- a/src/kde/kioslave/recoll/notes.txt +++ b/src/kde/kioslave/recoll/notes.txt @@ -34,3 +34,23 @@ le changement ne s'opere pas toujours immediatement quand on change le fichier .proto, y compris apres avoir tue tous les process kde (changement à la deuxieme execution de konqueror sur kde4.0). Sur kde4.0 il faut que le .proto soit sans entree "listing" + + +Les KIO slaves ne sont pas associes a une fenetre ! ils sont +reutilises au hasard, et leur etat n'a aucune raison de correspondre a +celui de l'affichage. On peut tres bien avoir 1 fenetre 2 kio ou 1 kio +deux fenetres, et le next d'un search peut arriver au kio qui a +l'autre search, donc n'importenaouak. Il faudrait que l'etat soit +partage et accede par un identifiant uniquement determine par l'url de +la fenetre. + +Meme pour une fenetre unique, au bout d'un moment le kio timeout et exite. + +En fait les slaves ne peuvent pas stocker d'etat du tout. Donc: + - soit un serveur central auquel ils parlent + - soit ils relancent dynamiquement les recherches si pas de match +C'est vrai aussi bien pour les dirlists que pour la version html. + +J'ai essaye de mettre une boucle timeout callback callspecial() mais +ca ne sert a rien, c'est gere dans le process kio_slave, ca ne +maintient pas l'association avec un konqueror.