/***************************************************************************
                          kbibeditentrydlg.cpp  -  description
                             -------------------
    begin                : Sat May 31 2003
    copyright            : (C) 2003 by Thach NguyenF
    email                : thach.nguyen@rmit.edu.au
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <klocale.h>
#include <kiconloader.h>
#include <kfiledialog.h>
#include <kmessagebox.h>
#include <qtooltip.h>
#include <qwhatsthis.h>

#include "kbibeditentrydlg.h"
#include "kbiblistview.h"
#include "kbib.h"
#include "kbibdoc.h"

#include "linefieldwidget.h"
#include "paragraphfieldwidget.h"
#include "multiplevaluefieldwidget.h"
#include "numberfieldwidget.h"
#include "urlfieldwidget.h"
#include "monthfieldwidget.h"


KBibEditEntryDlg::KBibEditEntryDlg ( BibEntry *entry, QWidget *parent, const char *name )
		:KDialogBase ( parent, name , false, i18n ( "Edit Entry" ), KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, false )
{

	mainTab = new QTabWidget ( this );
	setMainWidget ( mainTab );
	QWidget *fieldEdit = new  QWidget ( mainTab );
	QVBoxLayout* l1 = new QVBoxLayout ( fieldEdit, 0, KDialog::spacingHint() );
	l1->setMargin ( 10 );
	QHBox* box1 = new QHBox ( fieldEdit );
	box1->setMargin ( 4 );
	box1->setSpacing ( 4 );
	mainTab->setMinimumWidth ( 800 );


	entryTypeLabel = new QLabel ( i18n ( "Reference Type:" ), box1 );
	entryTypeLabel->setMinimumWidth ( 140 );
	entryTypeSelect = new QComboBox ( false, box1, "entryType" );
	entryTypeLabel->setBuddy ( entryTypeSelect );
	QToolTip::add ( entryTypeSelect, QString ( i18n ( "Select the reference type from the list" ) ) );
	QWhatsThis::add ( entryTypeSelect, QString ( i18n ( "Select from the list the reference type then the dialog will display all defined fields for the selected type. Undefined fields can be added in \"Extra Field\" tab. The reference type can be modified or new type being added using command Customise Reference Type in Bitex menu." ) ) );


	//editTypeBttn = new QPushButton("Edit Type", box1);
	editTypeBttn = new QPushButton ( box1 );
	// QPixmap editPix = KGlobal::iconLoader()->loadIcon(QString::fromLatin1("edit"), KIcon::Small);
	//editTypeBttn->setPixmap(editPix);
	editTypeBttn->setIconSet ( QIconSet ( SmallIcon ( "edit" ) ) );
	editTypeBttn->setSizePolicy ( QSizePolicy::Minimum, QSizePolicy::Minimum );
	QToolTip::add ( editTypeBttn, QString ( i18n ( "Edit current reference type" ) ) );
	QWhatsThis::add ( editTypeBttn, QString ( i18n ( "Edit current reference type" ) ) );
	editTypeBttn->setMinimumWidth ( 40 );
	QWidget *dummy = new QWidget ( box1 );
	box1->setStretchFactor ( entryTypeLabel, 0 );
	box1->setStretchFactor ( entryTypeSelect, 0 );
	box1->setStretchFactor ( editTypeBttn, 0 );
	box1->setStretchFactor ( dummy, 1 );
	l1->addWidget ( box1 );
	editTypeBttn->hide();

	QHBox* box2 = new QHBox ( fieldEdit );
	box2->setMargin ( 4 );
	box2->setSpacing ( 4 );

	keyLabel = new QLabel ( i18n("Citation Key:"), box2 );
	keyLabel->setMinimumWidth ( 140 );
	keyField = new KLineEdit ( box2 );
	keyField->setMinimumWidth ( 140 );
	keyLabel->setBuddy ( keyField );
	QToolTip::add ( keyField, QString ( i18n ( "Enter the citation key into this box" ) ) );
	QWhatsThis::add ( keyField, QString ( i18n ( "You can enter the citation key directly in this box or click on the %1 to have the citation key created automatically. This box is disable if the citation key is locked." ).arg ( i18n ( "Create Key" ) ) ) );


	createKeyBttn = new QPushButton ( i18n ( "Create Key" ), box2 );
	QToolTip::add ( createKeyBttn, QString ( i18n ( "Create citation key" ) ) );
	QWhatsThis::add ( createKeyBttn, QString ( i18n ( "Click this button to have the citation key created automatically based on author and year fields. This button is disabled when the citation key is locked." ) ) );
	createKeyBttn->setMinimumWidth ( createKeyBttn->sizeHint().width() );
	lockKeyBttn = new QPushButton ( box2 );
	lockKeyBttn->setMinimumWidth ( lockKeyBttn->sizeHint().width() );

	QToolTip::add ( lockKeyBttn, QString ( i18n ( "Lock citation key" ) ) );
	QWhatsThis::add ( lockKeyBttn, QString ( i18n ( "Click this button to toggle locking state of the citation key." ) ) );

	dummy = new QWidget ( box2 );
	box2->setStretchFactor ( keyLabel, 0 );
	box2->setStretchFactor ( keyField, 1 );
	box2->setStretchFactor ( createKeyBttn, 0 );
	box2->setStretchFactor ( lockKeyBttn, 0 );
	box2->setStretchFactor ( dummy, 1 );
	l1->addWidget ( box2 );

	reqTab = new QTabWidget ( fieldEdit );
	l1->addWidget ( reqTab );
	reqTab->setMargin ( 0 );
	reqTab->setMinimumHeight ( 200 );

	QToolTip::add ( reqTab, QString ( i18n ( "Fields that are requried for the current reference type." ) ) );
	QWhatsThis::add ( reqTab, QString ( i18n ( "This tab show all required fields of the current reference type. A required field should not be empty." ) ) );

	//  reqTab->setPaletteForegroundColor(QColor(255,0,0));

	rqScrollView = new QScrollView ( reqTab );

	rqScrollView->setFrameStyle ( 0 );
	rqScrollView->setResizePolicy ( QScrollView::AutoOneFit );
	reqTab->addTab ( rqScrollView, i18n("Required Fields") );

	rqBox = new QGroupBox ( rqScrollView->viewport() );
	rqLayout = new QVBoxLayout ( rqBox, 0, KDialog::spacingHint() );

	rqBox->setFrameStyle ( 0 );
	rqScrollView->addChild ( rqBox );



	optTab = new QTabWidget ( fieldEdit );
	QToolTip::add ( optTab, QString ( i18n ( "Fields that are optional for the current reference type." ) ) );
	QWhatsThis::add ( optTab, QString ( i18n ( "This tab show all optional fields of the current reference type. An optioanl field can be empty." ) ) );

	l1->addWidget ( optTab );

	reqTab->setMargin ( 0 );
	optTab->setMinimumHeight ( 200 );


	optScrollView = new QScrollView ( optTab );
	optScrollView->setFrameStyle ( 0 );
	optScrollView->setResizePolicy ( QScrollView::AutoOneFit );
	optTab->addTab ( optScrollView, i18n("Optional Fields") );

	optBox = new QGroupBox ( optScrollView->viewport() );
	optLayout = new QVBoxLayout ( optBox, 0, KDialog::spacingHint() );
	optBox->setFrameStyle ( 0 );

	optScrollView->addChild ( optBox );

	l1->addStretch ( 1 );



	connect ( createKeyBttn, SIGNAL ( clicked() ), this, SLOT ( slotCreateKey() ) );
	connect ( lockKeyBttn, SIGNAL ( clicked() ), this, SLOT ( slotLockKey() ) );





	rqFields.setAutoDelete ( true );
	optFields.setAutoDelete ( true );


	rqScrollView->setHScrollBarMode ( QScrollView::AlwaysOff );
	optScrollView->setHScrollBarMode ( QScrollView::AlwaysOff );

	entryTypeSelect->insertStringList ( BibEntryDefTable::self()->getEntryDefNames() );

	entryTypeSelect->setInsertionPolicy ( QComboBox::NoInsertion );

	if ( entry == 0 )
		m_entry = new BibEntry ( BibEntryDefTable::self()->getEntryTypeName ( 0 ), "" );
	else
		m_entry = new BibEntry ( *entry );

	QString entryTypeName = m_entry->getEntryType();

	entryTypeSelect->setCurrentText ( entryTypeName );

	mainTab->addTab ( fieldEdit, i18n("&Main Fields") );
	mainTab->setMargin ( 0 );

	//Exttra fields tab
	QWidget* extraFieldTab = new QWidget ( mainTab );

	QHBoxLayout* l4 = new QHBoxLayout ( extraFieldTab, 0, KDialog::spacingHint() );
	l4->setMargin ( 40 );
	extraFieldView = new KListView ( extraFieldTab );
	extraFieldView->setAllColumnsShowFocus ( true );
	extraFieldView->setShowSortIndicator ( false );
	extraFieldView->setDefaultRenameAction ( QListView::Accept );
	extraFieldView->setSortColumn ( -1 );
	extraFieldView->addColumn ( i18n ( "String Macro" ) );
	extraFieldView->addColumn ( i18n ( "Name" ) );
	extraFieldView->addColumn ( i18n ( "Value" ) );
	//extraFieldView->setColumnWidthMode(0, QListView::Manual);
	//extraFieldView->setColumnWidthMode(1, QListView::Manual);
	//extraFieldView->setColumnWidthMode(1, QListView::Maximum);
	//extraFieldView->setResizeMode(QListView::AllColumns);
	l4->addWidget ( extraFieldView );

	QVBoxLayout* box = new QVBoxLayout ( extraFieldTab, 0, KDialog::spacingHint() );

	extraFieldAddBtn = new KPushButton ( i18n("Add"), extraFieldTab );
	extraFieldEditBtn = new KPushButton ( i18n("Edit"), extraFieldTab );
	extraFieldDeleteBtn = new KPushButton ( i18n("Delete"), extraFieldTab );


	extraFieldAddBtn->setIconSet ( QIconSet ( SmallIcon ( "add" ) ) );
	extraFieldDeleteBtn->setIconSet ( QIconSet ( SmallIcon ( "editdelete" ) ) );
	extraFieldEditBtn->setIconSet ( QIconSet ( SmallIcon ( "edit" ) ) );

	box->addWidget ( extraFieldAddBtn );
	box->addWidget ( extraFieldDeleteBtn );
	box->addWidget ( extraFieldEditBtn );

	box->addStretch ( 0 );
	l4->addLayout ( box,0 );

	connect ( extraFieldView, SIGNAL ( selectionChanged() ), this, SLOT ( updateExtraFieldGUI() ) );
	connect ( extraFieldView, SIGNAL ( itemRenamed ( QListViewItem*, int, const QString& ) ), this, SLOT ( slotExtraFielItemRenamed ( QListViewItem*, int, const QString& ) ) );

	connect ( extraFieldAddBtn, SIGNAL ( clicked() ), this, SLOT ( slotExtraFieldAdd() ) );
	connect ( extraFieldEditBtn, SIGNAL ( clicked() ), this, SLOT ( slotExtraFieldEdit() ) );
	connect ( extraFieldDeleteBtn, SIGNAL ( clicked() ), this, SLOT ( slotExtraFieldDelete() ) );


	mainTab->addTab ( extraFieldTab, i18n("&Extra Fields") );


	//Abstract Tab
	abstractPage = new QWidget ( mainTab );
	QVBoxLayout* l2 = new QVBoxLayout ( abstractPage, 10, KDialog::spacingHint() );
	abstractEdit = new KTextEdit ( abstractPage );
	abstractLabel = new QLabel ( i18n ( "This reference type does not have %1 field" ).arg ( QString::fromLatin1 ( "abstract" ) ), abstractPage );
	abstractLabel->setAlignment ( AlignCenter );
	l2->addWidget ( abstractEdit );
	l2->addWidget ( abstractLabel );
	mainTab->addTab ( abstractPage, i18n("&Abstract") );
	abstractEdit->hide();


	//Note tab
	QWidget* noteTab = new QWidget ( mainTab );
	QVBoxLayout* noteLayout = new QVBoxLayout ( noteTab, 10, KDialog::spacingHint() );
	noteEdit = new KTextEdit ( noteTab );
	//noteEdit->setTextFormat(RichText);
	noteLabel = new QLabel ( i18n ( "This reference type does not have %1 field" ).arg ( QString::fromLatin1 ( "comment" ) ), noteTab );
	noteLabel->setAlignment ( AlignCenter );
	noteLayout->addWidget ( noteEdit );
	noteLayout->addWidget ( noteLabel );
	mainTab->addTab ( noteTab, i18n("&Comment") );
	noteEdit->hide();


	//Source tab
	QWidget* page3 = new QWidget ( mainTab );
	QVBoxLayout* l3 = new QVBoxLayout ( page3, 10, KDialog::spacingHint() );
	sourceEdit = new KTextEdit ( page3 );
	l3->addWidget ( sourceEdit );
	mainTab->addTab ( page3, i18n("&BibTeX Source") );




	connect ( entryTypeSelect, SIGNAL ( activated ( int ) ), this, SLOT ( slotEntryTypeChange ( int ) ) ) ;
	connect ( mainTab,SIGNAL ( currentChanged ( QWidget * ) ), this, SLOT ( slotTabChanged() ) );
	connect ( keyField, SIGNAL ( textChanged ( const QString& ) ), SLOT ( slotSetModified() ) );
	connect ( noteEdit, SIGNAL ( textChanged() ), SLOT ( slotSetModified() ) );
	connect ( abstractEdit, SIGNAL ( textChanged() ), SLOT ( slotSetModified() ) );
	connect ( sourceEdit, SIGNAL ( textChanged() ), SLOT ( slotSetModified() ) );

	prevTabIndex = 0;
	updateDlg ( entryTypeName );
	updateContent ( m_entry );
	slotSetModified ( false );




	mainTab->setCurrentPage ( 0 );

}

KBibEditEntryDlg::~KBibEditEntryDlg()
{
	prevTabIndex = 0;
	mainTab->setCurrentPage ( 0 );
	if ( sourceEdit )
		delete sourceEdit;
	if ( abstractEdit )
		delete abstractEdit;


	//delete m_entry;
	if ( entryTypeLabel )
		delete entryTypeLabel;
	if ( keyLabel )
		delete keyLabel;
	if ( keyField )
		delete keyField;
	if ( createKeyBttn )
		delete createKeyBttn;
	if ( lockKeyBttn )
		delete lockKeyBttn;
	rqFields.clear();

	optFields.clear();

	delete entryTypeSelect;
	delete editTypeBttn;

	delete m_entry;


	delete rqLayout;
	delete optLayout;

	delete rqBox;
	delete optBox;


	delete rqScrollView;
	delete optScrollView;

	delete reqTab;
	delete optTab;

	if ( mainTab )
		delete mainTab;

}

/** No descriptions */
void KBibEditEntryDlg::updateDlg ( QString entryTypeName )
{

	KBibApp* win = ( KBibApp* ) this->parent();
	KBibDoc* doc = win->getDocument();

	QStringList macroKeys = ( doc->getEntryList() )->getStringMacroKeys();


	if ( !rqFields.isEmpty() )
		rqFields.clear();
	if ( !optFields.isEmpty() )
		optFields.clear();

	if ( rqLayout )
		delete rqLayout;

	if ( optLayout )
		delete optLayout;

	abstractLabel->show();
	abstractEdit->hide();

	noteLabel->show();
	noteEdit->hide();


	rqLayout = new QVBoxLayout ( rqBox, 0, KDialog::spacingHint(), "reqBoxLayout" );
	rqLayout->setMargin ( 10 );

	optLayout = new QVBoxLayout ( optBox, 0, KDialog::spacingHint(), "optBoxLayout" );
	optLayout->setMargin ( 10 );


	if ( QString ( m_entry->getField ( QString::fromLatin1 ( "lockkey" ) ) ) =="Y" )
	{
		lockKeyBttn->setIconSet ( QIconSet ( SmallIcon ( "unlock" ) ) );
		lockKeyBttn->setSizePolicy ( QSizePolicy::Minimum, QSizePolicy::Minimum );
		QToolTip::add ( lockKeyBttn, QString ( i18n ( "Unlock the citation key" ) ) );
		createKeyBttn->setEnabled ( false );
		keyField->setEnabled ( false );

	}
	else
	{
		lockKeyBttn->setIconSet ( QIconSet ( SmallIcon ( "lock" ) ) );
		lockKeyBttn->setSizePolicy ( QSizePolicy::Minimum, QSizePolicy::Minimum );
		QToolTip::add ( lockKeyBttn, QString ( i18n ( "Lock the citation key" ) ) );
		createKeyBttn->setEnabled ( true );
		keyField->setEnabled ( true );
	}

	BibEntryDef *entryType = BibEntryDefTable::self()->getBibEntryDef ( entryTypeName );
	int nrq = entryType->numRequired();
	int maxLabelWidth = 0;
	int numEditField = 0;

	for ( int i = 0; i< nrq; i++ )
	{
		QString fn = entryType->getRequired ( i );
		if ( fn != QString::fromLatin1 ( "lockkey" ) )
		{
			if ( fn == QString::fromLatin1 ( "abstract" ) )
			{
				abstractLabel->hide();
				abstractEdit->show();
			}
			else if ( fn == QString::fromLatin1 ( "comment" ) )
			{
				noteLabel->hide();
				noteEdit->show();
			}
			else
			{
				GUI::FieldWidget *fieldEdit;
				RefField *field = BibEntryDefTable::self()->getRefField ( fn );
				int type;
				if ( field )
					type = field->type;
				else
					type = TEXT;
				switch ( type )
				{
					case PARAGRAPH:
					{
						GUI::ParagraphFieldWidget *paraFieldWg = new  GUI::ParagraphFieldWidget ( fn, field, macroKeys, rqBox );
						if ( ( win->kbibConfigState ).autocompletion && field )
							paraFieldWg->setAutoCompletion ( doc->getValueList ( fn ) );
						fieldEdit = paraFieldWg;
						break;
					}
					case MULTIPLE:
					{
						GUI::MultipleValueFieldWidget *multiValueFieldWg = new  GUI::MultipleValueFieldWidget ( fn, field, macroKeys, rqBox );
						if ( ( win->kbibConfigState ).autocompletion && field )
							multiValueFieldWg->setAutoCompletion ( doc->getValueList ( fn ) );
						fieldEdit = multiValueFieldWg;
						break;
					}
					case NUMBER:
					{
						GUI::NumberFieldWidget *numberFieldWg = new  GUI::NumberFieldWidget ( fn, field, rqBox );
						fieldEdit = numberFieldWg;
						break;
					}
					case URL:
					{
						GUI::UrlFieldWidget *urlFieldWg = new  GUI::UrlFieldWidget ( fn, field, macroKeys, rqBox );
						fieldEdit = urlFieldWg;
						break;
					}
					case MONTH:
					{
						GUI::MonthFieldWidget *monthFieldWg = new  GUI::MonthFieldWidget ( fn, field, rqBox );
						fieldEdit = monthFieldWg;
						break;
					}

					default:
					{
						GUI::LineFieldWidget *lineFieldWg = new  GUI::LineFieldWidget ( fn, field, macroKeys, rqBox );
						if ( ( win->kbibConfigState ).autocompletion && field )
							lineFieldWg->setAutoCompletion ( doc->getValueList ( fn ) );
						fieldEdit = lineFieldWg;
						break;
					}

				}

				fieldEdit->show();
				connect ( fieldEdit, SIGNAL ( modified() ), SLOT ( slotSetModified() ) );
				rqFields.append ( fieldEdit );
				rqLayout->addWidget ( fieldEdit );

				int w = fieldEdit->labelWidth();
				if ( w > maxLabelWidth )
					maxLabelWidth = w;
				numEditField++;

			}
		}
	}

	//Resize labels
	for ( GUI::FieldWidget *field = rqFields.first(); field; field = rqFields.next() )
	{
		field->setLabelWidth ( maxLabelWidth );
	}

	rqLayout->addStretch ( 1 );

	if ( numEditField )
		reqTab->show();
	else
		reqTab->hide();

	int nopt = entryType->numOptional();
	numEditField = 0;
	maxLabelWidth = 0;
	for ( int i = 0; i< nopt; i++ )
	{
		QString fn = ( entryType->getOptional ( i ) ).lower();

		if ( fn != QString::fromLatin1 ( "lockkey" ) )
		{
			if ( fn == QString::fromLatin1 ( "abstract" ) )
			{
				abstractLabel->hide();
				abstractEdit->show();
			}
			else if ( fn == QString::fromLatin1 ( "comment" ) )
			{
				noteLabel->hide();
				noteEdit->show();
			}
			else
			{

				GUI::FieldWidget *fieldEdit;
				RefField *field = BibEntryDefTable::self()->getRefField ( fn );
				int type;
				if ( field )
					type = field->type;
				else
					type = TEXT;
				switch ( type )
				{
					case PARAGRAPH:
					{
						GUI::ParagraphFieldWidget *paraFieldWg = new  GUI::ParagraphFieldWidget ( fn, field, macroKeys, optBox );
						if ( ( win->kbibConfigState ).autocompletion )
							paraFieldWg->setAutoCompletion ( doc->getValueList ( fn ) );
						fieldEdit = paraFieldWg;
						break;
					}
					case MULTIPLE:
					{
						GUI::MultipleValueFieldWidget *multiValueFieldWg = new  GUI::MultipleValueFieldWidget ( fn, field, macroKeys, optBox );
						if ( ( win->kbibConfigState ).autocompletion )
							multiValueFieldWg->setAutoCompletion ( doc->getValueList ( fn ) );
						fieldEdit = multiValueFieldWg;
						break;
					}
					case NUMBER:
					{
						GUI::NumberFieldWidget *numberFieldWg = new  GUI::NumberFieldWidget ( fn, field, optBox );
						fieldEdit = numberFieldWg;
						break;
					}
					case URL:
					{
						GUI::UrlFieldWidget *urlFieldWg = new  GUI::UrlFieldWidget ( fn, field, macroKeys, optBox );
						fieldEdit = urlFieldWg;
						break;
					}
					case MONTH:
					{
						GUI::MonthFieldWidget *monthFieldWg = new  GUI::MonthFieldWidget ( fn, field, optBox );
						fieldEdit = monthFieldWg;
						break;
					}
					default:
					{
						GUI::LineFieldWidget *lineFieldWg = new  GUI::LineFieldWidget ( fn, field, macroKeys, optBox );
						if ( ( win->kbibConfigState ).autocompletion )
							lineFieldWg->setAutoCompletion ( doc->getValueList ( fn ) );
						fieldEdit = lineFieldWg;
						break;
					}

				}

				int w = fieldEdit->labelWidth();
				if ( w > maxLabelWidth )
					maxLabelWidth = w;

				fieldEdit->show();
				connect ( fieldEdit, SIGNAL ( modified() ), SLOT ( slotSetModified() ) );

				optFields.append ( fieldEdit );
				optLayout->addWidget ( fieldEdit );



				numEditField++;



			}

		}

	}
	//Resize labels
	for ( GUI::FieldWidget *field = optFields.first(); field; field = optFields.next() )
	{
		field->setLabelWidth ( maxLabelWidth );
	}

	optLayout->addStretch ( 1 );
	if ( numEditField == 0 )
		optTab->hide();
	else
		optTab->show();
}
/** No descriptions */
void KBibEditEntryDlg::updateContent ( BibEntry *entry )
{
	abstractEdit->clear();
	noteEdit->clear();

	GUI::FieldWidget *field = rqFields.first();

	keyField->setText ( entry->getKey() );


	while ( field!=0 )
	{
		QString st = ( field->fieldName() ).lower();
		field->setText ( entry->getField ( st ) );
		field->setMacro ( entry->stringMacroIndicator ( st ) );
//        field->setCursorPosition(0);
		field = rqFields.next();

	}

	field = optFields.first();

	while ( field!=0 )
	{
		QString st = field->fieldName();
		field->setText ( entry->getField ( st ) );
		field->setMacro ( entry->stringMacroIndicator ( st ) );
//        field->setCursorPosition(0);
		field = optFields.next();

	}



	//Extra Field Tab
	extraFieldView->clear();
	for ( int i = 0; i < entry->getNoExtraFields(); i++ )
	{
		QString fn = entry->getFieldName ( i+entry->getNoReqFields() + entry->getNoOptFields() );

		if ( fn != QString::fromLatin1 ( "lockkey" ) )
		{
			if ( fn == QString::fromLatin1 ( "abstract" ) )
			{
				abstractLabel->hide();
				abstractEdit->show();
			}
			else if ( fn == QString::fromLatin1 ( "comment" ) )
			{
				noteLabel->hide();
				noteEdit->show();
			}
			else
			{
				QCheckListItem *item = new QCheckListItem ( extraFieldView, extraFieldView->lastItem(), "", QCheckListItem::CheckBox );
				item->setText ( 1, fn );
				item->setText ( 2, ( entry->getExtField ( i ) ).simplifyWhiteSpace() ) ;
				item->setOn ( entry->stringMacroIndicator ( fn ) );
				extraFieldView->ensureItemVisible ( item );
				item->setRenameEnabled ( 1,true );
				item->setRenameEnabled ( 2,true );
			}
		}
	}
	updateExtraFieldGUI();

	abstractEdit->setText ( entry->getField ( "abstract" ) );
	//Note Tab
	noteEdit->setText ( entry->getField ( "comment" ) );
	slotSetModified(false);
}


