You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
250 lines
6.9 KiB
250 lines
6.9 KiB
15 years ago
|
/*
|
||
|
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"
|