/***************************************************************************
*   Copyright (C) 2004-2009 by Thomas Fischer                             *
*   fischer@unix-ag.uni-kl.de                                             *
*                                                                         *
*   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.             *
***************************************************************************/
#include <tqtimer.h>
#include <tqheader.h>
#include <tqwidget.h>
#include <tqlayout.h>
#include <tqtooltip.h>
#include <tqframe.h>
#include <tqwidgetstack.h>
#include <tqlabel.h>
#include <tqcheckbox.h>
#include <tqspinbox.h>
#include <tqapplication.h>
#include <tqeventloop.h>
#include <tqbuffer.h>

#include <tdelocale.h>
#include <kcombobox.h>
#include <kiconloader.h>
#include <kdebug.h>
#include <kurllabel.h>
#include <klineedit.h>
#include <tdeapplication.h>
#include <kpushbutton.h>
#include <kprogress.h>
#include <kcompletion.h>
#include <tdemessagebox.h>
#include <tdeconfig.h>
#include <twin.h>

#include "settings.h"
#include "idsuggestions.h"
#include "entrywidget.h"
#include "webqueryarxiv.h"
#include "webquerybibsonomy.h"
#include "webquerycsb.h"
#include "webquerycitebase.h"
#include "webqueryciteseerx.h"
#include "webquerydblp.h"
#include "webquerygooglescholar.h"
#include "webqueryieeexplore.h"
#include "webquerymathscinet.h"
#include "webquerypubmed.h"
#include "webquerysciencedirect.h"
#include "webqueryspireshep.h"
#ifdef HAVE_YAZ
#include "webqueryz3950.h"
#endif // HAVE_YAZ
#include "webqueryzmath.h"
#include "webquery.h"

#define min(a,b) ((a)>(b)?(b):(a))

namespace KBibTeX
{
    WebQueryWidget::WebQueryWidget( TQWidget *parent, const char *name )
            : TQWidget( parent, name ), lineEditQuery( NULL ), spinBoxMaxHits( NULL )
    {
// nothing
    }

    bool WebQueryWidget::searchPossible()
    {
        return lineEditQuery != NULL && !lineEditQuery->text().stripWhiteSpace().replace( '$', "" ).isEmpty();
    }

    void WebQueryWidget::init()
    {
        TQVBoxLayout *vLayout = new TQVBoxLayout( this, 0, KDialog::spacingHint() );

        TQHBoxLayout *hLayout = new TQHBoxLayout( );
        vLayout->addLayout( hLayout );

        KPushButton *clearSearchText = new KPushButton( this );
        clearSearchText->setIconSet( TQIconSet( SmallIcon( "locationbar_erase" ) ) );
        hLayout->addWidget( clearSearchText );
        TQLabel *label = new TQLabel( i18n( "Search &term:" ), this );
        hLayout->addWidget( label );
        lineEditQuery = new KLineEdit( this );
        hLayout->addWidget( lineEditQuery );
        label->setBuddy( lineEditQuery );
        hLayout->addSpacing( KDialog::spacingHint() * 2 );
        connect( clearSearchText, SIGNAL( clicked() ), lineEditQuery, SLOT( clear() ) );
        connect( lineEditQuery, SIGNAL( textChanged( const TQString& ) ), this, SLOT( slotTextChanged( const TQString& ) ) );
        hLayout->setStretchFactor( lineEditQuery, 4 );
        TDECompletion *completionQuery = lineEditQuery->completionObject();

        label = new TQLabel( i18n( "&Number of results:" ), this );
        hLayout->addWidget( label );
        spinBoxMaxHits = new TQSpinBox( 1, 250, 1, this );
        spinBoxMaxHits->setValue( 10 );
        hLayout->addWidget( spinBoxMaxHits );
        label->setBuddy( spinBoxMaxHits );

        vLayout->addStretch( 0 );

        connect( lineEditQuery, SIGNAL( returnPressed() ), this, SIGNAL( startSearch() ) );
        connect( lineEditQuery, SIGNAL( returnPressed( const TQString& ) ), completionQuery, SLOT( addItem( const TQString& ) ) );
    }

