diff options
Diffstat (limited to 'src/webqueryz3950.cpp')
-rw-r--r-- | src/webqueryz3950.cpp | 397 |
1 files changed, 397 insertions, 0 deletions
diff --git a/src/webqueryz3950.cpp b/src/webqueryz3950.cpp new file mode 100644 index 0000000..1b62129 --- /dev/null +++ b/src/webqueryz3950.cpp @@ -0,0 +1,397 @@ +/*************************************************************************** + * Copyright (C) 2004-2009 by Thomas Fischer * + * [email protected] * + * * + * 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 <[email protected]> * + * Tellico is released under the GNU GPL 2, too. * + * http://www.periapsis.org/tellico/ * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <qfile.h> +#include <qapplication.h> +#include <qspinbox.h> +#include <qlayout.h> +#include <qlabel.h> + +#include <klocale.h> +#include <kstandarddirs.h> +#include <klineedit.h> +#include <kcombobox.h> +#include <kmessagebox.h> +#include <kpushbutton.h> +#include <kiconloader.h> +#include <kio/netaccess.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kurl.h> + +#include <fileimporterbibutils.h> +#include <settings.h> +#include "webqueryz3950.h" + +namespace KBibTeX +{ + const QString WebQueryZ3950Widget::attributesI18N[] = { i18n( "any" ), i18n( "title" ), i18n( "author" ), i18n( "publisher" )}; + + WebQueryZ3950Widget::WebQueryZ3950Widget( QWidget *parent, const char *name ) + : WebQueryWidget( parent, name ), lineEditQuery2( NULL ) + { + init(); + + Settings *settings = Settings::self(); + QString value = settings->getWebQueryDefault( "Z3950_server" ); + value = value == QString::null || value.isEmpty() ? "0" : value; + comboBoxServers->setCurrentItem( value.toInt() ); + value = settings->getWebQueryDefault( "Z3950_query1" ); + value = value == QString::null ? "" : value; + lineEditQuery->setText( value ); + slotTextChanged( value, true ); + value = settings->getWebQueryDefault( "Z3950_attr1" ); + value = value == QString::null ? "1" : value; + comboBoxInAttribute->setCurrentItem( value.toInt() ); + value = settings->getWebQueryDefault( "Z3950_query2" ); + lineEditQuery2->setText( value == QString::null ? "" : value ); + value = settings->getWebQueryDefault( "Z3950_attr2" ); + value = value == QString::null ? "1" : value; + comboBoxInAttribute2->setCurrentItem( value.toInt() ); + value = settings->getWebQueryDefault( "Z3950_booleanOp" ); + value = value == QString::null || value.isEmpty() ? "0" : value; + comboBoxBooleanOp->setCurrentItem( value.toInt() ); + } + + void WebQueryZ3950Widget::init() + { + QVBoxLayout *vLayout = new QVBoxLayout( this, 0, KDialog::spacingHint() ); + + QHBoxLayout *hLayout = new QHBoxLayout( ); + vLayout->addLayout( hLayout ); + + QLabel *label = new QLabel( 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 QLabel( i18n( "&Number of results:" ), this ); + hLayout->addWidget( label ); + hLayout->setStretchFactor( label, 1 ); + spinBoxMaxHits = new QSpinBox( 1, 50, 1, this ); + spinBoxMaxHits->setValue( 10 ); + hLayout->addWidget( spinBoxMaxHits ); + hLayout->setStretchFactor( spinBoxMaxHits, 3 ); + label->setBuddy( spinBoxMaxHits ); + + QGridLayout *layout = new QGridLayout( vLayout, 2, 6, KDialog::spacingHint() ); + + KPushButton *clearSearchText = new KPushButton( this ); + clearSearchText->setIconSet( QIconSet( SmallIcon( "locationbar_erase" ) ) ); + layout->addWidget( clearSearchText, 0, 1 ); + label = new QLabel( 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 QString& ) ), this, SLOT( slotTextChanged( const QString& ) ) ); + KCompletion *completionQuery = lineEditQuery->completionObject(); + connect( lineEditQuery, SIGNAL( returnPressed() ), this, SIGNAL( startSearch() ) ); + connect( lineEditQuery, SIGNAL( returnPressed( const QString& ) ), completionQuery, SLOT( addItem( const QString& ) ) ); + label = new QLabel( 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( QIconSet( SmallIcon( "locationbar_erase" ) ) ); + layout->addWidget( clearSearchText, 1, 1 ); + label = new QLabel( 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 QString& ) ), completionQuery, SLOT( addItem( const QString& ) ) ); + label = new QLabel( 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 ( QMap<QString, 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( QWidget* 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? + } + + QString WebQueryZ3950::title() + { + return i18n( "Z39.50" ); + } + + QString WebQueryZ3950::disclaimer() + { + return i18n( "Z39.50" ); + } + + QString 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", QString::number( m_widget->comboBoxServers->currentItem() ) ); + settings->setWebQueryDefault( "Z3950_query1", m_widget->lineEditQuery->text() ); + settings->setWebQueryDefault( "Z3950_attr1", QString::number( m_widget->comboBoxInAttribute->currentItem() ) ); + settings->setWebQueryDefault( "Z3950_query2", m_widget->lineEditQuery2->text() ); + settings->setWebQueryDefault( "Z3950_attr2", QString::number( m_widget->comboBoxInAttribute2->currentItem() ) ); + settings->setWebQueryDefault( "Z3950_booleanOp", QString::number( m_widget->comboBoxBooleanOp->currentItem() ) ); + +#ifdef HAVE_YAZ + + QString searchTerm = m_widget->lineEditQuery->text().stripWhiteSpace(); + if ( searchTerm.isEmpty() ) + { + setNumStages( 1 ); + setEndSearch( WebQuery::statusError ); + return; + } + + QString 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 ( QMap<QString, 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 + QString WebQueryZ3950::queryClause( const QString& text, int field ) + { + QString 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( QCustomEvent* 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, QString( 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 ); + } + } + + qApp->processEvents(); +#endif // HAVE_YAZ + } + +#ifdef HAVE_YAZ + void WebQueryZ3950::storeResult( const QString& resultText, const QString& syntax ) + { + if ( resultText.isEmpty() ) return; + QString convertedResultText = QString::null; + + if ( syntax == "mods" ) + convertedResultText = resultText; + else if ( syntax == "usmarc" || syntax == "marc21" ) + { + if ( m_marc21transformer == NULL ) m_marc21transformer = new BibTeX::XSLTransform( KGlobal::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( KGlobal::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 ( QStringList::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" |