Logo Search packages:      
Sourcecode: kbibtex version File versions  Download package

entrywidget.cpp

/***************************************************************************
*   Copyright (C) 2004-2006 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 <qlayout.h>
#include <qcheckbox.h>
#include <qlistview.h>
#include <qlabel.h>
#include <qtabwidget.h>
#include <qcombobox.h>
#include <qtimer.h>
#include <qlineedit.h>

#include <kdialogbase.h>
#include <klocale.h>
#include <kmessagebox.h>

#include <file.h>
#include <settings.h>
#include <entrywidgettab.h>
#include <entrywidgettitle.h>
#include <entrywidgetauthor.h>
#include <entrywidgetpublication.h>
#include <entrywidgetmisc.h>
#include <entrywidgetexternal.h>
#include <entrywidgetuser.h>
#include <entrywidgetsource.h>
#include <entrywidgetwarningsitem.h>
#include "entrywidget.h"

namespace KBibTeX
{
    QDialog::DialogCode EntryWidget::execute( BibTeX::Entry *entry, BibTeX::File *bibtexfile, bool isReadOnly, QWidget *parent, const char *name )
    {
        EntryWidget * entryWidget = new EntryWidget( entry, bibtexfile, isReadOnly, parent, name );

        QDialog::DialogCode result = ( QDialog::DialogCode ) entryWidget->exec();

        delete( entryWidget );

        return result;
    }

    EntryWidget::EntryWidget( BibTeX::Entry *entry, BibTeX::File *bibtexfile, bool isReadOnly, QWidget *parent, const char *name )
            : KDialogBase( parent, name, TRUE, i18n( "Edit BibTeX Entry" ), KDialogBase::Ok | KDialogBase::Cancel ), m_originalEntry( entry ), m_bibtexfile( bibtexfile ), m_isReadOnly( isReadOnly ), m_lastPage( NULL )
    {
        m_internalEntry = new BibTeX::Entry( m_originalEntry );
        setupGUI();
        reset();
    }

    EntryWidget::~EntryWidget()
    {
        m_updateWarningsTimer->stop();
        delete m_updateWarningsTimer;

        delete m_internalEntry;
    }

    void EntryWidget::closeEvent( QCloseEvent * e )
    {
        bool isModified = m_lineEditID->isModified();

        for ( QValueList<KBibTeX::EntryWidgetTab*>::iterator it( m_internalEntryWidgets.begin() ); !isModified && it != m_internalEntryWidgets.end(); ++it )
            isModified = ( *it ) ->isModified();

        KGuiItem discardBtn = KGuiItem( i18n( "Discard" ), "editshred" );
        if ( isModified && KMessageBox::warningContinueCancel( this, i18n( "The current entry has been modified. Do you want do discard your changes?" ), i18n( "Discard changes" ), discardBtn ) == KMessageBox::Cancel )
            e->ignore();
        else
            e->accept();
    }

    void EntryWidget::apply()
    {
        if ( m_tabWidget->currentPage() == m_sourcePage )
            m_sourcePage->apply();
        else
        {
            for ( QValueList<KBibTeX::EntryWidgetTab*>::iterator it( m_internalEntryWidgets.begin() ); it != m_internalEntryWidgets.end(); ++it )
                ( *it ) ->apply();
            internalApply();

            Settings * settings = Settings::self();
            settings->addToCompletion( m_internalEntry );
        }

        m_originalEntry->copyFrom( m_internalEntry );
    }

    void EntryWidget::reset()
    {
        m_sourcePage->reset();
        for ( QValueList<KBibTeX::EntryWidgetTab*>::iterator it( m_internalEntryWidgets.begin() ); it != m_internalEntryWidgets.end(); ++it )
            ( *it ) ->reset();

        internalReset();

        Settings * settings = Settings::self();
        m_checkBoxEnableAll->setChecked( settings->editing_EnableAllFields );

        updateGUI();
    }

    void EntryWidget::slotEnableAllFields( )
    {
        updateGUI();
    }

    void EntryWidget::slotEntryTypeChanged( )
    {
        updateGUI();
    }

    void EntryWidget::slotCurrentPageChanged( QWidget* newPage )
    {
        if ( newPage == m_sourcePage )
        {
            // switching to source tab
            m_updateWarningsTimer->stop();
            internalApply();
            for ( QValueList<KBibTeX::EntryWidgetTab*>::iterator it( m_internalEntryWidgets.begin() ); it != m_internalEntryWidgets.end(); ++it )
                ( *it ) ->apply();
            m_sourcePage->reset();

            m_comboBoxEntryType->setEnabled( FALSE );
            m_lineEditID->setEnabled( FALSE );
        }
        else if ( m_lastPage == m_sourcePage )
        {
            // switching from source tab away
            m_sourcePage->apply();
            internalReset();
            for ( QValueList<KBibTeX::EntryWidgetTab*>::iterator it( m_internalEntryWidgets.begin() ); it != m_internalEntryWidgets.end(); ++it )
                ( *it ) ->reset();
            updateWarnings();

            m_comboBoxEntryType->setEnabled( TRUE );
            m_lineEditID->setEnabled( TRUE );
            m_updateWarningsTimer->start( 500 );
        }

        m_lastPage = newPage;
    }

    void EntryWidget::warningsExecute( QListViewItem* item )
    {
        EntryWidgetWarningsItem * ewwi = dynamic_cast<KBibTeX::EntryWidgetWarningsItem*>( item );
        if ( ewwi != NULL )
        {
            ewwi->widget() ->setFocus();
            // find and activate corresponding tab page
            QObject *parent = ewwi->widget();
            KBibTeX::EntryWidgetTab *ewt = dynamic_cast<KBibTeX::EntryWidgetTab*>( parent );
            while ( ewt == NULL && parent != NULL )
            {
                parent = parent->parent();
                ewt = dynamic_cast<KBibTeX::EntryWidgetTab*>( parent );
            }
            m_tabWidget->setCurrentPage( m_tabWidget-> indexOf( ewt ) );
        }
    }

    void EntryWidget::setupGUI()
    {
        QWidget * container = new QWidget( this, "container" );

        QGridLayout * layout = new QGridLayout( container, 4, 4, 0, KDialog::marginHint() );

        // in the top row on the left, put an entry type label and combobox
        QLabel *label = new QLabel( i18n( "E&ntry Type:" ), container );
        layout->addWidget( label, 0, 0 );
        m_comboBoxEntryType = new QComboBox( TRUE, container, "m_comboBoxEntryType" );
        label->setBuddy( m_comboBoxEntryType );
        m_comboBoxEntryType->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed );
        m_comboBoxEntryType->setEnabled( !m_isReadOnly );
        layout->addWidget( m_comboBoxEntryType, 0, 1 );
        setupEntryTypes();

        // in the top row on the left, put an identifier label and combobox
        label = new QLabel( i18n( "&Identifier" ), container );
        layout->addWidget( label, 0, 2 );
        m_lineEditID = new QLineEdit( container, "m_lineEditID" );
        label->setBuddy( m_lineEditID );
        m_lineEditID->setReadOnly( m_isReadOnly );
        m_lineEditID->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed );
        layout->addWidget( m_lineEditID, 0, 3 );

        // central tab widget for all the tabs
        m_tabWidget = new QTabWidget( container );
        layout->addMultiCellWidget( m_tabWidget, 1, 1, 0, 3 );
        addTabWidgets();

        // a check box if the user want to edit all fields
        m_checkBoxEnableAll = new QCheckBox( i18n( "Enable all &fields for editing" ), container );
        layout->addMultiCellWidget( m_checkBoxEnableAll, 2, 2, 0, 3 );

        // list view for warnings, errors and suggestions
        m_listViewWarnings = new QListView( container );
        //         m_listViewWarnings->addColumn( i18n( "Level" ) );
        m_listViewWarnings->addColumn( i18n( "Message" ) );
        m_listViewWarnings->setAllColumnsShowFocus( true );
        layout->addMultiCellWidget( m_listViewWarnings, 3, 3, 0, 3 );

        connect( m_checkBoxEnableAll, SIGNAL( toggled( bool ) ), this, SLOT( slotEnableAllFields( ) ) );
        connect( m_comboBoxEntryType, SIGNAL( activated( int ) ), this, SLOT( slotEntryTypeChanged( ) ) );
        connect( m_comboBoxEntryType, SIGNAL( textChanged( const QString & ) ), this, SLOT( slotEntryTypeChanged() ) );
        connect( m_listViewWarnings, SIGNAL( doubleClicked( QListViewItem*, const QPoint&, int ) ), this, SLOT( warningsExecute( QListViewItem* ) ) );
        connect( m_tabWidget, SIGNAL( currentChanged( QWidget* ) ), this, SLOT( slotCurrentPageChanged( QWidget* ) ) );
        connect( this, SIGNAL( okClicked() ), this, SLOT( apply() ) );

        setMainWidget( container );

        m_updateWarningsTimer = new QTimer( this );
        connect( m_updateWarningsTimer, SIGNAL( timeout() ), this, SLOT( updateWarnings() ) );
        m_updateWarningsTimer->start( 500 );
    }

    void EntryWidget::addTabWidgets()
    {
        addTabWidget( new KBibTeX::EntryWidgetTitle( m_internalEntry, m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetTitle" ), i18n( "Title" ) );
        addTabWidget( new KBibTeX::EntryWidgetAuthor( m_internalEntry, m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetAuthor" ), i18n( "Author/Editor" ) );
        addTabWidget( new KBibTeX::EntryWidgetPublication( m_internalEntry, m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetPublication" ), i18n( "Publication" ) );
        addTabWidget( new KBibTeX::EntryWidgetMisc( m_internalEntry, m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetMisc" ), i18n( "Misc" ) );
        addTabWidget( new KBibTeX::EntryWidgetExternal( m_internalEntry, m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetExternal" ), i18n( "External" ) );
        addTabWidget( new KBibTeX::EntryWidgetUser( m_internalEntry, m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetUser" ), i18n( "User Fields" ) );

        m_sourcePage = new KBibTeX::EntryWidgetSource( m_internalEntry, m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetSource" );
        m_tabWidget->insertTab( m_sourcePage, i18n( "Source" ) );
    }

    void EntryWidget::addTabWidget( EntryWidgetTab *widget, const QString& title )
    {
        m_tabWidget->insertTab( widget, title );
        m_internalEntryWidgets.append( widget );
    }

    BibTeX::Entry::EntryType EntryWidget::currentEntryType()
    {
        return BibTeX::Entry::entryTypeFromString( m_comboBoxEntryType->currentText() );
    }

    void EntryWidget::setupEntryTypes()
    {
        int i = ( int ) BibTeX::Entry::etArticle;
        BibTeX::Entry::EntryType entryType = ( BibTeX::Entry::EntryType ) i;
        while ( entryType != BibTeX::Entry::etUnknown )
        {
            QString currentString = BibTeX::Entry::entryTypeToString( entryType );
            m_comboBoxEntryType->insertItem( currentString );
            entryType = ( BibTeX::Entry::EntryType ) ++i;
        }
    }

    void EntryWidget::updateGUI()
    {
        for ( QValueList<KBibTeX::EntryWidgetTab*>::iterator it( m_internalEntryWidgets.begin() ); it != m_internalEntryWidgets.end(); ++it )
            ( *it ) ->updateGUI( currentEntryType(), m_checkBoxEnableAll->isChecked() );
        updateWarnings( );
    }

    void EntryWidget::updateWarnings()
    {
        m_listViewWarnings->clear();

        if ( m_lineEditID->text().isEmpty() )
            new KBibTeX::EntryWidgetWarningsItem( KBibTeX::EntryWidgetWarningsItem::wlError, i18n( "An entry has to have an identifier" ), m_lineEditID, m_listViewWarnings );

        for ( QValueList<KBibTeX::EntryWidgetTab*>::iterator it( m_internalEntryWidgets.begin() ); it != m_internalEntryWidgets.end(); ++it )
            ( *it ) ->updateWarnings( currentEntryType(), m_listViewWarnings );

        QString text = m_lineEditID->text();
        for ( unsigned int i = 0; i < text.length(); i++ )
            if ( text.at( i ).unicode() > 127 )
            {
                new KBibTeX::EntryWidgetWarningsItem( KBibTeX::EntryWidgetWarningsItem::wlWarning, QString( i18n( "The identifier contains non-ascii characters, first one is ‘%1’" ) ).arg( text.at( i ) ) , m_lineEditID, m_listViewWarnings );
                break;
            }
    }

    void EntryWidget::internalApply()
    {
        m_internalEntry->setId( m_lineEditID->text() );
        BibTeX::Entry::EntryType entryType = currentEntryType();
        if ( entryType == BibTeX::Entry::etUnknown )
            m_internalEntry->setEntryTypeString( m_comboBoxEntryType->currentText() );
        else
            m_internalEntry->setEntryType( entryType );
    }

    void EntryWidget::internalReset()
    {
        m_lineEditID->setText( m_internalEntry->id() );
        bool foundEntryType = FALSE;
        for ( int i = 0; !foundEntryType && i < m_comboBoxEntryType->count(); i++ )
            if ( ( BibTeX::Entry::EntryType ) i + BibTeX::Entry::etArticle == m_internalEntry->entryType() )
            {
                m_comboBoxEntryType->setCurrentItem( i );
                foundEntryType = TRUE;
            }
        if ( !foundEntryType )
            m_comboBoxEntryType->setCurrentText( m_internalEntry->entryTypeString() );
    }
}
#include "entrywidget.moc"

Generated by  Doxygen 1.6.0   Back to index