/***************************************************************************
 *   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 <ntqlayout.h>
#include <ntqspinbox.h>
#include <ntqlabel.h>
#include <ntqcheckbox.h>
#include <ntqobjectlist.h>
#include <ntqscrollview.h>

#include <tdeglobalsettings.h>
#include <klineedit.h>
#include <tdepopupmenu.h>
#include <kcombobox.h>
#include <kpushbutton.h>
#include <kdialogbase.h>
#include <kiconloader.h>
#include <tdelocale.h>

#include <idsuggestions.h>
#include <fileimporter.h>
#include <fileimporterbibtex.h>
#include "idsuggestionswidget.h"

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

namespace KBibTeX
{
    TQString IdSuggestionsWidget::exampleBibTeXEntry = "@Article{ dijkstra1983terminationdetect,\nauthor = {Edsger W. Dijkstra and W. H. J. Feijen and A. J. M. {van Gasteren}},\ntitle = {{Derivation of a Termination Detection Algorithm for Distributed Computations}},\njournal = {Information Processing Letters},\nvolume = 16,\nnumber = 5,\npages = {217--219},\nmonth = jun,\nyear = 1983\n}";

    IdSuggestionComponent::IdSuggestionComponent( const TQString& title, TQWidget *parent ): TQFrame( parent ), m_toBeDeleted( false ), m_title( title ), m_parent( parent )
    {
        setFrameShape( TQFrame::Panel );
        setFrameShadow( TQFrame::Sunken );
        setLineWidth( 1 );
    }

    TQWidget *IdSuggestionComponent::moveWidgets( TQWidget *parent )
    {
        TQWidget *container = new TQWidget( parent );
        TQVBoxLayout *layout = new TQVBoxLayout( container, 0, KDialog::spacingHint() );
        m_pushButtonUp = new KPushButton( TQIconSet( SmallIcon( "up" ) ), i18n( "Up" ), container );
        m_pushButtonDown = new KPushButton( TQIconSet( SmallIcon( "down" ) ), i18n( "Down" ), container );
        m_pushButtonDel = new KPushButton( TQIconSet( SmallIcon( "remove" ) ), i18n( "Delete" ), container );
        layout->addWidget( m_pushButtonUp );
        layout->addWidget( m_pushButtonDown );
        layout->addWidget( m_pushButtonDel );
        layout->addStretch( 10 );
        connect( m_pushButtonUp, SIGNAL( clicked() ), this, SLOT( slotUp() ) );
        connect( m_pushButtonDown, SIGNAL( clicked() ), this, SLOT( slotDown() ) );
        connect( m_pushButtonDel, SIGNAL( clicked() ), this, SLOT( slotDelete() ) );
        return container;
    }

    void IdSuggestionComponent::setEnableUpDown( bool enableUp, bool enableDown )
    {
        m_pushButtonUp->setEnabled( enableUp );
        m_pushButtonDown->setEnabled( enableDown );
    }

    void IdSuggestionComponent::slotUp()
    {
        TQVBoxLayout *layout = dynamic_cast<TQVBoxLayout*>( m_parent->layout() );
        if ( layout == NULL ) return;
        int oldPos = layout->findWidget( this );
        if ( oldPos > 0 )
        {
            layout->remove( this );
            layout->insertWidget( oldPos - 1, this );
            emit moved();
        }
    }

    void IdSuggestionComponent::slotDown()
    {
        TQVBoxLayout *layout = dynamic_cast<TQVBoxLayout*>( m_parent->layout() );
        if ( layout == NULL ) return;
        int oldPos = layout->findWidget( this );
        int componentCount = dynamic_cast<IdSuggestionsWidget*>( m_parent->parent()->parent()->parent() )->numComponents();
        if ( oldPos < componentCount - 1 )
        {
            layout->remove( this );
            layout->insertWidget( oldPos + 1, this );
            emit moved();
        }
    }

    void IdSuggestionComponent::slotDelete()
    {
        m_toBeDeleted = true;
        emit deleted();
        delete this;
    }

    IdSuggestionComponentAuthor::IdSuggestionComponentAuthor( const TQString &text, TQWidget *parent ): IdSuggestionComponent( i18n( "Author" ), parent )
    {
        TQGridLayout *layout = new TQGridLayout( this, 6, 4, KDialog::marginHint(), KDialog::spacingHint() );

        TQLabel *label = new TQLabel( m_title, this );
        TQFont labelFont( label->font() );
        labelFont.setBold( TRUE );
        label->setFont( labelFont );
        label->setBackgroundColor( TDEGlobalSettings::highlightColor() );
        label->setPaletteForegroundColor( TDEGlobalSettings::highlightedTextColor() );
        label->setAlignment( TQt::AlignHCenter | TQt::AlignVCenter );
        layout->addMultiCellWidget( label, 0, 0, 0, 2 );

        m_comboBoxWhichAuthors = new KComboBox( false, this );
        layout->addMultiCellWidget( m_comboBoxWhichAuthors, 1, 1, 0, 1 );
        m_comboBoxWhichAuthors->insertItem( i18n( "All authors" ) );
        m_comboBoxWhichAuthors->insertItem( i18n( "First author only" ) );
        m_comboBoxWhichAuthors->insertItem( i18n( "All but first author" ) );
        switch ( text[0] )
        {
        case 'a': m_comboBoxWhichAuthors->setCurrentItem( 1 ); break;
        case 'z': m_comboBoxWhichAuthors->setCurrentItem( 2 ); break;
        default: m_comboBoxWhichAuthors->setCurrentItem( 0 );
        }
        connect( m_comboBoxWhichAuthors, SIGNAL( activated( const TQString& ) ), SIGNAL( modified() ) );

        struct IdSuggestionTokenInfo info = IdSuggestions::evalToken( text.mid( 1 ) );

        label = new TQLabel( i18n( "Casing:" ), this );
        layout->addWidget( label, 2, 0 );
        m_comboBoxCasing = new KComboBox( FALSE, this );
        label->setBuddy( m_comboBoxCasing );
        layout->addWidget( m_comboBoxCasing, 2, 1 );
        m_comboBoxCasing->insertItem( i18n( "No change" ) );
        m_comboBoxCasing->insertItem( i18n( "Lower case" ) );
        m_comboBoxCasing->insertItem( i18n( "Upper case" ) );
        if ( info.toLower )
            m_comboBoxCasing->setCurrentItem( 1 );
        else if ( info.toUpper )
            m_comboBoxCasing->setCurrentItem( 2 );
        else
            m_comboBoxCasing->setCurrentItem( 0 );
        connect( m_comboBoxCasing, SIGNAL( activated( const TQString& ) ), SIGNAL( modified() ) );

        label = new TQLabel( i18n( "Only first letters:" ), this );
        layout->addWidget( label, 3, 0 );
        m_spinBoxLen = new TQSpinBox( this );
        label->setBuddy( m_spinBoxLen );
        layout->addWidget( m_spinBoxLen, 3, 1 );
        m_spinBoxLen->setMinValue( 0 );
        m_spinBoxLen->setMaxValue( 9 );
        m_spinBoxLen->setSpecialValueText( i18n( "Complete name" ) );
        m_spinBoxLen->setValue( info.len > 9 ? 0 : info.len );
        m_spinBoxLen->setMinimumWidth( m_spinBoxLen->fontMetrics().width( i18n( "Complete name" ) ) + 32 );
        connect( m_spinBoxLen, SIGNAL( valueChanged( int ) ), SIGNAL( modified() ) );

        label = new TQLabel( i18n( "Text between authors:" ), this );
        layout->addWidget( label, 4, 0 );
        m_lineEditInBetween = new KLineEdit( this );
        label->setBuddy( m_lineEditInBetween );
        layout->addWidget( m_lineEditInBetween, 4, 1 );
        m_lineEditInBetween->setText( info.inBetween );
        connect( m_lineEditInBetween, SIGNAL( textChanged( const TQString& ) ), SIGNAL( modified() ) );

        layout->setRowStretch( 5, 1 );
        layout->setColStretch( 1, 1 );
        layout->setColSpacing( 2, KDialog::spacingHint() * 3 );
        layout->addMultiCellWidget( moveWidgets( this ), 0, 5, 3, 3 );
    }

    TQString IdSuggestionComponentAuthor::text() const
    {
        if ( m_toBeDeleted ) return TQString::null;

        TQString result;
        switch ( m_comboBoxWhichAuthors->currentItem() )
        {
        case 1: result = "a"; break;
        case 2: result = "z"; break;
        default: result = "A";
        }
        if ( m_spinBoxLen->value() > 0 && m_spinBoxLen->value() <= 9 ) result.append( TQString::number( m_spinBoxLen->value() ) );
        if ( m_comboBoxCasing->currentItem() == 1 ) result.append( "l" );
        else if ( m_comboBoxCasing->currentItem() == 2 ) result.append( "u" );
        if ( !m_lineEditInBetween->text().isEmpty() ) result.append( '"' ).append( m_lineEditInBetween->text() );

        return result;
    }

    IdSuggestionComponentTitle::IdSuggestionComponentTitle( const TQString &text, TQWidget *parent ): IdSuggestionComponent( i18n( "Title" ), parent )
    {
        TQGridLayout *layout = new TQGridLayout( this, 6, 4, KDialog::marginHint(), KDialog::spacingHint() );

        TQLabel *label = new TQLabel( m_title, this );
        TQFont labelFont( label->font() );
        labelFont.setBold( TRUE );
        label->setFont( labelFont );
        label->setBackgroundColor( TDEGlobalSettings::highlightColor() );
        label->setPaletteForegroundColor( TDEGlobalSettings::highlightedTextColor() );
        label->setAlignment( TQt::AlignHCenter | TQt::AlignVCenter );
        layout->addMultiCellWidget( label, 0, 0, 0, 2 );

        m_checkBoxRemoveSmallWords = new TQCheckBox( i18n( "Remove small words" ), this );
        layout->addMultiCellWidget( m_checkBoxRemoveSmallWords, 1, 1, 0, 1 );
        m_checkBoxRemoveSmallWords->setChecked( text[0] == 'T' );
        connect( m_checkBoxRemoveSmallWords, SIGNAL( toggled( bool ) ), SIGNAL( modified() ) );

        struct IdSuggestionTokenInfo info = IdSuggestions::evalToken( text.mid( 1 ) );

        label = new TQLabel( i18n( "Casing:" ), this );
        layout->addWidget( label, 2, 0 );
        m_comboBoxCasing = new KComboBox( FALSE, this );
        label->setBuddy( m_comboBoxCasing );
        layout->addWidget( m_comboBoxCasing, 2, 1 );
        m_comboBoxCasing->insertItem( i18n( "No change" ) );
        m_comboBoxCasing->insertItem( i18n( "Lower case" ) );
        m_comboBoxCasing->insertItem( i18n( "Upper case" ) );
        if ( info.toLower )
            m_comboBoxCasing->setCurrentItem( 1 );
        else if ( info.toUpper )
            m_comboBoxCasing->setCurrentItem( 2 );
        else
            m_comboBoxCasing->setCurrentItem( 0 );
        connect( m_comboBoxCasing, SIGNAL( textChanged( const TQString& ) ), SIGNAL( modified() ) );

        label = new TQLabel( i18n( "Only first letters:" ), this );
        layout->addWidget( label, 3, 0 );
        m_spinBoxLen = new TQSpinBox( this );
        label->setBuddy( m_spinBoxLen );
        layout->addWidget( m_spinBoxLen, 3, 1 );
        m_spinBoxLen->setMinValue( 0 );
        m_spinBoxLen->setMaxValue( 9 );
        m_spinBoxLen->setSpecialValueText( i18n( "Complete title" ) );
        m_spinBoxLen->setValue( info.len > 9 ? 0 : info.len );
        m_spinBoxLen->setMinimumWidth( m_spinBoxLen->fontMetrics().width( i18n( "Complete title" ) ) + 32 );
        connect( m_spinBoxLen, SIGNAL( valueChanged( int ) ), SIGNAL( modified() ) );

        label = new TQLabel( i18n( "Text between words:" ), this );
        layout->addWidget( label, 4, 0 );
        m_lineEditInBetween = new KLineEdit( this );
        label->setBuddy( m_lineEditInBetween );
        layout->addWidget( m_lineEditInBetween, 4, 1 );
        m_lineEditInBetween->setText( info.inBetween );
        connect( m_lineEditInBetween, SIGNAL( textChanged( const TQString& ) ), SIGNAL( modified() ) );

        layout->setRowStretch( 5, 1 );
        layout->setColStretch( 1, 1 );
        layout->setColSpacing( 2, KDialog::spacingHint() *2 );
        layout->addMultiCellWidget( moveWidgets( this ), 0, 5, 3, 3 );
    }

    TQString IdSuggestionComponentTitle::text() const
    {
        if ( m_toBeDeleted ) return TQString::null;

        TQString result = m_checkBoxRemoveSmallWords->isChecked() ? "T" : "t";
        if ( m_spinBoxLen->value() > 0 && m_spinBoxLen->value() <= 9 ) result.append( TQString::number( m_spinBoxLen->value() ) );
        if ( m_comboBoxCasing->currentItem() == 1 ) result.append( "l" );
        else if ( m_comboBoxCasing->currentItem() == 2 ) result.append( "u" );
        if ( !m_lineEditInBetween->text().isEmpty() ) result.append( '"' ).append( m_lineEditInBetween->text() );

        return result;
    }

    IdSuggestionComponentYear::IdSuggestionComponentYear( const TQString &text, TQWidget *parent ): IdSuggestionComponent( i18n( "Year" ), parent )
    {
        TQGridLayout *layout = new TQGridLayout( this, 3, 4, KDialog::marginHint(), KDialog::spacingHint() );

        TQLabel *label = new TQLabel( m_title, this );
        TQFont labelFont( label->font() );
        labelFont.setBold( TRUE );
        label->setFont( labelFont );
        label->setBackgroundColor( TDEGlobalSettings::highlightColor() );
        label->setPaletteForegroundColor( TDEGlobalSettings::highlightedTextColor() );
        label->setAlignment( TQt::AlignHCenter | TQt::AlignVCenter );
        layout->addMultiCellWidget( label, 0, 0, 0, 2 );

        label = new TQLabel( i18n( "Year:" ), this );
        layout->addWidget( label, 1, 0 );
        m_comboBoxDigits = new KComboBox( this );
        label->setBuddy( m_comboBoxDigits );
        layout->addWidget( m_comboBoxDigits, 1, 1 );
        m_comboBoxDigits->insertItem( i18n( "2 digits" ) );
        m_comboBoxDigits->insertItem( i18n( "4 digits" ) );
        m_comboBoxDigits->setCurrentItem( text[0] == 'y' ? 0 : 1 );
        connect( m_comboBoxDigits, SIGNAL( activated( int ) ), SIGNAL( modified() ) );

        layout->setColStretch( 1, 1 );
        layout->setRowStretch( 2, 1 );
        layout->setColSpacing( 2, KDialog::spacingHint() *2 );
        layout->addMultiCellWidget( moveWidgets( this ), 0, 2, 3, 3 );
    }

    TQString IdSuggestionComponentYear::text() const
    {
        if ( m_toBeDeleted ) return TQString::null;
        return m_comboBoxDigits->currentItem() == 0 ? "y" : "Y";
    }

    IdSuggestionComponentText::IdSuggestionComponentText( const TQString &text, TQWidget *parent ): IdSuggestionComponent( i18n( "Text" ), parent )
    {
        TQGridLayout *layout = new TQGridLayout( this, 3, 4, KDialog::marginHint(), KDialog::spacingHint() );

        TQLabel *label = new TQLabel( m_title, this );
        TQFont labelFont( label->font() );
        labelFont.setBold( TRUE );
        label->setFont( labelFont );
        label->setBackgroundColor( TDEGlobalSettings::highlightColor() );
        label->setPaletteForegroundColor( TDEGlobalSettings::highlightedTextColor() );
        label->setAlignment( TQt::AlignHCenter | TQt::AlignVCenter );
        layout->addMultiCellWidget( label, 0, 0, 0, 2 );

        label = new TQLabel( i18n( "Text in between:" ), this );
        layout->addWidget( label, 1, 0 );
        m_lineEditInBetween = new KLineEdit( this );
        label->setBuddy( m_lineEditInBetween );
        layout->addWidget( m_lineEditInBetween, 1, 1 );
        m_lineEditInBetween->setText( text.mid( 1 ) );
        connect( m_lineEditInBetween, SIGNAL( textChanged( const TQString& ) ), SIGNAL( modified() ) );

        layout->setColStretch( 1, 1 );
        layout->setRowStretch( 2, 1 );
        layout->setColSpacing( 2, KDialog::spacingHint() * 2 );
        layout->addMultiCellWidget( moveWidgets( this ), 0, 2, 3, 3 );
    }

    TQString IdSuggestionComponentText::text() const
    {
        if ( m_toBeDeleted ) return TQString::null;
        return m_lineEditInBetween->text().isEmpty() ? TQString::null : TQString( "\"" ).append( m_lineEditInBetween->text() );
    }

    IdSuggestionsScrollView::IdSuggestionsScrollView( TQWidget *parent, const char*name ): TQScrollView( parent, name ), m_widget( NULL )
    {
        setMinimumHeight( 256 );
        setHScrollBarMode( TQScrollView::AlwaysOff );
        setVScrollBarMode( TQScrollView::AlwaysOn );
        setLineWidth( 0 );
    }

    IdSuggestionsScrollView::~IdSuggestionsScrollView()
    {
        // nothing
    }

    void IdSuggestionsScrollView::viewportResizeEvent( TQResizeEvent * )
    {
        if ( m_widget != NULL )
            m_widget->setFixedWidth( viewport()->width() );
    }

    IdSuggestionsWidget::IdSuggestionsWidget( const TQString &formatStr, KDialogBase *parent, const char *name )
            : TQWidget( parent, name ), m_originalFormatStr( formatStr ), m_parent( parent )
    {
        BibTeX::FileImporter *importer = new BibTeX::FileImporterBibTeX( false );
        BibTeX::File *file = importer->load( exampleBibTeXEntry );
        m_example = new BibTeX::Entry( dynamic_cast<BibTeX::Entry*>( *( file->begin() ) ) );
        delete file;
        delete importer;

        setupGUI();
        reset( formatStr );
    }

    IdSuggestionsWidget::~IdSuggestionsWidget()
    {
        // nothing
    }

    int IdSuggestionsWidget::numComponents()
    {
        return m_componentCount;
    }

    TQDialog::DialogCode IdSuggestionsWidget::execute( TQString &formatStr, TQWidget *parent, const char *name )
    {
        KDialogBase * dlg = new KDialogBase( parent, name, true, i18n( "Edit Id Suggestions" ), KDialogBase::Ok | KDialogBase::Cancel );
        IdSuggestionsWidget* ui = new IdSuggestionsWidget( formatStr, dlg, "IdSuggestionsWidget" );
        dlg->setMainWidget( ui );

        TQDialog::DialogCode result = ( TQDialog::DialogCode ) dlg->exec();
        if ( result == TQDialog::Accepted )
            ui->apply( formatStr );

        delete( ui );
        delete( dlg );

        return result;
    }

    void IdSuggestionsWidget::reset( const TQString& formatStr )
    {
        TQLayoutIterator it = m_listOfComponents->layout()->iterator();
        TQLayoutItem *child;
        while (( child = it.current() ) != 0 )
        {
            IdSuggestionComponent *component = dynamic_cast<IdSuggestionComponent*>( child->widget() );
            ++it;
            if ( component != NULL )
                delete component;
        }

        m_componentCount = 0;
        TQStringList lines = TQStringList::split( '|', formatStr );
        for ( TQStringList::Iterator it = lines.begin(); it != lines.end();++it )
        {
            IdSuggestionComponent *component = NULL;
            if (( *it )[0] == 'a' || ( *it )[0] == 'A' )
                component = new IdSuggestionComponentAuthor( *it, m_listOfComponents );
            else if (( *it )[0] == 't' || ( *it )[0] == 'T' )
                component = new IdSuggestionComponentTitle( *it, m_listOfComponents );
            else if (( *it )[0] == 'y' || ( *it )[0] == 'Y' )
                component = new IdSuggestionComponentYear( *it, m_listOfComponents );
            else if (( *it )[0] == '"' )
                component = new IdSuggestionComponentText( *it, m_listOfComponents );

            if ( component != NULL )
            {
                ++m_componentCount;
                connect( component, SIGNAL( moved() ), this, SLOT( updateGUI() ) );
                connect( component, SIGNAL( deleted() ), this, SLOT( componentDeleted() ) );
                connect( component, SIGNAL( modified() ), this, SLOT( updateExample() ) );
            }
        }

        m_listOfComponents->adjustSize();
        m_scrollViewComponents->verticalScrollBar()->adjustSize();
        updateGUI();
        m_scrollViewComponents->resize( m_scrollViewComponents->width(), min( 384, m_listOfComponents->height() + 2 ) );
    }

    void IdSuggestionsWidget::apply( TQString& formatStr )
    {
        bool first = TRUE;
        formatStr = "";
        TQLayoutIterator it = m_listOfComponents->layout()->iterator();
        TQLayoutItem *child;
        while (( child = it.current() ) != 0 )
        {
            IdSuggestionComponent *component = dynamic_cast<IdSuggestionComponent*>( child->widget() );
            TQString text = TQString::null;
            if ( component != NULL && ( text = component->text() ) != TQString::null )
            {
                if ( first ) first = FALSE; else formatStr.append( "|" );
                formatStr.append( text );
            }
            ++it;
        }
    }

    void IdSuggestionsWidget::setupGUI()
    {
        TQGridLayout *gridLayout = new TQGridLayout( this, 3, 2, 0, KDialog::spacingHint() );
        gridLayout->setRowStretch( 2, 1 );
        gridLayout->setColStretch( 0, 1 );

        m_labelExample = new TQLabel( this );
        gridLayout->addMultiCellWidget( m_labelExample, 0, 1, 0, 0 );

        m_pushButtonAdd = new KPushButton( i18n( "Add" ), this );
        gridLayout->addWidget( m_pushButtonAdd, 1, 1 );

        m_scrollViewComponents = new IdSuggestionsScrollView( this );
        m_listOfComponents = new TQWidget( m_scrollViewComponents->viewport() );
        m_scrollViewComponents->setMainWidget( m_listOfComponents );
        m_scrollViewComponents->addChild( m_listOfComponents );
        gridLayout->addMultiCellWidget( m_scrollViewComponents, 2, 2, 0, 1 );
        TQVBoxLayout *listLayout = new TQVBoxLayout( m_listOfComponents, 0, KDialog::spacingHint() );
        listLayout->setAutoAdd( TRUE );

        TDEPopupMenu *addMenu = new TDEPopupMenu( m_pushButtonAdd );
        addMenu->insertItem( i18n( "Author" ), 1 );
        addMenu->insertItem( i18n( "Year" ), 2 );
        addMenu->insertItem( i18n( "Title" ), 3 );
        addMenu->insertItem( i18n( "Text" ), 4 );
        connect( addMenu, SIGNAL( activated( int ) ), this, SLOT( addMenuActivated( int ) ) );
        m_pushButtonAdd->setPopup( addMenu );
    }

    void IdSuggestionsWidget::addMenuActivated( int id )
    {
        IdSuggestionComponent *comp = NULL;
        if ( id == 1 )
            comp = new IdSuggestionComponentAuthor( "a", m_listOfComponents );
        else if ( id == 2 )
            comp = new IdSuggestionComponentYear( "y", m_listOfComponents );
        else if ( id == 3 )
            comp = new IdSuggestionComponentTitle( "t", m_listOfComponents );
        else if ( id == 4 )
            comp = new IdSuggestionComponentText( "", m_listOfComponents );

        if ( comp != NULL )
        {
            ++m_componentCount;

            comp->show();

            connect( comp, SIGNAL( moved() ), this, SLOT( updateGUI() ) );
            connect( comp, SIGNAL( deleted() ), this, SLOT( componentDeleted() ) );
            connect( comp, SIGNAL( modified() ), this, SLOT( updateExample() ) );
            m_listOfComponents->adjustSize();
            m_scrollViewComponents->ensureVisible( 10, m_listOfComponents->height() - 2 );
            updateGUI();
        }
    }

    void IdSuggestionsWidget::updateGUI()
    {
        TQLayoutIterator it = m_listOfComponents->layout()->iterator();
        TQLayoutItem *child = NULL;
        IdSuggestionComponent *lastComponent = NULL;
        bool first = TRUE;
        int i = 0;
        while (( child = it.current() ) != 0 )
        {
            IdSuggestionComponent *component = dynamic_cast<IdSuggestionComponent*>( child->widget() );
            ++it;
            if ( component != NULL )
            {
                if ( first )
                {
                    first = FALSE;
                    component->setEnableUpDown( FALSE, m_componentCount > 1 );
                }
                else
                    component->setEnableUpDown( TRUE, i < m_componentCount - 1 );

                ++i;
                lastComponent = component;
            }
        }

        if ( lastComponent != NULL )
            lastComponent->setEnableUpDown( m_componentCount > 1, FALSE );

        m_scrollViewComponents->updateGeometry();
        m_parent->enableButtonOK( m_componentCount > 0 );
        updateExample();
    }

    void IdSuggestionsWidget::componentDeleted()
    {
        --m_componentCount;
        updateGUI();
    }

    void IdSuggestionsWidget::updateExample()
    {
        TQString formatStr;
        apply( formatStr );
        TQString formatted = IdSuggestions::formatId( m_example, formatStr );
        m_labelExample->setText( TQString( i18n( "<qt>Example:<br/><b>%1</b></qt>" ) ).arg( formatted ) );
    }

}
#include "idsuggestionswidget.moc"