void KBibEditEntryDlg::slotCancel()
{
	getBibEntry();
	
	if ( m_modified )
	{
		int want_save = KMessageBox::warningYesNoCancel ( this,  i18n ( "The current reference has been modified.\n"
		                     "Do you want to apply the changes?" ), i18n ( "Unsaved Changes" ));
		switch ( want_save )
		{
			case KMessageBox::Yes:
				slotOk();
				break;

			case KMessageBox::No:
				hide();
				break;

			case KMessageBox::Cancel:
				break;
		}
	}
	else
		hide();
	
	
}

void KBibEditEntryDlg::slotEntryTypeChange ( int index )
{

	QString type = entryTypeSelect->text ( index );
	getBibEntry();
	BibEntry *new_entry = new BibEntry ( type, "" );
	QString key =  m_entry->getKey();
	new_entry->setKey ( key );
	new_entry->setIndex ( m_entry->getIndex() );
	new_entry->setFields ( *m_entry );

	delete m_entry;

	m_entry = new BibEntry ( *new_entry );

	updateDlg ( type );
	updateContent ( m_entry );
	slotSetModified ( true );
}

void KBibEditEntryDlg::accept ( void )
{
	if ( mainTab->currentPageIndex() == 4 )
	{
		QString str = sourceEdit->text();
		int dummy;
		BibEntry *tmp_entry = processBibEntryFromString ( str.ascii(), dummy );
		if ( !tmp_entry )
		{
			KMessageBox::error ( this, i18n ( "Errors in BibTex source." ) );
		}
		else
		{
			delete m_entry;
			m_entry = tmp_entry;
			QDialog::accept();
		}

	}
	else
	{

		getBibEntry();
		QDialog::accept();

	}


}