    void WebQueryWidget::slotTextChanged( const TQString& text )
    {
        slotTextChanged( text, false );
    }

    void WebQueryWidget::slotTextChanged( const TQString& text, bool delayed )
    {
        bool doEnable = !text.stripWhiteSpace().replace( '$', "" ).isEmpty();
        if ( delayed && doEnable )
            TQTimer::singleShot( 100, this, SLOT( slotEnableSearchTrue() ) );
        else if ( !delayed )
            emit enableSearch( doEnable );
    }

    void WebQueryWidget::slotEnableSearchTrue()
    {
        emit enableSearch( true );
    }

    WebQuery::WebQuery( TQWidget *parent ): TQObject(), m_parent( parent ), m_progressDialog( NULL ), m_currentJob( NULL )
    {
// nothing
    }

    WebQuery::~WebQuery()
    {
        if ( m_progressDialog != NULL )
            delete m_progressDialog;
    }

    void WebQuery::query()
    {
        if ( m_progressDialog != NULL )
            delete m_progressDialog;
        m_aborted = false;
        m_progressDialog = new KProgressDialog( m_parent, "WebQuery_progressDialog", i18n( "Searching" ), TQString( i18n( "Searching %1" ) ).arg( title() ) );
        m_progressDialog->progressBar()->setMinimumWidth( 256 );
        m_progressDialog->setAutoClose( true );
        m_progressDialog->setMinimumDuration( 10 );
        m_progressDialog->setEnabled( true );
        connect( m_progressDialog, SIGNAL( cancelClicked() ), this, SLOT( slotCancelQuery() ) );
    }

    void WebQuery::cancelQuery()
    {
        // nothing
    }

    void WebQuery::slotCancelQuery()
    {
        m_aborted = true;
        cancelQuery();
    }

    void WebQuery::setEndSearch( WebQuery::Status status )
    {
        if ( m_progressDialog != NULL )
            m_progressDialog->hide();
        emit endSearch( status );
    }

    void WebQuery::setNumStages( int numStages )
    {
        m_currentStage = 0;
        m_numStages = numStages;
        m_progressDialog->progressBar()->setTotalSteps( m_numStages * 100 );
    }

    void WebQuery::enterNextStage()
    {
        ++m_currentStage;
        if ( m_progressDialog != NULL )
            m_progressDialog->progressBar()->setProgress( m_currentStage * 100 );
    }

    TQString WebQuery::download( const KURL& url )
    {
        TQString data = downloadHTML( url );
        if ( data == TQString::null )
            return TQString::null;

        /** post-processing */
        if ( data != TQString::null )
        {
            data.replace( TQRegExp( "</?(p|br)[^>]*>" ), "\n" );
            data.replace( TQRegExp( "</?[^>]*>" ), "" );
            data.replace( "@import", "" );/// JavaScript import?
        }

        return data;
    }

    TQString WebQuery::downloadHTML( const KURL& url )
    {
        if ( m_currentJob != NULL ) return TQString::null;

        tqDebug( "WebQuery::download( %s )", url.prettyURL().latin1() );

        m_incomingData = "";
        m_currentJobTotalSize = -1;
        m_currentJob = TDEIO::get( url, false, false );
        connect( m_currentJob, SIGNAL( totalSize( TDEIO::Job*, TDEIO::filesize_t ) ), this, SLOT( slotSetJobTotalSize( TDEIO::Job*, TDEIO::filesize_t ) ) );
        connect( m_currentJob, SIGNAL( processedSize( TDEIO::Job*, TDEIO::filesize_t ) ), this, SLOT( slotSetJobProcessedSize( TDEIO::Job*, TDEIO::filesize_t ) ) );
        connect( m_currentJob, SIGNAL( data( TDEIO::Job*, const TQByteArray & ) ), this, SLOT( slotJobData( TDEIO::Job*, const TQByteArray & ) ) );
        connect( m_currentJob, SIGNAL( result( TDEIO::Job* ) ), this, SLOT( slotJobFinished( TDEIO::Job* ) ) );

        tqApp->eventLoop()->enterLoop();

        return m_incomingData;
    }

