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.
kbibtex/src/webqueryz3950.cpp

398 lines
16 KiB

/***************************************************************************
* Copyright (C) 2004-2009 by Thomas Fischer *
* fischer@unix-ag.uni-kl.de *
* *
* based on code from or inspired by *
* - Tellico by Robby Stephenson *
* - kbib by Thach Nguyen *
* *
* 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., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
* *
* This code is based on code from Tellico 1.2.10 *
* by Robby Stephenson <robby@periapsis.org> *
* Tellico is released under the GNU GPL 2, too. *
* http://www.periapsis.org/tellico/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <tqfile.h>
#include <tqapplication.h>
#include <tqspinbox.h>
#include <tqlayout.h>
#include <tqlabel.h>
#include <tdelocale.h>
#include <kstandarddirs.h>
#include <klineedit.h>
#include <kcombobox.h>
#include <tdemessagebox.h>
#include <kpushbutton.h>
#include <kiconloader.h>
#include <tdeio/netaccess.h>
#include <tdeapplication.h>
#include <kdebug.h>
#include <kurl.h>
#include "fileimporterbibutils.h"
#include "settings.h"
#include "webqueryz3950.h"
namespace KBibTeX
{
const TQString WebQueryZ3950Widget::attributesI18N[] = { i18n( "any" ), i18n( "title" ), i18n( "author" ), i18n( "publisher" )};
WebQueryZ3950Widget::WebQueryZ3950Widget( TQWidget *parent, const char *name )
: WebQueryWidget( parent, name ), lineEditQuery2( NULL )
{
init();
Settings *settings = Settings::self();
TQString value = settings->getWebQueryDefault( "Z3950_server" );
value = value == TQString::null || value.isEmpty() ? "0" : value;
comboBoxServers->setCurrentItem( value.toInt() );
value = settings->getWebQueryDefault( "Z3950_query1" );
value = value == TQString::null ? "" : value;
lineEditQuery->setText( value );
slotTextChanged( value, true );
value = settings->getWebQueryDefault( "Z3950_attr1" );
value = value == TQString::null ? "1" : value;
comboBoxInAttribute->setCurrentItem( value.toInt() );
value = settings->getWebQueryDefault( "Z3950_query2" );
lineEditQuery2->setText( value == TQString::null ? "" : value );
value = settings->getWebQueryDefault( "Z3950_attr2" );
value = value == TQString::null ? "1" : value;
comboBoxInAttribute2->setCurrentItem( value.toInt() );
value = settings->getWebQueryDefault( "Z3950_booleanOp" );
value = value == TQString::null || value.isEmpty() ? "0" : value;
comboBoxBooleanOp->setCurrentItem( value.toInt() );
}
void WebQueryZ3950Widget::init()
{
TQVBoxLayout *vLayout = new TQVBoxLayout( this, 0, KDialog::spacingHint() );
TQHBoxLayout *hLayout = new TQHBoxLayout( );
vLayout->addLayout( hLayout );
TQLabel *label = new TQLabel( i18n( "Server:" ), this );
hLayout->setStretchFactor( label, 1 );
hLayout->addWidget( label );
comboBoxServers = new KComboBox( false, this );
hLayout->addWidget( comboBoxServers );
hLayout->setStretchFactor( comboBoxServers, 7 );
label->setBuddy( comboBoxServers );
hLayout->addSpacing( KDialog::spacingHint() * 2 );
label = new TQLabel( i18n( "&Number of results:" ), this );
hLayout->addWidget( label );
hLayout->setStretchFactor( label, 1 );
spinBoxMaxHits = new TQSpinBox( 1, 50, 1, this );
spinBoxMaxHits->setValue( 10 );
hLayout->addWidget( spinBoxMaxHits );
hLayout->setStretchFactor( spinBoxMaxHits, 3 );
label->setBuddy( spinBoxMaxHits );
TQGridLayout *layout = new TQGridLayout( vLayout, 2, 6, KDialog::spacingHint() );
KPushButton *clearSearchText = new KPushButton( this );
clearSearchText->setIconSet( TQIconSet( SmallIcon( "locationbar_erase" ) ) );
layout->addWidget( clearSearchText, 0, 1 );
label = new TQLabel( i18n( "Search term 1:" ), this );
layout->addWidget( label, 0, 2 );
lineEditQuery = new KLineEdit( this );
layout->addWidget( lineEditQuery, 0, 3 );
label->setBuddy( lineEditQuery );
connect( clearSearchText, SIGNAL( clicked() ), lineEditQuery, SLOT( clear() ) );
connect( lineEditQuery, SIGNAL( textChanged( const TQString& ) ), this, SLOT( slotTextChanged( const TQString& ) ) );
TDECompletion *completionQuery = lineEditQuery->completionObject();
connect( lineEditQuery, SIGNAL( returnPressed() ), this, SIGNAL( startSearch() ) );
connect( lineEditQuery, SIGNAL( returnPressed( const TQString& ) ), completionQuery, SLOT( addItem( const TQString& ) ) );
label = new TQLabel( i18n( "Search in:" ), this );
layout->addWidget( label, 0, 4 );
comboBoxInAttribute = new KComboBox( false, this );
layout->addWidget( comboBoxInAttribute, 0, 5 );
label->setBuddy( comboBoxInAttribute );
comboBoxBooleanOp = new KComboBox( false, this );
layout->addWidget( comboBoxBooleanOp, 1, 0 );
clearSearchText = new KPushButton( this );
clearSearchText->setIconSet( TQIconSet( SmallIcon( "locationbar_erase" ) ) );
layout->addWidget( clearSearchText, 1, 1 );
label = new TQLabel( i18n( "Search term 2:" ), this );
layout->addWidget( label, 1, 2 );
lineEditQuery2 = new KLineEdit( this );
layout->addWidget( lineEditQuery2, 1, 3 );
label->setBuddy( lineEditQuery2 );
connect( clearSearchText, SIGNAL( clicked() ), lineEditQuery2, SLOT( clear() ) );
completionQuery = lineEditQuery->completionObject();
connect( lineEditQuery2, SIGNAL( returnPressed() ), this, SIGNAL( startSearch() ) );
connect( lineEditQuery2, SIGNAL( returnPressed( const TQString& ) ), completionQuery, SLOT( addItem( const TQString& ) ) );
label = new TQLabel( i18n( "Search in:" ), this );
layout->addWidget( label, 1, 4 );
comboBoxInAttribute2 = new KComboBox( false, this );
layout->addWidget( comboBoxInAttribute2, 1, 5 );
label->setBuddy( comboBoxInAttribute2 );
#ifdef HAVE_YAZ
Settings *settings = Settings::self();
for ( TQMap<TQString, Settings::Z3950Server>::Iterator it = settings->z3950_ServerList.begin(); it != settings->z3950_ServerList.end(); ++it )
comboBoxServers->insertItem( it.data().name );
#endif // HAVE_YAZ
for ( unsigned int i = 0; i < sizeof( attributesI18N ) / sizeof( attributesI18N[0] ); ++i )
{
comboBoxInAttribute->insertItem( attributesI18N[i] );
comboBoxInAttribute2->insertItem( attributesI18N[i] );
}
comboBoxBooleanOp->insertItem( i18n( "and" ) );
comboBoxBooleanOp->insertItem( i18n( "or" ) );
}
WebQueryZ3950::WebQueryZ3950( TQWidget* parent ) : WebQuery( parent )
#ifdef HAVE_YAZ
, m_marc21transformer( NULL ), m_unimarctransformer( NULL ), m_modsImporter( NULL ), m_conn( NULL )
#endif // HAVE_YAZ
{
m_widget = new WebQueryZ3950Widget( parent );
}
WebQueryZ3950::~WebQueryZ3950()
{
#ifdef HAVE_YAZ
if ( m_modsImporter != NULL ) delete m_modsImporter;
if ( m_marc21transformer != NULL ) delete m_marc21transformer;
if ( m_unimarctransformer != NULL ) delete m_unimarctransformer;
if ( m_conn != NULL ) delete m_conn;
#endif // HAVE_YAZ
// delete m_widget; FIXME Why does delete fail here?
}
TQString WebQueryZ3950::title()
{
return i18n( "Z39.50" );
}
TQString WebQueryZ3950::disclaimer()
{
return i18n( "Z39.50" );
}
TQString WebQueryZ3950::disclaimerURL()
{
return "http://[127.0.0.1]/";
}
WebQueryWidget *WebQueryZ3950::widget()
{
return m_widget;
}
void WebQueryZ3950::query()
{
WebQuery::query();
Settings *settings = Settings::self();
settings->setWebQueryDefault( "Z3950_server", TQString::number( m_widget->comboBoxServers->currentItem() ) );
settings->setWebQueryDefault( "Z3950_query1", m_widget->lineEditQuery->text() );
settings->setWebQueryDefault( "Z3950_attr1", TQString::number( m_widget->comboBoxInAttribute->currentItem() ) );
settings->setWebQueryDefault( "Z3950_query2", m_widget->lineEditQuery2->text() );
settings->setWebQueryDefault( "Z3950_attr2", TQString::number( m_widget->comboBoxInAttribute2->currentItem() ) );
settings->setWebQueryDefault( "Z3950_booleanOp", TQString::number( m_widget->comboBoxBooleanOp->currentItem() ) );
#ifdef HAVE_YAZ
TQString searchTerm = m_widget->lineEditQuery->text().stripWhiteSpace();
if ( searchTerm.isEmpty() )
{
setNumStages( 1 );
setEndSearch( WebQuery::statusError );
return;
}
TQString query = queryClause( searchTerm, m_widget->comboBoxInAttribute->currentItem() );
searchTerm = m_widget->lineEditQuery2->text().stripWhiteSpace();
if ( !searchTerm.isEmpty() )
{
if ( m_widget->comboBoxBooleanOp->currentItem() == 0 )
query = query.prepend( "@and " );
else
query = query.prepend( "@or " );
query = query.append( queryClause( searchTerm, m_widget->comboBoxInAttribute2->currentItem() ) );
}
kdDebug() << "query = " << query << endl;
m_conn = NULL;
settings = Settings::self();
for ( TQMap<TQString, Settings::Z3950Server>::Iterator it = settings->z3950_ServerList.begin(); m_conn == NULL && it != settings->z3950_ServerList.end(); ++it )
{
if ( it.data().name.compare( m_widget->comboBoxServers->currentText() ) == 0 )
{
m_syntax = it.data().syntax;
m_conn = new KBibTeX::Z3950Connection( this, it.data().host, it.data().port, it.data().database, it.data().charset, m_syntax, "f" );
m_conn->setUserPassword( it.data().user, it.data().password );
}
}
if ( m_conn != NULL )
{
setNumStages( m_widget->spinBoxMaxHits->value() );
m_started = true;
m_conn->setQuery( query, m_widget->spinBoxMaxHits->value() );
m_modsList.clear();
m_hitCounter = 0;
m_conn->start();
kdDebug() << "WebQueryZ3950::query: started" << endl;
}
else
#else // HAVE_YAZ
kdDebug() << "HAVE_YAZ not defined" << endl;
#endif // HAVE_YAZ
{
setNumStages( 1 );
setEndSearch( WebQuery::statusSuccess );
}
}
void WebQueryZ3950::cancelQuery()
{
#ifdef HAVE_YAZ
if ( m_started && m_conn != NULL )
{
m_started = false;
m_conn->abort();
m_conn->wait( 10000 );
setEndSearch( WebQuery::statusError );
}
#endif // HAVE_YAZ
}
#ifdef HAVE_YAZ
TQString WebQueryZ3950::queryClause( const TQString& text, int field )
{
TQString result = "@attr 1=";
switch ( field )
{
case 1: result.append( "4" ); break;
case 2: result.append( "1003" ); break;
case 3: result.append( "1006" ); break;
case 4: result.append( "1016" ); break;
default: result.append( "1018" ); break;
}
result.append( " @attr 2=3 \"" ).append( text ).append( "\" " );
return result;
}
#endif // HAVE_YAZ
void WebQueryZ3950::customEvent( TQCustomEvent* event )
{
kdDebug() << "WebQueryZ3950::customEvent of type " << event->type() << endl;
#ifdef HAVE_YAZ
if ( !m_conn )
{
return;
}
if ( event->type() == KBibTeX::Z3950ResultFound::uid() )
{
KBibTeX::Z3950ResultFound* e = static_cast<KBibTeX::Z3950ResultFound*>( event );
kdDebug() << "Z3950ResultFound: " << e->result().left( 24 ) << " [..] " << e->result().right( 24 ) << endl;
storeResult( e->result(), m_syntax );
m_hitCounter++;
enterNextStage();
}
else if ( event->type() == KBibTeX::Z3950ConnectionDone::uid() )
{
KBibTeX::Z3950ConnectionDone* e = static_cast<KBibTeX::Z3950ConnectionDone*>( event );
kdDebug() << "Z3950ConnectionDone: " << e->message() << " (" << e->messageType() << ")" << endl;
if ( e->messageType() > -1 )
KMessageBox::error( m_widget, TQString( i18n( "The server returned the following message:\n\n%1" ) ).arg( e->message() ), i18n( "Error querying Z39.50 server" ) );
m_started = false;
if ( m_conn != NULL )
m_conn->wait();
if ( !m_aborted )
{
evalStoredResults();
setEndSearch( e->messageType() > -1 ? WebQuery::statusError : WebQuery::statusSuccess );
}
}
tqApp->processEvents();
#endif // HAVE_YAZ
}
#ifdef HAVE_YAZ
void WebQueryZ3950::storeResult( const TQString& resultText, const TQString& syntax )
{
if ( resultText.isEmpty() ) return;
TQString convertedResultText = TQString::null;
if ( syntax == "mods" )
convertedResultText = resultText;
else if ( syntax == "usmarc" || syntax == "marc21" )
{
if ( m_marc21transformer == NULL ) m_marc21transformer = new BibTeX::XSLTransform( TDEGlobal::dirs()->findResource( "data", "kbibtexpart/xslt/MARC21slim2MODS3.xsl" ) );
convertedResultText = m_marc21transformer->transform( resultText );
}
else if ( syntax == "unimarc" )
{
if ( m_unimarctransformer == NULL ) m_unimarctransformer = new BibTeX::XSLTransform( TDEGlobal::dirs()->findResource( "data", "kbibtexpart/xslt/UNIMARC2MODS3.xsl" ) );
convertedResultText = m_unimarctransformer->transform( resultText );
}
m_modsList.append( convertedResultText );
}
void WebQueryZ3950::evalStoredResults()
{
if ( m_modsImporter == NULL )
m_modsImporter = new BibTeX::FileImporterBibUtils( BibTeX::File::formatMODS );
for ( TQStringList::Iterator it = m_modsList.begin(); it != m_modsList.end();++it )
{
BibTeX::File *bibtexFile = m_modsImporter->load( *it );
if ( bibtexFile != NULL )
{
for ( BibTeX::File::ElementList::iterator it = bibtexFile->begin(); it != bibtexFile->end(); ++it )
{
BibTeX::Entry *entry = dynamic_cast<BibTeX::Entry*>( *it );
if ( entry != NULL )
{
BibTeX::Entry *newEntry = new BibTeX::Entry( entry );
kdDebug() << "entry= " << newEntry->text() << endl;
emit foundEntry( newEntry, false );
}
}
delete bibtexFile;
}
}
}
#endif // HAVE_YAZ
}
#include "webqueryz3950.moc"