BibEntry * KBibEditEntryDlg::getEditedBibEntry ( void )
{
	return m_entry;

}


/** No descriptions */
BibEntry * KBibEditEntryDlg::getBibEntry ( void )
{
	QString qst;
	qst = keyField->text();
	qst = qst.stripWhiteSpace();

	QString lockkey = m_entry->getField(QString::fromLatin1("lockkey"));
	
	m_entry->setKey ( qst );

	GUI::FieldWidget *field = rqFields.first();

	QString lst;

	while ( field!=0 )
	{
		qst = field->getText();
		qst = qst.stripWhiteSpace();
		lst = field->fieldName();
		m_entry->setField ( lst.lower(), qst );
		m_entry->setStringMacroIndicator ( ( lst.lower() ), field->getMacro() );
		field = rqFields.next();

	}

	field = optFields.first();

	while ( field!=0 )
	{
		qst = field->getText();
		qst = qst.stripWhiteSpace();
		lst = field->fieldName();
		m_entry->setField ( lst.lower(), qst );
		m_entry->setStringMacroIndicator ( ( lst.lower() ), field->getMacro() );
		field = optFields.next();


	}

	QListViewItem *it;
	if (!m_modified){
		it =extraFieldView->firstChild();
		for ( int i = 0 ; i < extraFieldView->childCount(); i++ )
		{
			QString fn = it->text ( 1 );
			QCheckListItem *itm = dynamic_cast<QCheckListItem*> ( it );
			if ((m_entry->stringMacroIndicator(fn) && !(itm->isOn()) ) || 
			   	(!(m_entry->stringMacroIndicator(fn)) && (itm->isOn()) )){
				m_modified = true;
				break;
			}
		}
	}
	
	
	it =extraFieldView->firstChild();
	
	m_entry->clearExtraField();
	for ( int i = 0 ; i < extraFieldView->childCount(); i++ )
	{

		lst = it->text ( 1 );
		qst = it->text ( 2 );
		qst = qst.stripWhiteSpace();

		m_entry->setField ( lst, qst );
		QCheckListItem *itm = dynamic_cast<QCheckListItem*> ( it );
		m_entry->setStringMacroIndicator ( const_cast<char*> ( ( lst.lower() ).ascii() ), itm->isOn() );
		it = it->nextSibling();

	}


	if ( abstractEdit->isShown() )
		m_entry->setField ( QString::fromLatin1 ( "abstract" ), abstractEdit->text() );
	if ( noteEdit->isShown() )
		m_entry->setField ( QString::fromLatin1 ( "comment" ), noteEdit->text() );
	
	m_entry->setField(QString::fromLatin1("lockkey"), lockkey);
	return m_entry;

}