    BibTeX::File *WebQuery::downloadBibTeXFile( const KURL& url, TQTextStream::Encoding encoding )
    {
        TQString data = download( url );
        if ( data == TQString::null )
            return NULL;

        BibTeX::FileImporterBibTeX importer( FALSE );
        importer.setIgnoreComments( TRUE );
        TQBuffer buffer;

        buffer.open( IO_WriteOnly );
        TQTextStream ts( &buffer );
        ts.setEncoding( encoding );
        ts << data << endl;
        buffer.close();

        buffer.open( IO_ReadOnly );
        BibTeX::File *result = importer.load( &buffer );
        buffer.close();

        return result;
    }

    void WebQuery::slotSetJobTotalSize( TDEIO::Job *job, TDEIO::filesize_t size )
    {
        if ( job != m_currentJob ) return;
        m_currentJobTotalSize = size;
    }

    void WebQuery::slotSetJobProcessedSize( TDEIO::Job *job, TDEIO::filesize_t size )
    {
        if ( job != m_currentJob ) return;
        if ( m_currentJobTotalSize <= 0 ) m_currentJobTotalSize = size;
        m_progressDialog->progressBar()->setProgress( m_currentStage * 100 + min( 100, size * 100 / m_currentJobTotalSize ) );
    }

    void WebQuery::slotJobData( TDEIO::Job *job, const TQByteArray &data )
    {
        if ( job != m_currentJob ) return;
        TQCString dataStr = TQCString( data, data.size() + 1 );
        if ( data.size() > 0 )
            m_incomingData.append( dataStr );
    }

    void WebQuery::slotJobFinished( TDEIO::Job *job )
    {
        if ( job != m_currentJob ) return;
        m_currentJob = NULL;
        if ( job->error() )
        {
            job->showErrorDialog();
            m_incomingData = TQString::null;
        }
        enterNextStage();
        tqApp->eventLoop()->exitLoop();
    }

    WebQueryWizard::WebQueryWizard( KDialogBase *dlg, const char* name ) : TQWidget( dlg, name ), m_dlg( dlg ), m_pushButtonSearch( NULL )
    {
        setupGUI( );

        Settings *settings = Settings::self( NULL );
        m_comboBoxEngines->setCurrentItem( settings->webQuery_LastEngine );
        otherEngineSelected( settings->webQuery_LastEngine );
        m_checkBoxImportAll->setChecked( settings->webQuery_ImportAll );
        m_pushButtonSearch->setEnabled( false );
    }

    WebQueryWizard::~WebQueryWizard()
    {
        TDEConfig * config = kapp->config();
        config->setGroup( "WebQueryWizard" );
        saveWindowSize( config );
    }

    void WebQueryWizard::showEvent( TQShowEvent * )
    {
        TDEConfig * config = kapp->config();
        config->setGroup( "WebQueryWizard" );
        restoreWindowSize( config );
    }

