summaryrefslogtreecommitdiffstats
path: root/khelpcenter/searchhandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'khelpcenter/searchhandler.cpp')
-rw-r--r--khelpcenter/searchhandler.cpp249
1 files changed, 249 insertions, 0 deletions
diff --git a/khelpcenter/searchhandler.cpp b/khelpcenter/searchhandler.cpp
new file mode 100644
index 000000000..a25d2fe49
--- /dev/null
+++ b/khelpcenter/searchhandler.cpp
@@ -0,0 +1,249 @@
+/*
+ This file is part of KHelpCenter.
+
+ Copyright (c) 2005 Cornelius Schumacher <schumacher@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "searchhandler.h"
+
+#include "searchengine.h"
+#include "prefs.h"
+#include "docentry.h"
+
+#include <kdesktopfile.h>
+#include <kprocess.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+#include <stdlib.h>
+
+using namespace KHC;
+
+SearchHandler::SearchHandler()
+{
+ mLang = KGlobal::locale()->language().left( 2 );
+}
+
+SearchHandler *SearchHandler::initFromFile( const QString &filename )
+{
+ SearchHandler *handler = new SearchHandler;
+
+ KDesktopFile file( filename );
+
+ handler->mSearchCommand = file.readEntry( "SearchCommand" );
+ handler->mSearchUrl = file.readEntry( "SearchUrl" );
+ handler->mIndexCommand = file.readEntry( "IndexCommand" );
+ handler->mDocumentTypes = file.readListEntry( "DocumentTypes" );
+
+ return handler;
+}
+
+QStringList SearchHandler::documentTypes() const
+{
+ return mDocumentTypes;
+}
+
+QString SearchHandler::indexCommand( const QString &identifier )
+{
+ QString cmd = mIndexCommand;
+ cmd.replace( "%i", identifier );
+ cmd.replace( "%d", Prefs::indexDirectory() );
+ cmd.replace( "%l", mLang );
+ return cmd;
+}
+
+bool SearchHandler::checkPaths() const
+{
+ if ( !mSearchCommand.isEmpty() && !checkBinary( mSearchCommand ) )
+ return false;
+
+ if ( !mIndexCommand.isEmpty() && !checkBinary( mIndexCommand ) )
+ return false;
+
+ return true;
+}
+
+bool SearchHandler::checkBinary( const QString &cmd ) const
+{
+ QString binary;
+
+ int pos = cmd.find( ' ' );
+ if ( pos < 0 ) binary = cmd;
+ else binary = cmd.left( pos );
+
+ return !KStandardDirs::findExe( binary ).isEmpty();
+}
+
+void SearchHandler::search( DocEntry *entry, const QStringList &words,
+ int maxResults,
+ SearchEngine::Operation operation )
+{
+ kdDebug() << "SearchHandler::search(): " << entry->identifier() << endl;
+
+ if ( !mSearchCommand.isEmpty() ) {
+ QString cmdString = SearchEngine::substituteSearchQuery( mSearchCommand,
+ entry->identifier(), words, maxResults, operation, mLang );
+
+ kdDebug() << "SearchHandler::search() CMD: " << cmdString << endl;
+
+ KProcess *proc = new KProcess();
+
+ QStringList cmd = QStringList::split( " ", cmdString );
+ QStringList::ConstIterator it;
+ for( it = cmd.begin(); it != cmd.end(); ++it ) {
+ QString arg = *it;
+ if ( arg.left( 1 ) == "\"" && arg.right( 1 ) =="\"" ) {
+ arg = arg.mid( 1, arg.length() - 2 );
+ }
+ *proc << arg.utf8();
+ }
+
+ connect( proc, SIGNAL( receivedStdout( KProcess *, char *, int ) ),
+ SLOT( searchStdout( KProcess *, char *, int ) ) );
+ connect( proc, SIGNAL( receivedStderr( KProcess *, char *, int ) ),
+ SLOT( searchStderr( KProcess *, char *, int ) ) );
+ connect( proc, SIGNAL( processExited( KProcess * ) ),
+ SLOT( searchExited( KProcess * ) ) );
+
+ SearchJob *searchJob = new SearchJob;
+ searchJob->mEntry = entry;
+ searchJob->mProcess = proc;
+ searchJob->mCmd = cmdString;
+
+ mProcessJobs.insert( proc, searchJob );
+
+ if ( !proc->start( KProcess::NotifyOnExit, KProcess::All ) ) {
+ QString txt = i18n("Error executing search command '%1'.").arg( cmdString );
+ emit searchFinished( this, entry, txt );
+ }
+ } else if ( !mSearchUrl.isEmpty() ) {
+ QString urlString = SearchEngine::substituteSearchQuery( mSearchUrl,
+ entry->identifier(), words, maxResults, operation, mLang );
+
+ kdDebug() << "SearchHandler::search() URL: " << urlString << endl;
+
+ KIO::TransferJob *job = KIO::get( KURL( urlString ) );
+ connect( job, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotJobResult( KIO::Job * ) ) );
+ connect( job, SIGNAL( data( KIO::Job *, const QByteArray & ) ),
+ SLOT( slotJobData( KIO::Job *, const QByteArray & ) ) );
+
+ SearchJob *searchJob = new SearchJob;
+ searchJob->mEntry = entry;
+ searchJob->mKioJob = job;
+ mKioJobs.insert( job, searchJob );
+ } else {
+ QString txt = i18n("No search command or URL specified.");
+ emit searchFinished( this, entry, txt );
+ return;
+ }
+}
+
+void SearchHandler::searchStdout( KProcess *proc, char *buffer, int len )
+{
+ if ( !buffer || len == 0 )
+ return;
+
+ QString bufferStr;
+ char *p;
+ p = (char*) malloc( sizeof(char) * ( len + 1 ) );
+ p = strncpy( p, buffer, len );
+ p[len] = '\0';
+
+ QMap<KProcess *, SearchJob *>::ConstIterator it = mProcessJobs.find( proc );
+ if ( it != mProcessJobs.end() ) {
+ (*it)->mResult += bufferStr.fromUtf8( p );
+ }
+
+ free( p );
+}
+
+void SearchHandler::searchStderr( KProcess *proc, char *buffer, int len )
+{
+ if ( !buffer || len == 0 )
+ return;
+
+ QMap<KProcess *, SearchJob *>::ConstIterator it = mProcessJobs.find( proc );
+ if ( it != mProcessJobs.end() ) {
+ (*it)->mError += QString::fromUtf8( buffer, len );
+ }
+}
+
+void SearchHandler::searchExited( KProcess *proc )
+{
+// kdDebug() << "SearchHandler::searchExited()" << endl;
+
+ QString result;
+ QString error;
+ DocEntry *entry = 0;
+
+ QMap<KProcess *, SearchJob *>::ConstIterator it = mProcessJobs.find( proc );
+ if ( it != mProcessJobs.end() ) {
+ SearchJob *j = *it;
+ entry = j->mEntry;
+ result = j->mResult;
+ error = "<em>" + j->mCmd + "</em>\n" + j->mError;
+
+ mProcessJobs.remove( proc );
+ delete j;
+ } else {
+ kdError() << "No search job for exited process found." << endl;
+ }
+
+ if ( proc->normalExit() && proc->exitStatus() == 0 ) {
+ emit searchFinished( this, entry, result );
+ } else {
+ emit searchError( this, entry, error );
+ }
+}
+
+void SearchHandler::slotJobResult( KIO::Job *job )
+{
+ QString result;
+ DocEntry *entry = 0;
+
+ QMap<KIO::Job *, SearchJob *>::ConstIterator it = mKioJobs.find( job );
+ if ( it != mKioJobs.end() ) {
+ SearchJob *j = *it;
+
+ entry = j->mEntry;
+ result = j->mResult;
+
+ mKioJobs.remove( job );
+ delete j;
+ }
+
+ if ( job->error() ) {
+ emit searchError( this, entry, i18n("Error: %1").arg( job->errorString() ) );
+ } else {
+ emit searchFinished( this, entry, result );
+ }
+}
+
+void SearchHandler::slotJobData( KIO::Job *job, const QByteArray &data )
+{
+// kdDebug() << "SearchHandler::slotJobData()" << endl;
+
+ QMap<KIO::Job *, SearchJob *>::ConstIterator it = mKioJobs.find( job );
+ if ( it != mKioJobs.end() ) {
+ (*it)->mResult += data.data();
+ }
+}
+
+#include "searchhandler.moc"