/** No descriptions */
void KBibEditEntryDlg::slotCreateKey()
{
	KBibApp* win = ( KBibApp* ) this->parent();
	getBibEntry();
	if ( ( QString ( m_entry->getField ( "author" ) ).isEmpty() )  && ( QString ( m_entry->getField ( "editor" ) ).isEmpty() ) )
	{
		KMessageBox::error ( this, i18n ( "Author is empty.\nPlease correct it first. " ) );
		return;
	}
	m_entry->createKey ( ( ( win->kbibConfigState ).keyConnecting ).ascii() );

	//KBibListView *listView = (KBibListView *) parent();
	//QSplitter* vbox = (QSplitter*) listView->parent();


	QString fkey;
	char dletter='a';
	int oopscount=0;
	int idx;
	int this_id;

	fkey= m_entry->getKey();
	keyField->setText ( fkey );

	idx = win->searchKey ( fkey );

	this_id = m_entry->getIndex();

	if ( idx < 0 )
		return;

	if ( idx == this_id && idx >=0 )
	{
		idx = win->searchKey ( fkey, this_id+1 );
		if ( idx < 0 )
			return;

	}

	while ( 1 )
	{
		fkey= m_entry->getKey();
		for ( int j=0;j<oopscount;j++ )
			fkey+='x';
		fkey+=dletter;
		idx = win->searchKey ( fkey,0 );
		if ( idx < 0 )
		{
			m_entry->setKey ( fkey );
			keyField->setText ( fkey );
			break;
		}
		if ( idx == this_id && idx >= 0 )
		{
			idx = win->searchKey ( fkey, this_id+1 );
			if ( idx < 0 )
			{
				m_entry->setKey ( fkey );
				keyField->setText ( fkey );
				break;
			}
		}


		dletter++;
		if ( dletter=='z' )
		{
			oopscount++;
			dletter='a';
		}

	}
}