    int WebQueryWizard::execute( TQWidget *parent, TQValueList<BibTeX::Entry*> &results )
    {
        KDialogBase *dlg = new KDialogBase( parent, "WebQueryWizard", true, i18n( "Import" ), KDialogBase::Ok | KDialogBase::Cancel, ( KDialogBase::ButtonCode )0, true );
        WebQueryWizard *wiz = new WebQueryWizard( dlg, "WebQueryWizard" );
        dlg->setButtonOK( KGuiItem( i18n( "&Import" ), "import", i18n( "Import selected items" ) ) );
        dlg->setMainWidget( wiz );
        connect( wiz, SIGNAL( changeButtonOK( bool ) ), dlg, SLOT( enableButtonOK( bool ) ) );
        dlg->enableButtonOK( false );

        results.clear();
        int result = dlg->exec();
        if ( result == TQDialog::Accepted )
        {
            TQListViewItemIterator it = wiz->m_checkBoxImportAll->isChecked() ? TQListViewItemIterator( wiz->m_listViewResults ) : TQListViewItemIterator( wiz->m_listViewResults, TQListViewItemIterator::Selected );
            while ( it.current() )
            {
                ResultsListViewItem *item = dynamic_cast<ResultsListViewItem*>( it.current() );
                results.append( new BibTeX::Entry( item->entry() ) );
                ++it;
            }
        }

        Settings *settings = Settings::self( NULL );
        settings->webQuery_LastEngine = wiz->m_comboBoxEngines->currentItem();
        settings->webQuery_ImportAll = wiz->m_checkBoxImportAll->isChecked();

        delete dlg;

        return result;
    }

    void WebQueryWizard::previewEntry( TQListViewItem *item )
    {
        ResultsListViewItem *rlvi = dynamic_cast<ResultsListViewItem*>( item );
        if ( rlvi != NULL )
        {
            BibTeX::Entry *entry = rlvi->entry();
            KBibTeX::EntryWidget::execute( entry, NULL, TRUE, FALSE );
        }
    }

    void WebQueryWizard::importEnableChanging( )
    {
        TQListViewItemIterator it( m_listViewResults, TQListViewItemIterator::Selected );

        emit changeButtonOK(( m_checkBoxImportAll->isChecked() && m_listViewResults->childCount() > 0 ) || it.current() != NULL );
    }

    void WebQueryWizard::otherEngineSelected( int index )
    {
        if ( index < 0 || index >= ( int )m_webQueries.size() ) return;

        m_pushButtonSearch->setCaption( TQString( i18n( "Search %1" ) ).arg( m_webQueries[index]->title() ) );
        m_disclaimerLabel->setText( m_webQueries[index]->disclaimer() );
        m_disclaimerLabel->setURL( m_webQueries[index]->disclaimerURL() );
        TQToolTip::remove( m_disclaimerLabel );
        TQToolTip::add( m_disclaimerLabel, m_webQueries[index]->disclaimerURL() );
        m_widgetStackQueries->raiseWidget( m_webQueries[index]->widget() );
        m_pushButtonSearch->setEnabled( m_webQueries[index]->widget()->searchPossible() );
    }

    void WebQueryWizard::startSearch()
    {
        if ( !m_pushButtonSearch->isEnabled() )
        {
            kdDebug() << "WebQueryWizard::startSearch not enabled" << endl;
            return;
        }

        int index = m_comboBoxEngines->currentItem();

        setEnabled( FALSE );
        m_dlg->enableButtonCancel( FALSE );
        TQApplication::setOverrideCursor( TQt::waitCursor );
        m_listViewResults->clear();
        connect( m_webQueries[index], SIGNAL( foundEntry( BibTeX::Entry*, bool ) ), this, SLOT( addHit( BibTeX::Entry*, bool ) ) );
        connect( m_webQueries[index], SIGNAL( endSearch( WebQuery::Status ) ), this, SLOT( endSearch( WebQuery::Status ) ) );

        m_webQueries[index]->query();
    }

    void WebQueryWizard::endSearch( WebQuery::Status status )
    {
        int index = m_comboBoxEngines->currentItem();
        disconnect( m_webQueries[index], SIGNAL( foundEntry( BibTeX::Entry*, bool ) ), this, SLOT( addHit( BibTeX::Entry*, bool ) ) );
        disconnect( m_webQueries[index], SIGNAL( endSearch( WebQuery::Status ) ), this, SLOT( endSearch( WebQuery::Status ) ) );
        setEnabled( TRUE );
        m_dlg->enableButtonCancel( TRUE );
        importEnableChanging();
        TQApplication::restoreOverrideCursor();
        if ( status == WebQuery::statusInsufficientPermissions )
            KMessageBox::sorry( this, i18n( "You do not have the necessary permissions to query data from this service." ) );
    }

