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.
tdebase/khelpcenter/searchhandler.cpp

250 lines
6.9 KiB

/*
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"