void KBibEditEntryDlg::slotLockKey()
{

	if ( QString ( m_entry->getField ( "lockkey" ) ) =="Y" )
	{
		//lockKeyBttn->setText("Lock Key");
		//QPixmap pix = KGlobal::iconLoader()->loadIcon(QString::fromLatin1("lock"), KIcon::Small);
		//lockKeyBttn->setPixmap(pix);
		lockKeyBttn->setIconSet ( QIconSet ( SmallIcon ( "lock" ) ) );
		QToolTip::add ( lockKeyBttn, QString ( i18n ( "Lock the citation key" ) ) );
		createKeyBttn->setEnabled ( true );
		keyField->setEnabled ( true );
		m_entry->setField ( "lockkey", "N" );
	}
	else
	{
		//lockKeyBttn->setText("Unlock Key");
		//QPixmap pix = KGlobal::iconLoader()->loadIcon(QString::fromLatin1("unlock"), KIcon::Small);
		//lockKeyBttn->setPixmap(pix);
		lockKeyBttn->setIconSet ( QIconSet ( SmallIcon ( "unlock" ) ) );
		QToolTip::add ( lockKeyBttn, QString ( i18n ( "Unlock the citation key" ) ) );
		createKeyBttn->setEnabled ( false );
		keyField->setEnabled ( false );
		m_entry->setField ( "lockkey", "Y" );
	}
	slotSetModified ( true );

}