    void WebQueryWizard::addHit( BibTeX::Entry *entry, bool keepId )
    {
        Settings * settings = Settings::self();
        if ( !keepId && settings->idSuggestions_default >= 0 )
            entry->setId( IdSuggestions::createDefaultSuggestion( NULL, entry ) );
        new ResultsListViewItem( m_listViewResults, new BibTeX::Entry( entry ) );
    }

    void WebQueryWizard::enableSearch( bool enabled )
    {
        m_pushButtonSearch->setEnabled( enabled );
    }

    void WebQueryWizard::openURL( const TQString& url )
    {
        Settings::openUrl( KURL( url ), this );
    }

    void WebQueryWizard::setupGUI()
    {
        Settings * settings = Settings::self();
        setMinimumSize( 640, 384 );
        TQGridLayout *layout = new TQGridLayout( this, 5, 4, 0, KDialog::spacingHint() );
        layout->setColStretch( 2, 1 );
        layout->setRowStretch( 3, 1 );

        TQLabel *label = new TQLabel( i18n( "&Engine:" ), this );
        layout->addWidget( label, 0, 0 );
        m_comboBoxEngines = new KComboBox( FALSE, this );
        label->setBuddy( m_comboBoxEngines );
        layout->addWidget( m_comboBoxEngines, 0, 1 );
        connect( m_comboBoxEngines, SIGNAL( activated( int ) ), this, SLOT( otherEngineSelected( int ) ) );

        m_widgetStackQueries = new TQWidgetStack( this );
        layout->addMultiCellWidget( m_widgetStackQueries, 1, 2, 0, 2 );
        setupQueries();

        m_pushButtonSearch = new KPushButton( i18n( "&Search" ), this );
        layout->addWidget( m_pushButtonSearch, 0, 3 );
        m_pushButtonSearch->setIconSet( TQIconSet( SmallIcon( "edit-find" ) ) );
        m_pushButtonSearch->setEnabled( FALSE );

        m_listViewResults = new TDEListView( this );
        m_listViewResults->addColumn( i18n( "Year" ), 64 );
        m_listViewResults->addColumn( i18n( "Author" ), 128 );
        m_listViewResults->addColumn( i18n( "Title" ), 512 );
        if ( settings->editing_UseSpecialFont )
            m_listViewResults->setFont( settings->editing_SpecialFont );
        else
            m_listViewResults->setFont( TDEGlobalSettings::generalFont() );
        m_listViewResults->header() ->setFont( TDEGlobalSettings::generalFont() );
        m_listViewResults->setAllColumnsShowFocus( TRUE );
        m_listViewResults->setFullWidth( true );
        m_listViewResults->setSelectionMode( TQListView::Extended );
        layout->addMultiCellWidget( m_listViewResults, 3, 3, 0, 3 );
        connect( m_listViewResults, SIGNAL( executed( TQListViewItem* ) ), this, SLOT( previewEntry( TQListViewItem* ) ) );
        connect( m_listViewResults, SIGNAL( returnPressed( TQListViewItem* ) ), this, SLOT( previewEntry( TQListViewItem* ) ) );

        TQHBoxLayout *horizontalLayout = new TQHBoxLayout();
        layout->addMultiCellLayout( horizontalLayout, 4, 4, 0, 3 );
        m_disclaimerLabel = new KURLLabel( this );
        horizontalLayout->addWidget( m_disclaimerLabel );
        horizontalLayout->setStretchFactor( m_disclaimerLabel, 4 );
        m_checkBoxImportAll = new TQCheckBox( i18n( "Import all hits" ), this );
        m_checkBoxImportAll->setSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Minimum );
        horizontalLayout->addWidget( m_checkBoxImportAll );

