/*************************************************************************** * 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 * * Tellico is released under the GNU GPL 2, too. * * http://www.periapsis.org/tellico/ * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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::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::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( 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( 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( *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"