kio module sort of working with kde5 dolphin, but not konqueror
This commit is contained in:
parent
6938a4a4d4
commit
2de064796d
@ -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.
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -26,19 +26,15 @@
|
||||
|
||||
#include "autoconfig.h"
|
||||
|
||||
#include <kdeversion.h>
|
||||
|
||||
#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 <sys/stat.h>
|
||||
|
||||
#include <kurl.h>
|
||||
#include <kio/global.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <kdebug.h>
|
||||
#include <QDebug>
|
||||
#include <QUrl>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#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 <kurl.h>
|
||||
#include "kio_recoll.h"
|
||||
bool RecollProtocol::isRecollResult(const KUrl &, int *, QString *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -22,11 +22,7 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <kdebug.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#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
|
||||
" <a href=\"recoll:///" +
|
||||
url_encode(string(m_parent->m_query.query.toUtf8())) +
|
||||
"/\">Directory view</a> (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<string> 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");
|
||||
|
||||
@ -21,16 +21,12 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
#include <qglobal.h>
|
||||
#include <qfile.h>
|
||||
#include <qtextstream.h>
|
||||
#include <qstring.h>
|
||||
|
||||
#include <kdebug.h>
|
||||
#include <kcomponentdata.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <QCoreApplication>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QUrlQuery>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#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<Rcl::Query>(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<DocSequence>(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;
|
||||
}
|
||||
|
||||
@ -18,20 +18,16 @@
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
using std::string;
|
||||
|
||||
#include <qglobal.h>
|
||||
#include <qstring.h>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
#include <kurl.h>
|
||||
#include <kio/global.h>
|
||||
#include <kio/slavebase.h>
|
||||
#include <kdeversion.h>
|
||||
|
||||
#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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user