        connect( m_disclaimerLabel, SIGNAL( leftClickedURL( const TQString& ) ), this, SLOT( openURL( const TQString& ) ) );
        connect( m_listViewResults, SIGNAL( selectionChanged( ) ), this, SLOT( importEnableChanging( ) ) );
        connect( m_listViewResults, SIGNAL( clicked( TQListViewItem* ) ), this, SLOT( importEnableChanging( ) ) );
        connect( m_checkBoxImportAll, SIGNAL( toggled( bool ) ), this, SLOT( importEnableChanging( ) ) );
        connect( m_pushButtonSearch, SIGNAL( clicked() ), this, SLOT( startSearch() ) );
    }

    void WebQueryWizard::setupQueries()
    {
        WebQuery *query = new WebQueryArXiv( this );
        m_webQueries.append( query );
        //         query = new WebQueryAmatex( this );
        //         m_webQueries.append( query );
        query = new WebQueryBibSonomy( this );
        m_webQueries.append( query );
        query = new WebQueryCitebase( this );
        m_webQueries.append( query );
        query = new WebQueryCiteSeerX( this );
        m_webQueries.append( query );
        query = new WebQueryCSB( this );
        m_webQueries.append( query );
        query = new WebQueryDBLP( this );
        m_webQueries.append( query );
        query = new WebQueryGoogleScholar( this );
        m_webQueries.append( query );
        query = new WebQueryIEEExplore( this );
        m_webQueries.append( query );
        query = new WebQueryMathSciNet( this );
        m_webQueries.append( query );
        query = new WebQueryPubMed( this );
        m_webQueries.append( query );
        query = new WebQueryScienceDirect( this );
        m_webQueries.append( query );
        query = new WebQuerySpiresHep( this );
        m_webQueries.append( query );
#ifdef HAVE_YAZ
        query = new WebQueryZ3950( this );
        m_webQueries.append( query );
#endif // HAVE_YAZ
        query = new WebQueryZMATH( this );
        m_webQueries.append( query );

        for ( TQValueList<WebQuery*>::Iterator it = m_webQueries.begin(); it != m_webQueries.end(); ++it )
        {
            m_comboBoxEngines->insertItem(( *it )->title() );
            m_widgetStackQueries->addWidget(( *it )->widget() );
            connect(( *it )->widget(), SIGNAL( enableSearch( bool ) ), this, SLOT( enableSearch( bool ) ) );
            connect(( *it )->widget(), SIGNAL( startSearch() ), this, SLOT( startSearch() ) );
        }
    }

    /* This function was taken form TDEMainWindow of KDE 3.5 and modified to fit KBibTeX */
    void WebQueryWizard::saveWindowSize( TDEConfig *config ) const
    {
        int scnum = TQApplication::desktop()->screenNumber( parentWidget() );
        TQRect desk = TQApplication::desktop()->screenGeometry( scnum );
        int w, h;
#if defined Q_WS_X11
        // save maximalization as desktop size + 1 in that direction
        KWin::WindowInfo info = KWin::windowInfo( m_dlg->winId(), NET::WMState );
        w = info.state() & NET::MaxHoriz ? desk.width() + 1 : m_dlg->width();
        h = info.state() & NET::MaxVert ? desk.height() + 1 : m_dlg->height();
#else
        if ( isMaximized() )
        {
            w = desk.width() + 1;
            h = desk.height() + 1;
        }
        //TODO: add "Maximized" property instead "+1" hack
#endif
        TQRect size( desk.width(), w, desk.height(), h );
        bool defaultSize = false;//( size == d->defaultWindowSize );
        TQString widthString = TQString::fromLatin1( "Width %1" ).arg( desk.width() );
        TQString heightString = TQString::fromLatin1( "Height %1" ).arg( desk.height() );
        if ( !config->hasDefault( widthString ) && defaultSize )
            config->revertToDefault( widthString );
        else
            config->writeEntry( widthString, w );

        if ( !config->hasDefault( heightString ) && defaultSize )
            config->revertToDefault( heightString );
        else
            config->writeEntry( heightString, h );
    }

    /* This function was taken form TDEMainWindow of KDE 3.5 and modified to fit KBibTeX */
    void WebQueryWizard::restoreWindowSize( TDEConfig *config )
    {
        // restore the size
        int scnum = TQApplication::desktop()->screenNumber( parentWidget() );
        TQRect desk = TQApplication::desktop()->screenGeometry( scnum );
        TQSize size( config->readNumEntry( TQString::fromLatin1( "Width %1" ).arg( desk.width() ), 0 ),
                    config->readNumEntry( TQString::fromLatin1( "Height %1" ).arg( desk.height() ), 0 ) );
        if ( size.isEmpty() )
        {
            // try the KDE 2.0 way
            size = TQSize( config->readNumEntry( TQString::fromLatin1( "Width" ), 0 ),
                          config->readNumEntry( TQString::fromLatin1( "Height" ), 0 ) );
            if ( !size.isEmpty() )
            {
                // make sure the other resolutions don't get old settings
                config->writeEntry( TQString::fromLatin1( "Width" ), 0 );
                config->writeEntry( TQString::fromLatin1( "Height" ), 0 );
            }
        }
        if ( !size.isEmpty() )
        {
#ifdef Q_WS_X11
            int state = ( size.width() > desk.width() ? NET::MaxHoriz : 0 )
                        | ( size.height() > desk.height() ? NET::MaxVert : 0 );
            if (( state & NET::Max ) == NET::Max )
                ; // no resize
            else if (( state & NET::MaxHoriz ) == NET::MaxHoriz )
                m_dlg->resize( width(), size.height() );
            else if (( state & NET::MaxVert ) == NET::MaxVert )
                m_dlg->resize( size.width(), height() );
            else
                m_dlg->resize( size );
            // TQWidget::showMaximized() is both insufficient and broken
            KWin::setState( m_dlg->winId(), state );
#else
            if ( size.width() > desk.width() || size.height() > desk.height() )
                m_dlg->setWindowState( WindowMaximized );
            else
                m_dlg->resize( size );
#endif
        }
    }

    ResultsListViewItem::ResultsListViewItem( TQListView * parent, BibTeX::Entry * entry ) : TQListViewItem( parent ), m_entry( entry )
    {
        BibTeX::EntryField * field = entry->getField( BibTeX::EntryField::ftTitle );
        if ( field != NULL && field->value() != NULL )
            setText( 2, field ->value() ->text().replace( '{', "" ).replace( '}', "" ).replace( '~', ' ' ) );
        field = entry->getField( BibTeX::EntryField::ftAuthor );
        if ( field != NULL && field->value() != NULL )
        {
            BibTeX::PersonContainer* personContainer = dynamic_cast<BibTeX::PersonContainer*>( field->value()->items.first() );
            if ( personContainer != NULL )
            {
                TQStringList authors;
                TQValueList<BibTeX::Person*> list = personContainer->persons;
                for ( TQValueList<BibTeX::Person*>::ConstIterator it = list.begin(); it != list.end(); ++it )
                    authors.append(( *it ) ->text() );
                setText( 1, authors.join( " and " ).replace( '{', "" ).replace( '}', "" ).replace( '~', ' ' ) );
            }
            else setText( 1, field ->value() ->text().replace( '{', "" ).replace( '}', "" ).replace( '~', ' ' ) );
        }
        field = entry->getField( BibTeX::EntryField::ftYear );
        if ( field != NULL && field->value() != NULL )
            setText( 0, field ->value() ->text().replace( '{', "" ).replace( '}', "" ).replace( '~', ' ' ) );
    }

    ResultsListViewItem::~ResultsListViewItem()
    {
        if ( m_entry != NULL )
            delete m_entry;
    }

    BibTeX::Entry* ResultsListViewItem::entry()
    {
        return m_entry;
    }

}
#include "webquery.moc"