/*************************************************************************** * 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 #include #include #include "mergeelements.h" namespace KBibTeX { MergeElementsCliqueItem::MergeElementsCliqueItem( BibTeX::Entry* _entry, BibTeX::Macro* _macro, BibTeX::Preamble* _preamble, TQListView *parent ) : TQCheckListItem( parent, _entry == NULL ?( _macro == NULL ? _preamble->value()->text() : _macro->key() ) : _entry->id(), TQCheckListItem::CheckBox ), entry( _entry ), macro( _macro ), preamble( _preamble ) { // nothing } void MergeElementsCliqueItem::stateChange( bool ) { emit stateChanged( this ); }; MergeEntriesAlternativesController::MergeEntriesAlternativesController( const TQString &label, TQListView *parent ) : TQCheckListItem( parent, label, TQCheckListItem::RadioButtonController ), fieldType( BibTeX::EntryField::ftUnknown ), fieldName( label ) { // nothing } MergeEntriesAlternativesController::MergeEntriesAlternativesController( BibTeX::EntryField::FieldType _fieldType, TQListView *parent ) : TQCheckListItem( parent, BibTeX::EntryField::fieldTypeToString( _fieldType ), TQCheckListItem::RadioButtonController ), fieldType( _fieldType ), fieldName( BibTeX::EntryField::fieldTypeToString( _fieldType ) ) { // nothing } MergeMacrosAlternativesController::MergeMacrosAlternativesController( bool isKey, TQListView *parent ) : TQCheckListItem( parent, isKey ? i18n( "Key" ) : i18n( "Value" ), TQCheckListItem::RadioButtonController ) { // nothing } MergeEntriesAlternativesItem::MergeEntriesAlternativesItem( BibTeX::EntryField *_field, MergeEntriesAlternativesController *parent ) : TQCheckListItem( parent, _field->value()->text(), TQCheckListItem::RadioButton ), field( _field ) { // nothing } MergeMacrosAlternativesItem::MergeMacrosAlternativesItem( BibTeX::Value *_value, MergeMacrosAlternativesController *parent ) : TQCheckListItem( parent, _value->text(), TQCheckListItem::RadioButton ), value( _value ) { // nothing } MergeElementsAlternativesId::MergeElementsAlternativesId( const TQString & _id, MergeEntriesAlternativesController *parent ) : TQCheckListItem( parent, _id, TQCheckListItem::RadioButton ), id( _id ) { // nothing } MergeMacroAlternativesKey::MergeMacroAlternativesKey( const TQString & _key, MergeMacrosAlternativesController *parent ) : TQCheckListItem( parent, _key, TQCheckListItem::RadioButton ), key( _key ) { // nothing } MergeEntriesAlternativesEntryType::MergeEntriesAlternativesEntryType( const TQString & _typeString, MergeEntriesAlternativesController *parent ) : TQCheckListItem( parent, _typeString, TQCheckListItem::RadioButton ), typeString( _typeString ), type( BibTeX::Entry::entryTypeFromString( _typeString ) ) { // nothing } MergeEntriesAlternativesEntryType::MergeEntriesAlternativesEntryType( BibTeX::Entry::EntryType _type, MergeEntriesAlternativesController *parent ) : TQCheckListItem( parent, BibTeX::Entry::entryTypeToString( _type ), TQCheckListItem::RadioButton ), typeString( BibTeX::Entry::entryTypeToString( _type ) ), type( _type ) { // nothing } MergePreambleAlternativesController::MergePreambleAlternativesController( TQListView *parent ) : TQCheckListItem( parent, i18n( "Preamble text" ), TQCheckListItem::RadioButtonController ) { // nothing } MergePreambleAlternatives::MergePreambleAlternatives( const TQString &_text, MergePreambleAlternativesController *parent ) :TQCheckListItem( parent, _text, TQCheckListItem::RadioButton ), text( _text ) { // nothing } MergeElements::MergeElements( TQWidget *parent ) : KDialogBase( parent, "MergeElements", true, "undefined", Ok | Cancel | User1 | User2, User1, true, KGuiItem( i18n( "Next" ), "next" ), KGuiItem( i18n( "Previous" ), "previous" ) ), m_currentCliqueIndex( 0 ) { setupGUI(); } MergeElements::~MergeElements() { TDEConfig * config = kapp->config(); config->setGroup( "MergeElements" ); saveWindowSize( config ); } void MergeElements::setupGUI() { TQWidget *vboxContainer = new TQWidget( this ); setMainWidget( vboxContainer ); TQBoxLayout *vboxLayout = new TQVBoxLayout( vboxContainer, 0, KDialog::spacingHint() ); vboxLayout->setResizeMode( TQLayout::Minimum ); TQLabel *label = new TQLabel( i18n( "Select elements to merge. At least two elements must be checked to perform a merge operation. Checked entries will be replaced by the merged element, unchecked elements will be kept." ), vboxContainer ); label->setAlignment( TQt::WordBreak ); vboxLayout->addWidget( label ); m_listViewClique = new TDEListView( vboxContainer ); m_listViewClique->addColumn( i18n( "Entry/Macro Id" ) ); m_listViewClique->setFullWidth( true ); m_listViewClique->setAllColumnsShowFocus( true ); vboxLayout->addWidget( m_listViewClique ); vboxLayout->setStretchFactor( m_listViewClique, 1 ); label->setBuddy( m_listViewClique ); m_progressBar = new TQProgressBar( vboxContainer ); vboxLayout->addWidget( m_progressBar ); vboxLayout->addSpacing( KDialog::spacingHint() * 2 ); label = new TQLabel( i18n( "Choose from this list which alternatives you want to keep in the merged element." ), vboxContainer ); label->setAlignment( TQt::WordBreak ); vboxLayout->addWidget( label ); m_listViewAlternatives = new TDEListView( vboxContainer ); m_listViewAlternatives->addColumn( i18n( "Field/Key" ) ); m_listViewAlternatives->setFullWidth( true ); m_listViewAlternatives->setAllColumnsShowFocus( true ); vboxLayout->addWidget( m_listViewAlternatives ); vboxLayout->setStretchFactor( m_listViewAlternatives, 3 ); label->setBuddy( m_listViewAlternatives ); connect( m_listViewClique, SIGNAL( doubleClicked( TQListViewItem * ) ), this, SLOT( slotPreviewElement( TQListViewItem * ) ) ); connect( this, SIGNAL( user1Clicked() ), this, SLOT( slotNextClique() ) ); connect( this, SIGNAL( user2Clicked() ), this, SLOT( slotPreviousClique() ) ); connect( this, SIGNAL( okClicked() ), this, SLOT( saveCurrentMergeSet() ) ); } void MergeElements::setClique( int cliqueIndex ) { if ( m_currentCliqueIndex != cliqueIndex ) saveCurrentMergeSet(); m_currentCliqueIndex = cliqueIndex; m_listViewClique->clear(); FindDuplicates::DuplicateClique clique = m_duplicateCliqueList[cliqueIndex]; for ( FindDuplicates::DuplicateClique::Iterator it = clique.begin(); it != clique.end(); ++it ) { BibTeX::Entry *entry = dynamic_cast( *it ); if ( entry != NULL ) { MergeElementsCliqueItem *item = new MergeElementsCliqueItem( entry, NULL, NULL, m_listViewClique ); connect( item, SIGNAL( stateChanged( MergeElementsCliqueItem* ) ), this, SLOT( slotRefreshAlternatives() ) ); } else { BibTeX::Macro *macro = dynamic_cast( *it ); if ( macro != NULL ) { MergeElementsCliqueItem *item = new MergeElementsCliqueItem( NULL, macro, NULL, m_listViewClique ); connect( item, SIGNAL( stateChanged( MergeElementsCliqueItem* ) ), this, SLOT( slotRefreshAlternatives() ) ); } else { BibTeX::Preamble *preamble = dynamic_cast( *it ); if ( preamble!=NULL ) { MergeElementsCliqueItem *item = new MergeElementsCliqueItem( NULL, NULL, preamble, m_listViewClique ); connect( item, SIGNAL( stateChanged( MergeElementsCliqueItem* ) ), this, SLOT( slotRefreshAlternatives() ) ); } } } } restoreCurrentMergeSet(); enableButton( User1, ( cliqueIndex < ( int )( m_duplicateCliqueList.size() ) - 1 ) && m_duplicateCliqueList.size() > 1 ); enableButton( User2, cliqueIndex > 0 && m_duplicateCliqueList.size() > 1 ); m_progressBar->setProgress( cliqueIndex, m_duplicateCliqueList.size() - 1 ); } void MergeElements::saveCurrentMergeSet() { if ( m_mergeSetList[m_currentCliqueIndex] == NULL ) m_mergeSetList[m_currentCliqueIndex] = new MergeSet; else { m_mergeSetList[m_currentCliqueIndex]->entries.clear(); m_mergeSetList[m_currentCliqueIndex]->fields.clear(); } m_mergeSetList[m_currentCliqueIndex]->type = BibTeX::Entry::etUnknown; m_mergeSetList[m_currentCliqueIndex]->typeString = TQString::null; m_mergeSetList[m_currentCliqueIndex]->id = TQString::null; m_mergeSetList[m_currentCliqueIndex]->macroKey = TQString::null; m_mergeSetList[m_currentCliqueIndex]->macroValue = NULL; m_mergeSetList[m_currentCliqueIndex]->preambleText=TQString::null; for ( TQListViewItemIterator it( m_listViewClique, TQListViewItemIterator::Checked ); it.current(); ++it ) { MergeElementsCliqueItem *eci = dynamic_cast( *it ); BibTeX::Entry *entry = eci->entry; if ( entry != NULL ) m_mergeSetList[m_currentCliqueIndex]->entries.append( entry ); BibTeX::Macro *macro = eci->macro; if ( macro != NULL ) m_mergeSetList[m_currentCliqueIndex]->macros.append( macro ); BibTeX::Preamble *preamble = eci->preamble; if ( preamble !=NULL ) m_mergeSetList[m_currentCliqueIndex]->preambles.append( preamble ); } for ( TQListViewItemIterator it( m_listViewAlternatives, TQListViewItemIterator::Checked ); it.current(); ++it ) { MergeEntriesAlternativesItem *item = dynamic_cast( *it ); if ( item != NULL ) { BibTeX::EntryField *field = item->field; m_mergeSetList[m_currentCliqueIndex]->fields.append( field ); } else { MergeElementsAlternativesId *item = dynamic_cast( *it ); if ( item != NULL ) m_mergeSetList[m_currentCliqueIndex]->id = item->id; else { MergeEntriesAlternativesEntryType *itemT = dynamic_cast( *it ); if ( itemT != NULL ) { m_mergeSetList[m_currentCliqueIndex]->typeString = itemT->typeString; m_mergeSetList[m_currentCliqueIndex]->type = itemT->type; } else { MergeMacroAlternativesKey *itemK = dynamic_cast( *it ); if ( itemK != NULL ) m_mergeSetList[m_currentCliqueIndex]->macroKey = itemK->key; else { MergeMacrosAlternativesItem *itemMA = dynamic_cast( *it ); if ( itemMA != NULL ) m_mergeSetList[m_currentCliqueIndex]->macroValue = itemMA->value; else { MergePreambleAlternatives *itemP=dynamic_cast( *it ); if ( itemP!=NULL ) m_mergeSetList[m_currentCliqueIndex]->preambleText=itemP->text; } } } } } } } void MergeElements::restoreCurrentMergeSet() { if ( m_mergeSetList[m_currentCliqueIndex] == NULL ) { m_listViewAlternatives->clear(); return; } for ( TQListViewItemIterator it( m_listViewClique ); it.current(); ++it ) { MergeElementsCliqueItem *item = dynamic_cast( *it ); BibTeX::Entry *entry = item->entry; BibTeX::Macro *macro = item->macro; BibTeX::Preamble *preamble = item->preamble; if ( entry != NULL ) for ( TQValueList::Iterator it2 = m_mergeSetList[m_currentCliqueIndex]->entries.begin(); it2 != m_mergeSetList[m_currentCliqueIndex]->entries.end(); ++it2 ) { if ( entry->id() == ( *it2 )->id() ) { item->setOn( true ); break; } } else if ( macro != NULL ) { for ( TQValueList::Iterator it2 = m_mergeSetList[m_currentCliqueIndex]->macros.begin(); it2 != m_mergeSetList[m_currentCliqueIndex]->macros.end(); ++it2 ) if ( macro->key() == ( *it2 )->key() ) { item->setOn( true ); break; } } else if ( preamble!=NULL ) for ( TQValueList::Iterator it2 = m_mergeSetList[m_currentCliqueIndex]->preambles.begin(); it2 != m_mergeSetList[m_currentCliqueIndex]->preambles.end(); ++it2 ) if ( preamble->value()->text() == ( *it2 )->value()->text() ) { item->setOn( true ); break; } } slotRefreshAlternatives(); for ( TQListViewItemIterator it( m_listViewAlternatives ); it.current(); ++it ) { MergeEntriesAlternativesItem *item = dynamic_cast( *it ); if ( item != NULL ) { for ( TQValueList::Iterator it2 = m_mergeSetList[m_currentCliqueIndex]->fields.begin(); it2 != m_mergeSetList[m_currentCliqueIndex]->fields.end(); ++it2 ) if ( item->field->fieldTypeName().lower() == ( *it2 )->fieldTypeName().lower() && item->field->value()->text() == ( *it2 )->value()->text() ) { item->setOn( true ); break; } } else { MergeElementsAlternativesId *item = dynamic_cast( *it ); if ( item != NULL ) { if ( item->id == m_mergeSetList[m_currentCliqueIndex]->id ) item->setOn( true ); } else { MergeEntriesAlternativesEntryType *item = dynamic_cast( *it ); if ( item != NULL ) { if (( item->type != BibTeX::Entry::etUnknown && item->type == m_mergeSetList[m_currentCliqueIndex]->type ) || ( item->typeString.lower() == m_mergeSetList[m_currentCliqueIndex]->typeString.lower() ) ) item->setOn( true ); } else { MergeMacrosAlternativesItem *mai = dynamic_cast( *it ); if ( mai != NULL ) { if ( mai->value == m_mergeSetList[m_currentCliqueIndex]->macroValue ) mai->setOn( true ); } else { MergeMacroAlternativesKey *mak = dynamic_cast( *it ); if ( mak != NULL ) { if ( mak->key == m_mergeSetList[m_currentCliqueIndex]->macroKey ) mak->setOn( true ); } else { MergePreambleAlternatives *mpa =dynamic_cast( *it ); if ( mpa!=NULL ) { if ( mpa->text==m_mergeSetList[m_currentCliqueIndex]->preambleText ) mpa->setOn( true ); } else tqDebug( "Item is of unknown type" ); } } } } } } } void MergeElements::applyMergeSet( BibTeX::File *bibTeXFile, BibTeX::File *otherBibTeXFile ) { int n = m_duplicateCliqueList.size(); for ( int i = 0; i < n; ++i ) { if ( m_mergeSetList[i] == NULL ) continue; if ( !m_mergeSetList[i]->entries.isEmpty() ) { TQString id = m_mergeSetList[i]->id == TQString::null ? ( *m_mergeSetList[i]->entries.begin() )->id() : m_mergeSetList[i]->id; BibTeX::Entry *newEntry = NULL; if ( m_mergeSetList[i]->type == BibTeX::Entry::etUnknown ) { if ( m_mergeSetList[i]->typeString == TQString::null ) { BibTeX::Entry *firstEntry = *m_mergeSetList[i]->entries.begin(); if ( firstEntry->entryType() == BibTeX::Entry::etUnknown ) newEntry = new BibTeX::Entry( firstEntry->entryTypeString(), id ); else newEntry = new BibTeX::Entry( firstEntry->entryType(), id ); } else newEntry = new BibTeX::Entry( m_mergeSetList[i]->typeString, id ); } else newEntry = new BibTeX::Entry( m_mergeSetList[i]->type, id ); for ( TQValueList::Iterator it = m_mergeSetList[i]->fields.begin(); it != m_mergeSetList[i]->fields.end(); ++it ) { newEntry->addField( new BibTeX::EntryField( *it ) ); } for ( TQValueList::Iterator it = m_mergeSetList[i]->entries.begin(); it != m_mergeSetList[i]->entries.end(); ++it ) for ( TQValueList::ConstIterator fIt = ( *it )->begin(); fIt != ( *it )->end(); ++fIt ) if ( newEntry->getField(( *fIt )->fieldTypeName() ) == NULL ) { newEntry->addField( new BibTeX::EntryField( *fIt ) ); } for ( TQValueList::Iterator it = m_mergeSetList[i]->entries.begin(); it != m_mergeSetList[i]->entries.end(); ++it ) { BibTeX::Entry *entry = dynamic_cast( bibTeXFile->containsKey(( *it )->id() ) ); if ( entry != NULL ) bibTeXFile->deleteElement( entry ); else { BibTeX::Entry *entry = dynamic_cast( otherBibTeXFile->containsKey(( *it )->id() ) ); if ( entry != NULL ) otherBibTeXFile->deleteElement( entry ); } } bibTeXFile->appendElement( newEntry ); } else if ( !m_mergeSetList[i]->macros.isEmpty() ) { BibTeX::Macro *newMacro = new BibTeX::Macro( m_mergeSetList[i]->macroKey ); newMacro->setValue( m_mergeSetList[i]->macroValue ); for ( TQValueList::Iterator it = m_mergeSetList[i]->macros.begin(); it != m_mergeSetList[i]->macros.end(); ++it ) { bibTeXFile->deleteElement( *it ); if ( otherBibTeXFile != NULL ) otherBibTeXFile->deleteElement( *it ); } bibTeXFile->appendElement( newMacro ); } else if ( !m_mergeSetList[i]->preambles.isEmpty() ) { BibTeX::Preamble *newPreamble = new BibTeX::Preamble( m_mergeSetList[i]->preambleText ); for ( TQValueList::Iterator it = m_mergeSetList[i]->preambles.begin(); it != m_mergeSetList[i]->preambles.end(); ++it ) { bibTeXFile->deleteElement( *it ); if ( otherBibTeXFile != NULL ) otherBibTeXFile->deleteElement( *it ); } bibTeXFile->appendElement( newPreamble ); } } } int MergeElements::mergeDuplicates( BibTeX::File *bibTeXFile ) { setCaption( i18n( "Find Duplicates" ) ); Settings * settings = Settings::self( NULL ); int sensitivity = ( int )( FindDuplicates::maxDistance / exp( log( 10 ) * settings->editing_findDuplicatesSensitivity / 10.0 ) ); tqDebug( "sensitivity= %i / %i", sensitivity, FindDuplicates::maxDistance ); FindDuplicates findDuplicates( m_duplicateCliqueList, sensitivity, bibTeXFile, parentWidget( true ) ); if ( m_duplicateCliqueList.isEmpty() ) { KMessageBox::information( parentWidget( true ), i18n( "No duplicates found." ), i18n( "Find Duplicates" ) ); return TQDialog::Rejected; } m_mergeSetList = new MergeSet*[m_duplicateCliqueList.size()]; memset( m_mergeSetList, 0, sizeof( MergeSet* )*m_duplicateCliqueList.size() ); tqDebug( "%i cliques", m_duplicateCliqueList.size() ); setClique( 0 ); int result = exec(); if ( result == TQDialog::Accepted ) applyMergeSet( bibTeXFile ); delete[] m_mergeSetList; return result; } void MergeElements::slotRefreshAlternatives() { TQMap mapFieldToController; TQMap firstEntryData; bool first = true; MergePreambleAlternativesController* preambleController = NULL; MergeMacrosAlternativesController* macroKeyController = NULL; MergeMacrosAlternativesController* macroValueController = NULL; MergeEntriesAlternativesController *idController = NULL; MergeEntriesAlternativesController *typeController = NULL; TQString firstId = TQString::null; TQString firstMacroKey = TQString::null; BibTeX::Value *firstMacroValue = NULL; TQString firstPreambleText = TQString::null; BibTeX::Entry::EntryType firstType = BibTeX::Entry::etUnknown; TQString firstTypeString = TQString::null; m_listViewAlternatives->clear(); for ( TQListViewItemIterator it( m_listViewClique, TQListViewItemIterator::Checked ); it.current(); ++it ) { MergeElementsCliqueItem *meci = dynamic_cast( *it ); BibTeX::Entry *entry = NULL; BibTeX::Macro *macro = NULL; BibTeX::Preamble *preamble = NULL; if ( meci != NULL && ( entry = meci->entry ) != NULL ) { if ( first ) { firstId = entry->id(); firstType = entry->entryType(); firstTypeString = entry->entryTypeString(); for ( BibTeX::Entry::EntryFields::const_iterator efi = entry->begin(); efi != entry->end(); ++efi ) { First first; first.entry = entry; first.field = *efi; firstEntryData.insert(( *efi )->fieldType(), first ); } } else { if ( idController == NULL ) { if ( entry->id() != firstId ) { idController = new MergeEntriesAlternativesController( i18n( "Id" ), m_listViewAlternatives ); idController->setOpen( true ); MergeElementsAlternativesId *item = new MergeElementsAlternativesId( firstId, idController ); item->setOn( true ); new MergeElementsAlternativesId( entry->id(), idController ); } } else { TQString thisText = entry->id(); bool isNew = true; for ( TQListViewItem *cur = idController->firstChild(); isNew && cur != NULL; cur = cur->nextSibling() ) { MergeElementsAlternativesId *meai = dynamic_cast( cur ); isNew = meai->id != thisText; } if ( isNew ) new MergeElementsAlternativesId( thisText, idController ); } if ( typeController == NULL ) { if (( firstType != BibTeX::Entry::etUnknown && entry->entryType() != firstType ) || ( entry->entryTypeString().lower() != entry->entryTypeString().lower() ) ) { typeController = new MergeEntriesAlternativesController( i18n( "Type" ), m_listViewAlternatives ); typeController->setOpen( true ); MergeEntriesAlternativesEntryType *item = firstType != BibTeX::Entry::etUnknown ? new MergeEntriesAlternativesEntryType( firstType, typeController ) : new MergeEntriesAlternativesEntryType( firstTypeString, typeController ); item->setOn( true ); if ( entry->entryType() != BibTeX::Entry::etUnknown ) new MergeEntriesAlternativesEntryType( entry->entryType(), typeController ); else new MergeEntriesAlternativesEntryType( entry->entryTypeString(), typeController ); } } else { TQString typeString = entry->entryTypeString(); BibTeX::Entry::EntryType type = entry->entryType(); bool isNew = true; for ( TQListViewItem *cur = typeController->firstChild(); isNew && cur != NULL; cur = cur->nextSibling() ) { MergeEntriesAlternativesEntryType *meat = dynamic_cast( cur ); isNew = type == BibTeX::Entry::etUnknown && meat->typeString != typeString || meat->type != type; } if ( isNew ) { if ( type != BibTeX::Entry::etUnknown ) new MergeEntriesAlternativesEntryType( type, typeController ); else new MergeEntriesAlternativesEntryType( typeString, typeController ); } } for ( BibTeX::Entry::EntryFields::const_iterator efi = entry->begin(); efi != entry->end(); ++efi ) if ( mapFieldToController.contains(( *efi )->fieldType() ) ) { MergeEntriesAlternativesController *controller = mapFieldToController[( *efi )->fieldType()]; TQString thisText = ( *efi )->value()->text(); bool isNew = true; for ( TQListViewItem *cur = controller->firstChild(); isNew && cur != NULL; cur = cur->nextSibling() ) { MergeEntriesAlternativesItem *meai = dynamic_cast( cur ); isNew = meai->field->value()->text() != thisText; } if ( isNew ) new MergeEntriesAlternativesItem( *efi, controller ); } else if ( firstEntryData.contains(( *efi )->fieldType() ) ) { TQString firstText = firstEntryData[( *efi )->fieldType()].field->value()->text(); TQString thisText = ( *efi )->value()->text(); if ( firstText != thisText ) { MergeEntriesAlternativesController *controller = new MergeEntriesAlternativesController(( *efi )->fieldType(), m_listViewAlternatives ); controller->setOpen( true ); MergeEntriesAlternativesItem *item = new MergeEntriesAlternativesItem( firstEntryData[( *efi )->fieldType()].field, controller ); item->setOn( true ); item = new MergeEntriesAlternativesItem( *efi, controller ); mapFieldToController.insert(( *efi )->fieldType(), controller ); } } else { First first; first.entry = entry; first.field = *efi; firstEntryData.insert(( *efi )->fieldType(), first ); } } } else if ( meci != NULL && ( macro = meci->macro ) != NULL ) { if ( first ) { firstMacroKey = macro->key(); firstMacroValue = macro->value(); } else { if ( macroKeyController == NULL ) { if ( macro->key() != firstMacroKey ) { macroKeyController = new MergeMacrosAlternativesController( true, m_listViewAlternatives ); macroKeyController->setOpen( true ); MergeMacroAlternativesKey *item = new MergeMacroAlternativesKey( firstMacroKey, macroKeyController ); item->setOn( true ); new MergeMacroAlternativesKey( macro->key(), macroKeyController ); } } else { TQString thisText = macro->key(); bool isNew = true; for ( TQListViewItem *cur = macroKeyController->firstChild(); isNew && cur != NULL; cur = cur->nextSibling() ) { MergeMacroAlternativesKey *mak = dynamic_cast( cur ); isNew = mak->key != thisText; } if ( isNew ) new MergeMacroAlternativesKey( thisText, macroKeyController ); } } if ( macroValueController == NULL ) { if ( firstMacroValue->text() != macro->value()->text() ) { macroValueController = new MergeMacrosAlternativesController( false, m_listViewAlternatives ); macroValueController->setOpen( true ); MergeMacrosAlternativesItem *item = new MergeMacrosAlternativesItem( firstMacroValue, macroValueController ); item->setOn( true ); new MergeMacrosAlternativesItem( macro->value(), macroValueController ); } } else { TQString macroString = macro->value()->text(); bool isNew = true; for ( TQListViewItem *cur = macroValueController->firstChild(); isNew && cur != NULL; cur = cur->nextSibling() ) { MergeMacrosAlternativesItem *mai = dynamic_cast( cur ); isNew = macroString != mai->value->text(); } if ( isNew ) new MergeMacrosAlternativesItem( macro->value(), macroValueController ); } } else if ( meci != NULL && ( preamble = meci->preamble ) != NULL ) { if ( first ) firstPreambleText = preamble->value()->text(); else { if ( preambleController == NULL ) { if ( preamble->value()->text() != firstPreambleText ) { preambleController = new MergePreambleAlternativesController( m_listViewAlternatives ); preambleController->setOpen( true ); MergePreambleAlternatives *item = new MergePreambleAlternatives( firstPreambleText, preambleController ); item->setOn( true ); new MergePreambleAlternatives( preamble->value()->text(), preambleController ); } } else { TQString thisText = preamble->value()->text(); bool isNew = true; for ( TQListViewItem *cur = preambleController->firstChild(); isNew && cur != NULL; cur = cur->nextSibling() ) { MergePreambleAlternatives *mpa = dynamic_cast( cur ); isNew = mpa->text != thisText; } if ( isNew ) new MergePreambleAlternatives( thisText, preambleController ); } } } first = false; } } void MergeElements::slotNextClique() { if ( m_currentCliqueIndex < ( int )( m_duplicateCliqueList.size() ) - 1 ) { setClique( m_currentCliqueIndex + 1 ); } else enableButton( User1, false ); } void MergeElements::slotPreviousClique() { if ( m_currentCliqueIndex > 0 ) { setClique( m_currentCliqueIndex - 1 ); } else enableButton( User2, false ); } void MergeElements::slotPreviewElement( TQListViewItem *item ) { MergeElementsCliqueItem *meci = dynamic_cast( item ); if ( meci != NULL && meci->entry != NULL ) KBibTeX::EntryWidget::execute( meci->entry, NULL, TRUE, FALSE, this ); else if ( meci != NULL && meci->macro != NULL ) KBibTeX::MacroWidget::execute( meci->macro, TRUE, this ); else if ( meci!=NULL&& meci->preamble!=NULL ) KBibTeX::PreambleWidget::execute( meci->preamble, TRUE, this ); } /* This function was taken form TDEMainWindow of KDE 3.5 and modified to fit KBibTeX */ void MergeElements::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( winId(), NET::WMState ); w = info.state() & NET::MaxHoriz ? desk.width() + 1 : width(); h = info.state() & NET::MaxVert ? desk.height() + 1 : 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 ); } void MergeElements::showEvent( TQShowEvent * ) { tqDebug( "showEvent" ); TQTimer::singleShot( 10, this, SLOT( slotRestore() ) ); } void MergeElements::slotRestore() { tqDebug( "slotRestore" ); TDEConfig * config = kapp->config(); config->setGroup( "MergeElements" ); restoreWindowSize( config ); } /* This function was taken form TDEMainWindow of KDE 3.5 and modified to fit KBibTeX */ void MergeElements::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 ) resize( width(), size.height() ); else if (( state & NET::MaxVert ) == NET::MaxVert ) resize( size.width(), height() ); else resize( size ); // TQWidget::showMaximized() is both insufficient and broken KWin::setState( winId(), state ); #else if ( size.width() > desk.width() || size.height() > desk.height() ) setWindowState( WindowMaximized ); else resize( size ); #endif } } } #include "mergeelements.moc"