void KBibEditEntryDlg::slotTabChanged ( void )
{

	if ( prevTabIndex == 4 )
	{

		QString str = sourceEdit->text();
		int dummy;
		BibEntry *tmp_entry = processBibEntryFromString ( str.ascii(), dummy );
		if ( !tmp_entry )
		{
			KMessageBox::error ( this, i18n ( "Errors in BibTeX source." ) );
			QString entryTypeName = m_entry->getEntryType();
			updateDlg ( entryTypeName );
			updateContent ( m_entry );
		}
		else
		{
			tmp_entry->setIndex ( m_entry->getIndex() );
			delete m_entry;
			m_entry = tmp_entry;
			QString entryTypeName =m_entry->getEntryType();

			entryTypeSelect->setCurrentText ( entryTypeName );
			updateDlg ( entryTypeName );
			updateContent ( m_entry );

		}

		prevTabIndex = mainTab->currentPageIndex();
	}

	else
	{
		if ( mainTab->currentPageIndex() == 4 )
		{
			getBibEntry();

			if ( m_entry )
			{
				KBibApp* win = ( KBibApp* ) this->parent();
				QString ld, rd;
				switch ( ( win->kbibConfigState ).fieldDelimiter )
				{
					case 1:
						rd = ld="\"";
						break;
					case 2:
						ld = "(";
						rd = ")";
						break;
					default:
						ld = "{";
						rd = "}";
						break;
				}

				QString st = QString();
				st=st+"@"+m_entry->getEntryType() +"{"+m_entry->getKey();
				for ( int j=0; j < m_entry-> getNoFields(); j++ )
				{
					if ( m_entry->stringMacroIndicator ( m_entry->getFieldName ( j ) ) )
						st=st+",\n\t"+m_entry->getFieldName ( j ) +"="+m_entry->getField ( j );
					else
						st=st+",\n\t"+m_entry->getFieldName ( j ) +"="+ld+m_entry->getField ( j ) +rd;
				}
				st=st+"\n}\n";
				sourceEdit->blockSignals(true);
				sourceEdit->setText ( st );
				sourceEdit->blockSignals(false);
			}
			prevTabIndex = mainTab->currentPageIndex();

		}
	}


}



