From 2de064796db2d287490f0ba3969a1c99b07bfd9f Mon Sep 17 00:00:00 2001 From: Jean-Francois Dockes Date: Mon, 4 Apr 2016 19:53:30 +0200 Subject: [PATCH] kio module sort of working with kde5 dolphin, but not konqueror --- src/kde/kioslave/kio_recoll/00README.txt | 18 +-- src/kde/kioslave/kio_recoll/CMakeLists.txt | 85 +++++++++----- src/kde/kioslave/kio_recoll/dirif.cpp | 116 +++++++++++--------- src/kde/kioslave/kio_recoll/htmlif.cpp | 21 ++-- src/kde/kioslave/kio_recoll/kio_recoll.cpp | 106 +++++++++--------- src/kde/kioslave/kio_recoll/kio_recoll.h | 59 +++++----- src/kde/kioslave/kio_recoll/recoll.protocol | 4 +- 7 files changed, 212 insertions(+), 197 deletions(-) diff --git a/src/kde/kioslave/kio_recoll/00README.txt b/src/kde/kioslave/kio_recoll/00README.txt index 933b73b7..04f80651 100644 --- a/src/kde/kioslave/kio_recoll/00README.txt +++ b/src/kde/kioslave/kio_recoll/00README.txt @@ -55,12 +55,12 @@ Recipe: --prefix=/usr (or wherever KDE lives), build and install Recoll. - - In the Recoll source, go to kde/kioslave/recoll, then build and + - In the Recoll source, go to kde/kioslave/kio_recoll, then build and install the kio slave: mkdir builddir cd builddir -cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DQT_QMAKE_EXECUTABLE=/usr/bin/qmake-qt4 +cmake .. -DCMAKE_INSTALL_PREFIX=/usr make sudo make install @@ -78,17 +78,3 @@ You need to build/update the index with recollindex, the KIO slave doesn't deal with indexing for now. -Misc build problems: -=================== - -KUBUNTU 8.10 (updated to 2008-27-11) ------------------------------------- -cmake generates a bad dependancy on - /build/buildd/kde4libs-4.1.2/obj-i486-linux-gnu/lib/libkdecore.so -inside CMakeFiles/kio_recoll.dir/build.make - -Found no way to fix this. You need to edit the line and replace the -/build/[...]/lib with /usr/lib. This manifests itself with the -following error message: - - make[2]: *** No rule to make target `/build/buildd/kde4libs-4.1.2/obj-i486-linux-gnu/lib/libkdecore.so', needed by `lib/kio_recoll.so'. Stop. diff --git a/src/kde/kioslave/kio_recoll/CMakeLists.txt b/src/kde/kioslave/kio_recoll/CMakeLists.txt index c8dbd240..dd64a9e1 100644 --- a/src/kde/kioslave/kio_recoll/CMakeLists.txt +++ b/src/kde/kioslave/kio_recoll/CMakeLists.txt @@ -1,16 +1,42 @@ -cmake_minimum_required(VERSION 2.6) - project(kio_recoll) -find_package(KDE4 REQUIRED) +cmake_minimum_required(VERSION 2.8.12) -add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) -add_definitions(-DKDE_DEFAULT_DEBUG_AREA=7130 - -DRECOLL_DATADIR=\\"${CMAKE_INSTALL_PREFIX}/share/recoll\\" - -DLIBDIR=\\"${CMAKE_INSTALL_PREFIX}/lib\\" +include(FeatureSummary) + +set(QT_MIN_VERSION 5.2.0) +set(KF5_MIN_VERSION 5.0.0) + +find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS + Network + Widgets) + +find_package(ECM REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) + +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDECompilerSettings NO_POLICY_SCOPE) + +# CoreAddons? +find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS + KIO) + +add_definitions(-DQT_NO_URL_CAST_FROM_STRING) + +include_directories( + ${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR} +) + + +## Recoll stuff +add_definitions( + -DRECOLL_DATADIR="${CMAKE_INSTALL_PREFIX}/share/recoll" + -DLIBDIR="${CMAKE_INSTALL_PREFIX}/lib" -DHAVE_CONFIG_H ) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}") + set(rcltop ${CMAKE_CURRENT_SOURCE_DIR}/../../../) @@ -22,7 +48,7 @@ execute_process(COMMAND ${rcltop}/configure --disable-static --disable-qtgui --d link_directories(${rcltop}/.libs ${CMAKE_INSTALL_PREFIX}/lib) -include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES} +include_directories (${CMAKE_SOURCE_DIR} ${rcltop}/aspell ${rcltop}/bincimapmime ${rcltop}/common @@ -35,16 +61,9 @@ include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES} ${rcltop}/qtgui ) -set(kio_recoll_SRCS kio_recoll.cpp htmlif.cpp dirif.cpp ${rcltop}/qtgui/guiutils.cpp) +set(kio_recoll_SRCS kio_recoll.cpp htmlif.cpp dirif.cpp +${rcltop}/qtgui/guiutils.cpp) -CHECK_LIBRARY_EXISTS(dl dlopen "" DLOPEN_IN_LIBDL) -IF(DLOPEN_IN_LIBDL) - LIST(APPEND EXTRA_LIBS dl) -ENDIF(DLOPEN_IN_LIBDL) -CHECK_LIBRARY_EXISTS(pthread pthread_sigmask "" PTHREAD_IN_LIBPTHREAD) -IF(PTHREAD_IN_LIBPTHREAD) - LIST(APPEND EXTRA_LIBS pthread) -ENDIF(PTHREAD_IN_LIBPTHREAD) # Had the idea to add e.g. /usr/lib/recoll to the rpath so that the dyn lib # will be found at run time. But this does not seem to work with debian @@ -52,24 +71,30 @@ ENDIF(PTHREAD_IN_LIBPTHREAD) # paths but I did not find it). Link with the .a instead. #SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib/recoll") -kde4_add_plugin(kio_recoll ${kio_recoll_SRCS}) +add_library(kio_recoll MODULE ${kio_recoll_SRCS}) add_custom_target(rcllib - COMMAND make PicStatic + COMMAND make -j 6 PicStatic WORKING_DIRECTORY ${rcltop} ) add_dependencies(kio_recoll rcllib) -target_link_libraries(kio_recoll recoll xapian z ${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 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) -ENDIF ("${KDE_VERSION_MAJOR}.${KDE_VERSION_MINOR}" GREATER 4.0) +target_link_libraries(kio_recoll +recoll +xapian +KF5::KIOCore +z +pthread +) +install(FILES recoll.protocol DESTINATION ${SERVICES_INSTALL_DIR}) install(FILES data/welcome.html data/help.html DESTINATION ${DATA_INSTALL_DIR}/kio_recoll) + +# Tried but could not use PLUGIN_INSTALL_DIR (/usr/lib64/plugins), or +# /usr/lib64/qt5/plugins/kf5/kio/recoll.so: the module is not found by +# dolphin). Actually that's because of the protocol file. recoll has +# exec=kio_recoll, file has exec=kf5/kio/file + +set_target_properties(kio_recoll PROPERTIES OUTPUT_NAME "kio_recoll") +install(TARGETS kio_recoll DESTINATION ${LIB_INSTALL_DIR}/qt5/plugins) diff --git a/src/kde/kioslave/kio_recoll/dirif.cpp b/src/kde/kioslave/kio_recoll/dirif.cpp index 07d89ed8..28470bca 100644 --- a/src/kde/kioslave/kio_recoll/dirif.cpp +++ b/src/kde/kioslave/kio_recoll/dirif.cpp @@ -26,19 +26,15 @@ #include "autoconfig.h" -#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 // saying it's impossible)... #include -#include -#include -#include -#include +#include +#include +#include #include "kio_recoll.h" #include "pathut.h" @@ -52,18 +48,24 @@ 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, QString *q) +bool RecollProtocol::isRecollResult(const QUrl &url, int *num, QString *q) { *num = -1; - kDebug() << "url" << url; + qDebug() << "RecollProtocol::isRecollResult: url: " << url; // Basic checks if (!url.host().isEmpty() || url.path().isEmpty() || - (url.protocol().compare("recoll") && url.protocol().compare("recollf"))) + (url.scheme().compare("recoll") && url.scheme().compare("recollf"))) { + qDebug() << "RecollProtocol::isRecollResult: no: url.host " << + url.host() << " path " << url.path() << " scheme " << url.scheme(); return false; + } + QString path = url.path(); - if (!path.startsWith("/")) - return false; + qDebug() << "RecollProtocol::isRecollResult: path: " << path; +// if (!path.startsWith("/")) { +// return false; +// } // Look for the last '/' and check if it is followed by // resultBaseName (riiiight...) @@ -71,18 +73,18 @@ bool RecollProtocol::isRecollResult(const KUrl &url, int *num, QString *q) if (slashpos == -1 || slashpos == 0 || slashpos == path.length() -1) return false; slashpos++; - //kDebug() << "Comparing " << path.mid(slashpos, resultBaseName.length()) << + //qDebug() << "Comparing " << path.mid(slashpos, resultBaseName.length()) << // "and " << resultBaseName; if (path.mid(slashpos, resultBaseName.length()).compare(resultBaseName)) return false; // Extract the result number QString snum = path.mid(slashpos + resultBaseName.length()); - sscanf(snum.toAscii(), "%d", num); + sscanf(snum.toUtf8(), "%d", num); if (*num == -1) return false; - //kDebug() << "URL analysis ok, num:" << *num; + //qDebug() << "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 @@ -95,8 +97,8 @@ static const UDSEntry resultToUDSEntry(const Rcl::Doc& doc, int num) { UDSEntry entry; - KUrl url(doc.url.c_str()); -// kDebug() << doc.url.c_str(); + QUrl url(doc.url.c_str()); +// qDebug() << doc.url.c_str(); entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, url.fileName()); char cnum[30];sprintf(cnum, "%04d", num); @@ -105,7 +107,7 @@ static const UDSEntry resultToUDSEntry(const Rcl::Doc& doc, int num) 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_FILE_TYPE, S_IFDIR); + entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); } else { entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, doc.mimetype.c_str()); entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG); @@ -113,7 +115,7 @@ static const UDSEntry resultToUDSEntry(const Rcl::Doc& doc, int num) entry.insert(KIO::UDSEntry::UDS_LOCAL_PATH, url.path()); // For local files, supply the usual file stat information struct stat info; - if (lstat(url.path().toAscii(), &info) >= 0) { + if (lstat(url.path().toUtf8(), &info) >= 0) { entry.insert( KIO::UDSEntry::UDS_SIZE, info.st_size); entry.insert( KIO::UDSEntry::UDS_ACCESS, info.st_mode); entry.insert( KIO::UDSEntry::UDS_MODIFICATION_TIME, info.st_mtime); @@ -153,7 +155,8 @@ static void createGoHomeEntry(KIO::UDSEntry& entry) static void createGoHelpEntry(KIO::UDSEntry& entry) { QString location = - KStandardDirs::locate("data", "kio_recoll/help.html"); + QStandardPaths::locate(QStandardPaths::GenericDataLocation, + "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)"); @@ -165,45 +168,52 @@ static void createGoHelpEntry(KIO::UDSEntry& entry) entry.insert(KIO::UDSEntry::UDS_ICON_NAME, "help"); } -void RecollProtocol::stat(const KUrl & url) +void RecollProtocol::stat(const QUrl& url) { - kDebug() << url << endl ; + qDebug() << "RecollProtocol::stat:" << url; UrlIngester ingest(this, url); KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_TARGET_URL, url.url()); + entry.insert(KIO::UDSEntry::UDS_URL, url.url()); UrlIngester::RootEntryType rettp; QueryDesc qd; int num; if (ingest.isRootEntry(&rettp)) { + qDebug() << "RecollProtocol::stat: root entry"; switch(rettp) { case UrlIngester::UIRET_ROOT: + qDebug() << "RecollProtocol::stat: root"; createRootEntry(entry); break; case UrlIngester::UIRET_HELP: + qDebug() << "RecollProtocol::stat: root help"; createGoHelpEntry(entry); break; case UrlIngester::UIRET_SEARCH: + qDebug() << "RecollProtocol::stat: root search"; createGoHomeEntry(entry); break; default: - error(ERR_DOES_NOT_EXIST, ""); + qDebug() << "RecollProtocol::stat: ??"; + error(ERR_DOES_NOT_EXIST, QString()); break; } } else if (ingest.isResult(&qd, &num)) { + qDebug() << "RecollProtocol::stat: isresult"; if (syncSearch(qd)) { Rcl::Doc doc; - if (num >= 0 && !m_source.isNull() && - m_source->getDoc(num, doc)) { + if (num >= 0 && m_source && m_source->getDoc(num, doc)) { entry = resultToUDSEntry(doc, num); } else { - error(ERR_DOES_NOT_EXIST, ""); + error(ERR_DOES_NOT_EXIST, QString()); } } else { // hopefully syncSearch() set the error? } } else if (ingest.isQuery(&qd)) { + qDebug() << "RecollProtocol::stat: isquery"; // ie "recoll:/some string" or "recoll:/some string/" // // We have a problem here. We'd like to let the user enter @@ -214,23 +224,31 @@ void RecollProtocol::stat(const KUrl & url) // // Another approach would be to use different protocol names // to avoid any possibility of mixups - if (m_alwaysdir || ingest.alwaysDir() || ingest.endSlashQuery()) { - kDebug() << "Directory type"; + if (true || m_alwaysdir || ingest.alwaysDir() || ingest.endSlashQuery()) { + qDebug() << "RecollProtocol::stat: Directory type:"; + // Need to check no / in there +#if 0 + entry.insert(KIO::UDSEntry::UDS_NAME, "dockes bla"/*qd.query*/); + 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_CREATION_TIME, time(0)); 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); - entry.insert( KIO::UDSEntry::UDS_MODIFICATION_TIME, time(0)); - entry.insert( KIO::UDSEntry::UDS_CREATION_TIME, time(0)); +#endif } + } else { + qDebug() << "RecollProtocol::stat: none of the above ??"; } statEntry(entry); finished(); } -void RecollProtocol::listDir(const KUrl& url) +void RecollProtocol::listDir(const QUrl& url) { - kDebug() << url << endl; + qDebug() << "RecollProtocol::listDir: url: " << url; UrlIngester ingest(this, url); UrlIngester::RootEntryType rettp; @@ -240,7 +258,7 @@ void RecollProtocol::listDir(const KUrl& url) switch(rettp) { case UrlIngester::UIRET_ROOT: { - kDebug() << "list /" << endl; + qDebug() << "RecollProtocol::listDir:list /"; UDSEntryList entries; KIO::UDSEntry entry; createRootEntry(entry); @@ -254,7 +272,7 @@ void RecollProtocol::listDir(const KUrl& url) } return; default: - error(ERR_CANNOT_ENTER_DIRECTORY, ""); + error(ERR_CANNOT_ENTER_DIRECTORY, QString()); return; } } else if (ingest.isQuery(&qd)) { @@ -262,8 +280,8 @@ void RecollProtocol::listDir(const KUrl& url) // 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"); + qDebug() << "RecollProtocol::listDir: Ends With /"; + error(ERR_SLAVE_DEFINED, u8s2qs("Autocompletion search aborted")); return; } if (!syncSearch(qd)) { @@ -272,8 +290,8 @@ void RecollProtocol::listDir(const KUrl& url) } // Fallthrough to actually listing the directory } else { - kDebug() << "Cant grok input url"; - error(ERR_CANNOT_ENTER_DIRECTORY, ""); + qDebug() << "RecollProtocol::listDir: Cant grok input url"; + error(ERR_CANNOT_ENTER_DIRECTORY, QString()); return; } @@ -291,28 +309,18 @@ void RecollProtocol::listDir(const KUrl& url) int pagelen = m_source->getSeqSlice(pagebase, pagesize, page); UDSEntry entry; if (pagelen < 0) { - error(ERR_SLAVE_DEFINED, "Internal error"); - listEntry(entry, true); + error(ERR_SLAVE_DEFINED, u8s2qs("Internal error")); break; } + UDSEntryList entries; for (int i = 0; i < pagelen; i++) { - listEntry(resultToUDSEntry(page[i].doc, i), false); + entries.push_back(resultToUDSEntry(page[i].doc, i)); } + listEntries(entries); if (pagelen != pagesize) { - listEntry(entry, true); break; } pagebase += pagelen; } finished(); } - -#else // <--- KDE 4.1+ - -#include -#include "kio_recoll.h" -bool RecollProtocol::isRecollResult(const KUrl &, int *, QString *) -{ - return false; -} -#endif diff --git a/src/kde/kioslave/kio_recoll/htmlif.cpp b/src/kde/kioslave/kio_recoll/htmlif.cpp index d31dd72c..3acbd1a7 100644 --- a/src/kde/kioslave/kio_recoll/htmlif.cpp +++ b/src/kde/kioslave/kio_recoll/htmlif.cpp @@ -22,11 +22,7 @@ #include #include - -using namespace std; - -#include -#include +#include #include "rclconfig.h" #include "rcldb.h" @@ -44,6 +40,7 @@ using namespace std; #include "wipedir.h" #include "hldata.h" +using namespace std; using namespace KIO; bool RecollKioPager::append(const string& data) @@ -110,7 +107,7 @@ string RecollKioPager::pageTop() return pt; // 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 -#if 0 && KDE_IS_VERSION(4,1,0) +#if 0 "    m_query.query.toUtf8())) + "/\">Directory view (you may need to reload the page)" @@ -143,8 +140,9 @@ void RecollProtocol::searchPage() { mimeType("text/html"); if (welcomedata.empty()) { - QString location = - KStandardDirs::locate("data", "kio_recoll/welcome.html"); + QString location = + QStandardPaths::locate(QStandardPaths::GenericDataLocation, + "kio_recoll/welcome.html"); string reason; if (location.isEmpty() || !file_to_string((const char *)location.toUtf8(), @@ -239,7 +237,8 @@ void RecollProtocol::showPreview(const Rcl::Doc& idoc) Rcl::Doc fdoc; string ipath = idoc.ipath; if (!interner.internfile(fdoc, ipath)) { - error(KIO::ERR_SLAVE_DEFINED, "Cannot convert file to internal format"); + error(KIO::ERR_SLAVE_DEFINED, + u8s2qs("Cannot convert file to internal format")); return; } if (!interner.get_html().empty()) { @@ -254,7 +253,7 @@ void RecollProtocol::showPreview(const Rcl::Doc& idoc) ptr.set_inputhtml(!fdoc.mimetype.compare("text/html")); list otextlist; HighlightData hdata; - if (!m_source.isNull()) + if (m_source) m_source->getTerms(hdata); ptr.plaintorich(fdoc.text, otextlist, hdata); @@ -270,7 +269,7 @@ void RecollProtocol::showPreview(const Rcl::Doc& idoc) void RecollProtocol::htmlDoSearch(const QueryDesc& qd) { - kDebug() << "q" << qd.query << "option" << qd.opt << "page" << qd.page << + qDebug() << "q" << qd.query << "option" << qd.opt << "page" << qd.page << "isdet" << qd.isDetReq << endl; mimeType("text/html"); diff --git a/src/kde/kioslave/kio_recoll/kio_recoll.cpp b/src/kde/kioslave/kio_recoll/kio_recoll.cpp index 281ff254..9f421244 100644 --- a/src/kde/kioslave/kio_recoll/kio_recoll.cpp +++ b/src/kde/kioslave/kio_recoll/kio_recoll.cpp @@ -21,16 +21,12 @@ #include #include -using namespace std; -#include -#include -#include -#include - -#include -#include -#include +#include +#include +#include +#include +#include #include "rclconfig.h" #include "rcldb.h" @@ -47,6 +43,7 @@ using namespace std; #include "guiutils.h" using namespace KIO; +using namespace std; RclConfig *RecollProtocol::o_rclconfig; @@ -54,7 +51,10 @@ RecollProtocol::RecollProtocol(const QByteArray &pool, const QByteArray &app) : SlaveBase("recoll", pool, app), m_initok(false), m_rcldb(0), m_alwaysdir(false) { - kDebug() << endl; + qDebug() << "RecollProtocol::RecollProtocol()"; + int fd = ::creat("/tmp/recolldebug", 0666); + ::write(fd, "Hello\n", strlen("Hello\n")); + ::close(fd); if (o_rclconfig == 0) { o_rclconfig = recollinit(0, 0, m_reason); if (!o_rclconfig || !o_rclconfig->ok()) { @@ -102,7 +102,7 @@ RecollProtocol::RecollProtocol(const QByteArray &pool, const QByteArray &app) // Doesn't seem needed in the kio context. RecollProtocol::~RecollProtocol() { - kDebug(); + qDebug() << "RecollProtocol::~RecollProtocol()"; delete m_rcldb; } @@ -120,19 +120,19 @@ bool RecollProtocol::maybeOpenDb(string &reason) } // This is never called afaik -void RecollProtocol::mimetype(const KUrl &url) +void RecollProtocol::mimetype(const QUrl &url) { - kDebug() << url << endl; + qDebug() << "RecollProtocol::mimetype: url: " << url; mimeType("text/html"); finished(); } -UrlIngester::UrlIngester(RecollProtocol *p, const KUrl& url) +UrlIngester::UrlIngester(RecollProtocol *p, const QUrl& url) : m_parent(p), m_slashend(false), m_alwaysdir(false), m_retType(UIRET_NONE), m_resnum(0), m_type(UIMT_NONE) { - kDebug() << "Url" << url; - m_alwaysdir = !url.protocol().compare("recollf"); + qDebug() << "UrlIngester::UrlIngester: Url: " << url; + m_alwaysdir = !url.scheme().compare("recollf"); QString path = url.path(); if (url.host().isEmpty()) { if (path.isEmpty() || !path.compare("/")) { @@ -146,8 +146,9 @@ UrlIngester::UrlIngester(RecollProtocol *p, const KUrl& url) } else if (!path.compare("/search.html")) { m_type = UIMT_ROOTENTRY; m_retType = UIRET_SEARCH; + QUrlQuery q(url); // Retrieve the query value for preloading the form - m_query.query = url.queryItem("q"); + m_query.query = q.queryItemValue("q"); return; } else if (m_parent->isRecollResult(url, &m_resnum, &m_query.query)) { m_type = UIMT_QUERYRESULT; @@ -163,30 +164,33 @@ UrlIngester::UrlIngester(RecollProtocol *p, const KUrl& url) } else { // Non empty host, url must be something like : // //search/query?q=query¶m=value... - kDebug() << "host" << url.host() << "path" << url.path(); + qDebug() << "UrlIngester::UrlIngester: host " << + url.host() << " path " << url.path(); if (url.host().compare("search") || url.path().compare("/query")) { return; } m_type = UIMT_QUERY; // Decode the forms' arguments - m_query.query = url.queryItem("q"); + // Retrieve the query value for preloading the form + QUrlQuery q(url); + m_query.query = q.queryItemValue("q"); - m_query.opt = url.queryItem("qtp"); + m_query.opt = q.queryItemValue("qtp"); if (m_query.opt.isEmpty()) { m_query.opt = "l"; } - QString p = url.queryItem("p"); + QString p = q.queryItemValue("p"); if (p.isEmpty()) { m_query.page = 0; } else { - sscanf(p.toAscii(), "%d", &m_query.page); + sscanf(p.toUtf8(), "%d", &m_query.page); } - p = url.queryItem("det"); + p = q.queryItemValue("det"); m_query.isDetReq = !p.isEmpty(); - p = url.queryItem("cmd"); + p = q.queryItemValue("cmd"); if (!p.isEmpty() && !p.compare("pv")) { - p = url.queryItem("dn"); + p = q.queryItemValue("dn"); if (!p.isEmpty()) { // Preview and no docnum ?? m_resnum = atoi((const char *)p.toUtf8()); @@ -199,7 +203,7 @@ UrlIngester::UrlIngester(RecollProtocol *p, const KUrl& url) if (m_query.query.startsWith("/")) m_query.query.remove(0,1); if (m_query.query.endsWith("/")) { - kDebug() << "Ends with /"; + qDebug() << "UrlIngester::UrlIngester: query Ends with /"; m_slashend = true; m_query.query.chop(1); } else { @@ -210,10 +214,10 @@ UrlIngester::UrlIngester(RecollProtocol *p, const KUrl& url) bool RecollProtocol::syncSearch(const QueryDesc &qd) { - kDebug(); + qDebug() << "RecollProtocol::syncSearch"; if (!m_initok || !maybeOpenDb(m_reason)) { string reason = "RecollProtocol::listDir: Init error:" + m_reason; - error(KIO::ERR_SLAVE_DEFINED, reason.c_str()); + error(KIO::ERR_SLAVE_DEFINED, u8s2qs(reason)); return false; } if (qd.sameQuery(m_query)) { @@ -226,13 +230,13 @@ bool RecollProtocol::syncSearch(const QueryDesc &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 QUrl& url) { - kDebug() << url << endl; + qDebug() << "RecollProtocol::get: " << url; if (!m_initok || !maybeOpenDb(m_reason)) { string reason = "Recoll: init error: " + m_reason; - error(KIO::ERR_SLAVE_DEFINED, reason.c_str()); + error(KIO::ERR_SLAVE_DEFINED, u8s2qs(reason)); return; } @@ -245,8 +249,9 @@ void RecollProtocol::get(const KUrl& url) case UrlIngester::UIRET_HELP: { QString location = - KStandardDirs::locate("data", "kio_recoll/help.html"); - redirection(location); + QStandardPaths::locate(QStandardPaths::GenericDataLocation, + "kio_recoll/help.html"); + redirection(QUrl::fromLocalFile(location)); } goto out; default: @@ -268,9 +273,9 @@ void RecollProtocol::get(const KUrl& url) return; } Rcl::Doc doc; - if (resnum >= 0 && !m_source.isNull() && m_source->getDoc(resnum, doc)) { + if (resnum >= 0 && m_source && m_source->getDoc(resnum, doc)) { mimeType(doc.mimetype.c_str()); - redirection(KUrl::fromLocalFile((const char *)(doc.url.c_str()+7))); + redirection(QUrl::fromLocalFile((const char *)(doc.url.c_str()+7))); goto out; } } else if (ingest.isPreview(&qd, &resnum)) { @@ -278,7 +283,7 @@ void RecollProtocol::get(const KUrl& url) return; } Rcl::Doc doc; - if (resnum >= 0 && !m_source.isNull() && m_source->getDoc(resnum, doc)) { + if (resnum >= 0 && m_source && m_source->getDoc(resnum, doc)) { showPreview(doc); goto out; } @@ -289,7 +294,7 @@ void RecollProtocol::get(const KUrl& url) char cpage[20];sprintf(cpage, "%d", page); QString nurl = QString::fromAscii("recoll://search/query?q=") + query + "&qtp=" + opt + "&p=" + cpage; - redirection(KUrl(nurl)); + redirection(QUrl(nurl)); goto out; } #endif @@ -298,7 +303,7 @@ void RecollProtocol::get(const KUrl& url) goto out; } - error(KIO::ERR_SLAVE_DEFINED, "Unrecognized URL or internal error"); + error(KIO::ERR_SLAVE_DEFINED, u8s2qs("Unrecognized URL or internal error")); out: finished(); } @@ -306,7 +311,7 @@ void RecollProtocol::get(const KUrl& url) // Execute Recoll search, and set the docsource bool RecollProtocol::doSearch(const QueryDesc& qd) { - kDebug() << "query" << qd.query << "opt" << qd.opt; + qDebug() << "RecollProtocol::doSearch:query" << qd.query << "opt" << qd.opt; m_query = qd; char opt = qd.opt.isEmpty() ? 'l' : qd.opt.toUtf8().at(0); @@ -328,7 +333,7 @@ bool RecollProtocol::doSearch(const QueryDesc& qd) } if (!sd) { m_reason = "Internal Error: cant build search"; - error(KIO::ERR_SLAVE_DEFINED, m_reason.c_str()); + error(KIO::ERR_SLAVE_DEFINED, u8s2qs(m_reason)); return false; } @@ -337,14 +342,14 @@ bool RecollProtocol::doSearch(const QueryDesc& qd) query->setCollapseDuplicates(prefs.collapseDuplicates); if (!query->setQuery(sdata)) { m_reason = "Query execute failed. Invalid query or syntax error?"; - error(KIO::ERR_SLAVE_DEFINED, m_reason.c_str()); + error(KIO::ERR_SLAVE_DEFINED, u8s2qs(m_reason)); return false; } DocSequenceDb *src = new DocSequenceDb(STD_SHARED_PTR(query), "Query results", sdata); if (src == 0) { - error(KIO::ERR_SLAVE_DEFINED, "Can't build result sequence"); + error(KIO::ERR_SLAVE_DEFINED, u8s2qs("Can't build result sequence")); return false; } m_source = STD_SHARED_PTR(src); @@ -354,28 +359,19 @@ bool RecollProtocol::doSearch(const QueryDesc& qd) return true; } -// Note: KDE_EXPORT is actually needed on Unix when building with -// cmake. Says something like __attribute__(visibility(defautl)) -// (cmake apparently sets all symbols to not exported) -extern "C" {KDE_EXPORT int kdemain(int argc, char **argv);} - int kdemain(int argc, char **argv) { -#ifdef KDE_VERSION_3 - KInstance instance("kio_recoll"); -#else - KComponentData instance("kio_recoll"); -#endif - kDebug() << "*** starting kio_recoll " << endl; + QCoreApplication::setApplicationName("kio_recoll"); + qDebug() << "*** starting kio_recoll "; if (argc != 4) { - kDebug() << "Usage: kio_recoll proto dom-socket1 dom-socket2\n" << endl; + qDebug() << "Usage: kio_recoll proto dom-socket1 dom-socket2\n"; exit(-1); } RecollProtocol slave(argv[2], argv[3]); slave.dispatchLoop(); - kDebug() << "kio_recoll Done" << endl; + qDebug() << "kio_recoll Done"; return 0; } diff --git a/src/kde/kioslave/kio_recoll/kio_recoll.h b/src/kde/kioslave/kio_recoll/kio_recoll.h index b4fac1a9..841418a1 100644 --- a/src/kde/kioslave/kio_recoll/kio_recoll.h +++ b/src/kde/kioslave/kio_recoll/kio_recoll.h @@ -18,20 +18,16 @@ */ #include -using std::string; -#include -#include +#include +#include -#include -#include #include -#include #include "rclconfig.h" #include "rcldb.h" -#include "reslistpager.h" #include "docseq.h" +#include "reslistpager.h" #include MEMORY_INCLUDE class RecollProtocol; @@ -42,14 +38,14 @@ public: RecollKioPager() : m_parent(0) {} void setParent(RecollProtocol *proto) {m_parent = proto;} - virtual bool append(const string& data); - virtual bool append(const string& data, int, const Rcl::Doc&) + virtual bool append(const std::string& data); + virtual bool append(const std::string& data, int, const Rcl::Doc&) {return append(data);} - virtual string detailsLink(); - virtual const string &parFormat(); - virtual string nextUrl(); - virtual string prevUrl(); - virtual string pageTop(); + virtual std::string detailsLink(); + virtual const std::string &parFormat(); + virtual std::string nextUrl(); + virtual std::string prevUrl(); + virtual std::string pageTop(); private: RecollProtocol *m_parent; @@ -71,7 +67,7 @@ public: // and tell what we should do with it class UrlIngester { public: - UrlIngester(RecollProtocol *p, const KUrl& url); + UrlIngester(RecollProtocol *p, const QUrl& url); enum RootEntryType {UIRET_NONE, UIRET_ROOT, UIRET_HELP, UIRET_SEARCH}; bool isRootEntry(RootEntryType *tp) { if (m_type != UIMT_ROOTENTRY) return false; @@ -110,7 +106,6 @@ private: MyType m_type; }; - /** * A KIO slave to execute and display Recoll searches. * @@ -140,14 +135,12 @@ class RecollProtocol : public KIO::SlaveBase { public: RecollProtocol(const QByteArray &pool, const QByteArray &app ); virtual ~RecollProtocol(); - virtual void mimetype(const KUrl& url); - virtual void get(const KUrl& url); + virtual void mimetype(const QUrl& url); + virtual void get(const QUrl& url); // The directory mode is not available with KDE 4.0, I could find // no way to avoid crashing kdirmodel -#if KDE_IS_VERSION(4,1,0) - virtual void stat(const KUrl & url); - virtual void listDir(const KUrl& url); -#endif + virtual void stat(const QUrl & url); + virtual void listDir(const QUrl& url); static RclConfig *o_rclconfig; @@ -155,23 +148,24 @@ class RecollProtocol : public KIO::SlaveBase { friend class UrlIngester; private: - bool maybeOpenDb(string& reason); - bool URLToQuery(const KUrl &url, QString& q, QString& opt, int *page=0); + bool maybeOpenDb(std::string& reason); + bool URLToQuery(const QUrl &url, QString& q, QString& opt, int *page=0); bool doSearch(const QueryDesc& qd); void searchPage(); void queryDetails(); - string makeQueryUrl(int page, bool isdet = false); + std::string makeQueryUrl(int page, bool isdet = false); bool syncSearch(const QueryDesc& qd); void htmlDoSearch(const QueryDesc& qd); void showPreview(const Rcl::Doc& doc); - bool isRecollResult(const KUrl &url, int *num, QString* q); + bool isRecollResult(const QUrl &url, int *num, QString* q); bool m_initok; Rcl::Db *m_rcldb; - string m_reason; + std::string m_reason; bool m_alwaysdir; - string m_stemlang; // english by default else env[RECOLL_KIO_STEMLANG] + // english by default else env[RECOLL_KIO_STEMLANG] + std::string m_stemlang; // 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 @@ -186,6 +180,13 @@ class RecollProtocol : public KIO::SlaveBase { QueryDesc m_query; }; -extern "C" {int kdemain(int, char**);} +extern "C" { __attribute__ ((visibility("default"))) int + kdemain(int argc, char **argv);} + +inline QString u8s2qs(const string& s) +{ + return QString::fromUtf8(s.c_str()); +} + #endif // _RECOLL_H diff --git a/src/kde/kioslave/kio_recoll/recoll.protocol b/src/kde/kioslave/kio_recoll/recoll.protocol index c69fc77d..75f444fa 100644 --- a/src/kde/kioslave/kio_recoll/recoll.protocol +++ b/src/kde/kioslave/kio_recoll/recoll.protocol @@ -1,11 +1,11 @@ [Protocol] exec=kio_recoll protocol=recoll +Icon=recoll input=none output=filesystem listing=Name,Type, URL reading=true -defaultMimeType=text/html -Icon=recoll Class=:local URIMode=rawuri +defaultMimeType=text/html