/*************************************************************************** * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fieldlistview.h" namespace KBibTeX { FieldListView::FieldListView( const TQString& caption, const TQString& prefixNew, bool isReadOnly, TQWidget *parent, const char *name ) : TQWidget( parent, name ), m_value( new BibTeX::Value() ), m_caption( caption ), m_prefixNew( prefixNew ), m_isReadOnly( isReadOnly ), m_enabled( TRUE ), m_isComplex( FALSE ), m_isModified( FALSE ), m_newValueCounter( 0 ), m_fieldType( BibTeX::EntryField::ftUnknown ) { setupGUI(); m_listViewElements->installEventFilter( this ); m_listViewElements->renameLineEdit() ->installEventFilter( this ); m_value = new BibTeX::Value(); } FieldListView::~FieldListView() { delete m_value; } void FieldListView::setValue( const BibTeX::Value *value ) { if ( value != m_value ) { if ( m_value != NULL ) delete m_value; if ( value != NULL ) m_value = new BibTeX::Value( value ); else m_value = new BibTeX::Value( ); reset(); updateGUI(); m_isModified = FALSE; } } BibTeX::Value *FieldListView::value() { if ( m_value->items.isEmpty() ) return NULL; else return new BibTeX::Value( m_value ); } void FieldListView::setEnabled( bool enabled ) { m_enabled = enabled; updateGUI(); } void FieldListView::setFieldType( BibTeX::EntryField::FieldType fieldType ) { m_fieldType = fieldType; Settings * settings = Settings::self(); m_listViewElements->renameLineEdit() ->setCompletionObject( settings->completion( m_fieldType ) ); TQToolTip::add( m_listViewElements, TQString( i18n( "BibTeX field '%1'" ) ).arg( BibTeX::EntryField::fieldTypeToString( fieldType ) ) ); TQWhatsThis::add( m_listViewElements, TQString( i18n( "BibTeX field '%1'" ) ).arg( BibTeX::EntryField::fieldTypeToString( fieldType ) ) ); m_value->items.clear(); } TQString FieldListView::caption() { return m_caption; } bool FieldListView::isEmpty() { return m_value != NULL ? m_value->items.isEmpty() : TRUE; } bool FieldListView::isModified() { return m_isModified; } bool FieldListView::eventFilter( TQObject *o, TQEvent * e ) { if ( o == m_listViewElements->renameLineEdit() ) { if ( e->type() == TQEvent::Hide ) itemRenameDone(); } else if ( e->type() == TQEvent::AccelOverride ) { TQKeyEvent * ke = static_cast( e ); //override delete action if ( ke->key() == Key_Delete && ke->state() == NoButton ) { slotDelete(); ke->accept(); return true; } else if ( ke->key() == Key_F2 && ke->state() == NoButton ) { slotEdit(); ke->accept(); return true; } else if ( ke->key() == Key_A && ke->state() == ControlButton ) { slotAdd(); ke->accept(); return true; } else if ( ke->key() == Key_Up && ke->state() == ControlButton ) { slotUp(); ke->accept(); return true; } else if ( ke->key() == Key_Down && ke->state() == ControlButton ) { slotDown(); ke->accept(); return true; } else if ( ke->key() == Key_C && ke->state() == ( ControlButton | AltButton ) ) { slotComplex(); ke->accept(); return true; } } return false; } void FieldListView::updateGUI() { disconnect( m_checkBoxEtAl, SIGNAL( toggled( bool ) ), this, SLOT( apply() ) ); if ( m_value != NULL && !m_isComplex ) { bool isElementSelected = m_listViewElements->selectedItem() != NULL; m_pushButtonAdd->setEnabled( !m_isReadOnly ); m_pushButtonEdit->setEnabled( !m_isReadOnly && isElementSelected ); m_pushButtonDelete->setEnabled( !m_isReadOnly && isElementSelected ); m_pushButtonUp->setEnabled( !m_isReadOnly && isElementSelected && m_listViewElements->selectedItem() != m_listViewElements->firstChild() ); m_pushButtonDown->setEnabled( !m_isReadOnly && isElementSelected && m_listViewElements->selectedItem() != m_listViewElements->lastItem() ); m_listViewElements->setEnabled( !m_isReadOnly ); m_checkBoxEtAl->setEnabled( !m_isReadOnly ); } else { m_pushButtonAdd->setEnabled( FALSE ); m_pushButtonEdit->setEnabled( FALSE ); m_pushButtonDelete->setEnabled( FALSE ); m_pushButtonUp->setEnabled( FALSE ); m_pushButtonDown->setEnabled( FALSE ); m_listViewElements->setEnabled( FALSE ); m_checkBoxEtAl->setEnabled( FALSE ); } connect( m_checkBoxEtAl, SIGNAL( toggled( bool ) ), this, SLOT( apply() ) ); } void FieldListView::slotAdd() { if ( isSimple() ) { TDEListViewItem * item = new TDEListViewItem( m_listViewElements, m_listViewElements->lastItem(), TQString( "%1%2" ).arg( m_prefixNew ).arg( ++m_newValueCounter ) ); m_listViewElements->setSelected( item, TRUE ); updateGUI(); TQTimer::singleShot( 100, this, SLOT( slotEdit() ) ); } } void FieldListView::slotEdit() { if ( isSimple() ) { TDEListViewItem * item = static_cast( m_listViewElements->selectedItem() ); if ( item != NULL ) m_listViewElements->rename( item, 0 ); } } void FieldListView::slotDelete() { TQListViewItem * item = m_listViewElements->selectedItem(); if ( isSimple() && item != NULL ) { delete item; apply(); updateGUI(); m_isModified = TRUE; } } void FieldListView::slotUp() { TQListViewItem * item = m_listViewElements->selectedItem(); if ( isSimple() && !m_listViewElements->isRenaming() && item != NULL && item -> itemAbove() != NULL ) { item->itemAbove() ->moveItem( item ); apply(); updateGUI(); m_isModified = TRUE; } } void FieldListView::slotDown() { TQListViewItem * item = m_listViewElements->selectedItem(); if ( isSimple() && !m_listViewElements->isRenaming() && item != NULL && item -> itemBelow() != NULL ) { item->moveItem( item->itemBelow() ); apply(); updateGUI(); m_isModified = TRUE; } } void FieldListView::slotComplex() { if ( !m_listViewElements->isRenaming() && ValueWidget::execute( m_caption, m_fieldType, m_value, m_isReadOnly, this ) == TQDialog::Accepted ) { reset(); updateGUI(); m_isModified = TRUE; } } void FieldListView::slotListViewDoubleClicked( TQListViewItem * lvi ) { if ( lvi == NULL ) slotAdd(); } void FieldListView::slotItemRenamed( TQListViewItem * item, int /*col*/, const TQString & text ) { if ( text.isEmpty() && isSimple() && item != NULL ) { delete item; updateGUI(); } apply(); m_isModified = TRUE; } void FieldListView::setupGUI() { Settings * settings = Settings::self(); TQGridLayout * layout = new TQGridLayout( this, 8, 2, 0, KDialog::spacingHint() ); layout->setRowStretch( 5, 1 ); m_listViewElements = new TDEListView( this ); layout->addMultiCellWidget( m_listViewElements, 0, 6, 0, 0 ); m_listViewElements->renameLineEdit() ->setCompletionObject( settings->completion( m_fieldType ) ); m_listViewElements->renameLineEdit() ->setCompletionMode( TDEGlobalSettings::CompletionPopup ); m_listViewElements->renameLineEdit() ->completionObject() ->setIgnoreCase( true ); m_listViewElements->setDefaultRenameAction( TQListView::Accept ); m_listViewElements->addColumn( m_caption ); m_listViewElements->setSorting( -1, TRUE ); m_listViewElements->setItemsRenameable( TRUE ); if ( settings->editing_UseSpecialFont ) m_listViewElements->setFont( settings->editing_SpecialFont ); m_listViewElements->header() ->setFont( TDEGlobalSettings::generalFont() ); m_listViewElements->header() ->setClickEnabled( FALSE ); m_listViewElements->header() ->setStretchEnabled( TRUE, 0 ); connect( m_listViewElements, SIGNAL( selectionChanged() ), this, SLOT( updateGUI() ) ); connect( m_listViewElements, SIGNAL( clicked( TQListViewItem * ) ), this, SLOT( updateGUI() ) ); connect( m_listViewElements, SIGNAL( doubleClicked( TQListViewItem * ) ), this, SLOT( slotListViewDoubleClicked( TQListViewItem * ) ) ); connect( m_listViewElements, SIGNAL( currentChanged( TQListViewItem * ) ), this, SLOT( updateGUI() ) ); connect( m_listViewElements, SIGNAL( itemRenamed( TQListViewItem*, int, const TQString& ) ), this, SLOT( slotItemRenamed( TQListViewItem*, int, const TQString& ) ) ); m_pushButtonAdd = new TQPushButton( i18n( "Add" ), this ); layout->addWidget( m_pushButtonAdd, 0, 1 ); m_pushButtonAdd->setIconSet( TQIconSet( SmallIcon( "add" ) ) ); connect( m_pushButtonAdd, SIGNAL( clicked() ), this, SLOT( slotAdd() ) ); TQToolTip::add( m_pushButtonAdd, TQString( i18n( "Add new '%1' item (Ctrl+A)" ) ).arg( m_caption ) ); m_pushButtonEdit = new TQPushButton( i18n( "Edit" ), this ); layout->addWidget( m_pushButtonEdit, 1, 1 ); m_pushButtonEdit->setIconSet( TQIconSet( SmallIcon( "edit" ) ) ); connect( m_pushButtonEdit, SIGNAL( clicked() ), this, SLOT( slotEdit() ) ); TQToolTip::add( m_pushButtonEdit, TQString( i18n( "Edit current '%1' item (F2)" ) ).arg( m_caption ) ); m_pushButtonDelete = new TQPushButton( i18n( "Delete" ), this ); layout->addWidget( m_pushButtonDelete, 2, 1 ); m_pushButtonDelete->setIconSet( TQIconSet( SmallIcon( "editdelete" ) ) ); connect( m_pushButtonDelete, SIGNAL( clicked() ), this, SLOT( slotDelete() ) ); TQToolTip::add( m_pushButtonDelete, TQString( i18n( "Delete current '%1' item (Del)" ) ).arg( m_caption ) ); m_pushButtonUp = new TQPushButton( i18n( "Up" ), this ); layout->addWidget( m_pushButtonUp, 3, 1 ); m_pushButtonUp->setIconSet( TQIconSet( SmallIcon( "up" ) ) ); connect( m_pushButtonUp, SIGNAL( clicked() ), this, SLOT( slotUp() ) ); TQToolTip::add( m_pushButtonUp, TQString( i18n( "Move current '%1' item up (Ctrl+Up)" ) ).arg( m_caption ) ); m_pushButtonDown = new TQPushButton( i18n( "Down" ), this ); layout->addWidget( m_pushButtonDown, 4, 1 ); m_pushButtonDown->setIconSet( TQIconSet( SmallIcon( "down" ) ) ); connect( m_pushButtonDown, SIGNAL( clicked() ), this, SLOT( slotDown() ) ); TQToolTip::add( m_pushButtonDown, TQString( i18n( "Move current '%1' item down (Ctrl+Down)" ) ).arg( m_caption ) ); m_pushButtonComplexEdit = new TQPushButton( i18n( "Complex..." ), this ); layout->addWidget( m_pushButtonComplexEdit, 6, 1 ); m_pushButtonComplexEdit->setIconSet( TQIconSet( SmallIcon( "leftjust" ) ) ); connect( m_pushButtonComplexEdit, SIGNAL( clicked() ), this, SLOT( slotComplex() ) ); TQToolTip::add( m_pushButtonComplexEdit, TQString( i18n( "Edit current '%1' item as a concatenated string (Ctrl+Alt+C)" ) ).arg( m_caption ) ); m_checkBoxEtAl = new TQCheckBox( i18n( "... and others (et al.)" ), this ); layout->addMultiCellWidget( m_checkBoxEtAl, 7, 7, 0, 1 ); connect( m_checkBoxEtAl, SIGNAL( toggled( bool ) ), this, SLOT( apply() ) ); } void FieldListView::apply() { TQStringList elements; Settings * settings = Settings::self(); m_value->items.clear(); for ( TQListViewItemIterator it( m_listViewElements ); it.current(); it++ ) { TQString text = it.current() ->text( 0 ); elements.append( text ); } if ( elements.count() > 0 ) { m_value->items.clear(); BibTeX::PersonContainer *container = new BibTeX::PersonContainer( settings->editing_FirstNameFirst ); switch ( m_fieldType ) { case BibTeX::EntryField::ftAuthor: case BibTeX::EntryField::ftEditor: { for ( TQStringList::ConstIterator it = elements.constBegin(); it != elements.constEnd(); ++it ) { BibTeX::Person *person = new BibTeX::Person( *it, settings->editing_FirstNameFirst ); container->persons.append( person ); } } break; default: kdDebug() << "Don't know how to handle entries of type " << BibTeX::EntryField::fieldTypeToString( m_fieldType ) << endl; } if ( m_checkBoxEtAl->isChecked() ) container->persons.append( new BibTeX::Person( "others", settings->editing_FirstNameFirst ) ); if ( !container->persons.isEmpty() ) m_value->items.append( container ); else delete container; settings->addToCompletion( m_value, m_fieldType ); } } void FieldListView::reset() { disconnect( m_checkBoxEtAl, SIGNAL( toggled( bool ) ), this, SLOT( apply() ) ); m_listViewElements->clear(); m_checkBoxEtAl->setChecked( FALSE ); m_isComplex = FALSE; for ( TQValueList::ConstIterator it = m_value->items.constBegin(); !m_isComplex && it != m_value->items.constEnd(); ++it ) { BibTeX::MacroKey *macroKey = dynamic_cast( *it ); m_isComplex = macroKey != NULL; } if ( !m_isComplex ) switch ( m_fieldType ) { case BibTeX::EntryField::ftAuthor: case BibTeX::EntryField::ftEditor: { for ( TQValueList::ConstIterator it = m_value->items.constBegin(); it != m_value->items.constEnd(); ++it ) { BibTeX::PersonContainer *container = dynamic_cast( *it ); if ( container != NULL ) for ( TQValueList::ConstIterator pit = container->persons.constBegin(); pit != container->persons.constEnd(); ++pit ) { TQString text = ( *pit )->text(); if ( text == "others" ) m_checkBoxEtAl->setChecked( TRUE ); else new TQListViewItem( m_listViewElements, m_listViewElements->lastItem(), text ); } } } break; default: kdDebug() << "Don't know how to handle entries of type " << BibTeX::EntryField::fieldTypeToString( m_fieldType ) << endl; } connect( m_checkBoxEtAl, SIGNAL( toggled( bool ) ), this, SLOT( apply() ) ); } bool FieldListView::isSimple() { return m_value->items.count() == 0 || ( m_value->items.count() == 1 && dynamic_cast( m_value->items.first() ) == NULL ); } void FieldListView::itemRenameDone() { apply(); } } #include "fieldlistview.moc"