void KBibEditEntryDlg::slotExtraFieldAdd()
{
	QCheckListItem *item = new QCheckListItem ( extraFieldView, extraFieldView->lastItem(),  "", QCheckListItem::CheckBox );
	item->setText ( 1, "FieldName" );
	item->setText ( 2, "Field Value" ) ;
	extraFieldView->ensureItemVisible ( item );
	extraFieldView->setSelected ( item, true );
	item->setRenameEnabled ( 1,true );
	item->setRenameEnabled ( 2,true );
	slotSetModified(true);
	updateExtraFieldGUI();
	slotExtraFieldEdit();

}
void KBibEditEntryDlg::slotExtraFieldEdit()
{
	QListViewItem* item = extraFieldView->selectedItem();
	if ( item )
	{
		item->startRename ( 1 );
		//		item->startRename(1);
		//updateGUI();
	}
}
void KBibEditEntryDlg::slotExtraFieldDelete()
{
	QListViewItem* item = extraFieldView->selectedItem();
	if ( item )
	{
		extraFieldView->takeItem ( item );
		updateExtraFieldGUI();
		slotSetModified(true);
	}
}


void KBibEditEntryDlg::slotExtraFielItemRenamed ( QListViewItem * item, int col, const QString & text )
{
	if ( text.isEmpty()  && item != NULL )
	{
		if ( ( col == 1 && ( item->text ( 2 ) ).isEmpty() ) || ( col == 2 && ( item->text ( 1 ) ).isEmpty() ) )
		{
			delete item;
			updateExtraFieldGUI();
		}
	}
	slotSetModified(true);
}

void KBibEditEntryDlg::updateExtraFieldGUI()
{
	QListViewItem* item = extraFieldView->selectedItem();
	if ( item )
	{
		extraFieldDeleteBtn->setEnabled ( true );
		extraFieldEditBtn->setEnabled ( true );

	}
	else
	{
		extraFieldDeleteBtn->setEnabled ( false );
		extraFieldEditBtn->setEnabled ( false );
	}
}

void KBibEditEntryDlg::slotSetModified ( bool modified )
{
	m_modified = modified;
}
